diff --git a/.vale.ini b/.vale.ini index 00b45f3b9..47b105bf1 100644 --- a/.vale.ini +++ b/.vale.ini @@ -21,6 +21,9 @@ Elements.SummaryImplementation = NO [NOTICE.md] BasedOnStyles = +[DESIGN.md] +BasedOnStyles = + [**/NOTICE.md] BasedOnStyles = diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 000000000..c2eb84a12 --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,269 @@ +--- +version: "alpha" +name: "NVIDIA Elements" +description: "The official design language and UI agent contract for NVIDIA Elements interfaces." +colors: + nve-sys-accent-primary-background: "oklch(66% 0.18 127)" + nve-sys-accent-secondary-background: "oklch(55% 0.2 250)" + nve-sys-accent-tertiary-background: "oklch(0% 0 0)" + nve-sys-contrast-emphasis-color: "oklch(100% 0 0)" + nve-sys-contrast-mute-color: "oklch(100% 0 0)" + nve-sys-interaction-background: "oklch(90% 0.006 248)" + nve-sys-interaction-background-100: "oklch(90% 0.006 248)" + nve-sys-interaction-background-200: "oklch(93% 0.006 248)" + nve-sys-interaction-background-300: "oklch(93% 0.006 248)" + nve-sys-interaction-color: "oklch(20% 0.006 248)" + nve-sys-interaction-destructive-background: "oklch(55% 0.19 18)" + nve-sys-interaction-destructive-color: "oklch(100% 0 0)" + nve-sys-interaction-disabled-background: "oklch(90% 0.006 248)" + nve-sys-interaction-disabled-color: "oklch(82% 0.006 248)" + nve-sys-interaction-emphasis-background: "oklch(66% 0.18 127)" + nve-sys-interaction-emphasis-color: "oklch(0% 0 0)" + nve-sys-interaction-field-background: "oklch(90% 0.006 248)" + nve-sys-interaction-field-background-100: "oklch(90% 0.006 248)" + nve-sys-interaction-field-background-200: "oklch(93% 0.006 248)" + nve-sys-interaction-field-background-300: "oklch(93% 0.006 248)" + nve-sys-interaction-field-color: "oklch(20% 0.006 248)" + nve-sys-interaction-highlighted-background: "oklch(91% 0.04 250)" + nve-sys-interaction-highlighted-color: "oklch(20% 0.006 248)" + nve-sys-interaction-highlighted-muted-background: "oklch(97% 0.02 250)" + nve-sys-interaction-hover-background: "oklch(90% 0.006 248)" + nve-sys-interaction-hover-color: "oklch(20% 0.006 248)" + nve-sys-interaction-selected-background: "oklch(90% 0.006 248)" + nve-sys-interaction-selected-color: "oklch(20% 0.006 248)" + nve-sys-interaction-state-base: "oklch(90% 0.006 248)" + nve-sys-interaction-state-mix: "oklch(20% 0.006 248)" + nve-sys-layer-backdrop-background: "oklch(0% 0 0 / 0.0588)" + nve-sys-layer-canvas-accent-background: "oklch(94% 0.006 248)" + nve-sys-layer-canvas-background: "oklch(95% 0.006 248)" + nve-sys-layer-canvas-color: "oklch(20% 0.006 248)" + nve-sys-layer-container-accent-background: "oklch(98% 0.006 248)" + nve-sys-layer-container-background: "oklch(100% 0 0)" + nve-sys-layer-container-color: "oklch(20% 0.006 248)" + nve-sys-layer-overlay-accent-background: "oklch(98% 0.006 248)" + nve-sys-layer-overlay-background: "oklch(100% 0 0)" + nve-sys-layer-overlay-color: "oklch(20% 0.006 248)" + nve-sys-layer-popover-accent-background: "oklch(53% 0.006 248)" + nve-sys-layer-popover-background: "oklch(20% 0.006 248)" + nve-sys-layer-popover-color: "oklch(100% 0 0)" + nve-sys-layer-shell-accent-background: "oklch(98% 0.006 248)" + nve-sys-layer-shell-background: "oklch(100% 0 0)" + nve-sys-layer-shell-color: "oklch(20% 0.006 248)" + nve-sys-scrollbar-thumb-color: "oklch(88% 0.006 248)" + nve-sys-scrollbar-track-color: "oklch(0% 0 0 / 0.0118)" + nve-sys-status-color: "oklch(60% 0.006 248)" + nve-sys-status-failed-color: "oklch(55% 0.19 18)" + nve-sys-status-finished-color: "oklch(52% 0.13 147)" + nve-sys-status-ignored-color: "oklch(53% 0.006 248)" + nve-sys-status-pending-color: "oklch(53% 0.006 248)" + nve-sys-status-queued-color: "oklch(47% 0.16 270)" + nve-sys-status-restarting-color: "oklch(54% 0.14 76)" + nve-sys-status-running-color: "oklch(54% 0.19 250)" + nve-sys-status-scheduled-color: "oklch(47% 0.16 292)" + nve-sys-status-starting-color: "oklch(53% 0.09 178)" + nve-sys-status-stopping-color: "oklch(56% 0.22 343)" + nve-sys-status-unknown-color: "oklch(0% 0 0)" + nve-sys-support-accent-color: "oklch(55% 0.2 250)" + nve-sys-support-accent-emphasis-color: "oklch(54% 0.19 250)" + nve-sys-support-accent-muted-color: "oklch(95% 0.03 250)" + nve-sys-support-color: "oklch(60% 0.006 248)" + nve-sys-support-danger-color: "oklch(55% 0.19 18)" + nve-sys-support-danger-emphasis-color: "oklch(55% 0.19 18)" + nve-sys-support-danger-muted-color: "oklch(93% 0.03 18)" + nve-sys-support-emphasis-color: "oklch(60% 0.006 248)" + nve-sys-support-muted-color: "oklch(90% 0.006 248)" + nve-sys-support-success-color: "oklch(52% 0.13 147)" + nve-sys-support-success-emphasis-color: "oklch(52% 0.13 147)" + nve-sys-support-success-muted-color: "oklch(94% 0.03 147)" + nve-sys-support-warning-color: "oklch(81% 0.17 95)" + nve-sys-support-warning-emphasis-color: "oklch(73% 0.15 95)" + nve-sys-support-warning-muted-color: "oklch(98% 0.05 95)" + nve-sys-text-black-color: "oklch(0% 0 0)" + nve-sys-text-color: "oklch(20% 0.006 248)" + nve-sys-text-emphasis-color: "oklch(20% 0.006 248)" + nve-sys-text-link-color: "oklch(20% 0.006 248)" + nve-sys-text-link-disabled-color: "oklch(94% 0.006 248)" + nve-sys-text-link-emphasis-color: "oklch(55% 0.2 250)" + nve-sys-text-link-hover-color: "oklch(54% 0.19 250)" + nve-sys-text-link-visited-color: "oklch(52% 0.18 310)" + nve-sys-text-muted-color: "oklch(53% 0.006 248)" + nve-sys-text-placeholder-color: "oklch(65% 0.006 248)" + nve-sys-text-white-color: "oklch(100% 0 0)" + nve-sys-visualization-categorical-amber: "oklch(78% 0.17 76)" + nve-sys-visualization-categorical-cyan: "oklch(72% 0.11 212)" + nve-sys-visualization-categorical-grass: "oklch(61% 0.14 147)" + nve-sys-visualization-categorical-lavender: "oklch(56% 0.18 310)" + nve-sys-visualization-categorical-nova: "oklch(81% 0.17 95)" + nve-sys-visualization-categorical-pear: "oklch(80% 0.2 125)" + nve-sys-visualization-categorical-pumpkin: "oklch(69% 0.19 51)" + nve-sys-visualization-categorical-red: "oklch(60% 0.2 18)" + nve-sys-visualization-categorical-rose: "oklch(61% 0.21 343)" + nve-sys-visualization-categorical-seafoam: "oklch(64% 0.11 183)" + nve-sys-visualization-categorical-slate: "oklch(60% 0.006 248)" + nve-sys-visualization-categorical-violet: "oklch(51% 0.17 292)" + nve-sys-visualization-sequential-diverging-red-green-100: "oklch(49.9% 0.159 23.4)" + nve-sys-visualization-sequential-diverging-red-green-200: "oklch(59.6% 0.195 23.8)" + nve-sys-visualization-sequential-diverging-red-green-300: "oklch(68.4% 0.193 22)" + nve-sys-visualization-sequential-diverging-red-green-400: "oklch(83.3% 0.083 18.1)" + nve-sys-visualization-sequential-diverging-red-green-500: "oklch(94% 0.006 248)" + nve-sys-visualization-sequential-diverging-red-green-600: "oklch(86.4% 0.117 148.8)" + nve-sys-visualization-sequential-diverging-red-green-700: "oklch(72.5% 0.176 148.7)" + nve-sys-visualization-sequential-diverging-red-green-800: "oklch(62.7% 0.157 148.3)" + nve-sys-visualization-sequential-diverging-red-green-900: "oklch(47.5% 0.109 150.4)" + nve-sys-visualization-sequential-diverging-virdis-100: "oklch(91.8% 0.187 102.2)" + nve-sys-visualization-sequential-diverging-virdis-1000: "oklch(49.1% 0.083 242.3)" + nve-sys-visualization-sequential-diverging-virdis-1100: "oklch(45.3% 0.094 261.6)" + nve-sys-visualization-sequential-diverging-virdis-1200: "oklch(41.9% 0.108 278.7)" + nve-sys-visualization-sequential-diverging-virdis-1300: "oklch(37.1% 0.124 293.4)" + nve-sys-visualization-sequential-diverging-virdis-1400: "oklch(33.3% 0.134 306.3)" + nve-sys-visualization-sequential-diverging-virdis-1500: "oklch(27.6% 0.132 318.4)" + nve-sys-visualization-sequential-diverging-virdis-200: "oklch(85.9% 0.19 115)" + nve-sys-visualization-sequential-diverging-virdis-300: "oklch(82.1% 0.194 126.8)" + nve-sys-visualization-sequential-diverging-virdis-400: "oklch(77.5% 0.187 137.2)" + nve-sys-visualization-sequential-diverging-virdis-500: "oklch(73.4% 0.164 147.5)" + nve-sys-visualization-sequential-diverging-virdis-600: "oklch(69.1% 0.145 157.3)" + nve-sys-visualization-sequential-diverging-virdis-700: "oklch(64.6% 0.12 169.6)" + nve-sys-visualization-sequential-diverging-virdis-800: "oklch(60.2% 0.1 184.4)" + nve-sys-visualization-sequential-diverging-virdis-900: "oklch(56.8% 0.087 200.1)" + nve-sys-visualization-trend-negative-color: "oklch(60% 0.2 18)" + nve-sys-visualization-trend-negative-emphasis-color: "oklch(55% 0.19 18)" + nve-sys-visualization-trend-positive-color: "oklch(61% 0.14 147)" + nve-sys-visualization-trend-positive-emphasis-color: "oklch(52% 0.13 147)" +typography: + display-xl: + fontFamily: "'Inter', Roboto, 'Open Sans', 'Helvetica Neue', sans-serif" + fontSize: "50px" + fontWeight: 400 + lineHeight: "1.12" + display: + fontFamily: "'Inter', Roboto, 'Open Sans', 'Helvetica Neue', sans-serif" + fontSize: "40px" + fontWeight: 400 + lineHeight: "1.12" + heading: + fontFamily: "'Inter', Roboto, 'Open Sans', 'Helvetica Neue', sans-serif" + fontSize: "24px" + fontWeight: 600 + lineHeight: "1.25" + body: + fontFamily: "'Inter', Roboto, 'Open Sans', 'Helvetica Neue', sans-serif" + fontSize: "14px" + fontWeight: 400 + lineHeight: "1.375" + label: + fontFamily: "'Inter', Roboto, 'Open Sans', 'Helvetica Neue', sans-serif" + fontSize: "14px" + fontWeight: 500 + lineHeight: "1.375" + code: + fontFamily: "'Roboto Mono', 'Lucida Console', Monaco, monospace, sans-serif" + fontSize: "14px" + fontWeight: 400 + lineHeight: "1.5" +rounded: + none: "0px" + xs: "4px" + sm: "6px" + md: "8px" + lg: "14px" + full: "999px" +spacing: + none: "0px" + xs: "8px" + sm: "12px" + md: "16px" + lg: "24px" + xl: "32px" + xxl: "48px" +--- + +## Overview + +NVIDIA Elements is the design system and framework-agnostic Web Component system for operational interfaces across AI/ML infrastructure, robotics, and autonomous vehicle tooling. + +This is the official DESIGN.md for NVIDIA Elements. It describes the Elements product UI system, not the visual identity of every NVIDIA website or product. Use the exact `nve-*` component APIs, semantic CSS custom properties, examples, and accessibility behavior documented at [https://nvidia.github.io/elements/](https://nvidia.github.io/elements/). + +Build with Elements before creating custom UI. Install `@nvidia-elements/themes`, `@nvidia-elements/styles`, `@nvidia-elements/core`, `@nvidia-elements/cli` and the required component packages, or run `nve project.setup` to configure an existing project. Agents can query component APIs, examples, tokens, icons, and project validation through the [Elements CLI](https://nvidia.github.io/elements/docs/cli/) and [MCP server](https://nvidia.github.io/elements/docs/mcp/). + +## Colors + +The front matter exposes the complete light-theme baseline for shipped `nve-sys-*` color tokens. Each key uses the canonical Elements token name. In application CSS, prefix that key with `--`: for example, `{colors.nve-sys-layer-canvas-background}` corresponds to `--nve-sys-layer-canvas-background`. Use the custom property instead of copying its resolved front matter value so light, dark, high-contrast, and user-defined themes continue to work. + +- `nve-sys-accent-*` identifies primary, secondary, and tertiary accents. +- `nve-sys-layer-*` pairs canvas, shell, container, overlay, and popover backgrounds with their content colors. +- `nve-sys-text-*` provides default, muted, emphasis, placeholder, and link roles. +- `nve-sys-interaction-*` describes control surfaces and their emphasis, destructive, disabled, hover, selected, highlighted, and field states. +- `nve-sys-support-*` and `nve-sys-status-*` communicate semantic and operational states. Never rely on color alone; pair status color with text and an icon when appropriate. +- `nve-sys-visualization-*` provides categorical, sequential, diverging, and trend colors for data graphics. +- `nve-sys-contrast-*` and `nve-sys-scrollbar-*` support contrast composition and native scroll bar styling. + +Use the [design token reference](https://nvidia.github.io/elements/docs/foundations/themes/tokens/) for the complete token inventory and current CSS custom-property names. + +## Typography + +Inter is the primary interface typeface. Reserve `Roboto Mono` for code, identifiers, logs, metrics, and other content where character distinction matters. The compact scale helps operational applications present dense information without sacrificing legibility. + +- Use `{typography.display}` sparingly for page-level moments. +- Use `{typography.heading}` to organize content; do not choose heading markup for visual size alone. +- Use `{typography.body}` for most interface copy. Apply documented `nve-text` size variants when copy needs more emphasis. +- Use `{typography.label}` for controls, metadata, and compact navigation. +- Use `{typography.code}` for source code and machine-oriented values. + +Apply the `nve-text` utilities documented in the [typography foundation](https://nvidia.github.io/elements/docs/foundations/typography/) while preserving semantic HTML headings, labels, lists, and paragraphs. + +## Layout + +Prefer the `nve-layout` attribute utilities on semantic native elements. + +- Use `row` for toolbars, action groups, and horizontal navigation. +- Use `column` for forms, panels, page sections, and reading order. +- Use `grid` for dashboards, galleries, and responsive multi-column content. +- Start with a single-column small-screen layout, then add container or viewport adaptations. +- Keep the DOM order meaningful. Visual reordering must not break reading or keyboard order. + +See the [layout foundation](https://nvidia.github.io/elements/docs/foundations/layout/) for supported gap, padding, alignment, grid, and responsive patterns. + +## Elevation & Depth + +Layer roles communicate depth. Canvas holds the application background, containers group durable content, overlays sit above containers, and popovers represent temporary top-layer UI. Prefer layer backgrounds, borders, and restrained shadows over ornamental effects. + +Use elevation only when it explains containment or interaction. Dialogs, menus, tooltips, and transient panels must use the native top-layer patterns documented by Elements. Avoid decorative glass effects, large ambient shadows, and gradients that reduce text or status contrast. + +## Shapes + +The radius scale ranges from square `{rounded.none}` surfaces through `{rounded.lg}` containers. Standard controls use `{rounded.sm}`; cards and panels commonly use `{rounded.md}`. Reserve `{rounded.full}` for badges, tags, avatars, and other intentionally pill-shaped or circular objects. + +Do not introduce arbitrary radii when an Elements radius token fits. Consistent geometry helps dense application surfaces read as one system. + +## Components + +Use existing `nve-*` Custom Elements and their documented composition patterns before creating replacements. The component tokens in the front matter summarize common visual roles; the live API documentation remains normative for properties, events, slots, CSS parts, accessibility, and behavior. + +- All APIs available as [llms.txt](https://nvidia.github.io/elements/llms.txt) +- Use [nve-button](https://nvidia.github.io/elements/docs/elements/button/) and [nve-icon-button](https://nvidia.github.io/elements/docs/elements/icon-button/) for actions. +- Use [nve-input](https://nvidia.github.io/elements/docs/elements/input/), [nve-select](https://nvidia.github.io/elements/docs/elements/select/), and the form guidance for data entry. +- Use [nve-card](https://nvidia.github.io/elements/docs/elements/card/) and [nve-page](https://nvidia.github.io/elements/docs/elements/page/) for durable content structure. +- Use [nve-alert](https://nvidia.github.io/elements/docs/elements/alert/), badges, and notifications for status communication. +- Use [nve-dialog](https://nvidia.github.io/elements/docs/elements/dialog/), dropdowns, tooltips, and toggletips for temporary top-layer interaction. +- Use the [data grid](https://nvidia.github.io/elements/docs/elements/data-grid/) for interactive tabular data rather than recreating sorting, selection, pagination, or keyboard navigation. + +Import component `define.js` entrypoints explicitly unless the project intentionally uses a bundle. Compose through public slots and attributes; do not reach into component shadow roots or depend on undocumented internals. + +## Do and Don't + +**Do** + +- Start from Elements components, semantic tokens, examples, and patterns. +- Preserve semantic HTML, keyboard access, focus visibility, labels, and accessible names. +- Use semantic `--nve-sys-*` tokens in application CSS so themes continue to work. +- Keep operational content concise, scannable, and explicit about state. +- Check generated UI with the Elements lint tooling and relevant accessibility tests. +- Query the CLI or MCP server when an API, icon name, token, or example is uncertain. + +**Don't** + +- Recreate an Elements component with generic HTML when the maintained component already fits. +- Hard-code resolved colors, spacing, or typography values in production application CSS. +- Encode meaning through color, position, animation, or iconography alone. +- Add gradients, glass effects, oversized radii, or decorative shadows without a product need. +- Invent component properties, slots, events, CSS parts, token names, or icon names. diff --git a/README.md b/README.md index 9172be376..9406eb558 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ NVIDIA Design System and UI Agent Harness for AI/ML Factories, Robotics, and Aut - [Contribution Guidelines](https://NVIDIA.github.io/elements/docs/about/contributions/) - [Feature request](https://github.com/NVIDIA/elements/issues/new?issuable_template=feature) - [Bug report](https://github.com/NVIDIA/elements/issues/new?issuable_template=default) +- [Official NVIDIA Elements DESIGN.md](https://NVIDIA.github.io/elements/docs/design-md/) ## Organization diff --git a/package.json b/package.json index 61ee5b79d..2f3702369 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "./projects/starters/vue:ci", "./projects/styles:ci", "./projects/themes:ci", + "./projects/internals/design:ci", "./projects/internals/metadata:ci", "./projects/internals/patterns:ci", "./projects/internals/testing:ci", @@ -262,6 +263,7 @@ "./projects/create:lint:fix", "./projects/core:lint:fix", "./projects/forms:lint:fix", + "./projects/internals/design:lint:fix", "./projects/internals/metadata:lint:fix", "./projects/internals/patterns:lint:fix", "./projects/internals/testing:lint:fix", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d36efb0c1..298015902 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -788,6 +788,24 @@ importers: specifier: 'catalog:' version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-istanbul@4.1.10)(jsdom@28.1.0)(vite@8.1.4(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.16))(terser@5.48.0)(yaml@2.9.0)) + projects/internals/design: + devDependencies: + '@google/design.md': + specifier: 0.4.0 + version: 0.4.0 + '@internals/eslint': + specifier: workspace:* + version: link:../eslint + '@nvidia-elements/themes': + specifier: workspace:* + version: link:../../themes + eslint: + specifier: 10.6.0 + version: 10.6.0(jiti@2.7.0) + vitest: + specifier: 'catalog:' + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/browser-playwright@4.1.10)(@vitest/coverage-istanbul@4.1.10)(jsdom@28.1.0)(vite@8.1.4(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.16))(terser@5.48.0)(yaml@2.9.0)) + projects/internals/eslint: dependencies: '@eslint/css': @@ -3269,6 +3287,11 @@ packages: '@github/catalyst@1.8.1': resolution: {integrity: sha512-dnN4WWpbeuQvA17LvsGdlXEueJdBk9y+I+WO5pdNpoHNOXPsFcz3hJrq1iRmdsNgQOf4S8e83axtwIxvG62eWA==} + '@google/design.md@0.4.0': + resolution: {integrity: sha512-7aNIv6hslxIZ9igXq1abbVu+ue/ft/oFMUrAuhzpVFijGr9v+l0CkkCBQsHozucNiZHIBS43XC6l8gYDZRys9Q==} + engines: {node: '>=18.0.0'} + hasBin: true + '@gwhitney/detect-indent@7.0.1': resolution: {integrity: sha512-7bQW+gkKa2kKZPeJf6+c6gFK9ARxQfn+FKy9ScTBppyKRWH2KzsmweXUoklqeEiHiNVWaeP5csIdsNq6w7QhzA==} engines: {node: '>=12.20'} @@ -6292,6 +6315,9 @@ packages: '@types/css-tree@2.3.11': resolution: {integrity: sha512-aEokibJOI77uIlqoBOkVbaQGC9zII0A+JH1kcTNKW2CwyYWD8KM6qdo+4c77wD3wZOQfJuNWAr9M4hdk+YhDIg==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -6304,12 +6330,18 @@ packages: '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/hast@3.0.5': + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} + '@types/jsesc@2.5.1': resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} @@ -6319,6 +6351,12 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/mysql@2.15.26': resolution: {integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==} @@ -6360,6 +6398,12 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/web@0.0.312': resolution: {integrity: sha512-dh5IM+N4QS9Nkoq6ZLaTx8vaqUUfC9j8yIGhmYvlc/V19hfAvMjE+LjBHlWCf92nYIz4ZE352I7GrVWh5NBRuw==} @@ -7231,6 +7275,9 @@ packages: solid-js: optional: true + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -7442,6 +7489,9 @@ packages: caniuse-lite@1.0.30001790: resolution: {integrity: sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==} + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} @@ -7469,6 +7519,18 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} @@ -8113,6 +8175,9 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -8181,6 +8246,9 @@ packages: devalue@5.8.1: resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + devtools-protocol@0.0.1527314: resolution: {integrity: sha512-UohCFOlzpPPD/IcsxM0k4lVZp/GfhPVJ6l2No5XX+LknpGisPWJe17oOHQhZTHf6ThUFIMwHO6bSEZUq/6oP7w==} @@ -8559,6 +8627,12 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -8638,6 +8712,9 @@ packages: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -8694,6 +8771,9 @@ packages: fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + fd-package-json@2.0.0: resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} @@ -8811,6 +8891,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + formatly@0.3.0: resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} engines: {node: '>=18.3.0'} @@ -9451,6 +9535,9 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-in-ssh@1.0.0: resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} engines: {node: '>=20'} @@ -10078,6 +10165,9 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + lookup-closest-locale@6.2.0: resolution: {integrity: sha512-/c2kL+Vnp1jnV6K6RpDTHK3dgg0Tu2VVp+elEiJpjfS1UyY7AjOYHohRug6wT0OpoX2qFgNORndE9RqesfVxWQ==} @@ -10168,6 +10258,33 @@ packages: mathml-tag-names@4.0.0: resolution: {integrity: sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==} + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdn-data@2.0.28: resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} @@ -10216,6 +10333,93 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -10910,6 +11114,9 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-imports-exports@0.2.4: resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} @@ -11920,6 +12127,18 @@ packages: resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} engines: {node: '>= 0.10'} + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + replace-in-file@7.2.0: resolution: {integrity: sha512-CiLXVop3o8/h2Kd1PwKPPimmS9wUV0Ki6Fl8+1ITD35nB3Gl/PrW5IONpTE0AXk0z4v8WYcpEpdeZqMXvSnWpg==} engines: {node: '>=10'} @@ -12496,6 +12715,9 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -12897,6 +13119,9 @@ packages: peerDependencies: tslib: '2' + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-api-utils@2.5.0: resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} @@ -13072,6 +13297,9 @@ packages: resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} engines: {node: '>=20'} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + unimport@6.2.0: resolution: {integrity: sha512-4NcqaphAHQff4eBWQ3pjVOCYNLlmVGGMoLDmboobh8+OQe9yP7UyeoMP043M1bG0YNc3CqtukD2VuINxOqm4rQ==} engines: {node: '>=18.12.0'} @@ -13101,6 +13329,21 @@ packages: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} engines: {node: '>=12'} + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} @@ -13276,6 +13519,12 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-dev-rpc@1.1.0: resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} peerDependencies: @@ -13867,6 +14116,9 @@ packages: zod@4.4.3: resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: 3d-force-graph@1.79.0: @@ -15072,6 +15324,20 @@ snapshots: '@github/catalyst@1.8.1': {} + '@google/design.md@0.4.0': + dependencies: + citty: 0.1.6 + remark-frontmatter: 5.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + yaml: 2.9.0 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + '@gwhitney/detect-indent@7.0.1': {} '@harperfast/extended-iterable@1.0.3': @@ -18023,6 +18289,10 @@ snapshots: '@types/css-tree@2.3.11': {} + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} '@types/eslint-scope@3.7.7': @@ -18037,16 +18307,30 @@ snapshots: '@types/esrecurse@4.3.1': {} + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.9 + '@types/estree@1.0.8': {} '@types/estree@1.0.9': {} + '@types/hast@3.0.5': + dependencies: + '@types/unist': 3.0.3 + '@types/jsesc@2.5.1': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + '@types/mysql@2.15.26': dependencies: '@types/node': 25.9.3 @@ -18093,6 +18377,10 @@ snapshots: '@types/trusted-types@2.0.7': {} + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + '@types/web@0.0.312': {} '@types/yargs-parser@21.0.3': {} @@ -19188,6 +19476,8 @@ snapshots: optionalDependencies: solid-js: 1.9.12 + bail@2.0.2: {} + balanced-match@1.0.2: {} balanced-match@3.0.1: {} @@ -19440,6 +19730,8 @@ snapshots: caniuse-lite@1.0.30001790: {} + ccount@2.0.1: {} + chai@6.2.2: {} chalk@2.4.2: @@ -19461,6 +19753,14 @@ snapshots: char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + chardet@2.1.1: {} chart.js@4.5.1: @@ -20135,6 +20435,10 @@ snapshots: decimal.js@10.6.0: {} + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -20186,6 +20490,10 @@ snapshots: devalue@5.8.1: {} + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + devtools-protocol@0.0.1527314: {} devtools-protocol@0.0.1595872: {} @@ -20705,6 +21013,13 @@ snapshots: estraverse@5.3.0: {} + estree-util-is-identifier-name@3.0.0: {} + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -20824,6 +21139,8 @@ snapshots: dependencies: is-extendable: 0.1.1 + extend@3.0.2: {} + extract-zip@2.0.1: dependencies: debug: 4.4.3 @@ -20882,6 +21199,10 @@ snapshots: dependencies: reusify: 1.1.0 + fault@2.0.1: + dependencies: + format: 0.2.2 + fd-package-json@2.0.0: dependencies: walk-up-path: 4.0.0 @@ -21016,6 +21337,8 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + format@0.2.2: {} + formatly@0.3.0: dependencies: fd-package-json: 2.0.0 @@ -21679,6 +22002,8 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} + is-in-ssh@1.0.0: {} is-inside-container@1.0.0: @@ -22363,6 +22688,8 @@ snapshots: strip-ansi: 7.2.0 wrap-ansi: 9.0.2 + longest-streak@3.1.0: {} + lookup-closest-locale@6.2.0: {} lower-case@2.0.2: @@ -22476,6 +22803,104 @@ snapshots: mathml-tag-names@4.0.0: {} + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdn-data@2.0.28: {} mdn-data@2.27.1: {} @@ -22519,6 +22944,219 @@ snapshots: merge2@1.4.1: {} + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.9 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.9 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -23532,6 +24170,16 @@ snapshots: dependencies: callsites: 3.1.0 + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-imports-exports@0.2.4: dependencies: parse-statements: 1.0.11 @@ -23616,7 +24264,7 @@ snapshots: semver: 7.8.5 slash: 2.0.0 tmp: 0.2.6 - yaml: 2.8.3 + yaml: 2.9.0 path-browserify@1.0.1: {} @@ -24530,6 +25178,37 @@ snapshots: relateurl@0.2.7: {} + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + replace-in-file@7.2.0: dependencies: chalk: 4.1.2 @@ -25297,6 +25976,11 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -25729,6 +26413,8 @@ snapshots: dependencies: tslib: 2.8.1 + trough@2.2.0: {} + ts-api-utils@2.5.0(typescript@6.0.3): dependencies: typescript: 6.0.3 @@ -25916,6 +26602,16 @@ snapshots: unicorn-magic@0.4.0: {} + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + unimport@6.2.0(oxc-parser@0.133.0): dependencies: acorn: 8.17.0 @@ -25963,6 +26659,29 @@ snapshots: dependencies: crypto-random-string: 4.0.0 + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + universal-user-agent@7.0.3: {} universalify@2.0.1: {} @@ -26096,6 +26815,16 @@ snapshots: vary@1.1.2: {} + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + vite-dev-rpc@1.1.0(vite@8.1.4(@types/node@25.9.3)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.99.0)(sugarss@5.0.1(postcss@8.5.16))(terser@5.48.0)(yaml@2.9.0)): dependencies: birpc: 2.9.0 @@ -26865,3 +27594,5 @@ snapshots: zod@4.4.2: {} zod@4.4.3: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b7b12c6d6..c200126b7 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -33,6 +33,7 @@ packages: - projects/forms - projects/styles - projects/themes + - projects/internals/design - projects/internals/eslint - projects/internals/metadata - projects/internals/patterns @@ -126,6 +127,7 @@ minimumReleaseAgeExclude: - publint - typescript - vite + - '@google/design.md@0.4.0' allowBuilds: '@modelcontextprotocol/ext-apps': true diff --git a/projects/internals/design/README.md b/projects/internals/design/README.md new file mode 100644 index 000000000..83821e079 --- /dev/null +++ b/projects/internals/design/README.md @@ -0,0 +1,11 @@ +# Elements design artifacts + +This private workspace project owns build-time design analysis and generated artifacts that describe the NVIDIA Elements design system as a whole. + +## DESIGN.md + +`src/design-md.js` resolves maintained Elements theme tokens and combines them with reviewed design and component guidance. The build writes the result to `dist/DESIGN.md`. + +Run `pnpm build` to generate the internal artifact. Run `pnpm sync:root` when an intentional generator change should update the checked-in `DESIGN.md` at the repository root. + +Tests verify that the built and repository artifacts match the generator. The site consumes the built artifact and publishes it at `/DESIGN.md`. diff --git a/projects/internals/design/eslint.config.js b/projects/internals/design/eslint.config.js new file mode 100644 index 000000000..024a3da4a --- /dev/null +++ b/projects/internals/design/eslint.config.js @@ -0,0 +1,13 @@ +import { nodeJavaScriptConfig } from '@internals/eslint'; + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + ...nodeJavaScriptConfig, + { + files: ['src/design-md.js'], + rules: { + 'max-lines': 'off', + 'max-lines-per-function': 'off' + } + } +]; diff --git a/projects/internals/design/package.json b/projects/internals/design/package.json new file mode 100644 index 000000000..286f150e2 --- /dev/null +++ b/projects/internals/design/package.json @@ -0,0 +1,106 @@ +{ + "name": "@internals/design", + "version": "0.0.0", + "private": true, + "description": "Build-time analysis and generated design artifacts for NVIDIA Elements.", + "type": "module", + "scripts": { + "ci": "wireit", + "build": "wireit", + "sync:root": "wireit", + "lint": "wireit", + "lint:fix": "wireit", + "test": "wireit", + "test:spec": "wireit" + }, + "exports": { + "./DESIGN.md": "./dist/DESIGN.md" + }, + "devDependencies": { + "@google/design.md": "0.4.0", + "@internals/eslint": "workspace:*", + "@nvidia-elements/themes": "workspace:*", + "eslint": "catalog:", + "vitest": "catalog:" + }, + "wireit": { + "ci": { + "dependencies": [ + "lint", + "test" + ] + }, + "build": { + "command": "node ./scripts/write-design-md.js dist/DESIGN.md", + "files": [ + "src/design-md.js", + "scripts/write-design-md.js", + "../../themes/dist/index.json", + "package.json" + ], + "output": [ + "dist/DESIGN.md" + ], + "dependencies": [ + { + "script": "../../themes:build", + "cascade": false + } + ] + }, + "sync:root": { + "command": "node ./scripts/write-design-md.js ../../../DESIGN.md", + "files": [ + "src/design-md.js", + "../../themes/dist/index.json" + ], + "output": [ + "./dist/DESIGN.md" + ], + "dependencies": [ + "build" + ] + }, + "lint": { + "command": "eslint -c ./eslint.config.js --color --cache --cache-location .eslintcache/", + "files": [ + "src/**/*.js", + "src/**/*.ts", + "scripts/**/*.js", + "eslint.config.js" + ], + "output": [], + "dependencies": [ + "../eslint:ci" + ] + }, + "lint:fix": { + "command": "eslint -c ./eslint.config.js --fix", + "dependencies": [ + "../eslint:ci" + ] + }, + "test": { + "command": "vitest run", + "files": [ + "dist/DESIGN.md", + "src/**/*.test.js" + ], + "output": [], + "dependencies": [ + "build", + "test:spec" + ] + }, + "test:spec": { + "command": "designmd lint dist/DESIGN.md", + "files": [ + "dist/DESIGN.md" + ], + "output": [], + "dependencies": [ + "build" + ] + } + } +} diff --git a/projects/internals/design/scripts/write-design-md.js b/projects/internals/design/scripts/write-design-md.js new file mode 100644 index 000000000..45cc5fffc --- /dev/null +++ b/projects/internals/design/scripts/write-design-md.js @@ -0,0 +1,8 @@ +import { promises as fsp } from 'node:fs'; +import nodePath from 'node:path'; +import { createDesignMdContent } from '../src/design-md.js'; + +const outputPath = nodePath.resolve(process.argv[2] ?? 'dist/DESIGN.md'); + +await fsp.mkdir(nodePath.dirname(outputPath), { recursive: true }); +await fsp.writeFile(outputPath, createDesignMdContent(), 'utf-8'); diff --git a/projects/internals/design/src/design-md.js b/projects/internals/design/src/design-md.js new file mode 100644 index 000000000..ecd999900 --- /dev/null +++ b/projects/internals/design/src/design-md.js @@ -0,0 +1,234 @@ +import themeTokens from '@nvidia-elements/themes/index.json' with { type: 'json' }; + +const SITE_URL = 'https://nvidia.github.io/elements'; + +const CSS_COLOR_PATTERN = /^(?:#|(?:color|color-mix|hsl|hsla|lab|lch|oklab|oklch|rgb|rgba)\()/i; + +const TYPOGRAPHY_TOKENS = { + 'display-xl': { + fontFamily: 'nve-ref-font-family-inter', + fontSize: 'nve-ref-font-size-1200', + fontWeight: 'nve-ref-font-weight-regular', + lineHeight: 'nve-ref-font-line-height-tight' + }, + display: { + fontFamily: 'nve-ref-font-family-inter', + fontSize: 'nve-ref-font-size-1000', + fontWeight: 'nve-ref-font-weight-regular', + lineHeight: 'nve-ref-font-line-height-tight' + }, + heading: { + fontFamily: 'nve-ref-font-family-inter', + fontSize: 'nve-ref-font-size-600', + fontWeight: 'nve-ref-font-weight-semibold', + lineHeight: 'nve-ref-font-line-height-snug' + }, + body: { + fontFamily: 'nve-ref-font-family-inter', + fontSize: 'nve-ref-font-size-200', + fontWeight: 'nve-ref-font-weight-regular', + lineHeight: 'nve-ref-font-line-height-moderate' + }, + label: { + fontFamily: 'nve-ref-font-family-inter', + fontSize: 'nve-ref-font-size-200', + fontWeight: 'nve-ref-font-weight-medium', + lineHeight: 'nve-ref-font-line-height-moderate' + }, + code: { + fontFamily: 'nve-ref-font-family-roboto-mono', + fontSize: 'nve-ref-font-size-200', + fontWeight: 'nve-ref-font-weight-regular', + lineHeight: 'nve-ref-font-line-height-relaxed' + } +}; + +const ROUNDED_TOKENS = { + none: 'nve-ref-border-radius-none', + xs: 'nve-ref-border-radius-xs', + sm: 'nve-ref-border-radius-sm', + md: 'nve-ref-border-radius-md', + lg: 'nve-ref-border-radius-lg', + full: 'nve-ref-border-radius-full' +}; + +const SPACING_TOKENS = { + none: 'nve-ref-space-none', + xs: 'nve-ref-space-xs', + sm: 'nve-ref-space-sm', + md: 'nve-ref-space-md', + lg: 'nve-ref-space-lg', + xl: 'nve-ref-space-xl', + xxl: 'nve-ref-space-xxl' +}; + +function resolveTokenValue(tokenName, resolving = new Set()) { + if (resolving.has(tokenName)) { + throw new Error(`Circular NVIDIA Elements token reference: ${tokenName}`); + } + + const value = themeTokens[tokenName]; + if (value === undefined) { + throw new Error(`Unknown NVIDIA Elements token: ${tokenName}`); + } + + if (themeTokens[value] !== undefined) { + resolving.add(tokenName); + const resolved = resolveTokenValue(value, resolving); + resolving.delete(tokenName); + return resolved; + } + + const product = /^(\S+)\s+\*\s+(-?\d+(?:\.\d+)?)([a-z%]+)$/i.exec(value); + if (product && themeTokens[product[1]] !== undefined) { + resolving.add(tokenName); + const scale = Number(resolveTokenValue(product[1], resolving)); + resolving.delete(tokenName); + return `${scale * Number(product[2])}${product[3]}`; + } + + return value; +} + +function getSemanticColorTokens() { + return Object.fromEntries( + Object.keys(themeTokens) + .filter(tokenName => tokenName.startsWith('nve-sys-')) + .filter(tokenName => CSS_COLOR_PATTERN.test(String(resolveTokenValue(tokenName)).trim())) + .sort() + .map(tokenName => [tokenName, tokenName]) + ); +} + +function yamlScalar(value) { + return typeof value === 'number' ? String(value) : JSON.stringify(value); +} + +function renderSimpleTokenGroup(name, mapping) { + return [ + `${name}:`, + ...Object.entries(mapping).map(([tokenName, sourceToken]) => { + return ` ${tokenName}: ${yamlScalar(resolveTokenValue(sourceToken))}`; + }) + ].join('\n'); +} + +function renderTypography() { + const lines = ['typography:']; + for (const [tokenName, properties] of Object.entries(TYPOGRAPHY_TOKENS)) { + lines.push(` ${tokenName}:`); + for (const [propertyName, sourceToken] of Object.entries(properties)) { + const value = resolveTokenValue(sourceToken); + lines.push(` ${propertyName}: ${yamlScalar(propertyName === 'fontWeight' ? Number(value) : value)}`); + } + } + return lines.join('\n'); +} + +export function createDesignMdContent() { + const frontMatter = [ + '---', + 'version: "alpha"', + 'name: "NVIDIA Elements"', + 'description: "The official design language and UI agent contract for NVIDIA Elements interfaces."', + renderSimpleTokenGroup('colors', getSemanticColorTokens()), + renderTypography(), + renderSimpleTokenGroup('rounded', ROUNDED_TOKENS), + renderSimpleTokenGroup('spacing', SPACING_TOKENS), + '---' + ].join('\n'); + + return `${frontMatter} + +## Overview + +NVIDIA Elements is the design system and framework-agnostic Web Component system for operational interfaces across AI/ML infrastructure, robotics, and autonomous vehicle tooling. + +This is the official DESIGN.md for NVIDIA Elements. It describes the Elements product UI system, not the visual identity of every NVIDIA website or product. Use the exact \`nve-*\` component APIs, semantic CSS custom properties, examples, and accessibility behavior documented at [${SITE_URL}/](${SITE_URL}/). + +Build with Elements before creating custom UI. Install \`@nvidia-elements/themes\`, \`@nvidia-elements/styles\`, \`@nvidia-elements/core\`, \`@nvidia-elements/cli\` and the required component packages, or run \`nve project.setup\` to configure an existing project. Agents can query component APIs, examples, tokens, icons, and project validation through the [Elements CLI](${SITE_URL}/docs/cli/) and [MCP server](${SITE_URL}/docs/mcp/). + +## Colors + +The front matter exposes the complete light-theme baseline for shipped \`nve-sys-*\` color tokens. Each key uses the canonical Elements token name. In application CSS, prefix that key with \`--\`: for example, \`{colors.nve-sys-layer-canvas-background}\` corresponds to \`--nve-sys-layer-canvas-background\`. Use the custom property instead of copying its resolved front matter value so light, dark, high-contrast, and user-defined themes continue to work. + +- \`nve-sys-accent-*\` identifies primary, secondary, and tertiary accents. +- \`nve-sys-layer-*\` pairs canvas, shell, container, overlay, and popover backgrounds with their content colors. +- \`nve-sys-text-*\` provides default, muted, emphasis, placeholder, and link roles. +- \`nve-sys-interaction-*\` describes control surfaces and their emphasis, destructive, disabled, hover, selected, highlighted, and field states. +- \`nve-sys-support-*\` and \`nve-sys-status-*\` communicate semantic and operational states. Never rely on color alone; pair status color with text and an icon when appropriate. +- \`nve-sys-visualization-*\` provides categorical, sequential, diverging, and trend colors for data graphics. +- \`nve-sys-contrast-*\` and \`nve-sys-scrollbar-*\` support contrast composition and native scroll bar styling. + +Use the [design token reference](${SITE_URL}/docs/foundations/themes/tokens/) for the complete token inventory and current CSS custom-property names. + +## Typography + +Inter is the primary interface typeface. Reserve \`Roboto Mono\` for code, identifiers, logs, metrics, and other content where character distinction matters. The compact scale helps operational applications present dense information without sacrificing legibility. + +- Use \`{typography.display}\` sparingly for page-level moments. +- Use \`{typography.heading}\` to organize content; do not choose heading markup for visual size alone. +- Use \`{typography.body}\` for most interface copy. Apply documented \`nve-text\` size variants when copy needs more emphasis. +- Use \`{typography.label}\` for controls, metadata, and compact navigation. +- Use \`{typography.code}\` for source code and machine-oriented values. + +Apply the \`nve-text\` utilities documented in the [typography foundation](${SITE_URL}/docs/foundations/typography/) while preserving semantic HTML headings, labels, lists, and paragraphs. + +## Layout + +Prefer the \`nve-layout\` attribute utilities on semantic native elements. + +- Use \`row\` for toolbars, action groups, and horizontal navigation. +- Use \`column\` for forms, panels, page sections, and reading order. +- Use \`grid\` for dashboards, galleries, and responsive multi-column content. +- Start with a single-column small-screen layout, then add container or viewport adaptations. +- Keep the DOM order meaningful. Visual reordering must not break reading or keyboard order. + +See the [layout foundation](${SITE_URL}/docs/foundations/layout/) for supported gap, padding, alignment, grid, and responsive patterns. + +## Elevation & Depth + +Layer roles communicate depth. Canvas holds the application background, containers group durable content, overlays sit above containers, and popovers represent temporary top-layer UI. Prefer layer backgrounds, borders, and restrained shadows over ornamental effects. + +Use elevation only when it explains containment or interaction. Dialogs, menus, tooltips, and transient panels must use the native top-layer patterns documented by Elements. Avoid decorative glass effects, large ambient shadows, and gradients that reduce text or status contrast. + +## Shapes + +The radius scale ranges from square \`{rounded.none}\` surfaces through \`{rounded.lg}\` containers. Standard controls use \`{rounded.sm}\`; cards and panels commonly use \`{rounded.md}\`. Reserve \`{rounded.full}\` for badges, tags, avatars, and other intentionally pill-shaped or circular objects. + +Do not introduce arbitrary radii when an Elements radius token fits. Consistent geometry helps dense application surfaces read as one system. + +## Components + +Use existing \`nve-*\` Custom Elements and their documented composition patterns before creating replacements. The component tokens in the front matter summarize common visual roles; the live API documentation remains normative for properties, events, slots, CSS parts, accessibility, and behavior. + +- All APIs available as [llms.txt](https://nvidia.github.io/elements/llms.txt) +- Use [nve-button](${SITE_URL}/docs/elements/button/) and [nve-icon-button](${SITE_URL}/docs/elements/icon-button/) for actions. +- Use [nve-input](${SITE_URL}/docs/elements/input/), [nve-select](${SITE_URL}/docs/elements/select/), and the form guidance for data entry. +- Use [nve-card](${SITE_URL}/docs/elements/card/) and [nve-page](${SITE_URL}/docs/elements/page/) for durable content structure. +- Use [nve-alert](${SITE_URL}/docs/elements/alert/), badges, and notifications for status communication. +- Use [nve-dialog](${SITE_URL}/docs/elements/dialog/), dropdowns, tooltips, and toggletips for temporary top-layer interaction. +- Use the [data grid](${SITE_URL}/docs/elements/data-grid/) for interactive tabular data rather than recreating sorting, selection, pagination, or keyboard navigation. + +Import component \`define.js\` entrypoints explicitly unless the project intentionally uses a bundle. Compose through public slots and attributes; do not reach into component shadow roots or depend on undocumented internals. + +## Do and Don't + +**Do** + +- Start from Elements components, semantic tokens, examples, and patterns. +- Preserve semantic HTML, keyboard access, focus visibility, labels, and accessible names. +- Use semantic \`--nve-sys-*\` tokens in application CSS so themes continue to work. +- Keep operational content concise, scannable, and explicit about state. +- Check generated UI with the Elements lint tooling and relevant accessibility tests. +- Query the CLI or MCP server when an API, icon name, token, or example is uncertain. + +**Don't** + +- Recreate an Elements component with generic HTML when the maintained component already fits. +- Hard-code resolved colors, spacing, or typography values in production application CSS. +- Encode meaning through color, position, animation, or iconography alone. +- Add gradients, glass effects, oversized radii, or decorative shadows without a product need. +- Invent component properties, slots, events, CSS parts, token names, or icon names. +`; +} diff --git a/projects/internals/design/src/design-md.test.js b/projects/internals/design/src/design-md.test.js new file mode 100644 index 000000000..3a4b4aec4 --- /dev/null +++ b/projects/internals/design/src/design-md.test.js @@ -0,0 +1,49 @@ +import { promises as fsp } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; +import { createDesignMdContent } from './design-md.js'; + +const repositoryDesignMdPath = fileURLToPath(new URL('../../../../DESIGN.md', import.meta.url)); +const builtDesignMdPath = fileURLToPath(new URL('../dist/DESIGN.md', import.meta.url)); + +describe('DESIGN.md generation', () => { + it('should generate the Google DESIGN.md structure from resolved Elements tokens', () => { + const content = createDesignMdContent(); + + expect(content.startsWith('---\nversion: "alpha"\nname: "NVIDIA Elements"')).toBe(true); + expect(content).toContain('nve-sys-accent-primary-background: "oklch('); + expect(content).toContain('nve-sys-layer-container-background: "oklch('); + expect(content).toContain('nve-sys-interaction-selected-background: "oklch('); + expect(content).toContain('nve-sys-support-danger-emphasis-color: "oklch('); + expect(content).toContain('nve-sys-visualization-categorical-violet: "oklch('); + expect(content.match(/^ {2}nve-sys-/gm)).toHaveLength(126); + expect(content).toContain("fontFamily: \"'Inter'"); + expect(content).not.toMatch(/^ {2}(?:primary|canvas|surface|text|danger|success|warning):/m); + expect(content).not.toMatch(/:\s+"nve-(?:ref|sys)-/); + }); + + it('should emit specification sections in the required order', () => { + const content = createDesignMdContent(); + const headings = [ + '## Overview', + '## Colors', + '## Typography', + '## Layout', + '## Elevation & Depth', + '## Shapes', + '## Components', + "## Do and Don't" + ]; + + expect(headings.map(heading => content.indexOf(heading)).every(index => index > 0)).toBe(true); + expect([...headings].sort((left, right) => content.indexOf(left) - content.indexOf(right))).toEqual(headings); + }); + + it('should keep the repository artifact synchronized with the generator', async () => { + await expect(fsp.readFile(repositoryDesignMdPath, 'utf8')).resolves.toBe(createDesignMdContent()); + }); + + it('should keep the built artifact synchronized with the generator', async () => { + await expect(fsp.readFile(builtDesignMdPath, 'utf8')).resolves.toBe(createDesignMdContent()); + }); +}); diff --git a/projects/site/eleventy.config.js b/projects/site/eleventy.config.js index f0e046241..cdcbd0c77 100644 --- a/projects/site/eleventy.config.js +++ b/projects/site/eleventy.config.js @@ -17,6 +17,7 @@ import { } from './src/_11ty/utils/env.js'; import { searchPlugin } from './src/_11ty/plugins/search.js'; import { agentSkillsPlugin } from './src/_11ty/plugins/agent-skills.js'; +import { designMdPlugin } from './src/_11ty/plugins/design-md.js'; import { llmsTxtPlugin } from './src/_11ty/plugins/llms-txt.js'; import { sitemapPlugin } from './src/_11ty/plugins/sitemap-xml.js'; import { updatesFeedPlugin } from './src/_11ty/plugins/updates-feed.js'; @@ -171,6 +172,7 @@ export default function (eleventyConfig) { if (process.env.ELEVENTY_RUN_MODE === 'build') { eleventyConfig.addPlugin(llmsTxtPlugin); eleventyConfig.addPlugin(agentSkillsPlugin); + eleventyConfig.addPlugin(designMdPlugin); } // https://www.sitemaps.org diff --git a/projects/site/package.json b/projects/site/package.json index 9d1b7bab7..c9402121e 100644 --- a/projects/site/package.json +++ b/projects/site/package.json @@ -97,6 +97,7 @@ "../media/dist/**/*.examples.json", "../monaco/dist/**/*.js", "../monaco/dist/**/*.examples.json", + "../internals/design/dist/DESIGN.md", "../internals/metadata/static/**", "../internals/patterns/dist/**/*.js", "../internals/patterns/dist/**/*.examples.json", @@ -104,6 +105,10 @@ "../internals/tools/dist/**/*.examples.json" ], "dependencies": [ + { + "script": "../internals/design:build", + "cascade": false + }, { "script": "../core:build", "cascade": false diff --git a/projects/site/src/_11ty/layouts/common.js b/projects/site/src/_11ty/layouts/common.js index 6d6d0e341..de8027b74 100644 --- a/projects/site/src/_11ty/layouts/common.js +++ b/projects/site/src/_11ty/layouts/common.js @@ -22,6 +22,9 @@ export const renderBaseHead = data => { const meta = resolvePageMeta(data); const ogType = meta.url === '/' ? 'website' : 'article'; const robots = data.noindex ? 'noindex,follow' : 'all'; + const markdownAlternate = data.alternateMarkdown + ? `` + : ''; return /* html */ ` @@ -33,6 +36,7 @@ export const renderBaseHead = data => { ${UPDATE_FEEDS.map(({ label, outputPath, type }) => ``).join('\n ')} + ${markdownAlternate} @@ -183,7 +187,7 @@ export const renderDocsNav = data => /* html */ ` Migration - + Foundations Overview Typography @@ -212,6 +216,7 @@ export const renderDocsNav = data => /* html */ ` i18n Visualization View Transitions + DESIGN.md diff --git a/projects/site/src/_11ty/layouts/metadata.test.ts b/projects/site/src/_11ty/layouts/metadata.test.ts index 5dec43d4f..1b8caf2cc 100644 --- a/projects/site/src/_11ty/layouts/metadata.test.ts +++ b/projects/site/src/_11ty/layouts/metadata.test.ts @@ -55,6 +55,7 @@ const PRIORITY_DOC_ROUTES = [ '/', '/docs/elements/', '/docs/cli/', + '/docs/design-md/', '/docs/mcp/', '/docs/skills/', '/docs/integrations/', @@ -388,6 +389,20 @@ describe('renderBaseHead', () => { ); }); + it('should expose a page-specific Markdown alternate', () => { + const html = renderBaseHead({ + page: { url: '/docs/design-md/' }, + collections: { all: [] }, + title: 'NVIDIA DESIGN.md for AI Agents', + description: 'Official design system file.', + alternateMarkdown: '/DESIGN.md' + }); + + expect(html).toContain( + '' + ); + }); + it('should expose RSS and Atom update feeds for html discovery', () => { const html = renderBaseHead({ page: { url: '/' }, @@ -406,6 +421,14 @@ describe('renderBaseHead', () => { }); describe('renderDocsNav', () => { + it('should expose DESIGN.md in getting started navigation', () => { + const html = renderDocsNav({ page: { url: '/docs/design-md/' } }); + + expect(html).toContain( + 'DESIGN.md' + ); + }); + it('should link the elements section label to the component catalog', () => { const html = renderDocsNav({ page: { url: '/docs/elements/' } }); diff --git a/projects/site/src/_11ty/plugins/design-md.js b/projects/site/src/_11ty/plugins/design-md.js new file mode 100644 index 000000000..7f0925eb3 --- /dev/null +++ b/projects/site/src/_11ty/plugins/design-md.js @@ -0,0 +1,14 @@ +import { promises as fsp } from 'node:fs'; +import nodePath from 'node:path'; +import { getPublicOutputPath } from '../utils/public-output.js'; + +const DESIGN_MD_SOURCE_PATH = '../internals/design/dist/DESIGN.md'; + +export function designMdPlugin(eleventyConfig) { + eleventyConfig.on('eleventy.before', async ({ directories } = {}) => { + const publicOutputPath = getPublicOutputPath(directories); + + await fsp.mkdir(publicOutputPath, { recursive: true }); + await fsp.copyFile(DESIGN_MD_SOURCE_PATH, nodePath.join(publicOutputPath, 'DESIGN.md')); + }); +} diff --git a/projects/site/src/_11ty/plugins/sitemap-xml.js b/projects/site/src/_11ty/plugins/sitemap-xml.js index 5c647d81a..71b102786 100644 --- a/projects/site/src/_11ty/plugins/sitemap-xml.js +++ b/projects/site/src/_11ty/plugins/sitemap-xml.js @@ -4,6 +4,7 @@ import { getSiteUrl } from '../utils/site-url.js'; const EXCLUDED_PREFIXES = ['/docs/changelog/', '/docs/metrics/', '/examples/', '/404']; const UTILITY_FILE_URLS = ['/llms.txt', '/llms-full.txt']; +const INDEXABLE_FILE_URLS = ['/DESIGN.md']; const ROBOTS_NOINDEX = /]*name=["']robots["'][^>]*content=["'][^"']*\bnoindex\b/i; const JSON_LD_SCRIPT = /]*\btype=(?:"application\/ld\+json"|'application\/ld\+json'|application\/ld\+json)[^>]*>([\s\S]*?)<\/script>/gi; @@ -11,6 +12,7 @@ const JSON_LD_SCRIPT = export function isSitemapPageUrl(url) { if (!url) return false; if (UTILITY_FILE_URLS.includes(url)) return false; + if (INDEXABLE_FILE_URLS.includes(url)) return true; if (!url.endsWith('/') && !url.endsWith('.html')) return false; if (EXCLUDED_PREFIXES.some(prefix => url.startsWith(prefix))) return false; return true; @@ -36,7 +38,10 @@ function getResultModifiedDate(result) { } export function renderSitemap(results = []) { - const pages = new Map(results.filter(isPublishableResult).map(result => [result.url, result])); + const pages = new Map([ + ...INDEXABLE_FILE_URLS.map(url => [url, { url }]), + ...results.filter(isPublishableResult).map(result => [result.url, result]) + ]); const entries = [...pages.values()] .sort((left, right) => left.url.localeCompare(right.url)) .map(result => { diff --git a/projects/site/src/_11ty/plugins/sitemap-xml.test.ts b/projects/site/src/_11ty/plugins/sitemap-xml.test.ts index dc0bdb4bd..02f5de0ab 100644 --- a/projects/site/src/_11ty/plugins/sitemap-xml.test.ts +++ b/projects/site/src/_11ty/plugins/sitemap-xml.test.ts @@ -8,6 +8,7 @@ describe('isSitemapPageUrl', () => { expect(isSitemapPageUrl('/docs/cli/')).toBe(true); expect(isSitemapPageUrl('/docs/elements/')).toBe(true); expect(isSitemapPageUrl('/docs/foundations/')).toBe(true); + expect(isSitemapPageUrl('/DESIGN.md')).toBe(true); }); it('should exclude agent utility files from sitemap pages', () => { @@ -38,6 +39,7 @@ describe('isSitemapPageUrl', () => { 'https://nvidia.github.io/elements/docs/whats-new/06-2026/\n2026-07-24T00:00:00.000Z' ); expect(sitemap).toContain('https://nvidia.github.io/elements/docs/about/support/'); + expect(sitemap).toContain('https://nvidia.github.io/elements/DESIGN.md'); expect(sitemap.match(//g)).toHaveLength(1); }); }); diff --git a/projects/site/src/docs/design-md/index.md b/projects/site/src/docs/design-md/index.md new file mode 100644 index 000000000..07342d9d1 --- /dev/null +++ b/projects/site/src/docs/design-md/index.md @@ -0,0 +1,71 @@ +--- +{ + title: 'NVIDIA DESIGN.md for AI Agents', + description: 'Download the official NVIDIA Elements DESIGN.md for AI agents, with verified design tokens, typography, spacing, components, accessibility, and UI guidance.', + alternateMarkdown: '/DESIGN.md', + layout: 'docs.11ty.js' +} +--- + +

