# aidsgn > An accessible design system with native light DOM controllers, semantic design tokens, and React/Vue adapters. Use complete semantic light DOM. Consumers own every node; controllers attach behavior and synchronize state. Prefer the generated React/Vue adapters where available. Read the native contract before authoring custom-element markup. Never invent attributes, variants, or token names. ## Start here - [Installation](https://docs.aidsgn.de/ai/reference/installation.md) - [Use aidsgn with an AI agent](https://docs.aidsgn.de/ai/reference/ai/agents.md) - [Native Web Component contract](https://docs.aidsgn.de/ai/reference/architecture/web-components.md) - [React and Vue wrappers](https://docs.aidsgn.de/ai/reference/architecture/framework-wrappers.md) - [Component selection](https://docs.aidsgn.de/ai/reference/ai/component-selection.md) - [Design tokens](https://docs.aidsgn.de/ai/reference/foundations/tokens.md) - [Accessibility, responsive design, and RTL](https://docs.aidsgn.de/ai/reference/quality/accessibility.md) - [Browser support](https://docs.aidsgn.de/ai/reference/quality/browser-support.md) - [System status and delivery boundaries](https://docs.aidsgn.de/ai/reference/ai/system-status.md) ## Components - [Component specifications](https://docs.aidsgn.de/ai/reference/components/README.md) - [Accordion](https://docs.aidsgn.de/ai/reference/components/accordion.md) - [Alert](https://docs.aidsgn.de/ai/reference/components/alert.md) - [BottomSheet](https://docs.aidsgn.de/ai/reference/components/bottom-sheet.md) - [Breadcrumb](https://docs.aidsgn.de/ai/reference/components/breadcrumb.md) - [Button](https://docs.aidsgn.de/ai/reference/components/button.md) - [Card](https://docs.aidsgn.de/ai/reference/components/card.md) - [Carousel](https://docs.aidsgn.de/ai/reference/components/carousel.md) - [Checkbox](https://docs.aidsgn.de/ai/reference/components/checkbox.md) - [Dialog](https://docs.aidsgn.de/ai/reference/components/dialog.md) - [Heading](https://docs.aidsgn.de/ai/reference/components/heading.md) - [Icon](https://docs.aidsgn.de/ai/reference/components/icon.md) - [Image](https://docs.aidsgn.de/ai/reference/components/image.md) - [Input](https://docs.aidsgn.de/ai/reference/components/input.md) - [Link](https://docs.aidsgn.de/ai/reference/components/link.md) - [Pagination](https://docs.aidsgn.de/ai/reference/components/pagination.md) - [Price](https://docs.aidsgn.de/ai/reference/components/price.md) - [ProgressIndicator](https://docs.aidsgn.de/ai/reference/components/progress-indicator.md) - [Radio](https://docs.aidsgn.de/ai/reference/components/radio.md) - [Rating](https://docs.aidsgn.de/ai/reference/components/rating.md) - [Select](https://docs.aidsgn.de/ai/reference/components/select.md) - [SideSheet](https://docs.aidsgn.de/ai/reference/components/side-sheet.md) - [Switch](https://docs.aidsgn.de/ai/reference/components/switch.md) - [Tabs](https://docs.aidsgn.de/ai/reference/components/tabs.md) - [Tag](https://docs.aidsgn.de/ai/reference/components/tag.md) - [Textarea](https://docs.aidsgn.de/ai/reference/components/textarea.md) - [Toast](https://docs.aidsgn.de/ai/reference/components/toast.md) - [Tooltip](https://docs.aidsgn.de/ai/reference/components/tooltip.md) ## Machine-readable context - [Complete documentation](https://docs.aidsgn.de/llms-full.txt): All reference Markdown in one file. - [Versioned catalog](https://docs.aidsgn.de/agent-context.json): Manifest APIs, canonical native examples, DTCG token definitions, documentation, package versions, and content hash. ## Optional - [AI-assisted authoring](https://docs.aidsgn.de/ai/reference/ai/authoring.md) - [Component quality requirements](https://docs.aidsgn.de/ai/reference/architecture/component-requirements.md) - [Repository architecture](https://docs.aidsgn.de/ai/reference/architecture/repository.md) - [0001: Rolling browser support policy](https://docs.aidsgn.de/ai/reference/decisions/0001-browser-support-policy.md) - [0002: Generate framework wrappers from the Custom Elements Manifest](https://docs.aidsgn.de/ai/reference/decisions/0002-manifest-generated-framework-wrappers.md) - [0003: Use aidsgn as the public namespace](https://docs.aidsgn.de/ai/reference/decisions/0003-aidsgn-public-namespace.md) - [0004: Use a curated inline SVG icon registry](https://docs.aidsgn.de/ai/reference/decisions/0004-inline-icon-registry.md) - [0005: Keep native input types together and Select separate](https://docs.aidsgn.de/ai/reference/decisions/0005-native-form-control-boundaries.md) - [0006: Separate registration from tree-shakeable package exports](https://docs.aidsgn.de/ai/reference/decisions/0006-explicit-registration-and-bundle-budgets.md) - [0007: Use Changesets for package releases](https://docs.aidsgn.de/ai/reference/decisions/0007-changesets-release-management.md) - [0008: Standardize Press feedback for Pressable controls](https://docs.aidsgn.de/ai/reference/decisions/0008-standardize-press-feedback.md) - [0009: Keep brand primitives in brand bundles](https://docs.aidsgn.de/ai/reference/decisions/0009-keep-brand-primitives-in-brand-bundles.md) - [0010: Standardize form-control message layout](https://docs.aidsgn.de/ai/reference/decisions/0010-standardize-form-control-message-layout.md) - [0011: Separate action and selected-state colors](https://docs.aidsgn.de/ai/reference/decisions/0011-separate-action-and-selected-state-colors.md) - [0012: Render canonical light DOM with one topology owner](https://docs.aidsgn.de/ai/reference/decisions/0012-canonical-light-dom-rendering.md) - [0013: Emit runtime CSS and the Tailwind adapter from one Style Dictionary build](https://docs.aidsgn.de/ai/reference/decisions/0013-unified-style-dictionary-token-build.md) - [0014: Generate agent context from the public contracts](https://docs.aidsgn.de/ai/reference/decisions/0014-generated-agent-context.md) - [Architecture decisions](https://docs.aidsgn.de/ai/reference/decisions/README.md) - [Brands and themes](https://docs.aidsgn.de/ai/reference/foundations/brands-and-themes.md) - [Responsive layout](https://docs.aidsgn.de/ai/reference/foundations/responsive-layout.md) - [Tailwind CSS v4 integration](https://docs.aidsgn.de/ai/reference/foundations/tailwind.md) - [Component sizing audit](https://docs.aidsgn.de/ai/reference/quality/component-sizing-audit.md) - [Deployment and domains](https://docs.aidsgn.de/ai/reference/quality/deployment.md) - [Engineering quality](https://docs.aidsgn.de/ai/reference/quality/engineering.md) - [Reduced-motion audit](https://docs.aidsgn.de/ai/reference/quality/reduced-motion-audit.md) - [Package releases](https://docs.aidsgn.de/ai/reference/quality/releases.md) --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/apps/docs/src/content/docs/installation.md Choose the package for your application, then load the design tokens, component styles, and element registration once at your application entry point. ## Web Components Install the tokens and native components: ```sh npm install @aidsgn/tokens @aidsgn/components ``` Load the shared styles and register the complete component catalog: ```ts import "@aidsgn/tokens/css"; import "@aidsgn/components/styles.css"; import "@aidsgn/components/register"; ``` Native HTML owns its light-DOM structure. Include the semantic descendants in the server response; the custom element only attaches behavior: ```html ``` Prefer the React or Vue wrappers when available: they generate this structural boilerplate on the server while keeping application code concise. ## React The React wrappers require React 19 or newer. ```sh npm install @aidsgn/tokens @aidsgn/components @aidsgn/react ``` Load the styles and registration entry point once in browser-facing application code: ```ts import "@aidsgn/tokens/css"; import "@aidsgn/components/styles.css"; import "@aidsgn/react/register"; ``` Import components from the React package: ```tsx import { AidsgnButton } from "@aidsgn/react"; export function SaveButton() { return Save changes; } ``` For server-rendered applications, place the registration import at the client boundary. See [React and Vue](https://docs.aidsgn.de/architecture/framework-wrappers/) for event, ref, and server-rendering examples. ## Vue The Vue wrappers require Vue 3.5 or newer. ```sh npm install @aidsgn/tokens @aidsgn/components @aidsgn/vue ``` Load the styles and registration entry point once in browser-facing application code: ```ts import "@aidsgn/tokens/css"; import "@aidsgn/components/styles.css"; import "@aidsgn/vue/register"; ``` Import components from the Vue package: ```vue ``` See [React and Vue](https://docs.aidsgn.de/architecture/framework-wrappers/) for events, template configuration, refs, and server-rendering examples. ## Load fewer component styles `@aidsgn/components/styles.css` includes the complete component catalog. To reduce the CSS payload, import the reset, shared styles, and only the component styles you use: ```ts import "@aidsgn/tokens/css"; import "@aidsgn/components/styles/reset.css"; import "@aidsgn/components/styles/shared.css"; import "@aidsgn/components/styles/button.css"; ``` Native Web Component users can also import an individual `defineAidsgn*()` function from `@aidsgn/components` instead of registering the complete catalog. ## Tailwind CSS v4 Tailwind v4 applications can import the official semantic theme after Tailwind and the base token variables: ```css @import "tailwindcss"; @import "@aidsgn/tokens/css"; @import "@aidsgn/tokens/tailwind.css"; ``` This provides Brand-aware utilities such as `bg-aidsgn-surface-action`, `gap-aidsgn-24`, and `type-aidsgn-body` without a JavaScript preset or copied token configuration. See [Tailwind CSS v4](https://docs.aidsgn.de/foundations/tailwind/) for PostCSS setup, naming, themes, responsive variants, Next.js first paint, CSS size, and upgrades. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/agents.md # Use aidsgn with an AI agent Start with the component's purpose and the application's installed package versions. The agent context exposes exact APIs, native markup, tokens, and source references so an agent can use the existing system without inventing components or styles. ## Read documentation without a connector - [`/llms.txt`](https://docs.aidsgn.de/llms.txt) is the small entry point: setup, ownership rules, component contracts, and links to plain Markdown. - [`/llms-full.txt`](https://docs.aidsgn.de/llms-full.txt) contains the complete reference documentation for clients that accept one context file. - [`/agent-context.json`](https://docs.aidsgn.de/agent-context.json) contains manifest APIs for every custom element, canonical native HTML examples, DTCG token definitions, source documents, package versions, revision, and a content hash. The website describes the deployed repository revision. Match its package versions to the application's dependencies. A packaged MCP server contains its own snapshot and works offline after installation. ## Connect the local MCP server The server uses standard MCP over stdin/stdout. It reads its bundled context and has no write tools, network listeners, credential requirements, or arbitrary filesystem access. JSON-RPC is the only output on stdout; startup errors go to stderr. From a repository checkout, build the context: ```sh pnpm install --frozen-lockfile pnpm agents:build ``` Use an absolute path in an MCP client's configuration: ```json { "mcpServers": { "aidsgn": { "command": "node", "args": ["/absolute/path/to/aidsgn/packages/mcp/src/cli.mjs"] } } } ``` `@aidsgn/mcp` is also prepared for the repository's package release process. After its first npm publication, install and pin a released version locally, then use the `aidsgn-mcp` executable from that installation. The source-checkout configuration above works before registry publication. Adding the new package requires the [npm bootstrap and trusted publisher setup](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/quality/releases.md#one-time-npm-bootstrap). ## Available tools | Tool | Use | | ------------------------ | ----------------------------------------------------------------------------------------------------------- | | `aidsgn_list_components` | Discover all custom elements and their documentation resource URIs. | | `aidsgn_get_component` | Retrieve one element's exact manifest APIs, generated native example, and complete contract. | | `aidsgn_search_docs` | Find installation, framework, design, and accessibility guidance using bounded excerpts. | | `aidsgn_get_document` | Read the complete document using an ID returned by search. | | `aidsgn_search_tokens` | Find exact CSS custom properties, DTCG definitions, descriptions, and theme/brand sources, with pagination. | Clients with resource support can read `aidsgn://catalog` and the `aidsgn://docs/...` resources directly. Tool results include package versions and source identity. Token aliases are authored definitions; use the token build or browser styles when resolved runtime values are needed. ## Framework integration For React 19+ and Vue 3.5+, prefer the generated adapters. They emit canonical semantic markup, translate props/events, and preserve framework ownership during hydration. Read the [wrapper contract](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/architecture/framework-wrappers.md) for client registration and refs; Next.js and Nuxt have production SSR fixtures. For other frameworks, templates, and server languages, start from `example.nativeHtml` and the [native contract](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/architecture/web-components.md). Keep the semantic descendants, IDs, ARIA relationships, and stable classes. Use unique IDs for repeated instances, bind native bubbling events, and register custom elements at the browser boundary. Configure the framework to recognize `aidsgn-*` custom elements where necessary. The repository does not currently provide dedicated adapters or automated integration fixtures for every framework; verify hydration and reactive updates in the consuming application. Controllers use light DOM and preserve node ownership. Changing a prop that changes structure is the renderer's responsibility. Do not generate bare custom-element hosts and expect browser controllers to construct their children. ## Maintaining the context Root specifications, the Custom Elements Manifest, the canonical renderer, and DTCG JSON remain the sources of truth. `pnpm agents:build` generates the bundled context and the root `llms.txt`; never edit either by hand. Documentation builds also regenerate the context before emitting the plain-text endpoints. `pnpm agents:check` checks the committed index, and `pnpm test:mcp` exercises the real protocol plus packed-package execution outside the checkout. When a change affects bundled APIs, tokens, or guidance, include `@aidsgn/mcp` in its changeset so package consumers receive a new snapshot. Ordinary documentation builds regenerate only untracked build output; the committed index changes only with `pnpm agents:build`. Source-archive builds must set `AIDSGN_SOURCE_REVISION` to the full 40-character commit SHA of the exported source. The production workflow passes its checked-out `GITHUB_SHA` to Vercel as a build environment variable. Checkout builds use Git when the variable is absent. Missing archive provenance or an invalid supplied revision fails with an actionable error; source links never silently point to a moving branch. The design is recorded in [ADR 0014](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/decisions/0014-generated-agent-context.md). It uses the official [MCP TypeScript SDK](https://ts.sdk.modelcontextprotocol.io/server) and the [llms.txt proposal](https://llmstxt.org/). --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/authoring.md # AI-assisted authoring AI agents should use this repository as structured context, not infer a design system from isolated files. External clients can use the [agent guide](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/agents.md) for generated llms.txt, plain Markdown, JSON, and local MCP access. ## Context order 1. Read [AGENTS.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/AGENTS.md), then the task-specific document it links to. 2. Read [system status](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/system-status.md) when deciding whether an API already exists or is a planned capability. 3. For token work, read [tokens](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/foundations/tokens.md) and [brands and themes](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/foundations/brands-and-themes.md). 4. For component work, read its specification and [native component contract](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/architecture/web-components.md). 5. When selecting a component or variant, apply the [component selection guide](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/component-selection.md) before reading the selected specification. 6. Validate changes against [accessibility](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/quality/accessibility.md) and [engineering](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/quality/engineering.md). ## Generation rules - Do not invent token names, public APIs, or component variants without documenting the decision. - Prefer an existing semantic token over a new primitive; explain any new token's intended use with its DTCG description. - For component styling, follow the selection sequence and worked examples in [Design tokens](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/foundations/tokens.md#selecting-the-right-layer). Name the UI role before choosing a value. - Keep raw values in `packages/tokens/src/primitives/`. Semantic and theme tokens must directly reference a primitive; the token build rejects raw semantic values and invalid layer references. - Preserve native browser behavior and use logical CSS properties. - Treat Storybook examples as executable documentation; add or update them when public behavior changes. - Treat the Custom Elements Manifest as the input to React and Vue wrapper generation. Never hand-edit their `generated.ts` files; run `pnpm wrappers:generate` after a public component API changes. - Keep changes narrow and update the closest source-of-truth Markdown file with contractual changes. - Select components by user intent and semantics, not visual resemblance. Prefer the least complex component that meets the task, and never invent a variant that is absent from its specification. ## Reliable implementation loop 1. Inspect the component source, its Storybook story, and its Starlight page before editing. 2. Preserve light DOM and native descendant elements. Do not add a shadow root, framework base class, or undocumented host API. 3. For visual changes, first decide whether the value is a semantic token, a primitive scale entry, or a local layout detail. Do not hard-code a new design value in component CSS. 4. Update source contracts before consumer prose. State what is implemented now and separately name planned work; never present planned behavior as available. 5. Run the commands in [engineering](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/quality/engineering.md) that cover the affected packages. ## Documentation rules - Every component specification names the custom element, supported attributes/properties, generated native markup, events, supported states, accessibility behavior, and explicit non-goals. - Use the terms **implemented**, **planned**, and **not supported** precisely. - Keep root `docs/` as engineering truth. Keep the matching Starlight MDX page concise, user-facing, and aligned with it. - When an option set is finite, export an `as const` tuple from TypeScript and use it for Storybook select/radio controls. - Author every component-page recommendation as a visual Usage guidance item with a short imperative headline, concise rationale, meaningful alt text, and committed default-brand light and dark WebP assets. Group independent `do` and `dont` items with `UsageGuidelines`; use `UsageGuidancePair` only when two items benefit from direct comparison. - Keep Usage guidance examples non-interactive. Build their source scenes in the private Storybook fixture manifest, using actual components for recommended states and safe simulations for invalid or inaccessible mistakes, then regenerate the 1280×720 assets with `pnpm docs:usage-guidance:capture`. - Use the interactive `ComponentDemo` near the top of each component page for behavior and markup exploration. Run `pnpm docs:usage-guidance:check` after guidance changes to verify page coverage, themes, asset format, dimensions, and alt text. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/component-selection.md # Component selection Use the component whose semantics match the user's task. Visual resemblance is not enough: first decide whether the user is navigating, acting, entering data, choosing, or receiving status. Then select the least complex component that preserves native behavior. ## Actions and navigation | Need | Use | Choose something else when | | ---------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Perform an immediate action | **Button** | Use Link when the outcome is navigation. Use one `primary` action per local group, `secondary` for supporting actions, and `tertiary` for low-emphasis actions. `medium` is the default; reserve `small` for dense supporting controls. | | Navigate to a location or resource | **Link** | Use Button for mutation, submission, or an action that does not change location. | | Show the current location in a hierarchy | **Breadcrumb** | Use ordinary navigation for unrelated destinations. Omit Breadcrumb on a flat or single-level page. | | Move through known result pages | **Pagination** | Use Carousel for browsing a small visual collection. Pagination changes the application-owned result set and should usually correspond to stable pages. | ## Status and compact information | Need | Use | Choose something else when | | ---------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Show contextual status that remains with its content | **Alert** | Use Toast for a transient application outcome that is not tied to one page region. Choose `error` only for urgent failures; use `warning` for risk, `success` for completion, and `info` for neutral updates. | | Announce a short-lived application outcome | **Toast** | Use Alert when the message must remain visible in context. Toasts are persistent until the application or user closes them; do not place essential actions inside. | | Label a category or state | **Tag** | Use Button or Link if it is interactive. Choose `neutral` for metadata, `accent` for notable content, and the matching status variant only when the text names that status. | | Communicate a short non-essential description | **Tooltip** | Use visible text, helper text, or an Alert for instructions, validation, or essential information. Tooltip content cannot be interactive. | | Display an authored SVG symbol | **Icon** | Use text when an icon would be ambiguous. Decorative icons need no accessible label; icon-only controls must receive their accessible name from the control. | ## Forms and choices | Need | Use | Choose something else when | | -------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | Collect a single-line value | **Input** | Use Textarea for free-form multi-line content or Select for a predefined option set. Choose the native-backed `type` that matches the data. | | Collect free-form multi-line content | **Textarea** | Use Input for short, structured values. | | Choose from predefined options | **Select** | Use Radio when a short list benefits from showing every option, or Checkbox when choices are independent. Native Select is best when compactness matters. | | Choose any number of independent options | **Checkbox** | Use Radio for exactly one choice, or Switch when one setting takes effect immediately. | | Choose exactly one option from a short visible set | **Radio** | Use Select when the list is long or space is constrained. All options in a group share a `name`. | | Turn an immediately applied setting on or off | **Switch** | Use Checkbox when the value is part of a form submitted later or represents agreement/selection rather than a live setting. | | Choose a one-to-five-star score | **Rating** | Use Radio for choices whose labels are not an ordered star scale. | Helper text should prevent likely mistakes; error messages should explain how to recover after validation fails. Do not use placeholder text as a label. ## Modal tasks and disclosure | Need | Use | Choose something else when | | -------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Require a focused decision or compact task | **Dialog** | Use SideSheet for a longer supporting workflow or BottomSheet for a short touch-oriented task. Do not use a modal for passive information. | | Complete a longer supporting task while retaining page context | **SideSheet** | Use Dialog for a focused decision. Use a responsive page region when simultaneous access to the page is required. | | Present a short task near the viewport bottom | **BottomSheet** | Use SideSheet for longer editing or dense content. Drag-to-close supplements, but never replaces, keyboard and visible dismissal. | | Reveal optional content in place | **Accordion** | Use Tabs when users switch among peer sections and one should always remain visible. Use static headings when hiding content adds no value. | | Switch among peer sections in one region | **Tabs** | Use Accordion when multiple sections may remain open, or normal navigation when each section is a separate destination. Use manual activation when loading a panel is expensive. | ## Content, layout, and progress | Need | Use | Choose something else when | | ------------------------------------------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | Group related passive content | **Card** | Use plain semantic HTML when no visual grouping is needed. Do not make a passive Card look clickable. | | Establish document hierarchy | **Heading** | Choose `level` from the document outline, not the desired visual size. | | Render responsive raster content with format candidates or BlurHash | **Image** | Use native `img`/`picture` when upgrade-dependent loading behavior is unnecessary, especially for critical no-JavaScript content. | | Browse a short ordered collection horizontally | **Carousel** | Use a list or grid when comparison and scanability matter. Never hide essential information in undiscovered slides. | | Show progress through a known sequence | **ProgressIndicator** | Use Pagination for result pages. ProgressIndicator is status, not navigation; pair it with separate Back and Continue actions. | ## Agent selection checklist Before generating an interface: 1. State the user task in one verb: navigate, act, enter, choose, inspect, or acknowledge. 2. Prefer native page content over a modal and a visible explanation over a Tooltip. 3. Check the comparison rows above when two components seem plausible. 4. Read the selected component specification before choosing attributes or variants; never infer an unsupported API from another design system. 5. Preserve authored semantics and include labels, error recovery, keyboard paths, and non-color status cues. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/system-status.md # System status and delivery boundaries Read this after the task-specific source named by `AGENTS.md`. It is an inventory, not a replacement for component and token contracts. ## Implemented now | Area | Available contract | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Platform | Native TypeScript custom-element controllers, light DOM only, topology-free browser enhancement, a canonical wrapper render contract, global stylesheet, and reset. | | Wrappers | Manifest-generated React 19+ and Vue 3.5+ packages with typed props, events, slots, refs, server-safe module evaluation, complete semantic SSR, deterministic accessibility relationships, and topology-safe custom-element upgrade. | | Tokens | DTCG JSON primitives, semantic defaults, and generated CSS custom properties. Complete OKLCH palettes plus systematic spacing, radius, fluid typography, shadow, duration, and easing scales are available; semantic and theme values are build-validated primitive aliases, and intended text/surface pairs have light/dark browser contrast tests. | | Brands | Default aidsgn plus the opt-in Offprint Brand bundle, selected with `data-aidsgn-brand="offprint"`; both use the same component implementations and semantic contract. | | Theme modes | Light-fallback semantic values, automatic `prefers-color-scheme` dark mode, and explicit `data-aidsgn-theme="light"` and `data-aidsgn-theme="dark"` overrides for both Brands. | | Components | Accordion, Alert, BottomSheet, Breadcrumb, Button, Card, Carousel, Checkbox, Dialog, Heading, Icon, Image, Input, Link, Pagination, Price, ProgressIndicator, Radio, Rating, Select, SideSheet, Switch, Tag, Tabs, Textarea, Toast, and Tooltip. | | Documentation | Starlight live demos, native custom-element Storybook autodocs, and dedicated React and Vue wrapper Storybooks. | | Quality | Formatting, linting, TypeScript, unit and Chromium visual Vitest tests, manifest-wide canonical render/ownership guards, complete live Next.js and Nuxt SSR/hydration verification, generated output checks, bundle-size budgets for publishable packages and tree-shaken imports, and CI. | Agent clients can read the [generated context and local MCP server](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/agents.md). The catalog includes canonical native examples, manifest APIs, authored DTCG definitions, package versions, and source identity. ## Current boundaries - Native descendant controls participate in a surrounding HTML form when they have a `name`; custom-element hosts are **not** form-associated with `ElementInternals` yet. - Input, Select, Textarea, Checkbox, Radio, and Switch provide reusable helper text, error messages, and explicit invalid states linked to their native controls. Error messages imply invalid state. Input, Select, and Textarea provide visible labels, native values and events, disabled and required states, and control-specific native attributes; Input and Textarea also support readonly. - Checkbox has checked, disabled, required, label, name, value, and input-id. Indeterminate is not implemented. - Radio and Switch expose basic checked/disabled state and linked labels. They have no required or readonly API. - Accordion supports independent open items. Single-expand coordination is not implemented. - Tag is passive only. Removable tags are not implemented. - Card is passive only. It is not a link, button, or selectable surface. - Link delegates navigation to a native anchor. It does not implement disabled behavior, router integration, automatic external-link indicators, or visited-state tracking. - Native Storybook accessibility checks and React/Vue story interactions run in headless Chromium as required CI gates. All three Storybooks also have required production builds. - Visual tests discover named Storybook stories and store separate light/dark Linux baselines at a fixed Chromium viewport. Review screenshot changes before updating them; do not regenerate them incidentally during ordinary test runs. - Typography composites generate one `--aidsgn-typography-*` CSS font-shorthand property plus a paired `*-letter-spacing` property. Consumers must apply both rather than decomposing the composite into scalar font properties. - Browser support is a rolling current-and-previous stable-major policy. Native form contracts and the Next.js Carousel layout, scrolling, RTL, reduced-motion, and node-ownership regressions run in Chromium, Firefox, and WebKit. Screenshots, Storybook interactions, and general SSR/hydration checks use Chromium; release-family and mobile smoke testing remain manual requirements. ## Definition of done for a new or changed component 1. Add or revise the native light-DOM module and export it from `packages/components/src/index.ts`. 2. Add semantic tokens before introducing a new public visual value; give every token a DTCG description. 3. Update its root component specification, Storybook story/controls, and Starlight page/demo. 4. Ensure Custom Elements Manifest output describes the public API and the canonical render contract describes the complete semantic tree, then run `pnpm wrappers:generate`. 5. Cover changed behavior with Vitest when practical; manually inspect keyboard, dark mode, RTL, reduced motion, and narrow layout behavior. 6. Run `pnpm check`, `pnpm build`, and `pnpm --filter @aidsgn/storybook build`. ## Priority gaps before a production release 1. Keep the documented native-descendant form integration and validation contract covered by real-browser regression tests. Custom-element hosts are not form-associated. 2. Expand visual and interaction coverage to RTL, narrow layouts, and reduced-motion scenarios; named component stories cover individual light and dark baseline rendering. 3. Extend focused browser regressions to remaining interactive contracts; automated three-engine coverage currently targets forms and Carousel. 4. Define the compatibility and migration policy for the first stable package release. 5. Extend automated color verification beyond intended text/surface pairs to focus indicators and non-text component contrast. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/architecture/component-requirements.md # Component quality requirements Use this file when adding or revising a component. These requirements apply unless a component specification documents a justified exception. ## Native controls and states - Prefer the matching native control in light DOM. A Switch may use a checkbox with `role="switch"`, but must use a track-and-thumb UI visibly distinct from a Checkbox. - Every editable control visibly distinguishes default, focus-visible, disabled, and readonly where applicable. Inputs, Selects, and Textareas require a programmatically associated visible label; placeholders and prompt options never substitute for labels. - Required controls set native `required` and visibly mark their associated label with an asterisk or equivalent text indicator. - Alerts require `info`, `success`, `warning`, and `error` variants. Every variant includes a non-color icon. Errors use `role="alert"`; other alerts use `role="status"`. ## Form-control messages - Helper and error messages occupy separate rows in source order, remain visible together, and keep `aidsgn.space.4` block-start spacing. Hidden messages reserve no space. - Messages align to logical inline-start, use automatic hyphenation with an `overflow-wrap: anywhere` fallback, and default to a `65ch` maximum measure through `--aidsgn-field-message-max-inline-size`. - Checkbox, Radio, and Switch hosts fill their allocated inline size while their indicator-and-label Interactive targets remain content-bound. Message rows and unused host space are inert. ## Press feedback Press feedback is the brief physical response while an enabled Pressable control is natively active. A Pressable control is a component-owned button or a compact Selection control or Rating choice. It does not include links, editable fields, drag surfaces, Accordion summaries, passive surfaces, consumer-owned Tooltip triggers, or disabled controls. - Use the individual `scale` property with `aidsgn.press-feedback.scale`, `aidsgn.press-feedback.duration`, and `aidsgn.press-feedback.easing`. Do not change layout or interactive-target geometry. - Preserve component-specific active color, border, and surface styling. Button's former downward movement is replaced by shared Press feedback. - Scale a compound Visible indicator, such as the Switch track, thumb, and check, as one unit. - Keep Press feedback distinct from persistent Selection feedback. Checkbox, Radio, Switch, Rating, and Tabs retain their existing selected-state treatments. - Apply feedback through native CSS `:active`; do not synthesize press state in JavaScript. - Suppress Press feedback entirely under `prefers-reduced-motion: reduce`; do not merely shorten its transition. The initial inventory is Button, Checkbox, Radio, Switch, Rating choices, Tabs, Pagination buttons, Carousel buttons, modal close buttons, and Toast close buttons. Future controls that meet the definition inherit the requirement. ## Validation and documentation - Add arg-driven Storybook controls for every public prop. Use radio/select controls for finite option sets, sourced from exported `as const` option tuples where possible. - Export named stories for visually distinct variants and states. Every named story automatically receives an individual light and dark visual-regression baseline. - Generate the Custom Elements Manifest during builds and load it into Storybook Docs. - Add or revise the component specification, Storybook story, accessibility behavior, and live documentation whenever a public API or visual state changes. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/architecture/framework-wrappers.md # React and Vue wrappers The framework packages are generated adapters around the native custom elements. The Custom Elements Manifest at `packages/components/custom-elements.json` is the source for component names, tag names, attributes, public fields, and events. ## Packages and support floor | Package | Framework support | Contract | | --------------- | ----------------- | ------------------------------------------------------------------------- | | `@aidsgn/react` | React 19+ | Typed components, camel-cased props, native custom-event props, and refs | | `@aidsgn/vue` | Vue 3.5+ | Typed components, reactive props, emitted custom events, and exposed refs | Both package roots are safe to evaluate on the server and remain side-effect free so unused wrappers can be removed by a bundler. Each adapter renders the complete semantic light-DOM tree from the shared `@aidsgn/components/render-contract`, including native controls, accessibility nodes, inline icons, state, and authored-content placement. Applications import the framework's dedicated registration entry point once at their client boundary; it dynamically loads `@aidsgn/components/register` in a browser while leaving server rendering untouched. Adapter hosts carry `data-aidsgn-renderer="framework"`. React or Vue owns the topology of these subtrees on the server and client. Custom-element registration adopts the static descendants without changing node topology, so registration timing cannot race destructively with hydration. The wrappers intentionally own the structural boilerplate; custom-element classes contain behavior only and do not generate fallback markup in the browser. Applications that need to await element definition before imperative work can call the exported `registerAidsgnElements()` helper. It resolves without loading the browser implementation during server rendering. Consumers must also load the design tokens and component stylesheet: ```ts import "@aidsgn/tokens/css"; import "@aidsgn/components/styles.css"; import "@aidsgn/react/register"; // or @aidsgn/vue/register ``` `styles.css` remains the complete-catalog entry point. Applications that load only a subset of wrappers may instead import `@aidsgn/components/styles/reset.css`, `styles/shared.css`, and the CSS module for each component they render. Generated wrapper factory calls are annotated as pure. Package metadata identifies only the `register` entry point as a JavaScript side effect. ## Generation contract Run `pnpm wrappers:generate` after changing a custom element's public API. The command regenerates the manifest, then creates the committed files: - `packages/react/src/generated.ts` - `packages/vue/src/generated.ts` Do not edit those files by hand. `pnpm wrappers:check` fails when committed wrappers no longer match the manifest, and the root build regenerates them before compiling the framework packages. The generator applies these deterministic mappings: - `aidsgn-dialog` becomes `AidsgnDialog`. - Dash-cased attributes become framework-style props where needed: `close-label` becomes `closeLabel`, and `readonly` becomes `readOnly`. - Public fields documented by the manifest reuse the custom-element class's TypeScript type. - Known boolean and numeric attributes receive boolean or numeric runtime handling; attributes without manifest type information conservatively become strings. - React events such as `aidsgn-close` become `onAidsgnClose` callbacks. - Vue wrappers listen for the exact native event name and re-emit `aidsgn-close`, usable as `@aidsgn-close`. - React forwards its ref to the custom-element host. Vue exposes the host as the component ref's `element` property. - Default children become the custom element's default slot. Named-slot content continues to use the native `slot` attribute. - Generated adapters translate the canonical render contract with framework-native node creation; they do not inject raw HTML. - Framework SSR identity seeds deterministic control, tab, panel, modal-heading, and ARIA-reference IDs. If an attribute needs a stronger type, document a public field or a typed declaration in the component source so that the manifest can carry it. Add a generator exception only for platform-level naming or runtime coercion that cannot be represented in the manifest. ## React usage ```tsx import { useRef } from "react"; import { AidsgnDialog } from "@aidsgn/react"; import type { AidsgnDialog as AidsgnDialogElement } from "@aidsgn/components"; export function Example() { const dialog = useRef(null); return ( console.log(event.detail)} > ); } ``` ## Vue usage ```vue ``` Vue consumers that use the native `aidsgn-*` tags in templates instead of the generated components can pass the exported `isAidsgnElement` helper to `compilerOptions.isCustomElement` in their build configuration. ## Framework Storybooks The repository keeps wrapper verification separate from the native custom-element Storybook: | Application | Command | Port | Purpose | | ---------------------- | ---------------------- | ---- | ---------------------------------------------------------- | | `apps/storybook-react` | `pnpm storybook:react` | 6007 | React props, children, custom events, and forwarded refs | | `apps/storybook-vue` | `pnpm storybook:vue` | 6008 | Vue props, slots, custom-event emits, and reactive updates | Both Storybooks import the generated package entry point as a consumer would and include every wrapper export across typed stories. Their Dialog stories bridge `aidsgn-close` through the framework API and include a play function that verifies the resulting state update. The native, React, and Vue Storybooks share an aidsgn/Offprint Brand toolbar and a separate Light, Dark, or System Theme-mode toolbar. Together they control autodocs, controls, preview canvas, component tokens, and native `color-scheme`. Their canvases intentionally disable Storybook's separate Backgrounds toolbar because the active semantic surface token already provides the correct background. Run `pnpm storybook:build` to build the native, React, and Vue Storybooks. CI requires all three production builds. Run `pnpm test:wrappers` to build wrapper dependencies and execute the React/Vue stories in headless Chromium, including their play functions and accessibility checks. This separate required gate uses the real Storybook preview configuration and tests event bridges, props, and framework state updates. ## Next.js SSR fixture `apps/next-showcase` is a production Next.js App Router fixture. Server Component pages distribute the generated wrappers across overview, forms, and exploration routes, with `next/link` navigation shared by the application layout. Passive adapters can render directly in a Server Component; interactive compositions establish their own client boundary. The production check starts `next start`, fetches every route over HTTP, and asserts that every manifest tag contains its required canonical native structure. It then opens Chromium to verify topology-safe upgrade, hydration without warnings, and client navigation without a document reload. - Run `pnpm next` for the interactive showcase. - Run `pnpm build` to include its production build. - Run `pnpm test:ssr:next` after a build to verify the live server response. The fixture also compiles the public [Tailwind CSS v4 token adapter](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/foundations/tailwind.md) through PostCSS. Its production browser check covers initial server markup, Light/Dark/System and alternate Brand resolution, complete typography, responsive and container variants, and hydration without warnings. ## Nuxt SSR fixture `apps/nuxt-showcase` is a production Nuxt 4 fixture with generated Vue wrappers distributed across overview, forms, and exploration pages. Nuxt renders every page and the shared `NuxtLink` navigation on the server, while browser-side registration adopts the already-complete tree. Its production check validates the full manifest-derived canonical structure in raw Nitro responses, then verifies topology-safe upgrade, hydration without warnings, and client navigation without a document reload. - Run `pnpm nuxt` for the interactive showcase on port 3001. - Run `pnpm build` to include its production Nitro build. - Run `pnpm test:ssr:nuxt` after a build to verify its live server response. - Run `pnpm test:ssr` to verify both Next.js and Nuxt fixtures. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/architecture/repository.md # Repository architecture The repository is a pnpm workspace. It separates authored inputs from generated artifacts and published packages. ```text . ├── packages/ │ ├── tokens/ # DTCG JSON source and Style Dictionary build │ │ ├── src/primitives/ │ │ ├── src/semantic/ │ │ ├── src/themes/ # Theme-specific semantic overrides │ │ └── src/brands/ # Reserved for brand-specific overrides │ ├── components/ # Native TypeScript custom elements │ │ ├── src/ # One component module per element │ │ ├── styles.css # Backward-compatible CSS import index │ │ ├── styles/ # Reset, shared, and per-component CSS modules │ │ └── custom-elements.json # Generated Custom Elements Manifest │ ├── react/ # Generated React 19+ wrappers │ ├── mcp/ # Bundled agent context and local read-only MCP server │ └── vue/ # Generated Vue 3.5+ wrappers ├── apps/ │ ├── storybook/ # Native custom-element stories and visual tests │ ├── storybook-react/ # React wrapper integration stories │ ├── storybook-vue/ # Vue wrapper integration stories │ ├── next-showcase/ # Next.js SSR and hydration fixture │ ├── nuxt-showcase/ # Nuxt SSR and hydration fixture │ └── docs/ # Astro Starlight documentation site ├── assets/brand/ # Shared logo artwork for documentation surfaces ├── docs/ # Markdown specifications and system guidance ├── scripts/ # Repository-level code generators └── .github/workflows/ # Continuous integration ``` ## Ownership rules - `packages/tokens/src/**` is the authored token source of truth. Never hand-edit generated CSS. - `packages/components/src/**` owns runtime behavior, DOM structure, styles, and TypeScript APIs. - `packages/components/custom-elements.json` is the generated metadata source for framework wrappers. - `packages/react/src/generated.ts` and `packages/vue/src/generated.ts` are generated by `scripts/generate-framework-wrappers.mjs`; never edit them by hand. - `apps/storybook-react` and `apps/storybook-vue` own framework-integration examples and event/ref verification for the generated wrappers. - `apps/next-showcase` owns the production-server check that wrappers render into an SSR response and hydrate as client components. - `apps/nuxt-showcase` owns the corresponding production Nitro check for the generated Vue wrappers. - `docs/components/*.md` owns each component's intended public contract and accessibility behavior. - Storybook stories demonstrate and test the public contract; they do not define it. - `apps/docs` owns consumer-facing MDX pages and live demos. Keep them aligned with the matching root specification; root `docs/` owns engineering contracts. - `assets/brand` owns reusable aidsgn identity artwork consumed by the docs and Storybooks. Use `docs/decisions` for decisions that affect more than one package or change a public convention. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/architecture/web-components.md # Native Web Component contract Components are standard custom elements written in TypeScript, with no Lit, Stencil, or equivalent runtime abstraction. They use light DOM only: authored or wrapper-emitted markup stays visible to application CSS, DOM inspection, automation, and accessibility tooling. Prefer `HTMLElement`, Custom Elements, native controls, events, and CSS custom properties. ## Public API - Use the `aidsgn-` prefix for custom-element names, custom events, emitted classes, owned data attributes, CSS custom properties, CSS layers, and animation names. - Use the `Aidsgn` prefix for exported component classes and generated framework component names. - Reflect simple declarative state through attributes where it benefits HTML use; expose typed properties for richer values. - Use documented child markup and attributes for composition and emit bubbling `CustomEvent`s for user interactions. - Keep public events, attributes, properties, slots, and CSS custom properties documented in the relevant component specification. - Use `ElementInternals` and form-associated custom elements when a control participates in a form. - Until a host is form-associated, place a native named control in its light DOM and document that it is the form participant; do not imply the custom-element host itself is submitted. - Let native events bubble through light DOM. Do not re-dispatch a second synthetic event merely to change its target. ## Form participation Input, Select, Textarea, Checkbox, Radio, and Rating participate in a surrounding native form through named native controls rendered in their light DOM. The custom-element hosts are not form-associated: adding `name` or `value` only to a host does not add it to `FormData`, and APIs such as `form.elements` and native constraint validation expose the descendant control. Native successful-control rules apply unchanged. Disabled controls and unchecked checkboxes or radios are omitted, while controls that share a name contribute repeated entries. Switch does not expose `name` or `value`; it represents an immediate setting rather than a value selected for later form submission. ## Registration and tree shaking The package root exports component classes, constants, types, and idempotent `defineAidsgn*()` functions without registering elements as an import side effect. Register the complete catalog once when that is appropriate: ```ts import "@aidsgn/components/register"; ``` For a smaller native bundle, import and call only the definitions an application uses: ```ts import { defineAidsgnButton } from "@aidsgn/components"; defineAidsgnButton(); ``` Keep component modules free of top-level DOM mutations. If a component controls an authored descendant aidsgn element, its definition function must also define that dependency. Package `sideEffects` metadata must list only intentional registration and stylesheet entry points. ## Rendering and styles - Do not attach a shadow root. Native consumers author the semantic elements and stable `aidsgn-*` classes explicitly; framework wrappers emit them. Consumers can import the complete `styles.css` index or select `styles/reset.css`, `styles/shared.css`, and the component modules they use. - Every public component is represented by the canonical render contract exported from `@aidsgn/components/render-contract`. React and Vue wrappers translate that contract into complete static markup during server and client rendering. - Custom-element classes are topology-free controllers. They adopt native descendants already present in light DOM, synchronize attributes or properties, and attach behavior; they never render component markup. - Custom-element code must not create, move, clone, replace, append, prepend, or remove light-DOM nodes. React or Vue owns every node emitted by its wrapper; native HTML consumers own every explicitly authored node. - Node ownership includes text nodes and comments. Do not assign `innerHTML`, `textContent`, `innerText`, or native `output.value`: these replace children. Controllers synchronize existing text leaves through `Text.data`; authored inline markup remains under consumer control. - Native markup must include a text node for each controller-updated label, heading, field message, price, or status. Use ` ` inside an initially empty text container, including hidden field messages. Framework wrappers reserve these text nodes automatically. When supplying rich inline markup, the consumer also owns its text updates. - Preserve consumer CSS classes on hosts and authored descendants. Synchronize only the component's documented classes with `classList`; never replace an element's complete `className` to change its state or variant. - Consume semantic CSS custom properties only. Components must not directly select primitive tokens. - A paired literal fallback is permitted only for resilience when the semantic custom property is absent; it is not a second token source of truth. - Use logical CSS properties (`margin-inline`, `padding-block`, `inset-inline`, etc.) so RTL works without a separate stylesheet. - Respect user preferences such as reduced motion and contrast where applicable. See [accessibility requirements](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/quality/accessibility.md) before defining interactions. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/README.md # Component specifications Each component file owns its public contract: purpose, API, states, keyboard behavior, accessibility semantics, token hooks, and responsive considerations. All components use light DOM only. Consumers can import `@aidsgn/components/styles.css` once after token CSS for the complete catalog, or combine `styles/reset.css`, `styles/shared.css`, and individual modules such as `styles/button.css` for a smaller CSS payload. Start with [Choosing components](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/ai/component-selection.md) when more than one component could fit a task. It compares the complete catalog by user intent and documents the important variant decisions. Implemented inventory: | Component | Specification | Status | | ----------------- | ---------------------------------------------- | ----------- | | Accordion | [accordion.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/accordion.md) | Implemented | | Alert | [alert.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/alert.md) | Implemented | | BottomSheet | [bottom-sheet.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/bottom-sheet.md) | Implemented | | Breadcrumb | [breadcrumb.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/breadcrumb.md) | Implemented | | Button | [button.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/button.md) | Implemented | | Card | [card.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/card.md) | Implemented | | Carousel | [carousel.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/carousel.md) | Implemented | | Checkbox | [checkbox.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/checkbox.md) | Implemented | | Dialog | [dialog.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/dialog.md) | Implemented | | Heading | [heading.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/heading.md) | Implemented | | Icon | [icon.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/icon.md) | Implemented | | Image | [image.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/image.md) | Implemented | | Input | [input.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/input.md) | Implemented | | Link | [link.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/link.md) | Implemented | | Pagination | [pagination.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/pagination.md) | Implemented | | ProgressIndicator | [progress-indicator.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/progress-indicator.md) | Implemented | | Price | [price.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/price.md) | Implemented | | Radio | [radio.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/radio.md) | Implemented | | Rating | [rating.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/rating.md) | Implemented | | Select | [select.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/select.md) | Implemented | | SideSheet | [side-sheet.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/side-sheet.md) | Implemented | | Switch | [switch.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/switch.md) | Implemented | | Tag | [tag.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/tag.md) | Implemented | | Tabs | [tabs.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/tabs.md) | Implemented | | Textarea | [textarea.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/textarea.md) | Implemented | | Toast | [toast.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/toast.md) | Implemented | | Tooltip | [tooltip.md](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/tooltip.md) | Implemented | Each specification distinguishes current behavior from planned work. Use native HTML controls and semantics wherever possible; a custom element should enhance rather than replace platform behavior. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/accordion.md # Accordion ## Purpose Organizes related, optionally collapsible content sections. ## Contract - Element: `aidsgn-accordion`, containing one or more `aidsgn-accordion-item` elements. - Each item uses its `summary` attribute for the trigger label; child nodes become content inside the light-DOM panel's inner wrapper (`.aidsgn-accordion-item__panel > div`). - `open` controls state. Multiple sections can remain expanded; single-expand coordination is deferred. - Author native `details` and `summary` elements inside each item. The controller retains their built-in disclosure semantics while animating panel expansion. A decorative chevron rotates with state; reduced-motion preferences remove both animations and apply native open and closed state immediately. - The accordion fills its available inline space so collapsing content does not resize the trigger or shift its chevron. - Content may contain interactive elements and must remain usable in every expansion state. ## Accessibility Use the native `details`/`summary` disclosure pattern. Collapsed panels are hidden and summary keeps built-in keyboard behavior without custom ARIA duplication. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/alert.md # Alert `aidsgn-alert` communicates a non-interactive status message. Every variant includes a decorative inline SVG icon in addition to color; the icon aligns with the first message line and does not shift multi-line content. Alert icons do not rely on Unicode glyph or emoji rendering. ## Public attributes - `variant`: `info`, `success`, `warning`, or `error` Errors use the assertive `alert` role. Other variants use the polite `status` role. Use concise text that describes the outcome or necessary next step. All variants use the same neutral outer border in light and dark themes. Status is communicated by the paired surface, text, icon, and semantics rather than a variant-specific border. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/bottom-sheet.md # BottomSheet ## Purpose Presents a compact modal choice or task anchored to the bottom edge of the viewport. It is particularly suited to touch-oriented actions where the options should remain close to the bottom of the screen. ## Contract - Element: `aidsgn-bottom-sheet`. - Direct child nodes become the scrollable sheet body and remain in light DOM. - `open`, `heading`, and `close-label`; `show()` and `close(returnValue?)`; bubbling `aidsgn-close`; and cancelable `aidsgn-cancel` behave exactly as documented for [Dialog](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/dialog.md). - `heading` defaults to `Bottom sheet`, but applications must supply a task-specific heading. - The authored native dialog closes from its close button, backdrop, Escape, `
`, or the public API. - Holding the native close button applies shared Press feedback without changing its 44px target; reduced motion suppresses the scale. - A visible handle provides drag-to-close. Dragging the handle downward by 30% of the sheet height (capped at `10rem`) closes the sheet and reports `drag` as the `aidsgn-close` reason; shorter drags return it to rest. - A completed, canceled, or interrupted drag releases pointer capture and clears its offset. Closing or disconnecting during a gesture also resets it, so reopening the same instance starts at rest. - A direct child marked `data-aidsgn-modal-actions` receives the shared wrapping action-row layout. - Opening first establishes the sheet's final top-layer geometry, then fades the backdrop and slides the stable surface vertically from the viewport bottom without changing its dimensions. The transition is removed when the user prefers reduced motion. ## Accessibility and responsive behavior Native `showModal()` provides modal semantics, background inertness, focus containment, and focus restoration. The body scrolls when content exceeds the available height while the heading and close control remain visible. The sheet spans the viewport width and has a default maximum block size of `40rem` or `90dvh`, whichever is smaller. Override the component bound with `--aidsgn-bottom-sheet-max-block-size`. Keep BottomSheet tasks short. It must remain operable with a keyboard and at desktop sizes even when the primary product context is touch. Drag-to-close is a supplemental pointer interaction; the close button, backdrop, Escape, and dialog forms remain available without it. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/breadcrumb.md # Breadcrumb `aidsgn-breadcrumb` communicates the current page's position in a hierarchy with native navigation and list semantics. ## Contract - Direct child elements are the ordered crumbs. Use anchors for ancestor pages and plain text for the current page. - The component preserves those elements in light DOM, wraps them in a native `nav` and `ol`, and inserts decorative separators. - `label` provides the navigation's accessible name and defaults to `Breadcrumb`. - The final child receives `aria-current="page"`; earlier children have any stale `aria-current` removed. - The list wraps without changing reading or focus order. Logical margins keep separators correct in RTL. ## Example ```html Home Components Breadcrumb ``` --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/button.md # Button ## Purpose Triggers an immediate user action. Use a link instead when navigation is the primary outcome. ## Contract - Element: `aidsgn-button` - States: default, hover, active, focus-visible, disabled, and loading. - Variants: `primary` (dominant action), `secondary` (supporting action), and `tertiary` (low-emphasis action). Primary is the default; use at most one primary action in a local action group. - Sizes: `medium` is the default control with a 44px minimum height; `small` provides a compact visual treatment with a 36px minimum height for dense supporting actions. Both sizes use rem dimensions and grow with the root text scale. - Buttons are action controls with a minimum 44px interactive target, rectangular control shape, active feedback, primary elevation, and theme-appropriate text and surfaces. Secondary and tertiary hover states use a restrained action tint rather than a generic neutral fill. The small size extends its hit area by at least 4px beyond each visual edge; keep at least 8px between adjacent small buttons so targets do not overlap. - Its light-DOM children become the content of a native ` 1 of 2 ``` When JavaScript is unavailable or delayed, the authored child content remains visible in document order. The enhanced scroll track and controls require custom-element registration. ## Accessibility and keyboard behavior - The host is a named `region` with `aria-roledescription="carousel"`. Each slide receives a number and `aria-roledescription="slide"`. Generic slide containers receive `role="group"`; authored semantic elements and explicit roles are preserved. - The viewport is keyboard-focusable so browser scrolling keys can operate it. Native behavior may include Arrow keys, Page Up/Down, Home/End, or platform scrolling commands; the component does not override these keys. - Previous and Next are overlaid native buttons with 44px targets. Holding an enabled button applies shared Press feedback without replacing its existing hover treatment or changing target geometry. They disable at the page boundaries unless `loop` is enabled, follow document order, and use the browser's standard button keyboard behavior. - Manual touch, pointer, trackpad, keyboard, and assistive-technology scrolling remain available. Do not place essential information only in a slide users must discover. - Simulated touch handles only primary-button mouse pointers. It does not replace native touch or pen behavior. A drag suppresses the resulting click so links and controls are not accidentally activated; an ordinary click remains unchanged. - Dragged content follows the mouse in both text directions. From the first page, drag left in LTR or right in RTL to reveal subsequent items; native RTL scroll offsets become negative without reversing the physical pointer delta. - Pagination follows the viewport's measured page on the next animation frame during direct or button-initiated scrolling and animates without replacing its dots. Button navigation does not animate pagination before native scrolling begins. Its equivalent `current of total` text is polite and atomic; direct scrolling updates it after scrolling settles instead of announcing every scroll event. - Reduced-motion preferences remove smooth scrolling, Press scaling, and control transitions. RTL documents retain logical slide order and reverse the decorative arrows without changing the labels. - Every slide's authored interactive content remains keyboard reachable. Avoid a large number of focusable controls across off-screen slides; use a list or grid when all items need rapid comparison. ## Responsive behavior and CSS hooks The carousel occupies its container width and shows one full item by default. `per-page` divides the available width between complete items, while `preview-size` reserves room for a partial next item. Content determines slide height; the component does not force equal heights. The host uses `contain: inline-size` so its track and long slide content cannot expand an ancestor's intrinsic minimum width in nested grid or flex layouts. Its parent supplies the available width; avoid a shrink-to-fit parent with no assigned width. Containment leaves the block size dependent on content and does not add paint clipping. Keep this rule when customizing the component, and keep horizontal overflow on the native viewport instead of hiding overflow on the document. No measurement element, resize loop, or DOM restructuring is needed. Card content may have responsive minimum widths, but those widths can overflow an individual slide at narrow sizes. Use wrapping content or change `per-page` for the available space. When overriding `--aidsgn-carousel-slide-size`, keep its size consistent with `per-page`, gaps, and preview space so page navigation still represents complete items. Test the document width, not just the Carousel's clipped viewport. | Attribute / custom property | Default | Purpose | | ------------------------------ | ---------------------------------- | --------------------------------------------- | | `per-page` | `1` | Complete items visible on each page | | `preview-size` | `0px` | Partial inline size of the next item | | `gap` | `var(--aidsgn-space-16, 1rem)` | Gap between adjacent items | | `--aidsgn-carousel-gap` | `var(--aidsgn-space-16, 1rem)` | CSS-only gap override when `gap` is not set | | `--aidsgn-carousel-slide-size` | Calculated from the three settings | Advanced override for each item's inline size | For a two-item card rail that reveals the next card, use `per-page="2" preview-size="4rem"`. Verify the last page, focus indicators, zoom reflow, long content, and RTL at every size. ## Browser support Carousel uses only features in the design system's [supported browser contract](https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/quality/browser-support.md): Custom Elements, native CSS Scroll Snap, inline-size containment, logical CSS, native buttons, and `Element.scrollIntoView()`. It does not depend on `scrollend`, experimental scroll-driven animation, a gesture library, or a JavaScript smooth-scroll polyfill. ## Non-goals - Autoplay or interactive pagination controls. - A hero banner that advances without user input. - Virtualization or very large collections. - Replacing a grid, data table, or other layout where simultaneous comparison is required. --- Source: https://github.com/SimonEggert/aidsgn/blob/1c4400c4c89d10e62f2690b72f92c2c05502526e/docs/components/checkbox.md # Checkbox ## Purpose Lets a user select one or more independent options. ## Contract - Element: `aidsgn-checkbox` - Attributes: `label`, `input-id`, `name`, `value`, `checked`, `disabled`, `required`, `helper-text`, `error-message`, and `invalid`. - Properties: `checked`, `disabled`, and `required`. - Author a native checkbox and its `