Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 4 additions & 4 deletions .agents/skills/codeatlas-ui/ANTIPATTERNS.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ Explicit don'ts. Each one has a correct alternative.
<div style="background: #1e293b; color: #f8fafc;">

<!-- ✓ Semantic token -->
<div style="background: var(--ca-glass-bg); color: var(--ca-text-primary);">
<div style="background: var(--ca-surface-raised); color: var(--ca-text-primary);">
```

```css
/* ✗ Tint in OKLCH: gray tokens have hue 0°, so blue drifts to purple/pink */
background: color-mix(in oklch, var(--ca-brand-main) 15%, var(--ca-glass-tint));
background: color-mix(in oklch, var(--ca-brand-main) 15%, var(--ca-surface-raised));

/* ✓ Mix a color with a neutral (gray token, black, white, transparent) in OKLab */
background: color-mix(in oklab, var(--ca-brand-main) 15%, var(--ca-glass-tint));
background: color-mix(in oklab, var(--ca-brand-main) 15%, var(--ca-surface-raised));
```

---
Expand All @@ -68,7 +68,7 @@ background: color-mix(in oklab, var(--ca-brand-main) 15%, var(--ca-glass-tint));
<!-- ✓ -->
<Card flush>

<!-- ✗ will-change + backdrop-filter: kills glass blur -->
<!-- ✗ will-change + backdrop-filter (only when you blur: glass/frosted styles): kills the blur -->
<div style="will-change: transform; backdrop-filter: blur(12px);">

<!-- ✓ Never combine these two on the same element or its ancestors -->
Expand Down
8 changes: 4 additions & 4 deletions .agents/skills/codeatlas-ui/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ Parts: `ca-breadcrumb__current` `ca-breadcrumb__item` `ca-breadcrumb__link` `ca-

| Prop | Type | Default | Notes |
|---|---|---|---|
| `variant?` | `'filled' \| 'glass' \| 'outlined' \| 'ghost' \| 'destructive'` | `'filled'` | |
| `variant?` | `'filled' \| 'glass' \| 'outlined' \| 'ghost' \| 'destructive'` | `'filled'` | `filled` (default) is the primary action; `glass` is a tinted surface button (blur only under the glass and frosted styles). |
| `tone?` | `'brand' \| 'neutral'` | `'brand'` | `'neutral'` draws `outlined` and `ghost` without brand colour (neutral label and border), for a secondary action beside a brand `filled` one. Other variants ignore it. |
| `size?` | `'sm' \| 'md' \| 'lg'` | `'md'` | |
| `disabled?` | `boolean` | `false` | |
Expand Down Expand Up @@ -484,7 +484,7 @@ Parts: `ca-alert__content` `ca-callout`

`import { Card } from "@codeatlasdev/ui"`

Card — a Surface with a header (`title`, `headerActions`), padding and an optional link. Every Surface prop (`elevation`, `material`, `tone`, `variant`, `radius`, `glow`) passes through.
Card — a Surface with a header (`title`, `headerActions`), padding and an optional link. Every Surface prop (`elevation`, `material`, `tone`, `variant`, `radius`, `glow`) passes through; `material` defaults to `auto`, which follows the theme.

