@@ -137,7 +137,7 @@ A real `radiogroup` (roving tab stop, arrows/Home/End/Space/Enter), check icon o
`Card` props: `title?: string`, `headingLevel?: 2-6` (renders `title` as a real heading; omit for a ``), `padding?: 'none' | 'sm' | 'md' | 'lg' | | `, `flush?: boolean` (no padding, wins over `padding`), `gap?: 'sm' | 'md' | 'lg' | | ` (stacks children in a column), `full?: boolean`, `skeleton?: boolean`, `href?: string` (renders a link card). Snippets: `children`, `headerActions`.
-`Surface` props: `elevation` (0-5), `material` (`auto | solid | frosted | glass | liquid`), `tone` (`neutral | brand | success | warning | error | info`), `variant` (`filled | outlined | ghost`), `radius`, `interactive`, `glow`, `grain`, `as`, plus the `p`, `px`, `py` spacing steps.
+`Surface` props: `elevation` (0-5), `material` (`auto` follows the theme, the default; `solid | frosted | glass | liquid` force one material), `tone` (`neutral | brand | success | warning | error | info`), `variant` (`filled | outlined | ghost`), `radius`, `interactive`, `glow`, `grain`, `as`, plus the `p`, `px`, `py` spacing steps.
Under a page ``, give card titles and `EmptyState` titles a valid level (`EmptyState` inside `PageShell` defaults to ``) so axe `heading-order` passes.
diff --git a/.agents/skills/codeatlas-ui/DEMOS.md b/.agents/skills/codeatlas-ui/DEMOS.md
index 726f49a5..b8ead90e 100644
--- a/.agents/skills/codeatlas-ui/DEMOS.md
+++ b/.agents/skills/codeatlas-ui/DEMOS.md
@@ -230,7 +230,7 @@ Every demo has a stable number. Fetch one with `get_demo` (MCP) or https://ui.co
| 223 | Surfaces | foundation/colors | |
| 224 | Text | foundation/colors | |
| 225 | Button glass variants | foundation/materials | |
-| 226 | Glass tiers | foundation/materials | Surface |
+| 226 | Material tiers | foundation/materials | Surface |
| 227 | Tinted and glowing | foundation/materials | Surface |
| 228 | Shadow scale | foundation/shadows | |
| 229 | Body and UI scale | foundation/typography | |
diff --git a/.agents/skills/codeatlas-ui/LAYOUT.md b/.agents/skills/codeatlas-ui/LAYOUT.md
index c5c388ce..a455ba21 100644
--- a/.agents/skills/codeatlas-ui/LAYOUT.md
+++ b/.agents/skills/codeatlas-ui/LAYOUT.md
@@ -295,5 +295,5 @@ Pass token steps to layout primitives, not raw CSS: `` is correct.
…
-…
+…
```
diff --git a/.agents/skills/codeatlas-ui/SKILL.md b/.agents/skills/codeatlas-ui/SKILL.md
index 97828b80..795d7655 100644
--- a/.agents/skills/codeatlas-ui/SKILL.md
+++ b/.agents/skills/codeatlas-ui/SKILL.md
@@ -32,7 +32,7 @@ Svelte 5 UI framework. Components are self-contained and prop-driven. Compose th
4b. **A live map/canvas behind every screen goes in `AppShellLayout`'s `stage` snippet**, never in a hand-built `position: absolute` layer: it mounts once, is click-through (panels use `class="ca-stage-panel"`), and reads `--ca-shell-inset-*`. Hide and pause it with `stageVisible` or `data-ca-stage="hidden"` on ``.
5. **CSS imports go once, in the root layout only.**
6. **Import from `@codeatlasdev/ui`**, never from internal paths like `../../../components/Button`.
-7. **Never combine `will-change: transform` with `backdrop-filter`.** Kills glass blur.
+7. **Write for the default style.** The theme decides how things look (`ThemeOptions`, `defaultStyle` defaults to `solid`: opaque, no blur). Do not add `material="glass"`, `variant="glass"` or blur CSS to look finished; glass is one opt-in style, see "Glass and frosted styles" below.
## Setup (root layout, once)
@@ -117,11 +117,19 @@ Never guess a prop name. This skill and `API.md` track the `main` branch, which
- **Mobile.** Heights use `var(--ca-vh)`, never `100vh`/`100dvh`. Fixed UI pads with `var(--ca-safe-*)`. Keyboard-aware forms use `use:keyboardAware`. Full-screen mobile screens are `MobilePane`, sticky form bars are `StickyActions`. Never write a 44px touch override: it is global under `(pointer: coarse)`.
- **Opening a view with a text field (dialog, sheet, search).** iOS only opens the keyboard for `focus()` called synchronously inside the tap. In the tap handler call `primeKeyboard()` first, then open the view, and mark the real field `use:autofocus`: ` { primeKeyboard(); open = true; }}>`. On touch, `autofocus` and `focusTextField` only focus after `primeKeyboard()` (no half-focused field without a keyboard); pass `{ touch: true }` to force it. No-op with a mouse. Never hand-roll `setTimeout(() => input.focus())`.
- **Streaming, external links, export.** Rows arriving over time are a `LiveList` (polite batched announcements, follow-the-tail that pauses when the user scrolls up, never moves focus; no `StatusChip`/live regions inside rows). External links are `ExternalLink` (rel, icon, localised "opens in a new tab"), not a hand-written `target="_blank"`. A CSV/JSON download is `ExportMenu` or `toCsv`/`toJson`/`downloadFile`.
-- **Theme.** One `ThemeOptions` object in `src/lib/theme.ts`, passed to `caThemeHandle`/`caThemePlugin` (SvelteKit) or `caUI` (Astro). Keep it a plain object with a type-only import so config files can load it in Node. Override tokens by declaring `--ca-*` on `:root`, no `!important`. Local dark/light islands: `data-theme-scope="dark|light"`.
+- **Theme.** The theme drives the whole look: one `ThemeOptions` object in `src/lib/theme.ts` (preset color, scheme, `defaultStyle`, radius, density, fonts, paper), passed to `caThemeHandle`/`caThemePlugin` (SvelteKit) or `caUI` (Astro). Keep it a plain object with a type-only import so config files can load it in Node. Override tokens by declaring `--ca-*` on `:root`, no `!important`. Local dark/light islands: `data-theme-scope="dark|light"`.
- **Setup.** `bunx @codeatlasdev/ui init` wires all of the above into a fresh SvelteKit or Astro app and is a dry run unless `--write` is passed (it prints `would create` and diffs, never overwrites a file, and keeps a `theme` the app already imports from elsewhere).
- **SEO.** Public pages use `` from `@codeatlasdev/ui/seo` with `canonical`; private pages pass `noindex`.
- **A11y tests.** `await expectNoA11yViolations(container)` from `@codeatlasdev/ui/testing` in every state (open, error, empty, light, dark); needs the optional peer `axe-core`.
+## Glass and frosted styles
+
+`glass`, `frosted` and the `liquid` design recipe are opt-in values of `defaultStyle` / `` (as are `solid`, `flat`, `outlined`, `tonal`, `clay`, `neumorphic`, `chrome`). `Surface`/`Card` `material` is `auto` (follows the theme) unless you need one explicit `solid | frosted | glass | liquid` surface. These rules apply only when blur is used:
+
+- **Never combine `will-change: transform` with `backdrop-filter`** on the same element or an ancestor: it kills the blur.
+- Never put `backdrop-filter` in app or component CSS: a component sets `data-ca-blur=""` (or is a `.ca-surface`) and `html[data-style]` drives the blur.
+- Never put `isolation: isolate` on a parent of a blurred surface: it captures the isolated context, not the page behind.
+
## Actions (`@codeatlasdev/ui/actions`)
Import from the subpath, never copy the logic. Every export:
diff --git a/.changeset/docs-glass-not-default.md b/.changeset/docs-glass-not-default.md
new file mode 100644
index 00000000..ed5f76e3
--- /dev/null
+++ b/.changeset/docs-glass-not-default.md
@@ -0,0 +1,5 @@
+---
+"@codeatlasdev/ui": patch
+---
+
+Docs, skill, AGENTS.md, README, MCP `list_surfaces` and component JSDoc present the library as theme-driven with `style` as one knob (default `solid`) and glass as an opt-in style. Glass-only rules (`backdrop-filter`, `data-ca-blur`, `will-change`) are scoped to a "Glass and frosted styles" section with their wording unchanged. Examples, templates and demo specs no longer pin `material="glass"`. The `liquid-glass` npm keyword is replaced by `theming` and `design-tokens`. No API changes.
diff --git a/AGENTS.md b/AGENTS.md
index d67bfe80..58b73204 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -10,6 +10,8 @@ This document covers everything an AI agent needs to know to work in this reposi
`@codeatlasdev/ui` is CodeAtlas's UI package. It is a Svelte 5 library published publicly on npm. Every company frontend imports components, tokens and styles from here.
+It is theme-driven: one `ThemeOptions` object (preset color, scheme, `defaultStyle`, radius, density, fonts, paper) decides how every component looks. `defaultStyle` is one knob of that object and defaults to `solid` (opaque paper, no blur); `flat`, `outlined`, `tonal`, `clay`, `neumorphic`, `frosted`, `glass` and `chrome` are the other options. Glass is opt-in, never the default and never the identity: write examples and screens for the default style, and read "Glass and frosted styles" below only when blur is in play.
+
---
## Monorepo structure
@@ -84,7 +86,7 @@ Accessibility rules (package and apps):
- A page has exactly one `` and one `id="main"`. `DocsShell` and `AuthLayout` already provide them; `AppShellLayout` renders `` as the `SkipLink` target (pass `mainId={null}` if the page renders its own ``: the region becomes a plain `div`, and `skipLink={false}` when embedding the shell in a page that already has a skip link). `PageShell` never emits ``.
- Screen reader announcements go through `announce(msg, politeness)` (one shared live region); do not create a new local `role="status"`. In SvelteKit, mount `RouteAnnouncer` (`@codeatlasdev/ui/kit`) once in the root layout.
- An `aria-label` on a button must contain the visible text (WCAG 2.5.3); compose with `aria-labelledby` as `Combobox` does with `ariaLabel`.
-- New surface CSS with glass/shadow/`border: none` needs an entry in the `@media (forced-colors: active)` block of `materials.css` (`CanvasText` border). Contrast tokens (`prefers-contrast: more`) come from `themeCSS`/`presetCSS`; `tests/contrast.test.ts` measures 7:1 for text and 3:1 for outlines in every preset.
+- New surface CSS that blurs, adds a shadow or sets `border: none` needs an entry in the `@media (forced-colors: active)` block of `materials.css` (`CanvasText` border). Contrast tokens (`prefers-contrast: more`) come from `themeCSS`/`presetCSS`; `tests/contrast.test.ts` measures 7:1 for text and 3:1 for outlines in every preset.
- `site/tests/routes.a11y.spec.ts` runs axe in dark, light and `forcedColors: "active"` on every route, and ensures at most one `#main`, one `` and one skip link per page. Its timeout is sized per route from the page's node count (axe walks every node, three passes), never a hand-kept list of slow routes; `A11Y_CPU_THROTTLE=` (CDP CPU throttling) reproduces a loaded machine deterministically.
The browser setup (`tests/setup.browser.ts`) parks the Playwright pointer outside the viewport before every test: the pointer is page state, so without it a test that hovers leaves `:hover` active on whatever the next file renders at the top-left (a filled Button reads its hover fill, a tooltip is already open) and results depend on file order. A test that needs a pointer moves it itself (`userEvent.hover`); `src/lib/testing/pointer-reset.svelte.test.ts` guards the hook.
@@ -119,37 +121,42 @@ Reading failures: locators fail with an ARIA snapshot; traces are in `__traces__
```
SvelteKit 3 (`@sveltejs/kit ^3`): config goes into `sveltekit({ adapter, ... })` (no `svelte.config.js`, no `kit` namespace), `tsconfig.json` extends `$app/tsconfig`, `$lib` is removed in favor of `#lib/*` (with the `.ts` extension), and `vite.config.ts` imports the theme with its `.ts` extension. `bunx @codeatlasdev/ui init` detects the Kit version. Details: the SvelteKit 3 section of `.agents/skills/codeatlas-ui/SKILL.md`.
-2. **`backdrop-filter` + `will-change: transform`**: never combine the two on the same element or an ancestor. It kills the glass blur. `backdrop-filter` is declared in `styles/surface.css` and `styles/materials.css` only: a component sets `data-ca-blur=""` (roles: `ultra-thin`, `thin`, `regular`, `thick`, `chrome`, `mat-thin`, `mat-regular`, `overlay`, `chrome-layer`, `tooltip`; `FloatingLayer` takes it as `blur="overlay"|"tooltip"`), or is a `.ca-surface`, so `html[data-style]` drives every blur. The role rules write `-webkit-backdrop-filter` first. `data-ca-blur-wide-off` drops it from 900px up (an inline layout); `.ca-btn--glass` and `.ca-icon-btn--glass` are the `regular` role through their own class and lose it while disabled. The modal scrim is `dialog.ca-overlay::backdrop` in `surface.css`. New blurred element: add the attribute, never the property; the migration is guarded by `src/lib/theme/surface-migration.svelte.test.ts` (computed styles against `surface-migration.baseline.json`).
+2. **Svelte 5 runes**: all code uses runes (`$state`, `$derived`, `$effect`, `$props`). Never use legacy `writable`/`readable`.
-3. **`isolation: isolate`**: `backdrop-filter` inside an `isolation: isolate` parent captures the isolated context, not the real backdrop.
+3. **`{@const}`**: valid only as an immediate child of `{#each}`, `{#if}`, `{#snippet}`, `{:else}`, or `Component`. Never inside `` or another element.
-4. **Svelte 5 runes**: all code uses runes (`$state`, `$derived`, `$effect`, `$props`). Never use legacy `writable`/`readable`.
+4. **`svelte:component`**: deprecated in runes mode. Use `{@const Icon = X}
` or `
` directly.
-5. **`{@const}`**: valid only as an immediate child of `{#each}`, `{#if}`, `{#snippet}`, `{:else}`, or `Component`. Never inside `
` or another element.
+5. **Sub-components**: `DropdownMenuItem` etc. are separate `.svelte` files exported by name; there are no dotted namespaces.
-6. **`svelte:component`**: deprecated in runes mode. Use `{@const Icon = X}
` or `
` directly.
+6. **OKLCH**: the whole color palette uses OKLCH. MUI does not accept OKLCH directly; if you integrate with MUI, convert to hex.
-7. **Sub-components**: `DropdownMenuItem` etc. are separate `.svelte` files exported by name; there are no dotted namespaces.
+7. **No inline CSS**: never `style="padding: 20px"` or `style="max-width: 480px"`. Use CSS classes with tokens (`var(--ca-space-5)`). The only exception is dynamic CSS custom properties: `style="--bar-w:{pct}%"`.
-8. **OKLCH**: the whole color palette uses OKLCH. MUI does not accept OKLCH directly; if you integrate with MUI, convert to hex.
+8. **No `Stack`/`Flex` for field layout inside `FormSection`**: `FormSection` already has `layout="grid"` (default), `layout="list"` and `layout="stack"`. Do not wrap fields in `Stack gap="4"` as a layout workaround.
-9. **No inline CSS**: never `style="padding: 20px"` or `style="max-width: 480px"`. Use CSS classes with tokens (`var(--ca-space-5)`). The only exception is dynamic CSS custom properties: `style="--bar-w:{pct}%"`.
+9. **`ca-*` classes are a public contract**: consuming apps use the BEM classes (`.ca-btn`, `.ca-dialog__body`, …) as CSS targets. Renaming or removing a `ca-*` class listed in [`docs/css-api.md`](docs/css-api.md) is a **breaking change**. When you create or rename a component, update that file. The stable parts, scoped variables and `data-*` hooks of every component are generated from its CSS into `API.md`, `dist/parts.json` and the MCP `list_parts`; a class a component only uses internally is named `ca-x-*` (never a hook), and `@keyframes` names are internal. `codeatlas-ui workarounds --strict` fails when an app selector targets anything else.
-10. **No `Stack`/`Flex` for field layout inside `FormSection`**: `FormSection` already has `layout="grid"` (default), `layout="list"` and `layout="stack"`. Do not wrap fields in `Stack gap="4"` as a layout workaround.
+10. **Mobile**: heights use `var(--ca-vh)` (never `100vh`/`100dvh`); `fixed` UI uses `var(--ca-safe-*)`; a form with a keyboard uses `use:keyboardAware` (`@codeatlasdev/ui/actions`); a full-screen mobile view is `MobilePane`, an action bar is `StickyActions`; the 44px touch target is global under `(pointer: coarse)`, so do not write an override in the app. App viewport: `width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content`.
-11. **`ca-*` classes are a public contract**: consuming apps use the BEM classes (`.ca-btn`, `.ca-dialog__body`, …) as CSS targets. Renaming or removing a `ca-*` class listed in [`docs/css-api.md`](docs/css-api.md) is a **breaking change**. When you create or rename a component, update that file. The stable parts, scoped variables and `data-*` hooks of every component are generated from its CSS into `API.md`, `dist/parts.json` and the MCP `list_parts`; a class a component only uses internally is named `ca-x-*` (never a hook), and `@keyframes` names are internal. `codeatlas-ui workarounds --strict` fails when an app selector targets anything else.
+11. **Theme**: a single `ThemeOptions` in `src/lib/theme.ts` (plain object, `import type` only: `vite.config`/`astro.config` load the file in Node, where the package root does not evaluate `.svelte`), passed to `caThemeHandle` + `caThemePlugin` (SvelteKit) or `caUI` (Astro). `defaultStyle` (the surface material, `solid` by default) is one field of it, not a separate setup. Override a token by declaring `--ca-*` on `:root` in the app, without `!important`. Local islands: `data-theme-scope="dark|light"`. Automatic setup: `bunx @codeatlasdev/ui init`.
-12. **Mobile**: heights use `var(--ca-vh)` (never `100vh`/`100dvh`); `fixed` UI uses `var(--ca-safe-*)`; a form with a keyboard uses `use:keyboardAware` (`@codeatlasdev/ui/actions`); a full-screen mobile view is `MobilePane`, an action bar is `StickyActions`; the 44px touch target is global under `(pointer: coarse)`, so do not write an override in the app. App viewport: `width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content`.
+12. **SEO**: a public page uses `
` from `@codeatlasdev/ui/seo` with a required `canonical`; a private page passes `noindex`.
-13. **Theme**: a single `ThemeOptions` in `src/lib/theme.ts` (plain object, `import type` only: `vite.config`/`astro.config` load the file in Node, where the package root does not evaluate `.svelte`), passed to `caThemeHandle` + `caThemePlugin` (SvelteKit) or `caUI` (Astro). Override a token by declaring `--ca-*` on `:root` in the app, without `!important`. Local islands: `data-theme-scope="dark|light"`. Automatic setup: `bunx @codeatlasdev/ui init`.
+ **A11y tests**: test every state (open, error, empty, light, dark) with `await expectNoA11yViolations(container)` from `@codeatlasdev/ui/testing` (needs the optional peer `axe-core`). Inside this repo `packages/ui/tests/a11y.ts` re-exports the same `checkA11y`; never fork the axe options.
-14. **SEO**: a public page uses `` from `@codeatlasdev/ui/seo` with a required `canonical`; a private page passes `noindex`.
+13. **Discovering the API**: never guess a prop. Use the `ca-ui-mcp` MCP server (`get_component`, `get_export`, `get_equivalent`, `list_components`, `list_parts`, `get_migration`, `search_tokens`, `list_surfaces`, `get_guide`) or `.agents/skills/codeatlas-ui/API.md`; both cover components and every non-component export (stores, `kit`, `vite`, `astro`, `actions`, `seo`, `forms`, `tokens`: signature + summary) and are generated from the code by `packages/ui/scripts/build-manifest.ts` (runs on `build`). `[ca-ui]` dev warnings (via `devWarn`, `esm-env`) flag an `IconButton` without `aria-label` and a `Dialog` without `title`.
- **A11y tests**: test every state (open, error, empty, light, dark) with `await expectNoA11yViolations(container)` from `@codeatlasdev/ui/testing` (needs the optional peer `axe-core`). Inside this repo `packages/ui/tests/a11y.ts` re-exports the same `checkA11y`; never fork the axe options.
+14. **Agent skills layout** (`npx skills add codeatlasdev/ui`): one folder per skill under `.agents/skills/`, named exactly like the `name:` in its `SKILL.md` (`codeatlas-ui`, `codeatlas-dx`, `codeatlas-writing`). Never put a `SKILL.md` directly in `.agents/skills/` (the CLI then treats the directory as a single skill and lists nothing else), and quote any `description:` that contains `: ` (an unquoted one is a YAML error and the CLI silently skips the skill). `packages/ui/tests/skills.test.ts` enforces this.
+
+---
+
+## Glass and frosted styles
-15. **Discovering the API**: never guess a prop. Use the `ca-ui-mcp` MCP server (`get_component`, `get_export`, `get_equivalent`, `list_components`, `list_parts`, `get_migration`, `search_tokens`, `list_surfaces`, `get_guide`) or `.agents/skills/codeatlas-ui/API.md`; both cover components and every non-component export (stores, `kit`, `vite`, `astro`, `actions`, `seo`, `forms`, `tokens`: signature + summary) and are generated from the code by `packages/ui/scripts/build-manifest.ts` (runs on `build`). `[ca-ui]` dev warnings (via `devWarn`, `esm-env`) flag an `IconButton` without `aria-label` and a `Dialog` without `title`.
+`glass`, `frosted` and the `liquid` recipe are opt-in surface styles (the package default is `solid`: opaque, no blur). The rules below apply only when blur is used: `html[data-style]` is `glass` or `frosted`, a component sets `data-ca-blur`, or a surface has `material="glass" | "frosted" | "liquid"`. An app on the default style never needs them, and a new example must not add `material="glass"` just to look finished.
-16. **Agent skills layout** (`npx skills add codeatlasdev/ui`): one folder per skill under `.agents/skills/`, named exactly like the `name:` in its `SKILL.md` (`codeatlas-ui`, `codeatlas-dx`, `codeatlas-writing`). Never put a `SKILL.md` directly in `.agents/skills/` (the CLI then treats the directory as a single skill and lists nothing else), and quote any `description:` that contains `: ` (an unquoted one is a YAML error and the CLI silently skips the skill). `packages/ui/tests/skills.test.ts` enforces this.
+- **`backdrop-filter` + `will-change: transform`**: never combine the two on the same element or an ancestor. It kills the glass blur. `backdrop-filter` is declared in `styles/surface.css` and `styles/materials.css` only: a component sets `data-ca-blur=""` (roles: `ultra-thin`, `thin`, `regular`, `thick`, `chrome`, `mat-thin`, `mat-regular`, `overlay`, `chrome-layer`, `tooltip`; `FloatingLayer` takes it as `blur="overlay"|"tooltip"`), or is a `.ca-surface`, so `html[data-style]` drives every blur. The role rules write `-webkit-backdrop-filter` first. `data-ca-blur-wide-off` drops it from 900px up (an inline layout); `.ca-btn--glass` and `.ca-icon-btn--glass` are the `regular` role through their own class and lose it while disabled. The modal scrim is `dialog.ca-overlay::backdrop` in `surface.css`. New blurred element: add the attribute, never the property; the migration is guarded by `src/lib/theme/surface-migration.svelte.test.ts` (computed styles against `surface-migration.baseline.json`).
+- **`isolation: isolate`**: `backdrop-filter` inside an `isolation: isolate` parent captures the isolated context, not the real backdrop.
---
@@ -418,7 +425,7 @@ Units: `PageShell` `gap` is a number of pixels, and `KpiGrid` `gap` is a number
| `AppSettings` | Settings: side nav + scrollable content |
| `PageShell` | Dashboard/content: normal scroll, max-width, configurable gap |
| `MobilePane` | Full screen above the shell on mobile (chat thread, history, detail): header with back, Escape closes, focus enters/returns, safe-area and virtual keyboard |
-| `StickyActions` | Form action bar stuck to the end of the scroll (`align="end" \| "stretch"`, `show`): glass, safe-area and virtual keyboard |
+| `StickyActions` | Form action bar stuck to the end of the scroll (`align="end" \| "stretch"`, `show`): themed bar chrome, safe-area and virtual keyboard |
### Content layout
| Component | Use |
@@ -444,14 +451,14 @@ Units: `PageShell` `gap` is a number of pixels, and `KpiGrid` `gap` is a number
| `BottomNav` | Bottom navigation for mobile |
| `MobileHeader` | Mobile header |
-### Glass surfaces
+### Surfaces
| Component | Use |
|---|---|
-| `Surface` | Generic container with configurable `material` (`auto`, `solid`, `frosted`, `glass`, `liquid`) and `elevation` |
+| `Surface` | Generic container with `material` (`auto` follows the theme; `solid`, `frosted`, `glass`, `liquid` are explicit), `elevation`, `tone`, `variant`, `radius` |
| `Card` | Surface with default padding, optional title, `flush`, `full` |
-| `LiquidGlass` | Liquid Glass effect with background distortion |
+| `LiquidGlass` | The SVG refraction layer `Surface` paints for `material="liquid"`; rarely used directly |
-`GlassCard`, `GlassSurface` and `Row` are deprecated: use `Card`, `Surface` and `Flex` (`bunx @codeatlasdev/ui migrate --write`).
+`GlassCard`, `GlassSurface` and `Row` are deprecated and not for new code: use `Card`, `Surface` and `Flex` (`bunx @codeatlasdev/ui migrate --write`).
### DataTable (TanStack Table v9)
```ts
@@ -477,7 +484,7 @@ import { DataTable, createCaTable, createCaColumnHelper, caTableFeatures } from
```
- **Touch target**: `--ca-touch-target: 44px` (`tokens.css`). Under `@media (pointer: coarse)` it becomes `min-height`/`min-width` of `IconButton`, the `Select` trigger, `TabsTrigger`, `ToggleGroup`, `SegmentedControl`, `PinInput` and calendar cells. It is a media query, not a prop: do not write 44px overrides in the app.
-### Inputs (own primitives with glass tokens)
+### Inputs (own primitives, themed by tokens)
`Button` · `IconButton` · `TextField` · `TextArea` · `Select` · `Combobox` · `Checkbox` · `Switch` · `Slider` · `NumberField` · `FileUpload` · `ToggleGroup` · `SegmentedControl` · `SwatchGroup` · `PinInput` · `CopyButton` · `DatePicker` · `DateRangePicker` · `DateField` · `TimeField` · `Calendar` · `RangeCalendar`
- **`Button` / `IconButton` `loading`**: swaps `leading` (Button) or the icon (IconButton) for a `Spinner`, applies `aria-busy="true"`, disables the click (`onclick` does not fire) and keeps the label. Class: `ca-btn--loading`.
@@ -609,7 +616,7 @@ import {
--ca-ease-standard / decelerate / accelerate / spring
--ca-duration-fast / base / slow
-/* Glass */
+/* Surface fill and blur (every style rewrites these; they are translucent only under glass and frosted) */
--ca-glass-bg / --ca-glass-separator / --ca-glass-tint-* / --ca-glass-border
--ca-blur-ultra-thin / thin / regular / thick / chrome
@@ -656,7 +663,7 @@ export const theme: ThemeOptions = {
presets: [{ id: "acme", color: "#2563eb" }],
defaultPreset: "acme", // used until the user picks another
defaultScheme: "system", // "light" | "dark" | "system"
- defaultStyle: "glass", // "glass" | "frosted" | "solid" | "flat"
+ defaultStyle: "solid", // the default; also "flat" | "outlined" | "tonal" | "clay" | "neumorphic" | "frosted" | "glass" | "chrome"
fonts: { body: "Geist, system-ui, sans-serif" },
radius: 1, // multiplier of the radius scale
density: "comfortable", // or "compact"
diff --git a/README.md b/README.md
index 3c039689..bd60aa01 100644
--- a/README.md
+++ b/README.md
@@ -61,7 +61,7 @@ export const theme = defineTheme({
```
every token derives from it, light and dark, on the first frame.
-want a vibe? `designStyle('liquid')`, `'swiss'`, `'brutalism'`, `'sketchbook'`… same components, new language.
+want a vibe? `designStyle('swiss')`, `'brutalism'`, `'sketchbook'`, `'liquid'` (the glass one)… same components, new language.
@@ -71,7 +71,7 @@ want a vibe? `designStyle('liquid')`, `'swiss'`, `'brutalism'`, `'sketchbook'`
|---|---|
| 🧱 **pages, not bricks** | `AppList` `AppForm` `AppSettings` `AppShellLayout` `AuthLayout` `DocsShell` |
| 🎨 **tokens all the way down** | no raw px in components, a lint fails the build if one sneaks in |
-| 🪟 **glass is a material, not a component** | ``, or `auto` to follow the theme |
+| 🪟 **style is a theme knob** | `defaultStyle` picks solid (default), flat, outlined, tonal, clay, frosted, glass…; `` follows it |
| 🧭 **real layers** | native `` + popover top layer, no z-index wars |
| ♿ **boring stuff, guaranteed** | aa/aaa contrast, 44px touch targets, no sideways scroll. tested |
| 🤖 **agent-native** | skills, `llms.txt` and an MCP server (`ca-ui-mcp`) generated from the code |
diff --git a/packages/ui/README.md b/packages/ui/README.md
index aa1d4856..7ce05b2f 100644
--- a/packages/ui/README.md
+++ b/packages/ui/README.md
@@ -55,7 +55,7 @@ export const theme = defineTheme({
```
every token derives from it, light and dark, on the first frame.
-want a vibe? `designStyle('liquid')`, `'swiss'`, `'brutalism'`, `'sketchbook'`… same components, new language.
+want a vibe? `designStyle('swiss')`, `'brutalism'`, `'sketchbook'`, `'liquid'` (the glass one)… same components, new language.
@@ -65,7 +65,7 @@ want a vibe? `designStyle('liquid')`, `'swiss'`, `'brutalism'`, `'sketchbook'`
|---|---|
| 🧱 **pages, not bricks** | `AppList` `AppForm` `AppSettings` `AppShellLayout` `AuthLayout` `DocsShell` |
| 🎨 **tokens all the way down** | no raw px in components, a lint fails the build if one sneaks in |
-| 🪟 **glass is a material, not a component** | ``, or `auto` to follow the theme |
+| 🪟 **style is a theme knob** | `defaultStyle` picks solid (default), flat, outlined, tonal, clay, frosted, glass…; `` follows it |
| 🧭 **real layers** | native `` + popover top layer, no z-index wars |
| ♿ **boring stuff, guaranteed** | aa/aaa contrast, 44px touch targets, no sideways scroll. tested |
| 🤖 **agent-native** | skills, `llms.txt` and an MCP server (`ca-ui-mcp`) generated from the code |
diff --git a/packages/ui/bin/ca-ui-mcp.ts b/packages/ui/bin/ca-ui-mcp.ts
index 722c9016..6039bc2a 100755
--- a/packages/ui/bin/ca-ui-mcp.ts
+++ b/packages/ui/bin/ca-ui-mcp.ts
@@ -274,7 +274,7 @@ server.registerTool(
"list_surfaces",
{
description:
- "List the surface styles (, colorScheme.setStyle): glass, frosted, solid, flat, outlined, neumorphic, clay, tonal, chrome. Each has its blur behaviour (full/reduced/none), the tokens it rewrites and the design recipes that default to it. Generated from the [data-style] selectors in materials.css. Optional query filters by id, description, token or recipe.",
+ "List the surface styles, one knob of the theme (, colorScheme.setStyle, ThemeOptions.defaultStyle; the package default is solid, glass and frosted are opt-in): glass, frosted, solid, flat, outlined, neumorphic, clay, tonal, chrome. Each has its blur behaviour (full/reduced/none), the tokens it rewrites and the design recipes that default to it. Generated from the [data-style] selectors in materials.css. Optional query filters by id, description, token or recipe.",
inputSchema: { query: z.string().optional() },
},
({ query }) => {
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 93ea780f..49aafd27 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -24,7 +24,8 @@
"ai-friendly",
"sveltekit",
"oklch",
- "liquid-glass",
+ "theming",
+ "design-tokens",
"datatable",
"appshell"
],
diff --git a/packages/ui/scripts/build-manifest.ts b/packages/ui/scripts/build-manifest.ts
index 3a271f55..9b7aa171 100644
--- a/packages/ui/scripts/build-manifest.ts
+++ b/packages/ui/scripts/build-manifest.ts
@@ -1030,10 +1030,10 @@ export function extractSurfaces(
});
}
-/** Styles with no `[data-style]` block: glass is the `:root` token set every other style rewrites. */
+/** Styles with no `[data-style]` block: glass is the `:root` token set every other style rewrites (it is opt-in; the package default is solid). */
const GLASS_DESCRIPTION: Partial> = {
glass:
- "Glass: the :root tokens untouched, full blur, translucent tints, glow and rim (the opt-in liquid look)",
+ "Glass (opt-in): the :root tokens untouched, full blur, translucent tints, glow and rim (the look of the liquid recipe)",
};
/**
diff --git a/packages/ui/src/cli/init.ts b/packages/ui/src/cli/init.ts
index 6d288b04..263ef42d 100644
--- a/packages/ui/src/cli/init.ts
+++ b/packages/ui/src/cli/init.ts
@@ -31,7 +31,7 @@ const THEME_BODY = `/**
*
* Keep this a plain object and import only from \`@codeatlasdev/ui/vite\` (or \`/astro\`): vite.config
* loads it in Node, where the package root (which imports .svelte files) cannot be evaluated. That
- * entry also exports \`designStyle("liquid", { ... })\` for a design recipe.
+ * entry also exports \`designStyle("swiss", { ... })\` (or another id) for a design recipe.
*/
export const theme: ThemeOptions = {
defaultPreset: "amber",
diff --git a/packages/ui/src/lib/components/Button/Button.svelte b/packages/ui/src/lib/components/Button/Button.svelte
index 38ce2717..bc0fd2d6 100644
--- a/packages/ui/src/lib/components/Button/Button.svelte
+++ b/packages/ui/src/lib/components/Button/Button.svelte
@@ -14,6 +14,7 @@
/** Own props, shared by both renderings. */
interface Own {
+ /** `filled` (default) is the primary action; `glass` is a tinted surface button (blur only under the glass and frosted styles). */
variant?: Variant;
/**
* `'neutral'` draws `outlined` and `ghost` without brand colour (neutral label and border), for a
diff --git a/packages/ui/src/lib/components/Card/Card.svelte b/packages/ui/src/lib/components/Card/Card.svelte
index 75279f83..d5083f8e 100644
--- a/packages/ui/src/lib/components/Card/Card.svelte
+++ b/packages/ui/src/lib/components/Card/Card.svelte
@@ -1,7 +1,8 @@
-
+
Tinted
Brand tint over the fill.
-
+
Glowing
Brand halo behind the surface.
diff --git a/site/public/api/v1/en/e/069.txt b/site/public/api/v1/en/e/069.txt
index 8b8ec1cf..adb269c3 100644
--- a/site/public/api/v1/en/e/069.txt
+++ b/site/public/api/v1/en/e/069.txt
@@ -1,13 +1,13 @@
Element: #069 Content card (surfaces/card)
-What it shows: A single glass Card with a Featured eyebrow, a heading, a description and an Explore materials link.
+What it shows: A single Card with a Featured eyebrow, a heading, a description and an Explore materials link.
When to use: Promo or feature cards in a landing page or dashboard that lead to a detail page.
Spec:
-- `` with `max-width: 360px`
-- Body is a `` with an eyebrow paragraph, `
Liquid Glass materials `, a description paragraph and a link
+- `
` with `max-width: 360px`
+- Body is a `` with an eyebrow paragraph, `
Surface materials `, a description paragraph and a link
- Link is `
Explore materials → `
- The card itself has no `href`, only the inner anchor is a link
-Tags: card, glass, content-card, featured, link, promo
+Tags: card, content-card, featured, link, promo
Needs: @codeatlasdev/ui@4.5.0
Components: Card
Live demo: https://ui.codeatlas.com.br/docs/surfaces/card#content-card
@@ -16,12 +16,12 @@ Live demo: https://ui.codeatlas.com.br/docs/surfaces/card#content-card
import { Card } from '@codeatlasdev/ui';
-
+
Featured
-
Liquid Glass materials
+
Surface materials
- Depth and clarity for UI surfaces through real-time backdrop blur and optical refraction.
+ Five depth tiers for every surface, drawn by the theme: solid by default, frosted or glass on request.
Explore materials →
diff --git a/site/public/api/v1/en/e/070.txt b/site/public/api/v1/en/e/070.txt
index 899db6bd..1aa946e9 100644
--- a/site/public/api/v1/en/e/070.txt
+++ b/site/public/api/v1/en/e/070.txt
@@ -1,12 +1,12 @@
Element: #070 Header and actions (surfaces/card)
-What it shows: A glass Card with a built-in Team members header and an Invite button supplied through a headerActions snippet.
+What it shows: A Card with a built-in Team members header and an Invite button supplied through a headerActions snippet.
When to use: Panels whose header needs a title and an action, such as team, billing or settings sections.
Spec:
-- `` with `max-width: 420px`
+- `` with `max-width: 420px`
- `{#snippet headerActions()}` renders `Invite `
- Body is one paragraph explaining `title` and `headerActions`
-Tags: card, header-actions, title, snippet, button, glass
+Tags: card, header-actions, title, snippet, button
Needs: @codeatlasdev/ui@4.5.0
Components: Card, Button
Live demo: https://ui.codeatlas.com.br/docs/surfaces/card#header-and-actions
@@ -15,7 +15,7 @@ Live demo: https://ui.codeatlas.com.br/docs/surfaces/card#header-and-actions
import { Card, Button } from '@codeatlasdev/ui';
-
+
{#snippet headerActions()}Invite {/snippet}
Use title and headerActions for a built-in card header.
diff --git a/site/public/api/v1/en/e/072.txt b/site/public/api/v1/en/e/072.txt
index 0388f7ef..76f71797 100644
--- a/site/public/api/v1/en/e/072.txt
+++ b/site/public/api/v1/en/e/072.txt
@@ -1,13 +1,13 @@
Element: #072 Stat cards (surfaces/card)
-What it shows: Three glass stat Cards in a flex row, each with a label, a large value and a delta line.
+What it shows: Three stat Cards in a flex row, each with a label, a large value and a delta line.
When to use: Dashboard KPI strips showing a metric, its value and a short qualifier.
Spec:
-- `{#each stats as s}` renders `` once per stat
+- `{#each stats as s}` renders `` once per stat
- 3 stats with `label`, `value`, `delta`: Components 70+, Presets 8, Tokens 80+
- Each card has three paragraphs: `{s.label}`, `{s.value}` and `{s.delta}`
- `.stat` uses `min-width: 140px` inside a wrapping flex `.grid`
-Tags: card, stats, kpi, dashboard, glass, metrics
+Tags: card, stats, kpi, dashboard, metrics
Needs: @codeatlasdev/ui@4.5.0
Components: Card
Live demo: https://ui.codeatlas.com.br/docs/surfaces/card#stat-cards
@@ -24,7 +24,7 @@ Live demo: https://ui.codeatlas.com.br/docs/surfaces/card#stat-cards
{#each stats as s}
-
+
{s.label}
{s.value}
{s.delta}
diff --git a/site/public/api/v1/en/e/073.txt b/site/public/api/v1/en/e/073.txt
index fadaf91e..efb0e958 100644
--- a/site/public/api/v1/en/e/073.txt
+++ b/site/public/api/v1/en/e/073.txt
@@ -4,7 +4,7 @@ What it shows: Three independent Collapsible FAQ panels stacked with a small gap
When to use: Short FAQ or help blocks where each answer expands on its own.
Spec:
- `` with `max-width: 560px`
-- 3 `` child, two of them include a `` token
- Nothing is bound to the open state, each panel manages its own
Tags: collapsible, faq, stack, disclosure, expand, title
@@ -17,8 +17,8 @@ Live demo: https://ui.codeatlas.com.br/docs/surfaces/collapsible#default-closed
-
- A glass surface uses backdrop-filter blur and a translucent tint to create a layered depth effect that reacts to the content behind it.
+
+ A surface style is one knob of the theme. It decides whether cards are solid paper, outlined, tonal or blurred, and every component follows it.
Presets remap the brand hue token. Switching preset updates every component that reads from --ca-brand-* without any JS.
diff --git a/site/public/api/v1/en/e/097.txt b/site/public/api/v1/en/e/097.txt
index 6f26603a..8eb2a0a7 100644
--- a/site/public/api/v1/en/e/097.txt
+++ b/site/public/api/v1/en/e/097.txt
@@ -1,9 +1,9 @@
Element: #097 Card layout (feedback/skeleton)
-What it shows: A glass card skeleton with a circular avatar placeholder beside three text lines of different widths.
+What it shows: A card skeleton with a circular avatar placeholder beside three text lines of different widths.
When to use: Loading placeholder for a profile or list card so layout does not jump when data arrives.
Spec:
-- ``
+- ``
- ` ` inside ``
- Three lines in ``: `height="16px" width="40%"`, `height="13px" width="70%"`, `height="13px" width="55%"`
Tags: skeleton, card, loading, avatar, placeholder
@@ -15,7 +15,7 @@ Live demo: https://ui.codeatlas.com.br/docs/feedback/skeleton#card-layout
import { Skeleton, Card, Stack, Flex } from '@codeatlasdev/ui';
-
+
diff --git a/site/public/api/v1/en/e/098.txt b/site/public/api/v1/en/e/098.txt
index 0ec664c2..cf5a99f4 100644
--- a/site/public/api/v1/en/e/098.txt
+++ b/site/public/api/v1/en/e/098.txt
@@ -1,9 +1,9 @@
Element: #098 Image placeholder (feedback/skeleton)
-What it shows: A flush glass card skeleton with a 180px rectangular image placeholder above two caption lines.
+What it shows: A flush card skeleton with a 180px rectangular image placeholder above two caption lines.
When to use: Loading placeholder for media cards such as products, posts or galleries.
Spec:
-- ``
+- ``
- ` ` fills the top of the card
- Caption in ``: `height="16px" width="50%"` and `height="13px" width="80%"`
- Caption wrapper `` has `padding: 16px`
@@ -16,7 +16,7 @@ Live demo: https://ui.codeatlas.com.br/docs/feedback/skeleton#image-placeholder
import { Skeleton, Card, Stack } from '@codeatlasdev/ui';
-
+
diff --git a/site/public/api/v1/en/e/099.txt b/site/public/api/v1/en/e/099.txt
index 4dfc2f2f..07753961 100644
--- a/site/public/api/v1/en/e/099.txt
+++ b/site/public/api/v1/en/e/099.txt
@@ -1,9 +1,9 @@
Element: #099 Text lines (feedback/skeleton)
-What it shows: A glass card skeleton with a 60% wide heading line above a block of three text lines.
+What it shows: A card skeleton with a 60% wide heading line above a block of three text lines.
When to use: Loading placeholder for an article or description block.
Spec:
-- `` with ``
+- `` with ``
- Heading line ` `
- Body lines ` ` render three rows from one element
Tags: skeleton, text, rows, card, loading
@@ -15,7 +15,7 @@ Live demo: https://ui.codeatlas.com.br/docs/feedback/skeleton#text-lines
import { Skeleton, Card, Stack } from '@codeatlasdev/ui';
-
+
diff --git a/site/public/api/v1/en/e/101.txt b/site/public/api/v1/en/e/101.txt
index 95209b4b..e8e19bbe 100644
--- a/site/public/api/v1/en/e/101.txt
+++ b/site/public/api/v1/en/e/101.txt
@@ -1,9 +1,9 @@
Element: #101 Section loader (feedback/spinner)
-What it shows: A glass card with a centered 40px spinner and a Loading data text.
+What it shows: A card with a centered 40px spinner and a Loading data text.
When to use: Loader for a whole section or panel while its data is fetched.
Spec:
-- ``
+- ``
- `` centers the spinner and text
- ` ` above `Loading data… `
Tags: spinner, loader, card, section, loading
@@ -15,7 +15,7 @@ Live demo: https://ui.codeatlas.com.br/docs/feedback/spinner#section-loader
import { Spinner, Card, Stack } from '@codeatlasdev/ui';
-
+
Loading data…
diff --git a/site/public/api/v1/en/e/124.txt b/site/public/api/v1/en/e/124.txt
index b93428d7..d76ba2f8 100644
--- a/site/public/api/v1/en/e/124.txt
+++ b/site/public/api/v1/en/e/124.txt
@@ -1,9 +1,9 @@
Element: #124 Horizontal (display/divider)
-What it shows: Three stacked text sections inside a glass card separated by horizontal dividers.
+What it shows: Three stacked text sections inside a card separated by horizontal dividers.
When to use: Separating sections of content inside a card or panel.
Spec:
-- `` wraps the content
+- `` wraps the content
- `` stacks Section A, B and C paragraphs
- ` ` is placed between them with no props
Tags: divider, horizontal, separator, card, stack
@@ -15,7 +15,7 @@ Live demo: https://ui.codeatlas.com.br/docs/display/divider#horizontal
import { Divider, Card, Stack } from '@codeatlasdev/ui';
-
+
Section A content
diff --git a/site/public/api/v1/en/e/125.txt b/site/public/api/v1/en/e/125.txt
index ef0c3a87..77e0012e 100644
--- a/site/public/api/v1/en/e/125.txt
+++ b/site/public/api/v1/en/e/125.txt
@@ -1,9 +1,9 @@
Element: #125 Vertical (display/divider)
-What it shows: Three text items in a row inside a glass card separated by vertical dividers.
+What it shows: Three text items in a row inside a card separated by vertical dividers.
When to use: Separating inline items in a toolbar or meta row.
Spec:
-- `` wraps the content
+- `` wraps the content
- `` lays out Left, Center and Right
- ` ` is placed between them
Tags: divider, vertical, orientation, separator, flex
@@ -15,7 +15,7 @@ Live demo: https://ui.codeatlas.com.br/docs/display/divider#vertical
import { Divider, Card, Flex } from '@codeatlasdev/ui';
-
+
Left
diff --git a/site/public/api/v1/en/e/126.txt b/site/public/api/v1/en/e/126.txt
index da42d851..4421fb12 100644
--- a/site/public/api/v1/en/e/126.txt
+++ b/site/public/api/v1/en/e/126.txt
@@ -3,7 +3,7 @@ Element: #126 In a results table (display/external-link)
What it shows: A table of three domains where each row ends with an ExternalLink to a registrar URL.
When to use: Table cells that link out to a third-party site, with the external-link affordance.
Spec:
-- `` wraps ``
+- `` wraps ``
- `const rows` has 3 entries with `domain`, `price` and `url`
- Header cells are Domain, Price and Registrar
- `Buy at registrar ` is rendered in each last cell
@@ -23,7 +23,7 @@ Live demo: https://ui.codeatlas.com.br/docs/display/external-link#in-a-results-t
];
-
+
Domain Price Registrar
diff --git a/site/public/api/v1/en/e/136.txt b/site/public/api/v1/en/e/136.txt
index 8dd4027a..c904c7ec 100644
--- a/site/public/api/v1/en/e/136.txt
+++ b/site/public/api/v1/en/e/136.txt
@@ -1,9 +1,9 @@
Element: #136 Horizontal scroll (display/scroll-area)
-What it shows: A horizontal ScrollArea with an always visible scrollbar holding a row of 24 Tag chips inside a glass card.
+What it shows: A horizontal ScrollArea with an always visible scrollbar holding a row of 24 Tag chips inside a card.
When to use: Overflowing chip, tag or filter rows that should scroll sideways instead of wrapping.
Spec:
-- `` wraps the area
+- `` wraps the area
- ``
- `{ length: 24 }` builds 24 tags labelled Tag 1 to Tag 24, each rendered as ` `
- Chips sit in a `` styled with `width: max-content` so the content overflows
@@ -18,7 +18,7 @@ Live demo: https://ui.codeatlas.com.br/docs/display/scroll-area#horizontal-scrol
const tags = Array.from({ length: 24 }, (_, i) => `Tag ${i + 1}`);
-
+
{#each tags as tag}
{/each}
diff --git a/site/public/api/v1/en/e/137.txt b/site/public/api/v1/en/e/137.txt
index b2748919..5cd51a4d 100644
--- a/site/public/api/v1/en/e/137.txt
+++ b/site/public/api/v1/en/e/137.txt
@@ -1,9 +1,9 @@
Element: #137 Vertical scroll (display/scroll-area)
-What it shows: A vertical ScrollArea capped at 220px tall containing 20 Lorem ipsum rows inside a glass card.
+What it shows: A vertical ScrollArea capped at 220px tall containing 20 Lorem ipsum rows inside a card.
When to use: Bounded panels such as activity logs or long option lists that scroll inside a fixed height.
Spec:
-- `
` wraps the area
+- `` wraps the area
- ``
- `Array.from({ length: 20 }, (_, i) =>` builds items labelled Item 1 to Item 20: Lorem ipsum dolor sit amet
- Each row is a `` rendered with `{#each items as item}`
@@ -18,7 +18,7 @@ Live demo: https://ui.codeatlas.com.br/docs/display/scroll-area#vertical-scroll
const items = Array.from({ length: 20 }, (_, i) => `Item ${i + 1}: Lorem ipsum dolor sit amet`);
-
+
{#each items as item}
{item}
diff --git a/site/public/api/v1/en/e/138.txt b/site/public/api/v1/en/e/138.txt
index 44f887a9..034f2ede 100644
--- a/site/public/api/v1/en/e/138.txt
+++ b/site/public/api/v1/en/e/138.txt
@@ -1,9 +1,9 @@
Element: #138 Cards on narrow containers (display/table)
-What it shows: A SimpleTable that turns each row into a stacked card on narrow screens, listing three users in a flush glass card.
+What it shows: A SimpleTable that turns each row into a stacked card on narrow screens, listing three users in a flush card.
When to use: Data tables that must stay readable on phones without horizontal scrolling.
Spec:
-- `` wraps the table
+- `` wraps the table
- `` with plain `thead` and `tbody`
- Header columns: Name, Email, Role, Status
- 3 rows from `rows` with `name`, `email`, `role`, `status`
@@ -24,7 +24,7 @@ Live demo: https://ui.codeatlas.com.br/docs/display/table#cards-on-narrow-contai
];
-
+
Name Email Role Status
diff --git a/site/public/api/v1/en/e/139.txt b/site/public/api/v1/en/e/139.txt
index 81903f53..6e3a4785 100644
--- a/site/public/api/v1/en/e/139.txt
+++ b/site/public/api/v1/en/e/139.txt
@@ -1,9 +1,9 @@
Element: #139 Default (scroll) (display/table)
-What it shows: A default SimpleTable listing three users with name, email, role and status in a flush glass card.
+What it shows: A default SimpleTable listing three users with name, email, role and status in a flush card.
When to use: Compact read-only tables that keep their columns and scroll horizontally when space runs out.
Spec:
-- `` wraps the table
+- `` wraps the table
- `` with no props, plain `thead` and `tbody`
- Header columns: Name, Email, Role, Status
- 3 rows from `rows` with `name`, `email`, `role`, `status`
@@ -23,7 +23,7 @@ Live demo: https://ui.codeatlas.com.br/docs/display/table#default-scroll
];
-
+
Name Email Role Status
diff --git a/site/public/api/v1/en/e/143.txt b/site/public/api/v1/en/e/143.txt
index 3caa3118..e6339fbc 100644
--- a/site/public/api/v1/en/e/143.txt
+++ b/site/public/api/v1/en/e/143.txt
@@ -1,6 +1,6 @@
Element: #143 Custom delay (display/tooltip)
-What it shows: Three tooltips with different open delays on glass buttons: instant, default and slow.
+What it shows: Three tooltips with different open delays on buttons: instant, default and slow.
When to use: Tuning how quickly a tooltip appears, instant for dense toolbars and slower for hints that should not flash.
Spec:
- `delay={0}` on the Instant button with `content="No delay (delay=0)"`
diff --git a/site/public/api/v1/en/e/151.txt b/site/public/api/v1/en/e/151.txt
index a7ac5f40..d5ad4fd6 100644
--- a/site/public/api/v1/en/e/151.txt
+++ b/site/public/api/v1/en/e/151.txt
@@ -1,9 +1,9 @@
Element: #151 Default (navigation/app-bar)
-What it shows: A glass app bar with a title on the left and search, notifications and avatar on the right, inside a flush glass card.
+What it shows: An app bar with a title on the left and search, notifications and avatar on the right, inside a flush card.
When to use: Top bar of a page or panel with a product title and a few global quick actions.
Spec:
-- `` wraps the bar
+- `` wraps the bar
- `GlassAppBar` content is `My Application `
- `{#snippet trailing()}` holds two `IconButton` items with `aria-label="Search"` and `aria-label="Notifications"`
- Trailing also has ` `
@@ -18,7 +18,7 @@ Live demo: https://ui.codeatlas.com.br/docs/navigation/app-bar#default
import { Search, Bell } from '@lucide/svelte';
-
+
My Application
{#snippet trailing()}
diff --git a/site/public/api/v1/en/e/152.txt b/site/public/api/v1/en/e/152.txt
index 59d296f0..f68286b8 100644
--- a/site/public/api/v1/en/e/152.txt
+++ b/site/public/api/v1/en/e/152.txt
@@ -1,9 +1,9 @@
Element: #152 With leading icon (navigation/app-bar)
-What it shows: A glass app bar with a menu button in the leading slot and an Upgrade button plus avatar in the trailing slot.
+What it shows: An app bar with a menu button in the leading slot and an Upgrade button plus avatar in the trailing slot.
When to use: Mobile or dashboard headers that need a menu toggle on the left and a primary call to action on the right.
Spec:
-- `` wraps the bar
+- `` wraps the bar
- `GlassAppBar` content is `Dashboard `
- `{#snippet leading()}` holds `` with ` `
- `{#snippet trailing()}` holds `Upgrade `
@@ -18,7 +18,7 @@ Live demo: https://ui.codeatlas.com.br/docs/navigation/app-bar#with-leading-icon
import { Menu } from '@lucide/svelte';
-
+
Dashboard
{#snippet leading()} {/snippet}
diff --git a/site/public/api/v1/en/e/162.txt b/site/public/api/v1/en/e/162.txt
index 9acd2ecb..83b03401 100644
--- a/site/public/api/v1/en/e/162.txt
+++ b/site/public/api/v1/en/e/162.txt
@@ -1,11 +1,11 @@
Element: #162 Horizontal stepper (navigation/stepper)
-What it shows: A four-step horizontal stepper inside a glass card with Back and Next buttons that advance the step.
+What it shows: A four-step horizontal stepper inside a card with Back and Next buttons that advance the step.
When to use: Multi-step flows such as onboarding or checkout where the user moves through ordered stages.
Spec:
- ` ` with `let step = $state(0)`
- `const steps` has 4 entries with a `label` field: Account, Profile, Billing, Review
-- Wrapper is `` with ``
+- Wrapper is `` with ``
- Body shows `Step {step + 1}: {steps[step].label}`
- Back is ` step--}>`
- Next is `= steps.length - 1} onclick={() => step++}>` and reads Finish on the last step
@@ -21,7 +21,7 @@ Live demo: https://ui.codeatlas.com.br/docs/navigation/stepper#horizontal-steppe
const steps = [{ label: 'Account' }, { label: 'Profile' }, { label: 'Billing' }, { label: 'Review' }];
-
+
diff --git a/site/public/api/v1/en/e/166.txt b/site/public/api/v1/en/e/166.txt
index 765a86dd..8a15bed8 100644
--- a/site/public/api/v1/en/e/166.txt
+++ b/site/public/api/v1/en/e/166.txt
@@ -74,7 +74,7 @@ Live demo: https://ui.codeatlas.com.br/docs/layout/app-shell#live-shell
-
+
Click a rail icon or a panel item. The demo keeps the pathname in local state.
diff --git a/site/public/api/v1/en/e/185.txt b/site/public/api/v1/en/e/185.txt
index c1e393b6..0f35720f 100644
--- a/site/public/api/v1/en/e/185.txt
+++ b/site/public/api/v1/en/e/185.txt
@@ -1,14 +1,14 @@
Element: #185 PageShell (layout/list-page)
-What it shows: A dashboard page shell with four KPI cards and a placeholder glass card for a chart or table.
+What it shows: A dashboard page shell with four KPI cards and a placeholder card for a chart or table.
When to use: The base page layout of a dashboard: title, headline metrics and a main content area.
Spec:
- `` is the root, with no description or actions
- `` holds 4 `KpiCard` items: Revenue `$118k`, Users `24.8k`, Growth `34%`, Uptime `99.9%`
- Each card has a `trend` and an `icon`, for example `trend={23.4} icon={DollarSign}`
-- `` holds the text Chart or data table goes here
+- `` holds the text Chart or data table goes here
- Frame size is `height: 420px`
-Tags: page-shell, dashboard, kpi-grid, kpi-card, card, glass, list-page
+Tags: page-shell, dashboard, kpi-grid, kpi-card, card, list-page
Needs: @codeatlasdev/ui@4.5.0
Components: PageShell, KpiCard, KpiGrid, Card
Live demo: https://ui.codeatlas.com.br/docs/layout/list-page#pageshell
@@ -26,7 +26,7 @@ Live demo: https://ui.codeatlas.com.br/docs/layout/list-page#pageshell
-
+
Chart or data table goes here
diff --git a/site/public/api/v1/en/e/187.txt b/site/public/api/v1/en/e/187.txt
index 996b8856..0a281533 100644
--- a/site/public/api/v1/en/e/187.txt
+++ b/site/public/api/v1/en/e/187.txt
@@ -1,14 +1,14 @@
Element: #187 Dashboard page (layout/page-shell)
-What it shows: A page shell inside a flush glass card with a title, description, New report action, four KPI cards and a placeholder card.
+What it shows: A page shell inside a flush card with a title, description, New report action, four KPI cards and a placeholder card.
When to use: Dashboard pages with a header, a primary action, headline metrics and a content area.
Spec:
-- `` wraps ``
+- `` wraps ``
- `{#snippet actions()}New report {/snippet}`
-- `` holds a `KpiGrid` and a ``
+- `` holds a `KpiGrid` and a ``
- `KpiGrid` has 4 `KpiCard` items: Revenue `$118k`, Users `24.8k`, Growth `34%`, Uptime `99.9%`
- Placeholder card text is Chart or data table goes here
-Tags: page-shell, dashboard, kpi-grid, card, glass, actions, header
+Tags: page-shell, dashboard, kpi-grid, card, actions, header
Needs: @codeatlasdev/ui@4.5.0
Components: PageShell, KpiCard, KpiGrid, Card, Stack, Button
Live demo: https://ui.codeatlas.com.br/docs/layout/page-shell#dashboard-page
@@ -18,7 +18,7 @@ Live demo: https://ui.codeatlas.com.br/docs/layout/page-shell#dashboard-page
import { TrendingUp, Users, DollarSign, Activity } from '@lucide/svelte';
-
+
{#snippet actions()}New report {/snippet}
@@ -30,7 +30,7 @@ Live demo: https://ui.codeatlas.com.br/docs/layout/page-shell#dashboard-page
-
+
Chart or data table goes here
diff --git a/site/public/api/v1/en/e/190.txt b/site/public/api/v1/en/e/190.txt
index 5c9c16cd..315567b5 100644
--- a/site/public/api/v1/en/e/190.txt
+++ b/site/public/api/v1/en/e/190.txt
@@ -3,7 +3,7 @@ Element: #190 Horizontal bars (charts/bar)
What it shows: A horizontal bar chart ranking eight products by a single Sales series, with values formatted as thousands.
When to use: Ranking items by one metric, such as top products or top accounts, when category labels are long.
Spec:
-- ``
+- ``
- One series `{ name: 'Sales', data: [9840, 8720, 7650, 6430, 5980, 4810, 3920, 3140] }`
- `categories={products}` with 8 product names
- `horizontal` prop
@@ -21,7 +21,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/bar#horizontal-bars
const products = ['Atlas Pro', 'Nova Suite', 'Relay SDK', 'Mesh API', 'Drift UI', 'Pulse DB', 'Forge CI', 'Orbit ML'];
-
+
`
+- ``
- 4 series in `series`: Organic, Paid, Referral, Direct, each with 6 values
- `categories={months}` with `'Jan'` to `'Jun'`
- `stacked` prop
@@ -22,7 +22,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/bar#stacked-bars
const fmt = (v: number) => `$${(v / 1000).toFixed(0)}k`;
-
+
(mode = 'grouped')}>Grouped
(mode = 'stacked')}>Stacked
-
+
`
+- ``
- One series `{ name: 'Revenue', data: [38400, 54200, 71600, 89800] }`
- `categories={['Q1', 'Q2', 'Q3', 'Q4']}`
- `valueFormatter={fmt}` renders `$${(v / 1000).toFixed(0)}k`
@@ -20,6 +20,6 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/bar#vertical-bars
const fmt = (v: number) => `$${(v / 1000).toFixed(0)}k`;
-
+
diff --git a/site/public/api/v1/en/e/194.txt b/site/public/api/v1/en/e/194.txt
index dba27e14..ec02a5e7 100644
--- a/site/public/api/v1/en/e/194.txt
+++ b/site/public/api/v1/en/e/194.txt
@@ -31,7 +31,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/gauge#animated-counter
});
-
+
String(Math.round(v))} height="260px" />
{label}
diff --git a/site/public/api/v1/en/e/195.txt b/site/public/api/v1/en/e/195.txt
index b1a1fabf..5596fdb3 100644
--- a/site/public/api/v1/en/e/195.txt
+++ b/site/public/api/v1/en/e/195.txt
@@ -6,7 +6,7 @@ Spec:
- `let value = $state(65)` shared by gauge and slider
- ` `
- ` `
-- `` stacks gauge and slider inside ``
+- `` stacks gauge and slider inside ``
Tags: gauge-chart, ring, slider, bind-value, state, interactive
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, Stack, Slider, GaugeChart
@@ -19,7 +19,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/gauge#progress-ring
let value = $state(65);
-
+
diff --git a/site/public/api/v1/en/e/196.txt b/site/public/api/v1/en/e/196.txt
index fbaf6013..368b6112 100644
--- a/site/public/api/v1/en/e/196.txt
+++ b/site/public/api/v1/en/e/196.txt
@@ -4,7 +4,7 @@ What it shows: A single gauge showing a score of 78 with a Score label.
When to use: Showing one headline score or health percentage in a compact card.
Spec:
- ` `
-- Wrapped in ``
+- Wrapped in ``
Tags: gauge-chart, score, value, label, card
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, GaugeChart
@@ -15,4 +15,4 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/gauge#simple-gauge
import { GaugeChart } from '@codeatlasdev/ui/charts';
-
+
diff --git a/site/public/api/v1/en/e/197.txt b/site/public/api/v1/en/e/197.txt
index 2a1b6c10..9aa988fd 100644
--- a/site/public/api/v1/en/e/197.txt
+++ b/site/public/api/v1/en/e/197.txt
@@ -6,7 +6,7 @@ Spec:
- `const zones: GaugeZone[]` with 3 entries: `{ until: 0.5, color: 'success' }`, `{ until: 0.8, color: 'warning' }`, `{ until: 1, color: 'error' }`
- `const metrics` with 3 items: CPU `67`, Memory `82`, Disk `45`, fields `label` and `value`
- `{#each metrics as m}` renders ` `
-- Each gauge sits in its own `` inside ``
+- Each gauge sits in its own `` inside ``
Tags: gauge-chart, zones, thresholds, grid, metrics, card
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, Grid, GaugeChart
@@ -31,7 +31,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/gauge#custom-zones
{#each metrics as m}
-
+
{m.label}
diff --git a/site/public/api/v1/en/e/198.txt b/site/public/api/v1/en/e/198.txt
index 20a969c0..72a9c51a 100644
--- a/site/public/api/v1/en/e/198.txt
+++ b/site/public/api/v1/en/e/198.txt
@@ -7,7 +7,7 @@ Spec:
- `data` is `CalendarHeatmapPoint[]` built with `Array.from({ length: 258 }` as `[ 'YYYY-MM-DD', value ]` pairs
- `range={['2026-01-01', '2026-09-15']}`
- `tooltipFormatter={(v) => `${v} commits`}`
-- `height="160px"` inside ``
+- `height="160px"` inside ``
Tags: heatmap-chart, calendar, activity, range, tooltip-formatter, card
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, HeatmapChart
@@ -28,6 +28,6 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/heatmap#calendar-heatmap
});
-
+
`${v} commits`} height="160px" />
diff --git a/site/public/api/v1/en/e/199.txt b/site/public/api/v1/en/e/199.txt
index 5a395f8e..73bcafa8 100644
--- a/site/public/api/v1/en/e/199.txt
+++ b/site/public/api/v1/en/e/199.txt
@@ -8,7 +8,7 @@ Spec:
- `xCategories={hours}` built from `String(i).padStart(2, '0') + ':00'` (24 labels)
- `yCategories={days}` with `'Mon'` to `'Sun'`
- `tooltipFormatter={(v) => `${v} tasks`}`
-- `height="320px"` inside ``
+- `height="320px"` inside ``
Tags: heatmap-chart, matrix, hours, weekdays, tooltip-formatter, card
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, HeatmapChart
@@ -33,6 +33,6 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/heatmap#hour-by-day-matrix
}
-
+
`${v} tasks`} height="320px" />
diff --git a/site/public/api/v1/en/e/200.txt b/site/public/api/v1/en/e/200.txt
index 5ca39795..bf61dc58 100644
--- a/site/public/api/v1/en/e/200.txt
+++ b/site/public/api/v1/en/e/200.txt
@@ -43,7 +43,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/heatmap#year-toggle
(year = 2026)}>2026
(year = 2025)}>2025
-
+
`${v} commits`} height="160px" />
diff --git a/site/public/api/v1/en/e/201.txt b/site/public/api/v1/en/e/201.txt
index 9cedbe8f..dd6d5a14 100644
--- a/site/public/api/v1/en/e/201.txt
+++ b/site/public/api/v1/en/e/201.txt
@@ -8,7 +8,7 @@ Spec:
- `categories={months}` with `'Jan'` to `'Sep'`
- `area` prop
- `valueFormatter={fmt}` renders `$${(v / 1000).toFixed(0)}k`
-- `height="360px"` inside ``
+- `height="360px"` inside ``
Tags: line-chart, area, revenue, time-series, value-formatter, card
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, LineChart
@@ -23,6 +23,6 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/line#area-with-gradient-fill
const fmt = (v: number) => `$${(v / 1000).toFixed(0)}k`;
-
+
diff --git a/site/public/api/v1/en/e/202.txt b/site/public/api/v1/en/e/202.txt
index 600f457d..db7e2697 100644
--- a/site/public/api/v1/en/e/202.txt
+++ b/site/public/api/v1/en/e/202.txt
@@ -7,7 +7,7 @@ Spec:
- `const profit = revenue.map((r, i) => r - expenses[i])` derives the third series
- `categories={months}` with `'Jan'` to `'Sep'`
- `valueFormatter={fmt}` renders `$${(v / 1000).toFixed(0)}k`
-- `height="300px"` inside ``
+- `height="300px"` inside ``
Tags: line-chart, multi-series, revenue, expenses, time-series, card
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, LineChart
@@ -24,7 +24,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/line#multi-line-comparison
const fmt = (v: number) => `$${(v / 1000).toFixed(0)}k`;
-
+
`
+- `height="300px"` inside ``
Tags: line-chart, simple, revenue, time-series, value-formatter, card
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, LineChart
@@ -22,6 +22,6 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/line#simple-line
const fmt = (v: number) => `$${(v / 1000).toFixed(0)}k`;
-
+
diff --git a/site/public/api/v1/en/e/204.txt b/site/public/api/v1/en/e/204.txt
index ca7a32e7..dfa7e9f7 100644
--- a/site/public/api/v1/en/e/204.txt
+++ b/site/public/api/v1/en/e/204.txt
@@ -36,7 +36,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/line#real-time-stream
});
-
+
String(i))}
diff --git a/site/public/api/v1/en/e/205.txt b/site/public/api/v1/en/e/205.txt
index 332d38df..b2a619b8 100644
--- a/site/public/api/v1/en/e/205.txt
+++ b/site/public/api/v1/en/e/205.txt
@@ -43,12 +43,12 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/overview#dashboard
-
+
-
+
-
+
-
+
`${v.toFixed(1)}%`} height="260px" />
-
+
-
+
-
+
({ name, max: 100 }))}
series={[
diff --git a/site/public/api/v1/en/e/206.txt b/site/public/api/v1/en/e/206.txt
index 75132990..2b332b8b 100644
--- a/site/public/api/v1/en/e/206.txt
+++ b/site/public/api/v1/en/e/206.txt
@@ -7,7 +7,7 @@ Spec:
- `{#each quarters as q}` renders ` (selected = q)}` changes the quarter
- `qData` has 4 items per quarter: Cloud, Enterprise, SaaS, Other
-- ` ` inside ``
+- ` ` inside ``
Tags: pie-chart, donut, chip, quarters, state, derived
Needs: @codeatlasdev/ui@4.5.0 + echarts
Components: Card, Flex, Chip, PieChart
@@ -35,7 +35,7 @@ Live demo: https://ui.codeatlas.com.br/docs/charts/pie#animated-proportions
(selected = q)} variant="brand" size="sm" />
{/each}
-
+