NVIDIA Elements DESIGN.md

+ +The official design system file for AI coding agents building NVIDIA Elements interfaces. It combines exact, machine-readable design tokens with human-readable guidance for typography, layout, component selection, accessibility, and operational UI patterns. + +
+ + This file describes the NVIDIA Elements UI Design System. It does not represent a specification of NVIDIA marketing sites or NVIDIA corporate brand. + + +
+ +## What is `DESIGN.md`? + +`DESIGN.md` is a portable format for describing a visual identity to coding agents. The file does not depend on a specific framework or agent. The [open DESIGN.md specification](https://github.com/google-labs-code/design.md) combines YAML front matter for exact design tokens with Markdown prose explaining how and why to apply them. + +The NVIDIA Elements file gives agents a compact contract for: + +- Semantic colors for canvas, surfaces, text, links, interaction, and status +- Interface typography using Inter and `Roboto Mono` +- Spacing and border-radius scales +- Representative visual contracts for buttons, fields, cards, popovers, and status UI +- Layout, elevation, component composition, accessibility, and do-and-don't guidance +- Canonical links to maintained Elements components, tokens, CLI, and MCP tools + +## Download and use + +Place the file at the root of a project where an AI coding agent can read it: + +```shell +curl -fsSL https://nvidia.github.io/elements/DESIGN.md -o DESIGN.md +``` + +Then give the agent a direct instruction: + +```shell +Read DESIGN.md before changing the interface. Use NVIDIA Elements components and +semantic tokens, and verify uncertain APIs with the Elements MCP server or `nve` CLI. +``` + +The file works as portable context on its own. For exact component APIs, examples, icon names, and project validation, combine it with the [Elements MCP server](/docs/mcp/), [CLI](/docs/cli/), and [agent skills](/docs/skills/). + +## Why use the official file? + +Public `DESIGN.md` catalogs often infer a company's visual style from a marketing website. That can be useful for inspiration, but it does not represent the maintained component contracts, theme semantics, accessibility behavior, framework integrations, or operational UI patterns. + +The official file stays connected to the implementation. When an Elements source token changes, the generated values change with it; when component guidance changes, the Elements team reviews this page and the repository artifact together. + +## Related NVIDIA Elements resources + +- [Design tokens](/docs/foundations/themes/tokens/) for the complete CSS custom-property inventory +- [Typography](/docs/foundations/typography/) and [layout](/docs/foundations/layout/) foundations +- [Component catalog](/docs/elements/) with APIs, examples, and accessibility behavior +- [MCP server](/docs/mcp/) for live agent access to Elements metadata +- [CLI](/docs/cli/) for discovery, setup, scaffolding, and validation +- [llms.txt](/llms.txt) for the broader NVIDIA Elements agent-context index diff --git a/projects/site/src/index.md b/projects/site/src/index.md index b6d6f5af9..62cc579bc 100644 --- a/projects/site/src/index.md +++ b/projects/site/src/index.md @@ -6,6 +6,11 @@ } --- +

NVIDIA Elements

The Design Language and UI Agent Harness for AI/ML Factories, Robotics, and Autonomous Vehicles

@@ -101,6 +106,9 @@ import '@nvidia-elements/core/button/define.js'; npm + + DESIGN.md + TypeScript