| Prop | Type | Default | Notes |
|---|---|---|---|
Expand Down Expand Up @@ -3178,7 +3178,7 @@ Surface — the one painted container every card, panel and sheet is built on. I
| `py?` | `Responsive<Space>` | | Vertical padding. |
| `as?` | `string` | `'div'` | Element to render. Cards with an `href` render `a` through `Card`. |
| `elevation?` | `0 \| 1 \| 2 \| 3 \| 4 \| 5` | `1` | Depth 0–5: drop shadow, and the blur/fill tier of the material (0 flat, 3 regular, 5 chrome). |
| `material?` | `'auto' \| 'solid' \| 'frosted' \| 'glass' \| 'liquid'` | `'auto'` | `auto` follows `<html data-style>`; the others are absolute. `liquid` adds the SVG refraction layer. |
| `material?` | `'auto' \| 'solid' \| 'frosted' \| 'glass' \| 'liquid'` | `'auto'` | `auto` follows `<html data-style>`; `solid`, `frosted`, `glass` and `liquid` are absolute. `liquid` adds the SVG refraction layer. |
| `tone?` | `'neutral' \| 'brand' \| 'success' \| 'warning' \| 'error' \| 'info'` | `'neutral'` | Semantic tint over the fill (and the outline color of `variant="outlined"`). |
| `variant?` | `'filled' \| 'outlined' \| 'ghost'` | `'filled'` | `filled` (default), `outlined` (edge, no fill) or `ghost` (no fill, no edge). |
| `radius?` | `'none' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'pill'` | | Corner radius; omit for the large radius. |
Expand Down Expand Up @@ -4698,7 +4698,7 @@ Types:
| `Space` | `type Space = (typeof SPACE)[number] \| `${(typeof SPACE)[number]}`;` | |
| `StageInsets` | `interface StageInsets { top: number; right: number; bottom: number; left: number; }` | |
| `SurfaceColors` | `interface SurfaceColors { sunken: string; base: string; raised: string; overlay: string; }` | |
| `SurfaceStyle` | `type SurfaceStyle = \| "glass" \| "frosted" \| "solid" \| "flat" \| "outlined" \| "neumorphic" \| "clay" \| "tonal" \| "chrome";` | Surface material. glass/frosted blur the backdrop; the rest are opaque. |
| `SurfaceStyle` | `type SurfaceStyle = \| "glass" \| "frosted" \| "solid" \| "flat" \| "outlined" \| "neumorphic" \| "clay" \| "tonal" \| "chrome";` | Surface material, the `defaultStyle` knob of the theme (default `solid`). glass/frosted blur the backdrop and are opt-in; the rest are opaque. |
| `TextAreaTokens` | `interface TextAreaTokens extends FieldTokens { minHeight?: CssValue; }` | |
| `TextColors` | `interface TextColors { primary: string; secondary: string; disabled: string; }` | |
| `ThemeDefinition` | `interface ThemeDefinition { presets: PresetDefinition[]; defaultPreset: string; defaultScheme: ColorScheme; defaultStyle: SurfaceStyle; fonts: { display?: FontSpec; body?: FontSpec; mono?: FontSpec }; radius: number; controlRadius: "xs" \| "sm" \| "md" \| "lg" \| "xl" \| "pill"; density: Density; border: { width?: number; strong?: number }; typography: TypographyOptions; type: TypeScale; elevation: ElevationModel; motion: MotionOptions; iconStroke: number; noise: number; paper: Paper; components: ComponentTokens; overrides: { light?: TokenMap; dark?: TokenMap }; }` | |
Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/codeatlas-ui/COMPONENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ A real `radiogroup` (roving tab stop, arrows/Home/End/Space/Enter), check icon o

## Card / Surface

`Card` is the container for titled content. `Surface` is the painted container underneath it (elevation, material, tone, variant, radius) for panels and custom blocks that are not a titled card. `GlassCard`, `GlassSurface` and `Row` are deprecated: use `Card`, `Surface` and `Flex` (`bunx @codeatlasdev/ui migrate --write`).
`Card` is the container for titled content. `Surface` is the painted container underneath it (elevation, material, tone, variant, radius) for panels and custom blocks that are not a titled card. Leave `material` unset (`auto`): it follows the theme. `GlassCard`, `GlassSurface` and `Row` are deprecated and not for new code: use `Card`, `Surface` and `Flex` (`bunx @codeatlasdev/ui migrate --write`).

```svelte
<Card title="Revenue">
Expand All @@ -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 `<p>`), `padding?: 'none' | 'sm' | 'md' | 'lg' | <css length> | <number in px>`, `flush?: boolean` (no padding, wins over `padding`), `gap?: 'sm' | 'md' | 'lg' | <css length> | <number in px>` (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 `<h1>`, give card titles and `EmptyState` titles a valid level (`EmptyState` inside `PageShell` defaults to `<h2>`) so axe `heading-order` passes.

Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/codeatlas-ui/DEMOS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 | |
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/codeatlas-ui/LAYOUT.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,5 +295,5 @@ Pass token steps to layout primitives, not raw CSS: `<Flex gap="4">` is correct.
<div style="background: #1a1a2e; color: #e2e8f0;">…</div>

<!-- ✓ Correct -->
<div style="background: var(--ca-glass-bg); color: var(--ca-text-primary);">…</div>
<div style="background: var(--ca-surface-raised); color: var(--ca-text-primary);">…</div>
```
12 changes: 10 additions & 2 deletions .agents/skills/codeatlas-ui/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<html>`.
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)

Expand Down Expand Up @@ -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`: `<Button onclick={() => { 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 `<Seo>` 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` / `<html data-style>` (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="<role>"` (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:
Expand Down
5 changes: 5 additions & 0 deletions .changeset/docs-glass-not-default.md
Original file line number Diff line number Diff line change
@@ -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.
Loading