# @codeatlasdev/ui 4.6.0: Interfaces with soul: Theme Studio, a UI index and a faster gate
Released 2026-10-25. Page: https://ui.codeatlas.com.br/changelog/4.6.0/. Index: https://ui.codeatlas.com.br/llms/changelog.txt. 130 changes in 130 pull requests (57 features, 62 fixes), 111 changesets.
4.6.0 is the biggest release so far: 111 changesets, 130 merged pull requests. You can now design a whole theme in a studio built on the real engine, search every demo and page by facet, read each design style as a live page, check every claim about users against a source, add opt-in sound, render overlays inside a themed preview, and trust that a hover panel never opens under a modal. It also ships a maplibre-gl 6 fix for a critical advisory and a test system that runs only what your change reaches.
## Numbers
- Changesets: 111. 59 minor and 52 patch, counted from .changeset/ at the commit this post was written on. No major.
- Merged pull requests: 130. Between the 4.5.0 tag and commit a73cb682, from git log; 62 fixes, 57 features, 11 docs, chores and tests.
- Test run for a one-component edit: 28 s. Fresh dist, load 15 on a 12-core machine: unit 0.4 s, components 4.6 s, screenshots 6.7 s, routes 16.6 s. Recorded in PR 547.
- Sound engine, gzip: 3.55 kB. Own code of the sound entry with Svelte external, hard limit 4096 B in size-limit.json. Core carries 0 engine bytes.
## In short
1. Theme Studio. Design a whole theme on the real engine, preview it on eight screens at three widths, and export the code.
2. The UI index and gallery viewer. Every demo and page is searchable by facet, every filter is a shareable link, and every item opens on Preview, Code, Prompt and Anatomy.
3. Design style pages. Six styles as live pages, each rendered in its own style, with before and after on real components.
4. Evidence, atlas and concepts. 269 design terms and 45 sources that were opened and read, with every claim labelled by how strong its support is.
5. Opt-in sound. Synthesized interface sound in a separate entry, off by default and started only by a gesture.
6. Inline overlays. Dialog, Sheet, Drawer, Popover, DropdownMenu and Toaster can render in place, inside a themed island.
7. Hover that respects modals. A new layers store keeps tooltips, hover cards and menus from opening under a dialog.
8. A larger kit. Carousel, ResizablePanels, Menubar, ContextMenu, HoverCard, NavigationMenu, ButtonGroup, Stat, Kanban and more.
9. A test system that runs what you changed. Affected-only tests, one pass per route, a machine-wide lock and time budgets that fail a slow run.
10. maplibre-gl 6 and the advisory. MapStage works on maplibre-gl 6, which carries the fix for a critical XSS in the attribution sanitizer.
11. Accessibility fixes. Fixes found by axe and by keyboard, from the label that must contain the visible text to scroll regions you can reach.
## Theme Studio
The theme editor at [/theme/](/theme/) is now a studio built on the real engine. Every control maps one to one onto a `ThemeOptions` key; the studio invents nothing of its own, so what you see is what your app gets.
You start from one of 12 curated looks (or "Surprise me", which is seeded and always compiles), then shape it: the brand colour with an inline contrast report, 18 colour roles per scheme, nine surface materials, radius, density, fonts, the type scale by role and motion. The preview shows eight screens (dashboard, settings, list, sign in, landing, pricing, form and overlays) at 390, 768 and 1280 with light and dark side by side. It starts from `designDefaults()`, so it shows what a fresh app gets, not this site's sketchbook theme.
The colour controls are in the library now. `ColorField` takes a hex, `rgb()` or `oklch()` value and shows the WCAG contrast of the pair as you type; `SliderField` pairs a slider with an editable number and a unit. Both are real components, so this is the same code the studio runs:
The same stage that frames the studio's previews is exported as `PreviewStage`: a resizable device frame with a width control and a keyboard-operable splitter. Drag the splitter, or press an arrow key on it, and the components inside reflow at that width:
When you are done, the Code tab gives you `theme.ts`, the compiled CSS, the SvelteKit and Astro wiring and a share URL that round-trips (`#t=v1...`). "Apply to site" writes the compiled CSS under a key of its own in your browser only, replayed by an inline script before first paint; "Reset" removes it. There is no account and no server.
```ts
export const theme = defineTheme({
preset: "ocean",
defaultStyle: "solid",
radius: 12,
type: { label: { size: "13px", leading: 1.25, tracking: "0", weight: 500 } },
});
```
## The UI index and gallery viewer
The gallery used to be a long list. It is now an index: every numbered demo and every page template carries a block of facets (what it is, how it moves, which style, which technique, what it costs) and the gallery filters on them.
Chips for kind, subtype, style, motion, interaction, layout, colour mode, density, tech and cost narrow the cards as you click, show how many entries each value would match, and drop combinations that match nothing. Words match titles, aliases, tags and components. Facets, words and the group live in the URL, so `?kind=motion&style=aurora&q=fade` is a link you can share.
An item opens on four tabs. **Preview** is a large resizable stage; **Code** is the source; **Prompt** is the text to hand an AI (the `get_demo` call, the library parts, the behaviour to keep, the exact motion timings and the reduced-motion and keyboard promises read from the index); **Anatomy** lists the components with their package and docs link, how the demo is built and its related items.
The index is the same data for agents. `ca-ui-mcp` gains `search_ui`, `list_facets` and `get_related`, and the build writes `api/v1/index.json` plus one markdown twin per item.
There is a rule about what the index is allowed to say. A facet that a person read by hand reaches search only when the one-sided 95% upper bound of its error rate, on a seeded and folder-stratified audit, is at most 5%. 0 wrong of 73 reads is "at most about 4% wrong", never "0%". Today `industry` is withheld: 5 wrong of 73, an upper bound of about 14%. Only 203 of 385 entries were ever re-read by a person; the other 182 hold the first pass's value as corrected by rules, and we say so.
```bash
claude mcp add codeatlas-ui -- npx -y -p @codeatlasdev/ui ca-ui-mcp
# then ask: search_ui { "q": "fade", "motion": "subtle", "style": "aurora" }
```
## Design style pages
[/styles/](/styles/) has six pages: Swiss, Editorial, Brutalism, Sketchbook, Glassmorphism and Terminal. Each page is rendered in the style it describes, so the type, corners, depth and motion you see are `designStyle("...")` applied to that page.
Each page has the origin, the traits (type, colour, shape, depth, motion), do and don't, the accessibility pitfalls with their sources, the same components before and after, the recipe to copy and a prompt for your coding agent. A recipe is a proposal built from the library's design knobs, not a measurement of any named visual language, and no claim says one style performs better than another.
"Apply to site" works here too: it wears the recipe in your browser only. `designDefaults()` is now exported, so a scoped preview can reset whatever an outer theme set. And the docs no longer present glass as the identity of the library: the default style is `solid`, and glass is one style among many.
```ts
export const theme = defineTheme(designStyle("editorial"));
```
## Evidence, atlas and concepts
If a page says "people read faster with X", where does that come from? 4.6.0 adds a contract for exactly that, and the machinery to keep it.
The **design atlas** lists 269 terms (`DS001` to `DS269`) with category, definition, traits, sectors, UX risk and mitigation, three heuristic scales from 1 to 5, the status in 2026, a 2027 to 2030 trend (an editorial projection, not a forecast), how standard the term is and its references. You can browse it with facets at [/atlas/](/atlas/), and agents get `search_terms`, `get_term` and `get_reference`.
The **evidence** layer holds 45 sources. Every one was opened on a recorded date, with the wording relied on kept as an excerpt and the route used to read it. A claim carries one of five labels (established, supported, preliminary, practice, heuristic), a scope (who or what was studied, which task, which context) and its sources. A standard counts as practice, a vendor study as preliminary. A reference also records what it does not support. Tests fail on a banned phrase, on a claim with no scope and on a citation to a source that was not read.
The four Concepts pages (viewport-complete UX, motion that respects people, targets and focus, appeal is not usability) are written to that template, each with a dated Limits box.
## Opt-in sound
`@codeatlasdev/ui/sound` is a new optional entry: interface sound with no audio files. Every cue is a short oscillator and noise recipe, so the whole engine is small.
Sound is off by default. One shared `AudioContext` is created only inside the first pointer or key event after the visitor turns sound on with `SoundToggle` (`aria-pressed`, an accessible name, an optional volume slider); the choice persists in `localStorage` under `ca-sound`. Four profiles (`system`, `glass`, `brutal`, `terminal`) follow the design style through `--ca-sound-profile`, and `--ca-sound-gain`, `--ca-sound-pitch` and `--ca-sound-brightness` tune them. Hover and slider tick cues are off under `prefers-reduced-motion`, sound is suspended while the tab is hidden or media plays, and sound is never the only signal.
**Sound engine size**
- Own code of ./sound: 3.55 kB gzip
Conditions: Own code of the ./sound entry with the Svelte runtime external, gzip, as measured for pull request 577; the limit is 4096 B in packages/ui/size-limit.json. Core is a no-op hook (soundBus), and a test fails if any core module imports the engine.
```svelte
```
## Inline overlays
Overlays live in the browser's top layer, which is the right place for a real dialog and the wrong place for a preview: a dialog opened inside a themed island escapes to `body` and loses the island's tokens. That is why the old Theme Studio overlays screen showed static replicas.
`inline` on `Dialog`, `Sheet`, `Drawer`, `Popover`, `DropdownMenu` and `Toaster` renders the overlay in place: `position: absolute` inside its container, never moved to `body`, no `showModal()` or `showPopover()`, no scroll lock, no focus trap, no inert page and no global Escape or outside-press ownership (Escape closes it from inside). It resolves the tokens of its container, so it follows a `data-preset` or `data-theme-scope` island. `openLayer` takes the same option. The studio's overlays screen now shows the real components.
```svelte
```
## Hover that respects modals
A hover card that opens under a dialog is a bug you only see on a trackpad: you open the dialog, move the pointer, and a panel appears behind the scrim.
A new `layers` store has `layers.modalOpen`, reactive and true while a modal layer (`Dialog`, `AlertDialog`, `Drawer`, `Sheet`) is open, and `layers.blocks(trigger)`, which is the same but false for a trigger inside the topmost modal. `Tooltip`, `HoverCard` and `NavigationMenuItem` use it and no longer open on pointer movement while a modal is open. A tooltip that was open when its trigger opened a dialog also no longer leaves a stray second copy in the page after the dialog closes. Gate your own hover or edge UI with the same store.
```svelte
```
## A larger kit
Many of the 57 feature pull requests are components, driven by the work of moving real apps onto the library.
New: `Carousel` (scroll-snap, WAI-ARIA carousel, autoplay opt-in and never under reduced motion), `ResizablePanels` (window splitters, arrow keys 1%, Shift 10%), `Menubar`, `ContextMenu` (right-click, long-press and Shift+F10), `HoverCard`, `NavigationMenu`, `ButtonGroup`, `AspectRatio`, `Kanban` (on the new `useDnd` primitive from 4.5.0, with cross-column moves and per-column infinite scroll), `Stat`, `ChipGroup`, `Heading`, `Highlight`, `StrikeThrough`, `LocaleSwitcher`, `PageFrame` and a map-first `AppShellLayout` stage, `Turnstile`, `PasswordStrength`, `SplashScreen` and `PreviewStage`. Extended: `Toast` gets descriptions, one inline action and dedupe, `TextField` gets a password reveal, a `below` slot and input-group addons, `Button` gets `tone="neutral"` and a trailing hint, `Badge` gets a subtle pill, and `Tabs`, `Progress`, `Drawer`, `Dialog` and `SimpleTable` gain the options real screens asked for.
Theming reaches further too. `ThemeOptions.components` sets `--ca-btn-*`, `--ca-avatar-*`, `--ca-card-*` and other component tokens on one naming convention; `ThemeIsland` gives a block or a whole page its own preset and scheme with SSR parity; a named type scale by role (`title`, `heading`, `body`, `label`, `caption`, `num`) overrides any part for the whole app; presets can carry alpha colours and domain tokens (`--ca-token-status-new`).
A small one worth seeing: a trend is not always good news when it goes up. `Stat` and `KpiCard` take `trendTone`, so a falling churn reads as good.
## A test system that runs what you changed
The suites froze a 12-core machine: 2433 Playwright tests loaded all 182 docs routes four to six times, and visual tests ran in an emulated amd64 container. 4.6.0 changes the shape of testing, not just the speed.
`bun run test` now runs only what the diff against `origin/main` affects. Component tests are chosen by a static import graph (`scripts/test-graph.ts`), because Vitest's own `--changed` selected 198 of 198 files for a one-line `Avatar` edit in browser mode. Routes are chosen by `scripts/route-impact.ts`, which fails safe: a shared path or a file it cannot place selects everything and says why. Every route is loaded once per project by three specs (smoke and layout, axe in dark, light and forced colors, and static HTML rules read from `dist` with no browser). Visual baselines are native per platform, the Docker path is gone, and a machine-wide lock lets one suite run at a time.
Every command has a time budget that is enforced: a run over its budget fails and prints its 10 slowest tests. On an oversubscribed machine the verdict is printed as not enforced, because it would only measure the other processes.
**One-component edit, bun run test**
- Total: 28 s
- Routes: 16.6 s
- Screenshots: 6.7 s
- Components: 4.6 s
- Unit: 0.4 s
Conditions: A one-component edit with a fresh dist, wall time on the maintainer's 12-core machine at load 15 (shared with other work), from the pull request that introduced the system (547). The budget for this command is 60 s.
**Full sweeps, before and after**
- Route sweep, before: killed at 467 s
- Route sweep, after: 168 s
- Components, before: 178 to 227 s
- Components, after: 109 s
Conditions: Wall time, shared 12-core machine, load noted per row, from pull request 547. The old route sweep was killed at 467 s, so that bar is a floor, not a completion time. The numbers are comparable only because they were taken on the same machine in the same window; they are not a benchmark.
Later work held the land gate under its budget: with a shared change (every component test, 210 files) it measured 224.8 s with a cold social-card cache and 193.5 s with a warm one, at load 7 on 12 cores, against a 240 s budget (pull request 599). `bun run test:full` has a 300 s budget and, by the record in that same pull request, was not measured on a quiet machine: one run took 1092 s at load 50 and is not a result. We state it so you do not read the budget as a promise.
Three dev-tooling targets were not met in this release. A shared-change land (every component test) took 255 s against a 120 s target. Our own tooling peaks at 8 cores in one land against a 4-core cap, and that cap is not enforced yet (issue 632). The warm `bun run test` still takes 11 to 13 s against a 10 s target. The enforced budgets above hold; these targets are what we are still working toward, and the numbers are wall time on the maintainer's shared 12-core machine.
## maplibre-gl 6 and the advisory
`maplibre-gl` 6.4.0 and earlier carry a critical XSS in the attribution sanitizer (GHSA-jrc7-96c5-q579), fixed in 6.4.1. `MapStage` now works on `maplibre-gl` 6, so the peer range is `^5.0.0 || ^6.0.0` again and you can take the fix.
With `engine="maplibre"` the deck.gl `layers` go through `MapLibreOverlay` from the new optional peer `@deck.gl/maplibre` (`~9.4.0`, which supports `maplibre-gl` 4.5.1, 5 and 6), because `MapboxOverlay` throws `Cannot read properties of undefined (reading 'height')` on every frame there. `engine="mapbox"` keeps `@deck.gl/mapbox`. Fitting clear of a wide `PageFrame` no longer throws `Invalid LngLat object`: the padding was subtracted twice.
```bash
bun add maplibre-gl@^6.4.1 @deck.gl/maplibre@~9.4.0
```
On `maplibre-gl` 6 the app must also call `setWorkerUrl` once; the map docs show the Vite form.
## Accessibility fixes
The fixes came from running axe over every route, in dark, light and forced colors, and from using the keyboard.
- `FileUpload`, `NotificationBell`: the accessible name now contains the visible text (WCAG 2.5.3, axe `label-content-name-mismatch`).
- `Kanban` column titles are `h2` by default, so a board under a page `h1` passes `heading-order`.
- `--ca-brand-text` is solved per preset and scheme: a light brand (lime, yellow, light cyan) no longer gets a 1.6:1 label on outlined buttons, links and active nav; it holds 4.5:1 on every surface. `tests/contrast.test.ts` measures every preset.
- `AuthLayout`: the compact mobile mark holds 4.5:1 in dark on every preset (it failed on six of eight at 390px), and a flat panel's secondary text uses theme text levels (it measured 2.21:1 in light).
- `Carousel`, `PreviewStage`, `ResizablePanel` and `CodeSnippet` scroll regions are keyboard-reachable while they overflow (`scrollable-region-focusable`); `Carousel` and `Menubar` reach the 44px touch target; `SegmentedControl` items are 44px wide too, and the password reveal button got its hit area back.
- `NavigationMenu`: Enter or Space always toggles, also within 600 ms of a hover open.
- `PageFrame` no longer overflows a 390px viewport by the frame gap, and `SiteHeader` no longer overflows at 390px.
- `Switch` inside a `SettingItem` no longer needs a redundant `aria-label`: the row already names it.
## Behaviour changes
- A page with no data-style now renders the solid default. An app that does not use the theme plugin used to keep the glass tokens, so every blurred element (chips, tabs, toasts, rail, panels) blurred. Now it renders data-style solid: opaque surfaces, no blur, no glow. What to do: Nothing, if you want the default. To keep glass, set data-style on html.
- Kanban column titles are h2 by default. They were h3, which skipped a level under a page h1 and failed axe heading-order. Only the tag changes, never the look. What to do: Pass headingLevel={3} to keep the old markup under an h2 of your own.
- Only the most specific nav item is active. With items at /items and /items/a, visiting /items/a marks just Item A, and the mobile header shows its label. The overview item stays active on its other sub-paths. What to do: Nothing, unless your own CSS relied on both being active.
- DocsHeader is opaque. The bar was an 82% translucent fill with a blur, so scrolled content showed through. It is now a solid surface, and landing and template pages can use the same header. What to do: Nothing.
- AuthLayout brand replaces the whole logo. A brand snippet no longer renders the default CodeAtlas UI name beside it. What to do: Pass logoName to show a name next to your brand.
- Identical toasts no longer stack. toast.error with the same text ten times leaves one toast with a x10 badge; at most three show at once and the oldest is dropped. What to do: Pass an id to replace a specific toast in place.
- Interactive shapes get a pointer cursor from the reset layer. button, a[href], label[for], summary and the button, tab, option and menuitem roles get cursor pointer; disabled ones get not-allowed. nativeFeel no longer forces the arrow cursor back. What to do: An unlayered cursor declaration in your own CSS wins, no important needed.
- Twelve unused utility classes left the stylesheet. .glass-bg-extend, .glass-inner-sm|md|lg, .glass-prominent, .glass-scroll-edge-top|bottom, .ca-toolbar-sep, .ca-clear-btn, .ca-row-check and .ca-trend-up|down were never used by a component or a documented API. styles/global.css shrinks by 242 B gzip. What to do: If you styled an element with one of them, keep that rule in your own CSS.
## Upgrade
```bash
bun add @codeatlasdev/ui@4.6.0
```
Across majors: `bunx @codeatlasdev/ui migrate --from --to `, or the MCP tool `get_migration`.
## All changes
Between @codeatlasdev/ui@4.5.0 and a73cb682, grouped by area.
### Theme and Studio
- feat: theme studio: presets, colour roles, live preview, apply to site (https://github.com/codeatlasdev/ui/pull/562, closes https://github.com/codeatlasdev/ui/issues/560)
- docs: code surfaces guide and --ca-code-line-height token (integer px line-height) (https://github.com/codeatlasdev/ui/pull/554, closes https://github.com/codeatlasdev/ui/issues/551)
- fix: without data-style on the page renders glass blur instead of the solid default (https://github.com/codeatlasdev/ui/pull/565, closes https://github.com/codeatlasdev/ui/issues/564)
- feat: typography: named type scale by role (title, heading, body, label, caption, mono-num) with tracking and line-heigh (https://github.com/codeatlasdev/ui/pull/433, closes https://github.com/codeatlasdev/ui/issues/375)
- feat: authLayout: panel background is a fixed brand gradient with blobs, no token or prop for a flat panel (https://github.com/codeatlasdev/ui/pull/423, closes https://github.com/codeatlasdev/ui/issues/409)
- feat: density tokens for Avatar, TextArea, TextField, Card, SegmentedControl and EmptyState (no selectors against intern (https://github.com/codeatlasdev/ui/pull/431, closes https://github.com/codeatlasdev/ui/issues/373)
- feat: button / IconButton / Kbd: weight, tracking, line-height, gap and padding as component tokens (https://github.com/codeatlasdev/ui/pull/421, closes https://github.com/codeatlasdev/ui/issues/373)
- feat: theme presets: colors with alpha/OKLCH and extensible domain tokens (status, tier, channel) per preset and scheme (https://github.com/codeatlasdev/ui/pull/427, closes https://github.com/codeatlasdev/ui/issues/374)
- feat: editorial primitives: display scale, out-expo/quart easings, animated highlight/strike, paper grain (https://github.com/codeatlasdev/ui/pull/394, closes https://github.com/codeatlasdev/ui/issues/353)
- feat: typography: display font role for marketing/auth headlines (`--ca-font-display`) used by components (https://github.com/codeatlasdev/ui/pull/370, closes https://github.com/codeatlasdev/ui/issues/350)
- feat: theme island: full-page preset/scheme override with SSR parity (light landing inside a dark app) (https://github.com/codeatlasdev/ui/pull/399, closes https://github.com/codeatlasdev/ui/issues/352)
- feat: theme presets: override primary-button fill/contrast and field font size per preset (https://github.com/codeatlasdev/ui/pull/390, closes https://github.com/codeatlasdev/ui/issues/354)
- fix: theme: body text size is also the root font-size, so changing it rescales every rem token (https://github.com/codeatlasdev/ui/pull/371, closes https://github.com/codeatlasdev/ui/issues/351)
### UI index and gallery
- feat: the index, phase 2b: item page tabs Preview, Code, Prompt, Anatomy (https://github.com/codeatlasdev/ui/pull/587, closes https://github.com/codeatlasdev/ui/issues/580)
- feat: the index, phase 2a: faceted gallery search with URL state and instant filtering (https://github.com/codeatlasdev/ui/pull/585, closes https://github.com/codeatlasdev/ui/issues/579)
- feat: the index, phase 2c: MCP search_ui, list_facets, get_related (https://github.com/codeatlasdev/ui/pull/582, closes https://github.com/codeatlasdev/ui/issues/581)
- feat: the index, phase 1: facet schema, 4-digit id ranges, backfill of every demo, index.json and .md twins (https://github.com/codeatlasdev/ui/pull/570, closes https://github.com/codeatlasdev/ui/issues/569)
- feat: gallery viewer: big resizable stage, pages (templates) as a category, better cards, lib PreviewStage (https://github.com/codeatlasdev/ui/pull/558, closes https://github.com/codeatlasdev/ui/issues/557)
- fix: site: landing and templates render a different top header than docs, changelog and gallery (https://github.com/codeatlasdev/ui/pull/556, closes https://github.com/codeatlasdev/ui/issues/555)
### Design styles, atlas and evidence
- feat: design style pages: /styles/ index and six pages rendered in their own style (brutalism, editorial, sketchbo (https://github.com/codeatlasdev/ui/pull/584, closes https://github.com/codeatlasdev/ui/issues/583)
- docs: concepts viewport, motion, targets and focus, appeal (https://github.com/codeatlasdev/ui/pull/586, closes https://github.com/codeatlasdev/ui/issues/573)
- feat: design atlas, 269 terms with browse, term pages and MCP search_terms (https://github.com/codeatlasdev/ui/pull/578, closes https://github.com/codeatlasdev/ui/issues/572)
- docs: evidence foundation, verified references, concept template (https://github.com/codeatlasdev/ui/pull/576, closes https://github.com/codeatlasdev/ui/issues/571)
### Components
- fix: nativeFeel keeps the arrow cursor on buttons, tabs and menu items (beats the ca.reset pointer) (https://github.com/codeatlasdev/ui/pull/567, closes https://github.com/codeatlasdev/ui/issues/566)
- feat: reset layer gives every clickable control a pointer cursor (and not-allowed when disabled) (https://github.com/codeatlasdev/ui/pull/552, closes https://github.com/codeatlasdev/ui/issues/549)
- fix: motion demo: Press spring stays pressed (scale 0.94) when Pause lands during the autoplay press (https://github.com/codeatlasdev/ui/pull/536, closes https://github.com/codeatlasdev/ui/issues/535)
- feat: KpiCard: chart slot / sparkline prop so an icon + sparkline tile needs no Card+Stat+Sparkline composition (https://github.com/codeatlasdev/ui/pull/510, closes https://github.com/codeatlasdev/ui/issues/505)
- feat: stat, KpiCard: trend colour assumes up is good (churn, cost, latency need down is good) (https://github.com/codeatlasdev/ui/pull/487, closes https://github.com/codeatlasdev/ui/issues/486)
- feat: Carousel: scroll-snap slides with prev/next, dots and optional autoplay (https://github.com/codeatlasdev/ui/pull/451, closes https://github.com/codeatlasdev/ui/issues/445)
- feat: buttonGroup: attached buttons with role=group and orientation (https://github.com/codeatlasdev/ui/pull/452, closes https://github.com/codeatlasdev/ui/issues/448)
- feat: Image: ratio prop and AspectRatio wrapper (https://github.com/codeatlasdev/ui/pull/453, closes https://github.com/codeatlasdev/ui/issues/446)
- feat: badge: subtle tone with dot for inline pills; Button: responsive trailing hint and label/trailing alignment (https://github.com/codeatlasdev/ui/pull/422, closes https://github.com/codeatlasdev/ui/issues/378)
- feat: locale switcher component (and a SiteHeader slot for it) (https://github.com/codeatlasdev/ui/pull/404, closes https://github.com/codeatlasdev/ui/issues/349)
- feat: progress: configurable bar height (size prop or --ca-progress-height), currently fixed at 8px (https://github.com/codeatlasdev/ui/pull/395, closes https://github.com/codeatlasdev/ui/issues/358)
- feat: button: neutral/secondary tone for outlined and ghost (no brand-coloured label or border) (https://github.com/codeatlasdev/ui/pull/389, closes https://github.com/codeatlasdev/ui/issues/357)
- feat: stat: card-less statistic primitive (label, value, hint, trend) sharing KpiCard typography (https://github.com/codeatlasdev/ui/pull/397, closes https://github.com/codeatlasdev/ui/issues/359)
- fix: glassCard: header padding stacks on card padding, so title is misaligned with content (https://github.com/codeatlasdev/ui/pull/368, closes https://github.com/codeatlasdev/ui/issues/341)
### Overlays and layers
- feat: inline (non-modal, non-top-layer) mode for overlays, for theme previews and showcases (https://github.com/codeatlasdev/ui/pull/608, closes https://github.com/codeatlasdev/ui/issues/563)
- feat: layers.modalOpen store and hover UI that never opens under a modal (https://github.com/codeatlasdev/ui/pull/553, closes https://github.com/codeatlasdev/ui/issues/550)
- feat: navigationmenu: disclosure navigation for marketing headers (https://github.com/codeatlasdev/ui/pull/461, closes https://github.com/codeatlasdev/ui/issues/457)
- feat: menubar: APG menubar reusing the DropdownMenu items (https://github.com/codeatlasdev/ui/pull/460, closes https://github.com/codeatlasdev/ui/issues/456)
- feat: contextmenu: right-click, long-press and Shift+F10 menu (https://github.com/codeatlasdev/ui/pull/459, closes https://github.com/codeatlasdev/ui/issues/455)
- feat: hovercard: hover and focus preview card with open/close delays (https://github.com/codeatlasdev/ui/pull/458, closes https://github.com/codeatlasdev/ui/issues/454)
- feat: dialog split: configurable size, columns and mobile full-screen; Dnd: container-target mode without insertion line (https://github.com/codeatlasdev/ui/pull/428, closes https://github.com/codeatlasdev/ui/issues/377)
- feat: drawer: chromeless/full-bleed mode (no header, no body padding, full width) for side detail panels (https://github.com/codeatlasdev/ui/pull/391, closes https://github.com/codeatlasdev/ui/issues/362)
- feat: toast: optional description and a single inline action (label + handler) (https://github.com/codeatlasdev/ui/pull/392, closes https://github.com/codeatlasdev/ui/issues/356)
- fix: toast: mensagens idênticas empilham sem limite (sem dedupe nem teto) (https://github.com/codeatlasdev/ui/pull/367, closes https://github.com/codeatlasdev/ui/issues/363)
### Forms and inputs
- feat: button: form and type passthrough to submit from a Dialog actions footer (https://github.com/codeatlasdev/ui/pull/523, closes https://github.com/codeatlasdev/ui/issues/518)
- feat: inputgroup: prefix and suffix addons inside the textfield border (https://github.com/codeatlasdev/ui/pull/450, closes https://github.com/codeatlasdev/ui/issues/447)
- feat: auth building blocks: Turnstile, PasswordStrength, decorative Avatar and SplashScreen (https://github.com/codeatlasdev/ui/pull/426, closes https://github.com/codeatlasdev/ui/issues/379)
- feat: textField: password reveal toggle, and a field-level trailing link slot ("Forgot password?") (https://github.com/codeatlasdev/ui/pull/396, closes https://github.com/codeatlasdev/ui/issues/348)
- feat: chipGroup: single-choice chips that wrap (radiogroup, roving tabindex, check icon) (https://github.com/codeatlasdev/ui/pull/365, closes https://github.com/codeatlasdev/ui/issues/355)
### App shell and layout
- fix: kanban: board collapses to 0px wide in an auto-width flex wrapper (documented usage), layout audit fails on mobile (https://github.com/codeatlasdev/ui/pull/531, closes https://github.com/codeatlasdev/ui/issues/530)
- feat: kanban: per-column money total without losing the colour rail, title and count (header snippet replaces all three) (https://github.com/codeatlasdev/ui/pull/498, closes https://github.com/codeatlasdev/ui/issues/496)
- fix: pageFrame: bottom sheet overflows the viewport by the frame gap on mobile (side=left keeps left:12px with width:100 (https://github.com/codeatlasdev/ui/pull/492, closes https://github.com/codeatlasdev/ui/issues/489)
- feat: ResizablePanels: panel group with separator role and keyboard resize (https://github.com/codeatlasdev/ui/pull/449, closes https://github.com/codeatlasdev/ui/issues/444)
- fix: appShellLayout: a nav item stays active on its sub-paths, so an overview item and a more specific sibling are both (https://github.com/codeatlasdev/ui/pull/424, closes https://github.com/codeatlasdev/ui/issues/408)
- feat: kanban/Board: columns with cross-column drag, board pan, per-column infinite scroll and mobile stage tabs (https://github.com/codeatlasdev/ui/pull/393, closes https://github.com/codeatlasdev/ui/issues/361)
- feat: table: dense mode, pinned columns, group rows and interactive rows for CRM-style lists (https://github.com/codeatlasdev/ui/pull/372, closes https://github.com/codeatlasdev/ui/issues/360)
- feat: page frame primitive for map-first apps: floating panel / split / full page, non-modal bottom sheet on mobile, and (https://github.com/codeatlasdev/ui/pull/402, closes https://github.com/codeatlasdev/ui/issues/344)
- feat: appShellLayout: persistent background stage (map, canvas, video) that survives route changes, with pass-through co (https://github.com/codeatlasdev/ui/pull/401, closes https://github.com/codeatlasdev/ui/issues/343)
- feat: navigation: Rail labels and a search/⌘K trigger, plus a BottomNav overflow ("More") for more than 5 modules, with (https://github.com/codeatlasdev/ui/pull/364, closes https://github.com/codeatlasdev/ui/issues/346)
- feat: pageShell/AppShellLayout: no aside column and panel always open, leaving dead space on wide screens (https://github.com/codeatlasdev/ui/pull/388, closes https://github.com/codeatlasdev/ui/issues/342)
- fix: pageShell: mobile actions stretch StatusChip/Chip/Badge to full width (https://github.com/codeatlasdev/ui/pull/366, closes https://github.com/codeatlasdev/ui/issues/339)
- feat: authLayout: panel side, full-bleed custom panel (live map), header slot and form-first layout (https://github.com/codeatlasdev/ui/pull/387, closes https://github.com/codeatlasdev/ui/issues/347)
- fix: authLayout: brand snippet still renders logoName (defaults to "CodeAtlas UI") (https://github.com/codeatlasdev/ui/pull/369, closes https://github.com/codeatlasdev/ui/issues/340)
### Map and charts
- fix: map: MapStage on maplibre-gl 6 (critical XSS GHSA-jrc7-96c5-q579): use deck.gl MapLibreOverlay (https://github.com/codeatlasdev/ui/pull/602, closes https://github.com/codeatlasdev/ui/issues/601)
- fix: map: deck.gl overlay throws on maplibre-gl 6 (`reading 'height'`) on every frame (https://github.com/codeatlasdev/ui/pull/479, closes https://github.com/codeatlasdev/ui/issues/470)
- feat: map integration entry (`@codeatlasdev/ui/map`): Mapbox GL / MapLibre + deck.gl that follow the theme (https://github.com/codeatlasdev/ui/pull/403, closes https://github.com/codeatlasdev/ui/issues/345)
### Sound
- feat: @codeatlasdev/ui/sound: synthesized, opt-in UI sound engine (phase 3) (https://github.com/codeatlasdev/ui/pull/577, closes https://github.com/codeatlasdev/ui/issues/575)
### Accessibility
- fix: settings recipe tells Switch in SettingItem to add aria-label, SettingItem names it (https://github.com/codeatlasdev/ui/pull/527, closes https://github.com/codeatlasdev/ui/issues/525)
- fix: kanban: column title is a hard-coded h3, so a board under a PageShell h1 fails axe heading-order (no headingLevel p (https://github.com/codeatlasdev/ui/pull/503, closes https://github.com/codeatlasdev/ui/issues/501)
- fix: fileUpload: drop zone aria-label omits the visible hint (axe label-content-name-mismatch) (https://github.com/codeatlasdev/ui/pull/493, closes https://github.com/codeatlasdev/ui/issues/490)
- fix: notificationBell: trigger label does not contain its visible unread count (axe label-content-name-mismatch) (https://github.com/codeatlasdev/ui/pull/480, closes https://github.com/codeatlasdev/ui/issues/471)
- fix: authLayout: mobile brand mark fails color contrast in dark at 390px (https://github.com/codeatlasdev/ui/pull/483, closes https://github.com/codeatlasdev/ui/issues/472)
- fix: authLayout: flat panel text levels fail color-contrast (--panel-text-secondary/tertiary are alpha mixes of the fg) (https://github.com/codeatlasdev/ui/pull/442, closes https://github.com/codeatlasdev/ui/issues/440)
- fix: theme: light brand presets get a --ca-brand-text that fails contrast in the light scheme (~1.6:1) (https://github.com/codeatlasdev/ui/pull/420, closes https://github.com/codeatlasdev/ui/issues/410)
- fix: touch-target list in base.css fused into a descendant selector (.glass-btn-clear .ca-tf__reveal) (https://github.com/codeatlasdev/ui/pull/418, closes https://github.com/codeatlasdev/ui/issues/417)
### Agents, MCP and docs
- fix: 14 pages emit the same heading id more than once (e.g. id="props" ×4 on /docs/display/table/) (https://github.com/codeatlasdev/ui/pull/600, closes https://github.com/codeatlasdev/ui/issues/548)
- fix: glass reads as the lib's identity and default; present it as one style among many (https://github.com/codeatlasdev/ui/pull/561, closes https://github.com/codeatlasdev/ui/issues/559)
- fix: landing recipe copied alone fails prerender on /sign-up (https://github.com/codeatlasdev/ui/pull/528, closes https://github.com/codeatlasdev/ui/issues/526)
- fix: recipes import #lib which only exists on Kit 3, no Kit 2 form shown (https://github.com/codeatlasdev/ui/pull/520, closes https://github.com/codeatlasdev/ui/issues/515)
- fix: landing recipe hrefs 404 on prerender when copied whole (https://github.com/codeatlasdev/ui/pull/522, closes https://github.com/codeatlasdev/ui/issues/517)
- fix: llms.txt should say components.json is { components: [] } (https://github.com/codeatlasdev/ui/pull/524, closes https://github.com/codeatlasdev/ui/issues/519)
- fix: manifest: union prop values missing from props tables (Avatar shape, SkipLink props) (https://github.com/codeatlasdev/ui/pull/514, closes https://github.com/codeatlasdev/ui/issues/509)
- fix: manifest: NavModule and NavItem fields missing from components.json/API.md (get_export/get_component) (https://github.com/codeatlasdev/ui/pull/513, closes https://github.com/codeatlasdev/ui/issues/508)
- fix: list-page recipe Export link 404s on prerender (https://github.com/codeatlasdev/ui/pull/512, closes https://github.com/codeatlasdev/ui/issues/507)
- fix: templates: Billing uses :global(.grid-auto-180) instead of Grid props (templates are what AIs copy) (https://github.com/codeatlasdev/ui/pull/511, closes https://github.com/codeatlasdev/ui/issues/506)
- fix: map recipe offline basemap in the shell-less variant, scatterplot radius units, centsToDisplay options (https://github.com/codeatlasdev/ui/pull/504, closes https://github.com/codeatlasdev/ui/issues/502)
- feat: pageShell: dev warning when there is no landmark (docs-only agents ship pages without one) (https://github.com/codeatlasdev/ui/pull/499, closes https://github.com/codeatlasdev/ui/issues/495)
- fix: installation says nothing about the TypeScript major Kit 3 needs (ERESOLVE with typescript 5) (https://github.com/codeatlasdev/ui/pull/500, closes https://github.com/codeatlasdev/ui/issues/497)
- fix: standalone single-page app (no AppShellLayout) has no recipe; PageShell alone has no (https://github.com/codeatlasdev/ui/pull/481, closes https://github.com/codeatlasdev/ui/issues/473)
- fix: docs+lint: i18n-literal rule is undocumented and every recipe fails it; app copy pattern missing (https://github.com/codeatlasdev/ui/pull/484, closes https://github.com/codeatlasdev/ui/issues/474)
- fix: llms.txt: links point at HTML pages; the readable /llms//.txt form and index pages are not discoverabl (https://github.com/codeatlasdev/ui/pull/482, closes https://github.com/codeatlasdev/ui/issues/477)
- fix: SiteHeader overflows at 390px with nav + LocaleSwitcher + 2 buttons; no marketing-header recipe (https://github.com/codeatlasdev/ui/pull/485, closes https://github.com/codeatlasdev/ui/issues/476)
- fix: site build fails on button-group.mdx (escaped quote in a JSX attribute) (https://github.com/codeatlasdev/ui/pull/463, closes https://github.com/codeatlasdev/ui/issues/462)
- docs: teach the 4.6 APIs in recipes, choosing and workarounds (https://github.com/codeatlasdev/ui/pull/416, closes https://github.com/codeatlasdev/ui/issues/415)
- feat: dX: official list of stable .ca-* parts, variables and data attributes for overrides (API.md, manifest, MCP) (https://github.com/codeatlasdev/ui/pull/425, closes https://github.com/codeatlasdev/ui/issues/381)
- fix: give llms-full.txt a fixed shape instead of a growing byte budget (https://github.com/codeatlasdev/ui/pull/437, closes https://github.com/codeatlasdev/ui/issues/436)
- docs: make the site and skill one-shot friendly for AI agents (https://github.com/codeatlasdev/ui/pull/386, closes https://github.com/codeatlasdev/ui/issues/384)
### CLI and migration
- fix: init: Kit 2 gets no svelte.config.js with the detected adapter (https://github.com/codeatlasdev/ui/pull/521, closes https://github.com/codeatlasdev/ui/issues/516)
- fix: fresh Kit 3 app needs svelte-kit sync before svelte-check; init leaves a root and PWA-only keys in mess (https://github.com/codeatlasdev/ui/pull/494, closes https://github.com/codeatlasdev/ui/issues/491)
- fix: init: Kit 3 scaffold does not build/lint out of the box (tsconfig exclude build, #lib map, PWA optional, prerender, (https://github.com/codeatlasdev/ui/pull/478, closes https://github.com/codeatlasdev/ui/issues/475)
- feat: migration tooling: help teams move an existing app (React/Tailwind/shadcn) onto @codeatlasdev/ui (https://github.com/codeatlasdev/ui/pull/430, closes https://github.com/codeatlasdev/ui/issues/383)
- feat: release: migration changelog per major, codemods for known breaking changes and deprecation warnings (https://github.com/codeatlasdev/ui/pull/429, closes https://github.com/codeatlasdev/ui/issues/382)
### Tests and release gates
- test: replace the remaining real-time sleeps in component tests with conditions or a fake clock (https://github.com/codeatlasdev/ui/pull/603, closes https://github.com/codeatlasdev/ui/issues/568)
- fix: budget of test:changed follows the selection scope (https://github.com/codeatlasdev/ui/pull/605, closes https://github.com/codeatlasdev/ui/issues/604)
- fix: land gate: bring landShared back under 4 minutes (https://github.com/codeatlasdev/ui/pull/599, closes https://github.com/codeatlasdev/ui/issues/598)
- fix: test budget: landShared 360 s cannot hold components ALL + routes ALL + the mandatory rebuild (https://github.com/codeatlasdev/ui/pull/597, closes https://github.com/codeatlasdev/ui/issues/596)
- fix: route-impact: a CLI source under packages/ui/bin selects every docs route (https://github.com/codeatlasdev/ui/pull/594, closes https://github.com/codeatlasdev/ui/issues/593)
- fix: test:changed --land: dist counts as fresh when it predates the rebase (https://github.com/codeatlasdev/ui/pull/592, closes https://github.com/codeatlasdev/ui/issues/591)
- fix: issue-land: new generated files (demo e/ and p/ api/v1 files) are never committed (https://github.com/codeatlasdev/ui/pull/590, closes https://github.com/codeatlasdev/ui/issues/589)
- test: lighter suites: one pass per route, targeted local runs, machine-wide lock, native VRT (https://github.com/codeatlasdev/ui/pull/547, closes https://github.com/codeatlasdev/ui/issues/546)
- fix: browser tests fail intermittently under machine load (Menubar, VirtualList, NestedLayers) (https://github.com/codeatlasdev/ui/pull/545, closes https://github.com/codeatlasdev/ui/issues/544)
- fix: bring styles/global.css back under 17450 B (https://github.com/codeatlasdev/ui/pull/543, closes https://github.com/codeatlasdev/ui/issues/542)
- fix: playwright config picks 100% workers whenever CI is set, so agent shells on a shared machine get random 30s t (https://github.com/codeatlasdev/ui/pull/540, closes https://github.com/codeatlasdev/ui/issues/539)
- fix: a11y routes spec times out on /docs/getting-started/recipes/ (10k DOM nodes) and on light pages under load (https://github.com/codeatlasdev/ui/pull/534, closes https://github.com/codeatlasdev/ui/issues/533)
- fix: unit tests leave their temporary project directories behind in the system temp directory (https://github.com/codeatlasdev/ui/pull/532, closes https://github.com/codeatlasdev/ui/issues/529)
- fix: render visual baselines locally in Docker while CI is paused (https://github.com/codeatlasdev/ui/pull/469, closes https://github.com/codeatlasdev/ui/issues/468)
- fix: HoverCard closeDelay and CommandPalette announce tests fail intermittently in the full browser suite (https://github.com/codeatlasdev/ui/pull/467, closes https://github.com/codeatlasdev/ui/issues/466)
- fix: site e2e gate fails on carousel, image, text-field and menubar (a11y, mobile overflow, touch targets) (https://github.com/codeatlasdev/ui/pull/465, closes https://github.com/codeatlasdev/ui/issues/464)
- fix: check: bun --check (check:native) reports 10 type errors that validate does not run (https://github.com/codeatlasdev/ui/pull/443, closes https://github.com/codeatlasdev/ui/issues/441)
- fix: site build fails: StatusTokens demo canvas role=img (a11y_no_interactive_element_to_noninteractive_role) (https://github.com/codeatlasdev/ui/pull/439, closes https://github.com/codeatlasdev/ui/issues/438)
- fix: mobile motion e2e flakes in settle, scroll takeover, ripple (#411) (https://github.com/codeatlasdev/ui/pull/434, closes https://github.com/codeatlasdev/ui/issues/411)
- fix: full browser suite poisoned by an unresolved site-demo import (#407) (https://github.com/codeatlasdev/ui/pull/419, closes https://github.com/codeatlasdev/ui/issues/407)
- chore: raise styles/global.css budget for the 4.6 component batch (https://github.com/codeatlasdev/ui/pull/414, closes https://github.com/codeatlasdev/ui/issues/413)
- fix: check:native fails on main: implicit-any in build-manifest.ts and strict errors in two tests (https://github.com/codeatlasdev/ui/pull/400, closes https://github.com/codeatlasdev/ui/issues/398)
### Dependencies
- chore: bump @vitest/ui from 5.0.4 to 5.0.5 in /packages/ui (https://github.com/codeatlasdev/ui/pull/435)
- chore: bump happy-dom from 21.0.1 to 21.0.4 in /site (https://github.com/codeatlasdev/ui/pull/588)
- chore: bump happy-dom from 21.0.1 to 21.0.4 in /packages/ui (https://github.com/codeatlasdev/ui/pull/541)