Repository navigation
The one-site release. Every chapter and gallery example is a native, pre-rendered studio page in one tile language, with its own head; old links land in the studio. The studio has a new shell (search, one-button mode, custom color, icon rail, sticky side nav, On this page) and a new home (live product hero, ambient Get started). Package changes: .badge.bloom is neutral; the React parts run on React 18 and 19 (react/inert.ts); LiveActivity gains optional emptyAction and onOpenChange; verseva add warns below React 18; the console and landing blocks hold at phone width. No class or token is renamed.
Added
- design.verseva.com is pre-rendered. Every route in the studio routes table ships its own HTML: real headings
without JS, a unique title and description, a canonical on design.verseva.com, Open Graph and Twitter tags, and
JSON-LD (BreadcrumbList, plus WebSite on home). Pages hydrate in place, and client navigation keeps the whole head
in step. The SPA rewrites invercel.jsonare gone: each route is a file. - SEO kit, generated at build time from the emblem and the dark canvas tokens at full clear space:
favicon.ico,
icon.svg,apple-touch-icon.png, 192 and 512 icons plus a maskable one, theog.pngsocial card,
site.webmanifest,robots.txtandsitemap.xml(every route). - A studio 404 page. Unknown paths return 404 with the studio shell and a way back to Overview (noindex).
- The gallery lives in the studio.
/galleryis a native page, and each example opens at/gallery/<slug>
(the example in a frame that fits its document and follows the studio theme and brand) with its source at
/gallery/<slug>/code(pre-rendered, with Copy). Links inside an example route through
the studio./examples/*.htmlstill serve as files. - Components links to Widgets from its header.
- Old site links land in the studio.
/code.html?f=examples/<slug>.html(and/site/code.html?f=) 308s to
/gallery/<slug>/code; any othercode.htmlrequest goes to/gallery. Every/site/<page>.html308s to its
studio route (/site/index.htmlto/,/site/examples.htmlto/gallery), as the root copies already did. The
registry JSON (/r/*,/site/r/*),/examples/**,/site/examples/**,site.cssandtheme.jsstay files. - Studio command bar. The top bar search (⌘K / Ctrl K) opens the package command bar over every route and
every chapter and page section, built from the routes table and the section ids. A result navigates in the shell
and lands focus on its section. Below 900px the search is an icon button and the bar is a full-height sheet. - Custom accent. The color dot opens a popover with the five presets and Custom: a hue control and a hex field.
Any pick is derived to--accent,--accent-hover,--accent-inkand--focusfor dark and light, gated live
(ink on accent and hover at 4.5:1, the accent and its hover on bg at 3:1, the accent on both surfaces at 3:1, text on the
accent tint at 4.5:1; hover steps away from the page, as the presets do), and
moved in OKLCH lightness to the nearest passing value when it fails, with the adjusted value and a pass or fail per
check shown. The hue control changes only the hue of the original pick, so stepping back returns it. The popover
traps focus while open. A chunk that fails to load shows a Retry in place. The choice persists and applies before first paint. Copy theme copies a ready
[data-brand="custom"]theme file in the presets' shape (contrast-gate clean). - Icon rail. The sidebar collapses to a 72px rail: one icon per Studio page and one per group, a tooltip on each,
and a keyboard-operable flyout per group (arrows, Home, End, Enter, Esc back to the icon). The rail state persists
and applies before first paint. - On this page. Chapter and Foundations pages carry a right rail of their sections from 1200px, with scroll-spy
(aria-current="location") and focus moved on click.
Changed
- Top bar. The studio header is the package three-column
.tbar: lockup and version, the search trigger,
then color, mode, pause motion and GitHub. Mode is one icon button that cycles light, dark and system, named
"Theme: current. Switch to next", announced politely, and drawn from the head script'sdata-modeso it never
shows a wrong icon. The five brand chips and the Light / Dark / System segmented control left the top bar (the
Overview hero keeps its theme picker). The npm link left the bar. - Sidebar. Studio, Chapters and Gallery are collapsible groups (open state persists; the group holding the
active item stays open), Gallery lists its examples, counts stay neutral badges, and the active item carries the
nav bloom. Per-chapter section anchors left the sidebar for the On this page rail and the command bar. - Phone shell from 900px. The page and section select and the stacked header now apply below 900px (was 760px).
- Lazy chunks. The command bar (studio and /widgets), the color panel and the search commands load on first
intent; their triggers stay in the main chunk, which measures 147.1 kB gzip under the unchanged 150 kB budget. - Studio home (
/) is a live product hero. "One source. Every surface" with one primary action, Get started
(copiesnpm i @verseva/design, shows Copied, then lands on/components#install), and a quieter Browse
(/components). Beside it, a real widget home on the package parts (.wgridtiles): the smart stack rotates with
its visible pause, a demo job ticks in the live activity capsule, and the focus widget's chart settles. Only the
focus widget carries the accent. At phone widths the home drops to two tiles and the CTA stays above the fold. - Ambient motion on the home. Get started carries a slow catch-light sweep inside its matte body (transform only,
no glow, no outer shadow), held on hover and focus. A neutral drift (text-ladder and surface tones, no accent)
moves behind the hero. Both start after mount and stop under Pause motion and under reduced motion. - Entry tiles into Components, Widgets, Foundations and Gallery, labels and counts only, in the
/widgetstile
language, routed in the shell. The theme picker, token readout, frame stage and counts row leave the home (the
header's color popover and Foundations carry them); the home no longer loads the 3D stage. - Studio specimen tiles. Components and Foundations take the /widgets tile language: the package
.wgrid
bento and.wtileglass at--r-lg, with a header (category icon, name, neutral meta count), the live specimen
in the body, and Show code with Copy in the footer. Tiles size to their content (S, M, L, XL; rows hug the
specimen), XL drops to the M span under 1100px and every tile to one column under 560px. The tile carries the
loading, empty and error states, and is one component (studio/src/tiles/SpecimenTile.tsx) for the chapters
and the gallery to follow. - Components: 50 sections as tiles. Section ids, deep links, the On this page rail and the demos are
unchanged; each code panel shows the generated, byte-checked sample fromchapter-code.mjs. - Foundations: each token family is a tile, with its declarations (
:rootand the light flip) as its code. - Gallery: a bento of example tiles.
/galleryshows the 8 mock sites as XL, M and S tiles: the name and its
tags as neutral badges in the header, a live thumbnail in the body, Live (/gallery/<slug>) and Code
(/gallery/<slug>/code) in the footer. The tag filter chips stay, as neutral selection, with a count on each.
Thumbnails are the example files scaled from 1280px: inert,aria-hidden, no pointer events, themed and branded
with the studio. They load lazily (IntersectionObserver), at most 6 at once, 3 on phones, and sit still (CSS
animations at their end state, the example's animation-frame loop held) until their tile is hovered or holds
focus; never under Pause motion or reduced motion. Details and inspiration shots are tiles too. - Gallery example and code routes in the tile language.
/gallery/<slug>puts its frame in a tile (the file
and tags in the header, Code in the footer) and/gallery/<slug>/codeits source (Open live and Copy in the
footer, Retry in the body on a failed chunk). Height fitting, theme and brand following, one scrollbar, the
pre-rendered source, the breadcrumb JSON-LD and the 404s for unknown slugs are unchanged. - Retired: gallery parity.
/galleryand the code route no longer matchsite/examples.htmland
site/code.htmlelement for element; both are logged instudio/test/redesigned.tsand held by
gallery-tiles.test.tsxand the servedgallery.test.mjsinstead. - Web UI, Distribute and Docs + PDF as tiles. Web UI: the ladders, type trio and radius tables, then the four
contract specimens (Buttons, Status, Card + stat, Segmented + field) under their section. Distribute: the command
blocks, the agent tool table and the theme presets. Docs + PDF: the memo in one XL tile. Section ids, cold deep links
and the On this page rail are unchanged; the bento has no holes at 4 and 2 columns. The legacy doctrine sublabels
above the Web UI specimens are gone (labels and counts only). These pages have no generated code samples, so their
tiles show no code. - Data viz, Motion and Decks as tiles. Data viz keeps law 3 the way a product must: one focus tile (Line + area)
spends the data accent and the other nine charts draw on the text ladder. Motion's Replay, Roll it, Point at it,
Resolve it and Open it sit in their tiles' footers; the theme wipe, the curves race and the Pause motion control
work as before. Decks: the slide and the structure table side by side. The Data viz and Motion samples load on
first intent (main chunk 141.22 to 137.56 kB gzip). - Data viz recipes follow the data-intensity rule. Bar magnitude goes through
data-l(new.bar .fill[data-l]
rungs incomponents.css, with their text-ladder twins in a tile withoutdata-focus), Stacked segments take
series identity (series one,--data-alt, a neutral third on--text-2) instead of the magnitude ladder, the intensity legend
uses the same rungs as its cells, and the source dot uses a neutral token, not--success. No chart colour is
inline. The Data viz samples are generated from these specimens as drawn and held byte for byte
(specimen-code.test.tsx), so a sample cannot drift from what renders. - Chart marks clear 3:1 and their labels 4.5:1 in both modes. The text-ladder rung 1 a tile without
data-focus
draws (bars, heat cells, activity strips) lifts from 30% to 50%--text-1(light was 2.0:1, dark 2.6:1); the
Stacked third series fills--text-2with a--bglabel, and the Priced label takes--surface(4.46 to 5:1). SpecimenTilefocusprop (default true): false dropsdata-focus, so the package recolours the tile's charts.
Fixed
-
Gallery sources load per page, not in the main bundle. Each
/gallery/<slug>/coderoute loads only its own
example's source as a separate chunk; the pre-rendered page still holds the full text without JS and hydrates with
it in place. The main entry chunk drops from 176.3 kB to 146.8 kB gzip, held under a 150 kB budget by
test/served/bundle.test.mjs, which also fails if any example source returns to it. -
The landing example holds at phone width. Below 600px its nav wraps the section links to their own row, so
examples/landing.htmlis 375px wide at 375px (was 433px). Unchanged at 1280px. -
Components no longer scrolls sideways on phones. The
#tablespecimen sits in its.tscrollscroller and the
#table-pinspecimen lets its.pin.boxscroll, at 375px. -
Theme before first paint. The inline head script runs ahead of every stylesheet, and the Mode control shows the
stored mode from first paint instead of sliding from System after load. -
/<route>/index.htmlopens that route instead of the not-found page. -
Overview's Pulse and Launch tiles open their gallery pages (
/gallery/pulse,/gallery/launch) inside the
studio, instead of the bare example files. -
What's new New tag spends no accent.
.badge.bloommoves from--accent-bloomto the text ladder:
--text-1at weight 600 on--surface-2, a step above Improved (--text-2). Law 3 budget: counts and info
badges are neutral. The console-view accent test now renders an open What's new drawer. -
Studio Pause motion stops every auto-moving element (WCAG 2.2.2). The header control now stops every CSS
animation on the page and in same-origin example frames (marquee, border beam, spinners, shimmer) and the
Live now smart stack's rotation, as well as the 3D stage. Reduced motion is unchanged. -
In-page anchors move focus (WCAG 2.4.1). Ported chapter anchors, including the skip-link specimens
(#sh-main,#shr-main), scroll and focus their target, addingtabindex="-1"where it is not focusable. -
Deep links clear the sticky studio header. Every studio scroll margin reads one variable,
--studio-scroll-pad, built from the header's and the phone page select's measured heights (191px and 61px at
375px, 66px at 1280px), with per-breakpoint fallbacks. Cold deep links now land on their section. -
React 18 consumers:
widget-gridandsmart-stackcompile and work again. Both setinert, which
@types/react18 does not know, sotscfailed on React 18 projects; React 18 also drops a boolean
inert, so edit mode and hidden stack pages were not inert there. A new registry util,inert
(react/inert.ts), rendersinerton both:trueon React 19,""on React 18. Re-add the two parts
(npx verseva add widget-grid smart-stack, which bringsinert). Every registry React part now
type-checks against@types/react18 and 19 in CI. React 18 or later is needed for the React parts
only; the CSS, tokens and preset need no React, and the package declares no React peer, so it installs
into any project.verseva addwarns in one line when it copies React parts into a project on an
older React. -
Skip to content (WCAG 2.4.1). Every studio route opens with a "Skip to content" link, the first
focusable element of the shell, hidden until focused, with the focus ring. It moves focus to the page's
main content, in the pre-rendered HTML and after hydration. -
The /widgets console keeps its phone nav. The Home console specimen carries a
.navshellbelow
900px, where the console hides its sidebar, inside the specimen instead of fixed to the page. -
Overview's Pulse and Launch covers open without a page reload. They route through the studio like
every other studio link. -
Components and the console example hold at 360px. The
#bulktable specimen sits in a.tscroll
scroller (it spilled past its box and scrolled the page sideways below 372px), and
examples/console.html(andblocks/console.html) tightens its quotes table cells below 400px
(366px wide at 360px before). -
Old
/code.html?f=links land on a clean URL. The redirect passed its query through, so the code
page opened at/gallery/<slug>/code?f=...; the studio now drops the strayfin place, on any
gallery route. -
On this page marks the deep-linked section on a page too short to scroll (Decks at 1440x900: both tiles in
one row below the line marked Slide anatomy for/decks#structure). -
Gallery: the filter shows its result. A filtered-out tile is no longer rendered (its
display:nonelost to the
package.wtiledisplay in the built CSS, so all 8 stayed on screen). Each filter's subset is sized to fill every
row at 4 and 2 columns (its own sizes when they fit, else an XL first on an odd count and Ms in pairs), and the
result is announced politely ("2 examples"). -
Gallery: a thumbnail that does not load shows the tile error with Retry. A missing example answers with the
studio shell (404.html); the tile no longer nests a studio in its thumbnail. -
Gallery: the details bento has no holes (Count-up stat and Skeleton to loaded take M), and the gallery joins the
chapter copy guard (no em dash, no doctrine sublabels, every legacy text accounted for). -
3D hero example: the copy holds its contrast over the scene. The scene read its colours once at load, so a
frame the studio flips to light after load kept a dark knot behind dark copy (about 1:1). It now re-reads the tokens
on every theme or brand change and when a theme sheet lands, with light-mode lighting from the surface tones. A
directional scrim in the ground colour sits between the scene and the copy (left to right on desktop, a band on
phones), and the hint sits on a pill. A served probe samples the scene behind every line of copy over several
frames, in both themes at 1440 and 375: headline and body at least 4.5:1, kicker and hint at least 3:1. -
The studio side nav stays fixed while the page scrolls. Expanded and collapsed to the rail, it sits below the
header at full height, scrolls its own list when that is longer than the viewport, and keeps the collapse toggle
in view at its foot (the expanded toggle had scrolled out of reach on long pages). -
Home: the demo job is quiet. It ticks visually but says nothing in its live region until the visitor opens the
capsule panel. -
Home: Copied is honest. Get started says Copied only once
writeTextresolves. When the clipboard is denied or
missing, orwriteTextthrows, it says "Command below" and still lands on/components#installwith focus there. -
Home: the demo restarts. Restart sits in the capsule panel whenever no job runs (done, rested or cancelled),
and Cancel now stops the job. With the panel shut after a Cancel, a Restart shows in the tile instead. -
LiveActivitytakesemptyActionandonOpenChange.emptyActionrenders in the panel's empty state (a
Restart, a Start);onOpenChangereports the panel opening and closing. -
Dropped the unused
.picker-lgrules fromstudio.css.
Tests
test/served/sidebar.test.mjs: at 1280,/componentsscrolled to its end, the sidebar's top stays at the header
bottom, it fills to the viewport bottom, and its collapse toggle is in view, expanded and collapsed.test/served/home.test.mjs: the law 3 accent budget on/at 1440 and 375 in both schemes (with a planted
spend), the hero's animations (running, transform and opacity only, stopped by Pause motion and by reduced
motion), Get started in Chrome (copied and denied, focus on#install), the budget with the job panel open, and the 375px fold at 667, 812 and 360 by 640. The served harness takes
reducedMotion.- The Components port's element-for-element parity with
site/components.html(markup,<style>and the
FROZEN pin) is retired, as the redesign changes its presentation on purpose (studio/test/redesigned.ts). The
tile contract test (specimen-tile.test.tsx) replaces it; the specimen-to-sample and chapter script tests stay.
Other chapters keep their parity tests. - The class-name rule now covers the studio tile CSS.