Toolkit changes
This record describes public toolkit changes and consumer migrations. The package manifest owns the current version. Entries describe source changes, not proof of publication or deployment.
010.4.0
Compatible additions, breaking renames and removals, and changed visual defaults; each breaking change states its migration. Not published by this change.
Components
Analyticsmeasures page views and declared events with the shared Umami instance, from the configuration the host serves at/analytics-config.json. Statistics are on by default: its privacy dialog, in thePagelanguage, turns them off and on again, and Do Not Track and Global Privacy Control always turn them off. Every app shares one Umami website: the path starts with the domain,/404stands for missing pages, and the domain is also the distinct ID, so visitor identifiers stay specific to each site; the first measurement adds the origin of an external referrer.track(name)sends one of the names passed toevents. Every workspace app mounts it in its root layout and serves the configuration from its Caddyfile; Bloom's own opt-in measurement is removed. Migration: Bloom dropsUMAMI_ENABLED. Workspace Caddyfiles default to the shared distributed·gallery website, formerly Bloom's;UMAMI_ENDPOINTandUMAMI_WEBSITE_IDoverride it, and an empty website ID turns statistics off.Footershows the privacy and statistics control after its notice onceAnalyticshas loaded its configuration. The notice and the control wrap as two units in a row; withoutAnalytics, the footer is unchanged.Dialogopens a native modal as a centered panel, a start or end drawer, a full-screen framed sheet or a transparent full-screen media view, with a titled bar, a close button, a blurred backdrop, scroll locking and focus return.open()andclose()control it. The media placement hides its title visually, floats the close button in a framed box and closes on a press beside its content; the site's image lightbox uses it.--dialog-widthoverrides the preferred width of the panel and drawers, and an overflowing body becomes a focusable scrolling region. Bloom's reference reader and drawer use it.Headerbuilds its narrow-screen menu onDialog. Its appearance, keyboard behavior and focus handling are unchanged; the menu bar title is now the dialog's heading. It accepts anactionssnippet for compact controls, placed before the theme switch and kept in the bar beside the menu button below--medium;IconButtonadds asearchicon for them. The DS opens its search from there.Heading. Acceptsnum, an optional section number shown before the title inSectionHead's numbering style. The editorial offset above the title is--space-8instead of--space-7. Migration: passpadding="var(--space-7) var(--layout-padding-inline) var(--layout-padding-block)"to keep the former inset. Workspace apps adopt the new default.Sectiondraws crosses at all four corners by default (crosses="both"instead of"bottom");HeadingandErrorPageinherit it. At a junction, the new top crosses coincide with the preceding frame's bottom crosses. Migration: passcrosses="bottom"to keep the former corners. Workspace apps adopt the new default. Its inset preset is renamedlayoutinstead ofdefault, so the name states the applied tokens. Migration: replacepadding="default"withpadding="layout", or omit the prop; workspace apps never pass it.gapaccepts the presetslayout(default),content,controlandnone, likepadding; custom CSS gap expressions still apply unchanged. Workspace apps,HeadingandErrorPagepassgap="none"instead ofgap="0".ChatMessagesets the body role on its message body instead of on every paragraph inside it, and only its plain-text paragraph keeps line breaks. Paragraphs in children no longer lose their margins or collapse their whitespace, so.formattedcontent applies unchanged. Migration: pass plain text throughtext, or setwhite-space: pre-wrapon the element that holds it in children. Bloom renders user messages throughtextand drops its paragraph overrides.SectionHeadacceptspadding:noneby default, orlayoutfor the shared inset when the head sits in aSection padding="none"with full-width content, so the head stays inside the section it names.Button. The defaultsubtlevariant drops its visible border and marks its four corners with accent half-crosses, drawn like the focus marks of text fields; hover replaces them with the inverted fill. Keyboard focus keeps the outer outline, and forced-colors mode shows a system border.solidandaccentare unchanged. Migration: restoreborder-color: var(--border-prominent)andbackground-image: noneon.buttonin app styles to keep the former look. Workspace apps adopt the new default.Grid.Cardcells of a dividedGridtake the layout inset (--layout-padding-*) instead of the content inset, so a grid of cards aligns with the shell gutter. Migration: compose divided grids inSection padding="none" gap="none"so their dividers reach the frame; give custom cells the layout inset. Workspace apps are migrated.Cards.minWidthtakes a CSS length instead of a pixel number; the default is"17.5rem"(280px at a 16px root). Migration: replaceminWidth={240}withminWidth="15rem"or another CSS length. Workspace apps are migrated.Pagemargins come from the spacing scale:--space-7(48px instead of 44px) above--narrowand--space-4(16px, unchanged) below. Its defaultwidthis"100rem"instead of"1600px": the same 1600px at a 16px root, but it now follows a larger text size together with the breakpoints. Migration: passwidth="1600px"to keep a fixed pixel maximum. A directasidenow becomes a sidebar:Pageplaces it in a start column of 14 to 18rem beside the content, betweenHeaderandFooter, and stacks it above the content below--medium. Compositions without an aside are unchanged. The DS catalogue uses it instead of a local grid wrapper.- Role alignment. Components use the shared role tokens instead of local values:
Card,Heading,ErrorPageand the narrow-screen menu titles take--heading-line-heightand--heading-letter-spacing;Cardcontent andChatMessagetake--body-line-height;Quotetakes the prose line height and tracking; section numbers take the interface or metadata weight.ChatComposer's hint uses.feedback, theChatWindowbadge the metadata size, and its launcher and suggestions the interface tracking.ChatWindowfullscreen locks scrolling on the root element, likeDialog.IconButtonaddspreviousandnexticons, whichCardsuses for its scrolling controls. Migration: restore local values in app styles where the former rhythm mattered.
Typography
- Strong emphasis.
--strong-font-weight(400) is one emphasis weight shared by everystrong,b,thanddt, inside or outside.formatted, above every role and keeping the family, size and color of its context. Table headers and definition terms were set apart by color only, at the surrounding weight, and.formatted thcancelled the native bold; athoutside.formattedtook the browser's bold (700), andstrongandbthe browser's relativebolder. A role class on the element itself, such as<th class="ui">, sets that role's weight instead; set the role on an ancestor to keep the emphasis, astheaddoes with the interface role. Migration: setfont-weight: inheritonthanddtin app styles to keep the former weight. www drops its local weight on press sources. - Type scale.
--font-size-basedefaults to0.95reminstead of1rem. At a 16px root, body text is 15.2px, interface text 11.4px and metadata 10.45px; headings scale in proportion and spacing is unchanged. Migration: set--font-size-base: 1remon:rootto keep the former sizes. - Type scale steps.
--font-size-sm,--font-size-mdand--font-size-lgare removed:--font-size-baseis the only shared length, and each role derives its own factor from it. Migration: replacevar(--font-size-sm)withcalc(var(--font-size-base) * 0.6875),var(--font-size-md)withcalc(var(--font-size-base) * 0.75)andvar(--font-size-lg)withvar(--font-size-base). Workspace apps never used them. - Code role.
.codesets code blocks and literal data, such as token names and values, in monospace at--code-font-size(0.85× the base, 12.92px at a 16px root, between interface and body text) with its own weight, line height and slightly tightened tracking (-0.05em), keeping the source casing even inside.uior.metadata.--code-font-size,--code-font-weight,--code-line-heightand--code-letter-spacingdefine it, and.formattedcode blocks now use it instead of the surrounding text size. Migration: setfont-size: inheriton.formatted prein app styles to keep the former code block size. - Inline code. Every
codeelement takes the code role's family, weight (200) and tracking (-0.05em), with the surrounding text size andline-height: 1; code insideprekeeps the block line height. Outside.formatted,codeformerly used the browser's generic monospace and the inherited weight; inside, the inherited weight without tracking. Migration: setfont-weight: inheritandletter-spacing: normaloncodein app styles to keep the former weight and tracking. Workspace apps adopt the new default. - Preformatted text and literals.
pretakes the complete code role everywhere, as.formatted prealready did, andkbdandsampfollow inlinecode. They formerly used the browser's generic monospace, which reduces the size to about 13/16 of the surrounding text. All four are upright and keep their source casing, so code inside italic text or a.uior.metadataparent is no longer slanted or uppercased. Everyprescrolls long lines inside the block instead of overflowing its container;.formatted prekeeps only its surface and padding, and the0.85emreduction of.proseapplies to inlinecode,kbdandsampbut not insidepre, and only once: the keys of a nestedkbdcombination inherit it instead of shrinking again. Migration: setfont-family: monospaceonpre,kbdorsampin app styles to keep the browser default, orfont-style: inheritandtext-transform: inheritto let literals follow their context. Workspace apps usepreonly inside.formattedor with.code, so their rendering is unchanged. - Formatted content. The
.proseclass is renamed.formatted..constrained-widthworks on any element instead of only beside.formatted, filling the available width up to the measure, and--prose-max-widthis renamed--reading-max-width. Inline code takes the surrounding text size instead of0.9em, since Roboto Mono shares Roboto's glyph heights, and setsline-height: 1so lines containing it keep the body rhythm. Migration: replace the class and token names; setfont-size: 0.9emon.formatted codein app styles to keep the former code size. Workspace apps and svx-deck are migrated. - Prose role.
.prosenow sets continuous authored writing in the serif family, with its own--prose-font-size,--prose-font-weight,--prose-line-heightand--prose-letter-spacing; inline code inside it is reduced to0.85em. An element still using the former.proseloses its formatted rhythm and becomes serif; complete the rename above before adopting the role. The site's presentation and artwork texts use it. - Serif italics. Teodor italics show the font's drawn slant at 10° in every browser. The face's slant range stops at
10deginstead of12deg, andbodysetsfont-synthesis-style: none: since the range stays below the browsers' italic threshold, Chromium added a synthetic skew of about 14° on top of the axis (about 25° in all) and WebKit skewed the upright glyphs by about 14°. OnlyQuote, which turned synthesis off itself, showed the drawn slant; it now relies on the document default. A font without an italic face stays upright instead of being skewed. Migration: setfont-synthesis-style: autoonbodyin app styles to let browsers synthesize italics again. Workspace apps adopt the new default. - Local type scale.
.typographyis renamed.typescale; behavior is unchanged. Migration: replace the class name where a local--font-size-baseis set. The DS and svx-deck are migrated. - Tables and rules. Tables replace their native rendering with one appearance, inside or outside
.formatted. They collapse their borders, fill their container and draw a--borderrule between rows, without an outer frame. Cells and captions align to the start instead of centering. Cells take--space-2and--space-3padding, except on the table's outer edges so the first and last columns align with the surrounding text; they align their content to the top, use tabular numbers and size columns around whole words instead of the inheritedanywhere, and literals inside them do not wrap.theadtakes the interface role,thanddtprominent text, and table captions--text-subtle,--space-2above their table. Figure captions take the same subtle text everywhere; formatted content keeps--space-2between a figure and its caption. Everyhrdraws one--border-prominentrule instead of the native inset line. A.scrollablewrapper scrolls wide tables. Migration: remove local table, caption and rule styles that duplicate these, or override them on the app's own selectors, such asborder-collapse: separate,min-inline-size: autoortext-align: center, to keep the native rendering, and setoverflow-wrap: anywhereon.formatted tdto keep the former breaks. Bloom is migrated, and www drops its local term color. - Underlined text.
.underlinedgives any element the underline of.formattedlinks, a 1px line offset by0.16em, for a link or a button presented as a text link that color alone would not distinguish. Migration: replace local underline declarations with the class. The site's exhibition links, Bloom's reference button andFooter's privacy control use it; Bloom's buttons move from offsets of0.2emand0.3emto the shared one. - Scrollable regions.
.scrollablescrolls content wider than its column, such as a wide table, horizontally inside the column; the owner addstabindex="0",role="region"and an accessible name. Migration: replace local horizontal scrolling wrappers with the class. Bloom's Markdown tables and the DS reference tables use it instead of their local.tableand.table-scrollrules. - Formatted blocks. In a loose list, whose items wrap their content in paragraphs, items and their paragraphs are separated by
--content-gap-block, as quotation paragraphs are, instead of--space-2between items and no gap between paragraphs; a nested list in such an item takes the same gap. An ordered list of ten items or more, or with astartother than 1, indents by--space-6instead of--space-5, so two-digit numbers no longer touch the column edge; Bloom setsstartonly when a list does not begin at 1. Unordered items replace the native bullet with a muted cross centered on the first line, and ordered numbers take the same--text-muted.hrtakes one and a half times the content gap on both sides, like a subsection heading. Definition lists gain list styling: definitions at the list indent and--space-2between items, with the prominent terms that everydtnow takes. A figure caption placed before its media no longer gets a top margin. Code blocks draw their edge with--border-subtleinstead of--border, since their fill identifies them. Migration: in app styles, setborder-color: var(--border)on.formatted preto keep the former edge. Workspace apps adopt the new defaults.
Colors, surfaces and interaction
- Colors. The accent has one value in both themes: the dark theme no longer redefines
--accent, which was a different, out-of-gamut pink, and--accent-subtleand--focusderive from it at the root.--text-subtlesits midway between default and muted text (47%light,71%dark), and the dark--backgroundtakes hue260like the other dark neutrals instead of340, a difference below one sRGB level. Migration: redefine--accentunder[data-theme="dark"]to keep a distinct dark accent, with--accent-subtleand--focusbeside it. - Feedback colors. The four light
--feedback-*colors are more saturated; the light error moves from pink toward red, away from the accent, and the light warning toward orange. In the dark theme, error and warning are more saturated, success shifts slightly toward teal and info is unchanged. The light values stay below 4.5:1 on light surfaces, and the browser suite checks feedback contrast in the dark theme only. Migration: redefine the four tokens under:rootand[data-theme="dark"]to keep the former values. - Dark shadows and overlay. The dark theme redefines
--floating-control-shadowand--floating-shadowat 45% and 60% black, and--overlayat 60% black instead of 32%, so floating surfaces and modal backdrops separate from the near-black page; light values are unchanged. Migration: redefine them under[data-theme="dark"]to keep the former, nearly invisible shadows and veil. - OKLCH notation. Every color token and component color is written in OKLCH, and every
color-mix()interpolates inoklch.--backgroundreadsoklch(100% 0 0)instead of#fff, and the shadows and overlay useoklch(0% 0 0 / …)instead ofrgb(0 0 0 / …); these values are exact equivalents. Mixes withtransparentrender identically. Only theThemeToggleoutline changes, as it mixes text and background: it is imperceptibly different in the light theme and slightly darker in the dark theme. Migration: scripts that read a token withgetPropertyValue()receive the OKLCH string. - Overlay tokens.
--overlay(the translucent veil behind modal surfaces) and--overlay-blur(the blur of the page seen through it) hold theDialogbackdrop values;ChatComposer's fade uses the same blur. Workspace modals and translucent bands use them. - Half-crosses.
.half-crossedmarks the four corners of any element with accent half-crosses, drawn as background layers. The defaultButtonvariant and the focus of text fields and select share this drawing instead of separate copies; their rendering is unchanged. - Focus color.
--focus-coloris renamed--focus: like--borderbeside--border-width, the bare name holds the color of the focus group. Its value is unchanged. Migration: replacevar(--focus-color)withvar(--focus). Workspace apps are migrated. - Motion tokens. Durations are named by function:
--state-duration(120ms) for interaction state changes and--motion-duration(220ms) for positional transitions, with--motion-easing.--duration-normal(160ms) is merged into--state-duration, soHeaderNavandThemeTogglecolor changes and the site's artwork arrow take120ms. Migration: replace--duration-fastand--duration-normalwith--state-duration,--duration-slowwith--motion-durationand--ease-standardwith--motion-easing. Workspace apps are migrated. - Inset focus.
--focus-inset-offset(-3px) holds the inner focus clearance thatCard,Cards,Grid,HeaderNav,ChatThreadandTabsused as local values; rendering is unchanged. - Radius tokens.
--radius-smalland--radius-mediumare removed: each served a single component, andChatMessageandChatComposernow keep their0.75remand1remcorners locally.--radius-fullremains the shared capsule. Migration: replacevar(--radius-small)with0.75remandvar(--radius-medium)with1remin app styles. Workspace apps never used them.
Document defaults
- Cascade layers. A
formattedlayer betweenbaseandutilitiesholds the.formattedrules, and cascade layers define the question each layer answers. A class placed on an element inside formatted content, such as.framedon a code block, now overrides the formatted styles instead of losing to their more specific selectors..feedbackand.visually-hiddenmove frombasetoutilities, beside the classes they belong with;.feedbackshares the rules of.metadata. Unlayered app styles still override every layer, so the rendering of workspace apps is unchanged. - Lists. The reset removes the native markers of
ulandol, which hung outside lists left without padding; formatted content draws crosses and restores the numbers. Migration: setlist-styleon lists outside.formattedthat should keep native markers. Workspace interface lists drop their locallist-style: none. - Hidden attribute.
hiddenhides its element even when a class, component or app style setsdisplay; an element withhiddenand.stack, for instance, formerly stayed visible as a flex container.hidden="until-found"keeps its native behavior. Migration: to show an element that carrieshidden, remove the attribute instead of overridingdisplay. The DS contents band drops its local[hidden]rule. - Dialog margins. The reset keeps the native auto margins of
dialog, so a native modal without component styles is centered in the viewport instead of pinned to the top-left corner.DialogandChatWindowset their own margins and are unchanged. - Text size adjustment. The root sets
text-size-adjust: 100%, so iOS Safari no longer enlarges text when a phone turns to landscape.
Native forms
- Search fields. The clear button of a search field draws a thin cross in
--text-subtle, turning--accenton hover, instead of the browser's icon and color. Migration: setappearance: autoandbackground: noneoninput[type="search"]::-webkit-search-cancel-buttonin app styles to restore the browser's button. - Native form controls. Select and text fields use the
--background-prominentfill without a visible border, and focus draws accent half-crosses at their corners instead of an outer outline, following:focus-withinso date and time fields keep them on their internal segments and picker buttons; read-only text fields drop the fill. Checkbox and radio replace their native appearance with a 17px box:--border-prominentboundary, below the 3:1 contrast of a control boundary, accent square or dot when checked, thin ring for keyboard focus.ChatComposer's focus turns its frame to the focus color instead of drawing an outer outline. Date and time inputs share the text field skin, fieldsets drop their native frame, and native widgets follow the active theme throughcolor-scheme. Forced-colors mode keeps system indicators. Migration: in app styles, restoreborder-color: var(--text-muted)on fields, orappearance: autowithaccent-coloron choice controls, to keep the former look. Workspace apps adopt the new defaults. - Native form messages.
.feedbackuses metadata typography (mono, uppercase, metadata size and tracking) instead of body text, and untoned feedback takes--text-mutedinstead of the inherited color. It now also carries field help and validation errors:.field-helpand.field-errorare removed, since they duplicated untoned and error-toned feedback. Migration: replaceclass="field-help"withclass="feedback"andclass="field-error"withclass="feedback" data-tone="error", and restore body typography on.feedbackin app styles to keep the former look. Workspace apps are migrated. - Labels, legends and select. Every
label,legendandselecttakes the complete interface role, uppercase included, wherever it sits: the typography of.uiwithout the class. Labels beside a checkbox or radio follow it, and select no longer inherits from its context. Text fields keep body typography..field-labelis removed, since the element default replaces it; labels lose its--text-prominentcolor and its source casing. Migration: removeclass="field-label"; a.uiclass on a select is now redundant. To keep the former look, setcolor: var(--text-prominent)andtext-transform: noneonlabelandlegend, orfont: inherit,letter-spacing: inheritandtext-transform: noneonselect, in app styles. Workspace apps are migrated. - Input zoom. Text fields and the
ChatComposertextarea keep at least1remunder(pointer: coarse)instead of below--narrow, since touch browsers zoom on focus regardless of viewport width; a narrow desktop window keeps the body size. Select gains the same floor over its interface size, so it shows 16px instead of 11.4px on touch devices. Migration: setfont-size: var(--ui-font-size)onselectin app styles to keep the interface size.
Layout
- Breakpoints.
--narrowis(width < 48rem)and--wideis renamed--medium,(width < 70rem). Both thresholds follow the root size inremand exclude their boundary: 768px and 1120px at a 16px root, instead of the inclusive 760px and 1100px. Usenot (--medium)for the range above. Migration: replace(--wide)with(--medium)and check layouts at the new boundaries. Workspace apps are migrated. - Spacing.
--space-8(16 units, 64px at a 16px root) extends the scale.
Token names
- Naming rule. Functional tokens name the role first, then the property, as described in Tokens; values are unchanged. Migration: replace
--{heading,body,ui,metadata}-weightwith--{role}-font-weight,--heading-{1..6}-sizewith--heading-{1..6}-font-size,--section-number-weightwith--section-number-font-weight,--crosswith--cross-size,--shadow-controland--shadow-floatingwith--floating-control-shadowand--floating-shadow, and--layer-floating-control,--layer-floatingand--layer-skip-linkwith--floating-control-layer,--floating-layerand--skip-link-layer, and--text-primaryand--text-secondarywith--textand--text-subtle, matching the default and subtle levels of the background and border colors. Workspace apps are migrated.
Configuration
Configuration factories.
createViteConfig,createSvelteConfigand the shared compiler options move from the repository'stooling/into the package as@dg/ui/config/vite.js,@dg/ui/config/svelte.jsand@dg/ui/config/tsconfig.json; behavior is unchanged. The package now declares the PostCSS plugins the Vite factory uses and resolvesbreakpoints.cssitself, so an app's build depends only on its own directory and@dg/ui. Migration: replace../../tooling/vite.js,../../tooling/svelte.jsand../../tooling/tsconfig.jsonwith these package paths. Workspace apps are migrated.SvelteKit 3. Workspace apps move to SvelteKit 3, Vite 8,
@sveltejs/vite-plugin-svelte7 andadapter-static4, which require Node.js 22.17 or later. SvelteKit 3 no longer readssvelte.config.js, so@dg/ui/config/svelte.jsis removed andcreateViteConfig(sveltekit, adapter)passes the adapter and root-relative asset URLs to the SvelteKit plugin.@dg/ui/config/tsconfig.jsonnow only keeps type checks non-strict, which TypeScript 6 no longer does by default; SvelteKit's$app/tsconfigprovides the other options. Migration: deletesvelte.config.js, import the adapter invite.config.jsand pass it as the second argument; injsconfig.json, extend["$app/tsconfig", "@dg/ui/config/tsconfig.json"]with"include": ["src", "*"]; replace$lib/imports with#lib/and declare"imports": { "#lib/*": "./src/lib/*" }in the app'spackage.json. Workspace apps are migrated.Browser test configuration.
createPlaywrightConfig({ port, server })from@dg/ui/config/playwright.jsruns a package'stests/*.spec.jswith Playwright against one app's dev server on a dedicated port, with the shared viewport, workers and failure traces. Each workspace app and@dg/uikeep their tests in their owntests/directory; Node tests (*.test.js) run withnode --test, and@dg/uitests its components on the DS pages. The repository'stests/uisuite,tooling/playwright.jsandtooling/playwright-toolkit.jsare removed. Migration: add aplaywright.config.jsand atest:uiscript as in the boilerplate. Workspace apps are migrated.
Removals
GridFlickeris removed, with its--grid-maskoverride; it was an experiment, and the site's home hero no longer shows its dot field. Migration: removeGridFlickerimports and usages..grid-bgis removed: no workspace app used the decorative background grid afterGridFlicker. Migration: copy its twolinear-gradientlayers andbackground-sizeinto the app's own styles.- Instrument Serif is removed from
@dg/ui/fonts/*and from the--font-serifstack, which now falls back from Teodor to the system serif. Migration: an app that names"Instrument Serif"must host the font itself. Workspace apps never used it.
Documentation
- Foundation references. Each foundation subject is one page in
docs/foundations/, holding its token roles, classes and usage: colors, typography, spacing, stack and row, frames and surfaces, native forms, interaction and responsive.tokens.mdkeeps loading and override guidance;foundations/frames.mdbecomesfoundations/surfaces.md, and native form guidance moves fromfoundations/css.mdtofoundations/native-forms.md. Component pages order their sections as they are read: Usage, Notes, Parameters, Overrides, Methods, Accessibility. CSS and the public API are unchanged. Migration: update links to formertokens.mdanchors andfoundations/frames.md; the DS no longer redirects former gallery, token and frame URLs. - Sections. Each documentation folder is a section whose
README.mdlists its pages in reading order:getting-started/,foundations/,components/,guides/andmaintain/.quick-reference.mdmoves togetting-started/quick-reference.md,guides/new-app.mdtogetting-started/new-app.md,guides/composition.mdtogetting-started/composition.md,foundations/css.mdtogetting-started/css.md,tokens.mdtofoundations/README.mdandchanges.mdtomaintain/changes.md; the rootREADME.mdlinks to the sections. DS URLs drop the/docsprefix and mirror these paths, such as/components/buttonand/foundations. CSS and the public API are unchanged. Migration: update links to the moved files; former/docs/...URLs are not redirected. - One owner per subject.
getting-started/css.mdbecomesfoundations/document.md, covering cascade layers, native element defaults and focus; its export table moves togetting-started/new-app.md, and font loading tofoundations/typography.md.foundations/layout.mdbecomesfoundations/stack-and-row.md. The maintenance process moves frommaintain/format.mdtomaintain/evolution.md#maintenance-process, and DS rendering conventions to the DS README.new-app.mdexplains the boilerplate's files instead of reproducing them, andcomposition.mddrops its component table in favor of the quick reference. Section indexes describe each section without repeating its pages, and guides group into patterns and process. CSS and the public API are unchanged. Migration: update links to the moved files and anchors; former URLs are not redirected. - Editorial recipe.
guides/recipe-editorial.mdand its DS page are removed:components/heading.mdandfoundations/typography.md#editorial-contentalready document the composition, including.formatted.prose.constrained-width. CSS and the public API are unchanged. Migration: link to those references instead;/guides/recipe-editorialis not redirected.
020.3.0
Breaking simplification of the public contract; not published by this change. All workspace apps are migrated.
- Fonts. Reading text uses Roboto and interface text Roboto Mono, both self-hosted variable fonts under the SIL Open Font License; Ioskeley Mono and the bundled license files are removed.
- Serif. Headings use Teodor (variable) at weight 100 with
--heading-letter-spacing: -0.07em. - Readability. Body text is 16px at weight 200, interface text 12px and metadata 11px. Interface tracking is
--ui-letter-spacing: 0.1em, applied by components instead of local values.--font-size-xsis removed; the scale is--font-size-sm,--font-size-mdand--font-size-lg. - Type scale.
--font-size-basedefaults to1remand is no longer a registered property. Migration: set local bases inremorpx; a consumer with a container-relative base registers the property itself (see type scale). - Contrast. Select, text fields and
ChatComposeroutline with--text-muted(at least 3:1).--accent-subtlederives from--accent; feedback colors use oklch with unchanged values. - Frames. Direct frames of
PageandMaindrop their bottom rule; the next frame's top rule is the shared line. A cross erases the lines around it, so neighboring crosses coincide without coordination. Migration: replacestyle="border-bottom: none"on a preceding frame withborder-top: noneon the following one; remove styles that targeted the former::beforeframe drawing. Tickeris removed.- Exports.
CloseButton,FullscreenButton,ControlIcon,HeaderNav,InfoBlock,ChatContext,ChatControls,ChatHeader,ChatLauncher,ChatNotice,ChatSendButtonandChatWelcomeare no longer exported. Migration: useIconButton icon="close"forCloseButton; write an empty state, context row or notice as app markup insideChatPanel;ChatWindowkeeps its own launcher, header and controls. Tabsis now a WAI-ARIA tabs widget that switches panels within the page:itemstake{ value, label, panel }andvalueis bindable. Migration: page navigation styled as tabs uses native links instead.- Language.
Pagetakeslang(enorfr); every built-in label follows it.SkipLinkis placed first insidePage. Removed props:HeadermenuLabel,closeLabel,themeLabel,themeLabels;ThemeTogglelabel,lightLabel,darkLabel;CardsscrollLabel,previousLabel,nextLabel;TickerpauseLabel,resumeLabel;ChatComposersendLabel,stopLabel;ErrorPagelang. Content-naming props such aslabelandplaceholderremain as overrides. - Theme. The outermost
Pagerestores the saved theme before first paint. Migration: delete the theme script fromapp.html. - Fields. Text inputs and textareas share the native field skin by default; the
.fieldclass is removed.Section'shorizontal,verticalandno-toppadding presets are removed. - Responsive. Breakpoints are
--narrow(760px) and--wide(1100px);--compactand--mediumare removed.Gridswitches to one column from its own width (40rem) through a container query. - Component behavior.
Buttonkeeps its natural width inside stacks.Gridequalizes row heights only with several columns, and itsdividedlines replace aCardcell's border.ChatComposerkeeps the draft focused and read-only whilepending, and returns focus to it after a stop. - Cascade.
base.cssuses thereset,baseandutilitiescascade layers; unlayered component and app styles always override them. - Every component forwards native attributes, DOM callbacks,
classandstyleto its root element, except the names it owns.SectionHeadno longer shows a default number.
030.2.1
Contract hardening; not published by this change.
- Forwarded attributes use native Svelte HTML types rather than accepting every property name. Consumer tests cover all eleven forwarding components, supported HTML attributes, invalid values and ignored content.
Tabs' JSDoc annotation is corrected. - Class names remain strings.
Header,FooterandTabsdo not accept unrendered children;Headingkeeps ownership of children and gap while forwardingSection's padding and crosses. Replace invented attributes with documented props or appropriate data attributes; remove content these components never rendered. - Generated agent context resolves prose links directly to Markdown or repository sources. Code examples and raw Markdown endpoints stay unchanged.
pnpm check:toolkitruns contract checks without dev servers or browser engines. The canonical Markdown index alone owns current component grouping; legacy gallery URLs remain compatible.- The repository's Node engine declaration matches its documented prerequisites. An independent editorial, collection and conversation evaluation protocol describes how to measure agent autonomy without treating automated checks as accessibility certification.
Existing documented runtime behavior and visual defaults are unchanged. Types now report previously unchecked unsupported usage; read each reference's Notes before forwarding attributes.
040.2.0
Development baseline; not published by this change.
- Spacing derives from one base unit while retaining the previous default scale. Shared radius, focus, disabled, short-motion, elevation and feedback roles are documented.
- Native text fields, field labels, help, errors and feedback have an opt-in CSS contract. Existing square frames and circular drawing geometry remain intact.
ThemeToggleaddslabel,lightLabelanddarkLabel.HeaderandHeaderNavforwardthemeLabels;CardsaddsscrollLabel,previousLabelandnextLabel. English defaults and existing call sites remain compatible.- The registered root typography base resolves from
1em, preserving its default size while allowing WebKit to follow root text enlargement. Scoped bases still resolve once before inheritance. - Public documentation includes composition recipes, native checkbox/radio guidance, evolution rules and an agent workflow. The DS generates agent-readable context from the canonical references and CSS rather than a separate editable catalogue.
- Toolkit checks cover documentation, APIs, consumers and critical behavior on Chromium, Firefox and WebKit. Manual screen-reader and real browser zoom review remain required where relevant.
No consumer migration is required for these optional additions. Translate labels in an application when its audience needs it. Recheck unusual local CSS overrides against the documented spacing and focus contracts before adoption.