You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/scripts/theming-sentinel-exceptions.ts

1506 lines
121 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* theming-sentinel-exceptions — the written adjudications R-5.4 requires.
*
* A public token the sentinel reports as "no effect" is EITHER a lie (retire
* it) OR its silence has a measured reason that lives here, one line per
* token: the part is conditional and the demo does not mount it, the state
* needs forcing, the consumer is a pseudo-element or a composed component the
* instrument cannot read, the value sits behind a media query. "Forced →
* reaches" means the adjudication PROVED the token alive by mounting what it
* needs; an instrument-limit entry names the limit (they are also registered
* in next-features §13).
*
* An entry whose token starts moving again is reported as STALE by the guard —
* prune it (a stale exception is the same debt as a stale allowlist row).
*
* All entries below were measured during the F2-A adversarial review
* (2026-08-21) unless dated otherwise.
*/
const PLANE_SUPERSEDED =
'SUPERSEDED by the depth plane: the part carries data-depth=overlay, and [data-depth=overlay] declares this property at the same specificity (0,1,0) and LATER in the cascade, so the recipe key is bypassed (see next-features 12.9, measured on tooltip, popover and float-panel)';
export const SENTINEL_EXCEPTIONS: Record<string, Record<string, string>> = {
slider: {
// 2026-08-24. Seven keys, seven measured reasons, zero retirements: an
// orientation, a pointer held DOWN, two demo states and the transition
// pair the guard freezes. Every one reaches once its state exists — the
// contract does not lie, the stage only wears one of its faces.
'min-block-size':
"only [data-slider][data-orientation='vertical'] reads it, and the stage boots horizontal. Measured 2026-08-24 through the orientation chip of the demo: vertical -> reaches (block-size and min-block-size 160px -> 1234px)",
'active-thumb-scale':
'the pickup lift lives in `[data-slider-thumb]:active`, which needs the pointer HELD DOWN, and the static pass of the guard parks the pointer. Measured with a real mouse.down() on the real thumb, transitions frozen -> reaches (scale 1.15 -> 4.56)',
'active-thumb-shadow':
'same :active pickup, measured the same way -> reaches (rgba(15, 23, 42, 0.12) 0px 8px 24px -> rgb(1, 2, 3) 0px 0px 0px 7px)',
'active-tick-bg':
'a tick carries data-active only while its value sits INSIDE [min(values), max(values)] (soma SliderTickProvider.isActive), so one thumb at 40 with ticks at 0/50/100 leaves the three inactive — the token is not dead, its state is unreachable with a single value. Measured with the `multiple` chip of the demo (values 20-80, tick 50 goes active) -> reaches (oklch(0.5556 0.1829 305.86) -> rgb(1, 2, 3))',
'disabled-opacity':
'`[data-slider][data-disabled]`, and the stage boots enabled. Measured with the disabled toggle of the demo -> reaches (opacity 0.4 -> 0.123)',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s on the four transitioned properties of the thumb)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(4))'
},
'scroll-area': {
// 2026-08-24. Three keys, three measured reasons, zero retirements: one
// MODE the demo has no control for, and the transition pair the guard
// freezes in order to make every other token measurable.
'auto-max-block':
'the rule is `[data-scroll-area][data-autosize] [data-scroll-area-viewport]` and the stage mounts the default fixed-fill mode. There is no control for it, and `data-autosize` is stamped by the EIDOS wrapper from a prop, not declared by the morfo, so the demo exception of PLAN 7.8 does not open it either. Measured 2026-08-24 on the real viewport: the token alone leaves `max-block-size: none`; forcing data-autosize on the real root makes the same write reach (none -> 1234px), and removing the token restores none',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s on both transitioned properties of the scrollbar and on the one of the thumb)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(4), on scrollbar and thumb)'
},
fab: {
// 2026-08-24. ONE key, and it is the guard's blind spot for `translate` —
// the same limit already adjudicated for `transform` on background,
// rating-group and card, on the sibling property. Three independent
// reasons, all measured: the property is not in the read set; the static
// pass parks the pointer and this rule is `:hover`-only; and a sentinel-
// sized lift moves the node OUT from under the cursor, so the state
// cancels itself (`:hover` true at t+50ms, false by t+300ms).
lift: 'the guard does not snapshot `translate` (the `transform` limit of background / rating-group / card on the sibling property) and its static pass never hovers, while this rule is `[data-fab]:hover:not([data-disabled]):not(:active)`. Measured by hand with a real pointer: set --fab-lift=1234px BEFORE hovering and the FAB computes `translate: 0px -1234px` at t+300ms -> reaches. Note the self-cancel that makes it unmeasurable even with a hover pass: a 1234px lift carries the node out from under the cursor, :hover drops and it settles back to none by t+900ms'
},
'tags-input': {
// 2026-08-24. Four reasons, all measured on the real nodes with a real
// pointer; the twenty-four tone keys are the palette cascade and ride the
// PATTERN entry below.
'item-fg':
"the ARCHETYPE ink always wins: the morfo stamps aria-selected='true' as a LITERAL on EVERY tag, so archetypes.css's `[data-archetype='item'][aria-selected='true']:not([data-state='checked']):not([data-state='on'])` (0,4,0) out-ranks the recipe's `[data-tags-input-item]` (0,1,0) on every item, at rest and always. Measured 2026-08-24: with the attribute as shipped the token moves nothing (the ink stays oklch(0.2435 0 0) = --color-content-primary, the archetype's); set aria-selected=false on the real tag and the same write reaches (rgb(1, 2, 3)). Same class as table.selected-row-fg and the listbox ink (next-features §12); the aria literal is a morfo decision and is registered, not touched from this axis",
'placeholder-fg':
"the input carries a `placeholder` attribute only while it is EMPTY (soma: `isEmpty ? opts.placeholder : undefined`) and the stage boots with two tags, so ::placeholder returns the ELEMENT's style — the trap already measured on field. Emptying the stage is not an option for this run: it deletes every item node, which is where a third of the contract paints. Measured both ways 2026-08-24: clearing the tags through the demo's own Clear trigger gives the input placeholder=\"Add tag\", and forcing the attribute on the real input makes the token reach (rgb(1, 2, 3); its default is oklch(0.61 0 0) = --color-content-muted)",
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 4.321s on the three transitioned properties of the control)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))'
},
avatar: {
// 2026-08-23. Five steps of scales the measured stage does not wear, all
// forced on the REAL nodes with transitions frozen. Two of them sit on the
// `xxl` step, which the size sweep of the guard does not reach (the same
// limit `metrics` recorded below).
'size-xxl':
'the size sweep of the guard stops at xl; forced data-size=xxl -> reaches (block-size 96px -> 1234px)',
'font-size-xxl':
'same xxl step, read on the fallback initials (the image carries no font); forced -> reaches (28px -> 37px)',
'radius-none': 'only the step in force paints; forced data-radius=none -> reaches (0px -> 37px)',
'ring-width-sm':
'only the step in force paints (the demo boots ringWidth=md); forced data-ring-width=sm -> reaches (halo 1.5px -> 17px)',
'group-overlap-xxl':
'same xxl step, on AvatarGroup; forced data-size=xxl on the real group -> reaches (margin-inline-start -33.6px -> 37px)'
},
editable: {
// 2026-08-23. Only two reasons, both measured: the transition pair IS the
// transition the guard freezes, and the twelve tone keys are the palette
// cascade (adjudicated by PATTERN below).
'submit-fg':
'OSCILLATES: read ALIVE in 3 of 4 runs on the same HEAD (42/56) and dead in the fourth (41/56). Leaving the edit mode is what a blur does, and the guard opens by focus + prepareWith, so the surface it measures is not deterministic. Measured alive with the editor open and transitions frozen -> reaches. Without this entry the fourth run fails R-5.4 with a token that does not lie (2026-08-23)',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 4.321s on the three transitioned properties of the preview)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))',
// NOT the palette pattern: this one key is ALSO read straight by the invalid
// rules, so its silence has a second, different cause — the demo is valid.
'risk-border':
'the palette path is superseded like its eleven siblings, but this key is ALSO the invalid tint, read directly by three rules; forced data-invalid on the real root -> reaches on the input AND on the control (oklch(0.8059 0.1123 59.96) -> rgb(1, 2, 3))'
},
background: {
// 2026-08-23. Its parts are independent OPT-IN layers and only ONE pattern
// renders at a time, so the default stage moved 3 of 37 tokens. The guard
// now switches the scrim on and sweeps `data-pattern` (18/37); what is
// left is measured here, forcing the attribute on the REAL layer — never
// on a node built by hand.
//
// The mask: the guard does not read `mask-image`, so both read dead while
// being perfectly alive (instrument gap, next-features §13).
'fade-size':
'the guard does not snapshot mask-image; measured by hand → reaches (the radial mask changes)',
'fade-at':
'the guard does not snapshot mask-image; measured by hand → reaches (at 50% 35% → at 11% 50%)',
// The ink context: only under `on='dark'` / `on='light'`.
'scrim-fg-over-dark': "only under on='dark'; forced → reaches (the veil colour changes)",
'scrim-fg-over-light': "only under on='light'; forced → reaches (the veil colour changes)",
// Two scales where only the step in force paints (the `section` / `qr-code`
// class): every step measured one by one on the real scrim layer.
'scrim-blur-sm': 'only the step in force paints; forced data-blur=sm → reaches (4px → 33px)',
'scrim-blur-md': 'only the step in force paints; forced data-blur=md → reaches (8px → 33px)',
'scrim-blur-lg': 'only the step in force paints; forced data-blur=lg → reaches (12px → 33px)',
'scrim-blur-xxl': 'only the step in force paints; forced data-blur=xxl → reaches (24px → 33px)',
'scrim-strength-xs':
'only the step in force paints; forced data-strength=xs → reaches (alpha 0.08 → 0.9)',
'scrim-strength-sm':
'only the step in force paints; forced data-strength=sm → reaches (alpha 0.13 → 0.9)',
'scrim-strength-lg':
'only the step in force paints; forced data-strength=lg → reaches (alpha 0.4 → 0.9)',
'scrim-strength-xl':
'only the step in force paints; forced data-strength=xl → reaches (alpha 0.7 → 0.9)',
// A gradient layer EXCLUDES a pattern layer, so the sweep cannot have both.
'gradient-drift-duration':
'the gradient layer is exclusive with the pattern one the sweep needs; forced data-kind=gradient → reaches (24s → 42s)',
// The spotlight is off on the default stage and, once on, it repaints the
// pattern layer it shares a node with — measured on its own pass.
'spotlight-size':
'spotlight is off in the demo; forced data-spotlight → reaches (40% 40% → 42px)',
'spotlight-strength':
'spotlight is off in the demo; forced data-spotlight → reaches (the mix stop moves)',
'spotlight-fg':
'spotlight is off AND the demo layer carries data-color, where --palette-solid wins by design; forced data-spotlight with no data-color → reaches',
// Structural, not conditional: the travel only enters through the
// scroll-linked `background-parallax` keyframes, which need a scroll
// timeline the measured stage does not have.
'parallax-travel':
'the demo boots at speed 0, so no layer carries data-parallax; forced data-parallax + speed 1 on the real layer, the scroll-linked translate follows it (14.6 -> 60.5 px at the same scrollY). The guard would not see it anyway: translate / transform are not in its property snapshot (next-features 13)',
// No node at all: the demo never mounts the pause control.
'pause-offset': 'the pause control is not mounted in the demo (0 nodes on the page)',
'pause-z': 'the pause control is not mounted in the demo (0 nodes on the page)'
},
'chat-composer': {
// 2026-08-23. Four, and three of them are the guard's own two habits.
'focus-border':
'only paints under :focus-within, and the guard blurs the active element after opening; focused the REAL textarea with transitions frozen -> reaches (color(srgb 0.745 0.577 0.894 / 0.48) -> rgb(1, 2, 3) on the shell border)',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 4.321s on the shell AND on the send)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))',
// NOT the guard: a cross-recipe collision, and the composer is on the losing
// side of it BY DESIGN — its documented composition puts it inside FileUpload.
'disabled-opacity':
'file-upload sweeps DESCENDANTS: `[data-file-upload] [data-disabled]` is (0,2,0), the same weight as `[data-chat-composer-send][data-disabled]`, and its recipe is emitted LATER, so it wins over every disabled node inside a FileUpload — which is where the demo (and the documented composition) puts the composer; measured on the REAL nodes with the ancestor attr removed -> reaches (0.4 -> 0.123 on the send AND on the shell). Both defaults are --opacity-disabled, so the collision is invisible until a theme moves one'
},
'chat-message': {
// 2026-08-24. Four, and every one of them is a limit of the INSTRUMENT —
// measured on the real nodes, one by one.
'bubble-tail-radius':
'the guard snapshots exactly ONE corner (`borderTopLeftRadius`) and the tail is the BOTTOM one — `border-end-start-radius` incoming, `border-end-end-radius` outgoing. Measured on the real bubble across the 8 direction x run combinations: 4px -> 1234px on solo and last in BOTH directions (10px/10px/10px/4px -> 10px/10px/10px/1234px in, 10px/10px/4px/10px -> 10px/10px/1234px/10px out), while the corner the guard reads never moves. Its sibling `bubble-radius-run` reads alive because `middle` flattens the START corner, which IS in the read set',
'emphasize-duration':
'the guard freezes transitions and this token IS the transition (the jump-to-message flash is a two-state toggle + a transition, R-4.5 — there are no keyframes); measured unfrozen on the real row -> reaches (0.24s -> 4.321s)',
'focus-radius':
'the row is tabbable ONLY when composed into a Feed — soma merges `Feed.Article`s identity (tabindex, keyboard) into the provider props when a Feed ancestor exists — and its own demo mounts it standalone, so `:focus-visible` has no node there. Measured on /uix/components/chat-log, where the rows ARE feed articles (tabindex=0), with transitions frozen: rest 6px (the emphasize corner), focused 4px -> 1234px, both by programmatic focus and by a real Tab walk',
'quick-react-hover-scale':
'two limits at once: the guard does not snapshot `transform` (the same blind spot adjudicated for background / rating-group / card) and the cell is a PORTALED tapback button whose rule is `:hover, :focus-visible`. Measured with a real pointer on the open bar, transitions frozen -> reaches (matrix(1.18, 0, 0, 1.18, 0, 0) -> matrix(7.77, 0, 0, 7.77, 0, 0))'
},
'chat-log': {
// 2026-08-23. ONE key, and only because the guard blurs after opening: the
// event row is a tabbable feed article whose corner exists only under the
// focus ring (it is square at rest).
'event-radius':
'only paints under :focus-visible, and the guard blurs the active element after opening; keyboard-focused the REAL row with transitions frozen -> reaches (rest 0px, focused 4px -> 1234px)'
},
badge: {
// 2026-08-23. The demo mounts ONE chip, and its `rounded` axis paints only
// the step in force — measured forcing each on the real chip.
'radius-sm': 'only the step in force paints; forced data-rounded=sm → reaches (4px → 37px)',
'radius-lg': 'only the step in force paints; forced data-rounded=lg → reaches (10px → 37px)'
},
'color-swatch': {
// 2026-08-23. The inset ring is OPT-IN (`bordered`, off by default) and NO
// consumer in the repo passes it, so the `::after` that draws it exists on
// no page. Forced `data-bordered` on a real chip of the gradient-builder
// stage, transitions frozen: the ring appears and both tokens follow.
'border-width':
'the `bordered` ring is opt-in and no consumer mounts it; forced data-bordered on the real chip → reaches (inset 0 0 0 1px → 1234px)',
'border-fg':
'same opt-in ring; forced data-bordered on the real chip → reaches (oklch(0.931 0 0) → rgb(1, 2, 3))'
},
form: {
// 2026-08-23.
'grid-min':
"only under [data-layout='grid'], and the computed template only CHANGES when the value alters the column count: forced the layout and 90px -> reaches (502px -> four 110.5px columns)",
'error-summary-list-indent':
'the summary renders EMPTY in the demo (no errors), so it has no <ul> to indent',
'link-underline-offset': 'same empty summary: no <a> inside it',
'auto-fields-array-padding':
"the array branch needs a schema field of type array; the demo's `auto` mode mounts group + field only",
'auto-fields-border-width': 'same array branch',
'auto-fields-radius': 'same array branch',
'auto-fields-item-gap': 'same array branch (the item exists only inside an array)',
'auto-fields-item-padding': 'same array branch',
'widget-padding-inline': 'the widget is the array toolbar affordance; same missing branch',
'widget-radius': 'same missing branch',
'widget-border-width': 'same missing branch',
'grid-column-gap':
"the demo runs layout='stack'; forced data-layout=grid -> reaches (20px -> 37px)",
'invalid-accent':
'only under [data-form][data-invalid]; forced on the form -> reaches (oklch(0.8059 0.1123 59) -> rgb(1,2,3)) on the summary border',
'link-underline-fg': 'same empty summary as the offset above: no <a> to underline',
'auto-fields-array-bg': 'same array branch the demo never mounts',
'auto-fields-item-bg': 'same array branch',
'auto-fields-border': 'same array branch (the group and the field do not draw it)',
'widget-bg': 'same missing branch',
'widget-border': 'same missing branch'
},
dialog: {
// 2026-08-23. Seven tokens of states the demo does not mount: it shows a
// middle-centred `md` dialog, open and neutral. All forced on the real
// content node, transitions frozen.
'content-max-height-sheet':
'only under [data-sheet] (the wrapper sets it below the sm breakpoint); forced -> reaches (850px -> 377px)',
'content-full-inset': "only under [data-size='full']; forced -> reaches (12px -> 37px)",
'content-position-inset':
'only on the 8 non-centred cells of the position grid; forced data-position=top-left -> reaches (16px -> 37px)',
'close-inset':
'the close button carries NO data-position in this demo, and every rule that reads it needs one; forced data-position=top-right -> reaches (12px -> 37px)',
// The exit tint: the morfo writes `data-last-action` before `data-state`
// flips to closed, so both attributes only coexist WHILE the dialog leaves.
'saved-border':
'only during the exit, with [data-state=closed][data-last-action=saved]; forced -> reaches (oklch(0.9582 0.0223 155) -> rgb(1,2,3))',
'failed-border':
'same exit window; forced -> reaches (oklch(0.9555 0.0207 13.8) -> rgb(1,2,3))',
'dismissed-border':
'same exit window (cancelled / dismissed / dismissed-outside share it); forced -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))'
},
'pin-input': {
// 2026-08-23. Six STATE tokens: the demo shows an empty, editable, valid
// pin. Forced on the real nodes — note WHERE: `filled` and `active` are
// per-CELL attributes, but `invalid` and `readonly` are stamped on the
// CONTAINER and cascade down (forcing them on the cell does nothing).
'cell-filled-bg':
'no filled cell in the demo; forced data-filled -> reaches (oklch(0.9588 0.0249 311.71) -> rgb(1,2,3))',
'cell-filled-border':
'same state; forced -> reaches (oklch(0.8043 0.0918 309.69) -> rgb(1,2,3))',
'cell-active-border':
'the cell under the caret; forced data-active -> reaches (oklch(0.5556 0.1829 305.86) -> rgb(1,2,3))',
'cell-invalid-border':
'stamped on the CONTAINER (soma OR-merges it with the enclosing Field); forced there -> reaches (oklch(0.6256 0.1933 23.03) -> rgb(1,2,3))',
'cell-readonly-bg':
'container attribute too; forced there -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))',
'disabled-opacity':
'no disabled pin in the demo; forced data-disabled -> reaches (0.4 -> 0.137)'
},
'spin-field': {
// 2026-08-23. Measured inside number-field (this is a shared LAYER with no
// route of its own), transitions frozen except for the last pair.
'active-control-border':
"the ACTIVE state is the scrubber's [data-scrubbing], not :active; forced on the real scrubber -> reaches (oklch(0.8043 0.0918 309.69) -> rgb(1,2,3))",
'active-control-bg':
'same drag state; forced -> reaches (oklch(0.9932 0.0034 325.6) -> rgb(1,2,3))',
'active-control-fg':
'same drag state; forced -> reaches (oklch(0.5168 0.1733 305.88) -> rgb(1,2,3))',
'focus-control-bg':
'only under :focus-visible, which the guard blurs away on purpose; forced the pseudo via CDP -> reaches (oklch(0.931 0 0) -> rgb(1,2,3))',
'control-disabled-opacity':
'no disabled stepper in the demo; forced data-disabled -> reaches (0.48 -> 0.137)',
'transition-duration':
'frozen by the guard by design; unfrozen pass -> reaches (0.12s -> 11.5s)',
'transition-ease':
'same freeze; unfrozen pass -> reaches (cubic-bezier(0.4,0,0.2,1) -> steps(7))'
},
meter: {
// 2026-08-23. The demo sits on the OPTIMUM zone, so the two off-zone inks
// have no node to paint; forced on the real root, transitions frozen.
'indicator-bg-below':
"only under [data-state='below']; forced -> reaches (oklch(0.6908 0.1909 45.02) -> rgb(1,2,3))",
'indicator-bg-above':
"only under [data-state='above']; forced -> reaches (oklch(0.6256 0.1933 23.03) -> rgb(1,2,3))",
'transition-duration':
'frozen by the guard by design; unfrozen pass -> reaches (0.18s -> 11.5s)',
'transition-ease':
'same freeze; unfrozen pass -> reaches (cubic-bezier(0.4,0,0.2,1) -> steps(7))'
},
progress: {
// 2026-08-23. The guard now sweeps `data-shape` (like its twin meter) and
// switches the demo's indeterminate + vertical controls on, which takes it
// from 22/41 to 40/43. What is left needs a state the demo cannot hold at
// the same time as the ones already forced, or a property the guard freezes.
'indicator-bg-loaded':
"only under [data-state='loaded'], and the run holds `indeterminate` to reach the sweep tokens; forced on the real root -> reaches (oklch(0.6406 0.1329 157.68) -> rgb(1,2,3))",
'transition-duration':
'frozen by the guard by design; unfrozen pass -> reaches (0.18s -> 11.5s)',
'transition-ease':
'same freeze; unfrozen pass -> reaches (cubic-bezier(0.4,0,0.2,1) -> steps(7))'
},
'emoji-picker': {
// 2026-08-23. Four keys of the PORTALED panel. The guard writes the
// sentinel on :root and on the host, and :root does cross the portal
// (verified) — what it cannot do is measure a node the demo never mounts
// or one that carries no attribute of the component.
'tone-marker-size':
'the corner dot lives on [data-tone-capable]::after and the demo mounts ZERO tone-capable cells; forced the attribute on a real option -> reaches (4px -> 37px)',
'tone-marker-radius': 'same pseudo, same absent state; forced -> reaches (9999px -> 37px)',
'tone-marker-bg': 'same pseudo, same absent state; forced -> reaches (-> rgb(1,2,3))',
'preview-name-fg':
'the preview children are bare <span>s stamped inline, with no data-emoji-picker-* attr, so they are outside the measured set; read on the last child -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
// NON-DETERMINISTIC, and that is the reason: three runs of the same code
// gave 17/21, 16/21, 16/21 — the panel closes somewhere in the pass and the
// trigger loses [data-state=open], which is what this rule selects on.
// Measured alive FOUR times, the last one replicating the guard's own
// staticPass step by step (moved on the first size): oklch(0.2435 0 0) ->
// rgb(1,2,3), from :root and from the host. An openMarker on the trigger was
// tried and did NOT fix it (still oscillates), so the cause is the reopen
// timing, not the marker. EXPECT THIS ENTRY TO BE FLAGGED STALE on the runs
// where it does reach — do not delete it on that alone. next-features 13.
'open-trigger-fg':
'OSCILLATES: oscillates run to run (17/21 vs 16/21 on the same code); measured alive four times, including a step-by-step replica of the guard staticPass -> reaches (oklch(0.2435 0 0) -> rgb(1,2,3))'
},
'color-field': {
// 2026-08-23. Thirteen tokens, none of them a lie: the demo boots with a
// value, in `md`, editable, with three formats allowed — so every state
// and every size step but the mounted one has no node to paint. All
// forced on the REAL nodes (never a fabricated one), transitions frozen.
'placeholder-fg':
'no empty field in the demo; forced data-placeholder → reaches (oklch(0.61 0 0) → rgb(1,2,3))',
'segment-invalid-fg':
'invalid is off in the demo; forced data-invalid → reaches (oklch(0.5855 0.1743 42.74) → rgb(1,2,3))',
'segment-readonly-bg':
'readonly is off in the demo; forced data-readonly → reaches (oklch(0.931 0 0) → rgb(1,2,3))',
'segment-readonly-fg':
'readonly is off in the demo; forced data-readonly → reaches (oklch(0.5032 0 0) → rgb(1,2,3))',
'segment-readonly-decoration':
'readonly is off in the demo; forced data-readonly → reaches (underline dotted → overline wavy)',
'disabled-opacity': 'disabled is off in the demo; forced data-disabled → reaches (0.4 → 0.123)',
// The swatch scale: only the step in force paints. Forced each size on the
// real root and measured the swatch — every step reaches.
'swatch-size-xs': 'only the size in force paints; forced data-size=xs → reaches (14px → 77px)',
'swatch-size-sm': 'only the size in force paints; forced data-size=sm → reaches (16px → 77px)',
'swatch-size-lg': 'only the size in force paints; forced data-size=lg → reaches (20px → 77px)',
'swatch-size-xl': 'only the size in force paints; forced data-size=xl → reaches (32px → 77px)',
// The locked-format LABEL only renders when a single format is allowed
// (`isLocked`). Driven through the demo's own chips — not a hand-made node.
'format-select-fg':
'the static label only renders with ONE allowed format; unchecked rgb+hsl in the demo → reaches (oklch(0.5032 0 0) → rgb(1,2,3))',
// The known law: the guard freezes `transition` to make everything else
// measurable, so the tokens that ARE the transition can never move under
// it. Measured in a separate unfrozen pass, on an EDITABLE segment — the
// first segment is a `literal`, which declares `transition: none` of its
// own and reads 0s whatever the token says.
'transition-duration':
'frozen by the guard by design; unfrozen pass on the hex segment → reaches (0.12s → 11.5s)',
'transition-ease':
'frozen by the guard by design; unfrozen pass on the hex segment → reaches (cubic-bezier(0.4,0,0.2,1) → steps(7))'
},
'navigation-menu': {
// 2026-08-23. The rule is `[…-trigger][data-disabled], […-link][data-disabled]`
// and the demo mounts neither — measured with transitions FROZEN, because
// `color` is transitioned on this part and an immediate read returns the
// OLD value (the eyedropper trap: three false diagnoses before freezing).
'disabled-trigger-fg':
'no disabled trigger or link in the demo; forced data-disabled → reaches on BOTH parts (rgb(1,2,3))'
},
command: {
'focus-input-border':
'consumed only under :focus-visible, which the guard blurs away ON PURPOSE (the click-focus poisoning fix); focused by hand → reaches (rgb(9,9,9))',
'loading-height': 'the loading bar is conditional and the demo does not mount it',
'loading-fg': 'the loading bar is conditional and the demo does not mount it',
'viewport-padding': 'the non-ScrollArea viewport variant is not mounted in the demo',
'empty-padding-block': 'the empty state is conditional and not mounted at measurement',
'empty-fg': 'the empty state is conditional and not mounted at measurement'
},
table: {
'header-z':
'consumed only under [data-sticky-header], which the demo does not set; forced → reaches (2 → 4321)',
'row-detail-fg':
'detail rows are closed (display:none) in the demo initial state; forced data-state=open → reaches (rgb(1,2,3))',
'row-detail-padding-block':
'detail rows are closed (display:none) in the demo initial state; forced data-state=open → reaches (12 → 1234)'
},
'media-player': {
'accent-strong': 'consumed by the live indicator, which only paints under [data-live]',
'buffered-bg':
'forwarded into the composed Slider (SecondaryRange) — outside this component attribute space',
'captions-bg': 'captions are conditional and the demo video carries no track',
'captions-fg': 'captions are conditional and the demo video carries no track',
'captions-radius': 'captions are conditional and the demo video carries no track',
'captions-padding-block': 'captions are conditional and the demo video carries no track',
'captions-padding-inline': 'captions are conditional and the demo video carries no track',
'captions-line-height': 'captions are conditional and the demo video carries no track',
'volume-vertical-length': 'the volume float is interaction-mounted; not open at measurement',
'volume-float-padding-block':
'the volume float is interaction-mounted; not open at measurement',
'volume-float-padding-inline':
'the volume float is interaction-mounted; not open at measurement',
'rate-button-min-width': 'the rate control is conditional and the demo does not mount it',
'audio-title-padding-block': 'audio variant — the video demo does not mount the audio title',
'audio-title-padding-inline': 'audio variant — the video demo does not mount the audio title'
},
'tree-grid': {
'header-z':
'consumed only under [data-sticky-header], which the demo does not set; forced → reaches (2 → 4321)',
'disabled-row-fg': 'no disabled row in the demo; forced data-disabled → reaches (rgb(1,2,3))'
},
'gradient-picker': {
'chip-radius':
'the swatch is a CLASS hook (.gradient-picker-trigger-swatch) outside the attribute-filtered node set; direct read → reaches (§13 class-hook debt)',
'chip-border':
'the swatch is a CLASS hook outside the attribute-filtered node set; direct read → reaches (§13 class-hook debt)',
'content-width-sm':
"sized by data-picker-size (picker-shell's axis, not data-size); forced → reaches (288 → 512)",
'content-width-lg':
"sized by data-picker-size (picker-shell's axis, not data-size); forced → reaches (352 → 512)",
'stoplist-max-block':
"consumer node lives in the composed ScrollArea's attribute space (--scroll-area-auto-max-block on the viewport); direct read → reaches (132 → 1234)",
'stoplist-scrollbar-size':
'the design scrollbar only mounts on overflow; the demo list is short',
'stoplist-scrollbar-inset':
"consumer node lives in the composed ScrollArea's attribute space; direct read → reaches (12 → 1234)",
'presets-panel-width':
"the presets popover needs a second click the guard's open step does not perform; forced → reaches (240 → 1234)",
'presets-gap': 'presets popover not mounted by the open step; forced → reaches (8 → 1234)',
'presets-min-column':
'presets popover not mounted by the open step; forced → reaches (66px columns → 1234)',
'preset-height': 'presets popover not mounted by the open step; forced → reaches (32 → 1234)',
'preset-radius': 'presets popover not mounted by the open step; forced → reaches (6 → 1234)',
'preset-border': 'presets popover not mounted by the open step; forced → reaches (rgb(1,2,3))',
'hover-preset-border':
'presets popover not mounted by the open step; forced + real hover → reaches (rgb(1,2,3))',
'selected-preset-border':
'presets popover not mounted by the open step; forced data-selected → reaches (rgb(1,2,3))',
'selected-preset-outline-offset':
'presets popover not mounted by the open step; forced data-selected → reaches (2 → 1234)'
},
listbox: {
'invalid-border': 'no invalid listbox in the demo; forced data-invalid → reaches (rgb(1,2,3))'
},
carousel: {
'vertical-block-size':
'vertical orientation not mounted in the demo; forced → reaches (256 → 1234)'
},
feed: {
'sentinel-spinner-size':
'the spinner only exists while [data-busy], and the guard WAITS for the busy window to close (the settle fix); measured live during the busy window (::before, 12 → 1234)',
'sentinel-spinner-width':
'the spinner only exists while [data-busy]; measured live during the busy window (::before border)',
'sentinel-spinner-gap':
'the spinner only exists while [data-busy]; measured live during the busy window (::before margin)',
'sentinel-spinner-duration':
'the spinner only exists while [data-busy]; measured live during the busy window (animation-duration 0.7s → 11.5s)',
'article-title-font-size-5':
'the demo mounts heading levels 3–4 only; forced aria-level=5 → reaches (14 → 1234)',
'article-title-font-size-6':
'the demo mounts heading levels 3–4 only; forced aria-level=6 → reaches (12 → 1234)',
'sentinel-spinner-reduced-duration':
'behind prefers-reduced-motion; emulated reduce context → reaches (4s → 11.5s)'
},
'drag-drop': {
'preview-padding-block':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (8 → 1234px)',
'preview-padding-inline':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (12 → 1235px)',
'preview-radius':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (6 → 1236px)',
'preview-border-width':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (1 → 9px)',
'preview-bg':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (rgb(1,2,3))',
'preview-fg':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (rgb(4,5,6))',
'preview-font-family':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (Zapfino)',
'preview-font-size':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (14 → 99px)',
'preview-shadow':
'the drag PREVIEW is created only while a drag is in flight (0 nodes at rest, counted); forced → reaches (0 0 0 7px rgb(7,8,9))'
},
link: {
'external-icon-size':
'the demo mounts no EXTERNAL link, so the glyph never renders (0 nodes, counted); forced → reaches (11.89 → 77px on both axes)',
'underline-width':
"the demo link sits at data-underline='hover' with no pointer on it, so there IS no underline to move (text-decoration-line: none, thickness: auto). Forced 'always' → reaches (1 → 9px). textDecorationThickness was missing from the guard prop list and was added in the same pass",
'underline-offset':
"same: no underline at rest under data-underline='hover'; forced → reaches (2 → 11px). textUnderlineOffset added to the guard prop list too"
},
knob: {
'label-font-size-sm':
'the demo mounts no [data-knob-label] (0 nodes, counted); forced → reaches (per-size coordinate; the resolved name moves with it)',
'label-font-size-md':
'the demo mounts no [data-knob-label] (0 nodes, counted); forced → reaches (16 → 99px)',
'label-font-size-lg':
'the demo mounts no [data-knob-label] (0 nodes, counted); forced → reaches (per-size coordinate)',
'label-font-size-xl':
'the demo mounts no [data-knob-label] (0 nodes, counted); forced → reaches (per-size coordinate)',
'label-font-size':
'the demo mounts no [data-knob-label] (0 nodes, counted); forced → reaches (16 → 99px)',
'label-fg':
'the demo mounts no [data-knob-label] (0 nodes, counted); forced → reaches (rgb(1,2,3))',
'label-line-height':
'the demo mounts no [data-knob-label] (0 nodes, counted); forced → reaches (20px → 3.77em)',
'dragging-shadow':
'consumed only under [data-dragging], and the demo knob is at rest (0 nodes, counted); forced → reaches (0 0 0 7px rgb(4,5,6))'
},
label: {
'disabled-fg':
'the demo mounts no disabled label (0 [data-disabled] nodes, counted); forced → reaches (rgb(1,2,3))'
},
'link-preview': {
'trigger-fg':
'the panel opens on HOVER, so measuring it REQUIRES the pointer on the trigger — and hover is exactly the state whose rule overrides the resting ink. Structural, not a demo gap: the hover token (`hover-trigger-fg`) reads live in the same run',
'trigger-underline':
'same structural conflict: the hover rule sets `text-decoration-color: currentColor` over the resting mix, and the panel cannot be opened without hovering'
},
'menu-dial': {
'backdrop-bg':
'the backdrop only exists while the dial is open (0 nodes at rest, counted); forced → reaches (rgb(1,2,3))',
'stagger-step':
"consumed only by `[data-stagger] [data-state='open'] .menu-dial-action`, and the demo dial is closed and un-staggered; forced both attrs with index 3 → reaches (0.084s → 2.331s = 3 × 777ms)"
},
'picker-shell': {
'section-gap-xs':
'its size axis is `data-picker-size` on the PORTALED [data-popover-content], not `data-size` on itself, and the guard only cycles `data-size`; the demo popover sits at md. Cycled by hand across the four picker-sizes 2026-08-21 → reaches (section/row/footer spacing follows the picker size)',
'section-gap-sm':
'its size axis is `data-picker-size` on the PORTALED [data-popover-content], not `data-size` on itself, and the guard only cycles `data-size`; the demo popover sits at md. Cycled by hand across the four picker-sizes 2026-08-21 → reaches (section/row/footer spacing follows the picker size)',
'section-gap-lg':
'its size axis is `data-picker-size` on the PORTALED [data-popover-content], not `data-size` on itself, and the guard only cycles `data-size`; the demo popover sits at md. Cycled by hand across the four picker-sizes 2026-08-21 → reaches (section/row/footer spacing follows the picker size)',
'row-spacing-xs':
'its size axis is `data-picker-size` on the PORTALED [data-popover-content], not `data-size` on itself, and the guard only cycles `data-size`; the demo popover sits at md. Cycled by hand across the four picker-sizes 2026-08-21 → reaches (section/row/footer spacing follows the picker size)',
'row-spacing-lg':
'its size axis is `data-picker-size` on the PORTALED [data-popover-content], not `data-size` on itself, and the guard only cycles `data-size`; the demo popover sits at md. Cycled by hand across the four picker-sizes 2026-08-21 → reaches (section/row/footer spacing follows the picker size)',
'footer-gap-xs':
'its size axis is `data-picker-size` on the PORTALED [data-popover-content], not `data-size` on itself, and the guard only cycles `data-size`; the demo popover sits at md. Cycled by hand across the four picker-sizes 2026-08-21 → reaches (section/row/footer spacing follows the picker size)',
'footer-gap-lg':
'its size axis is `data-picker-size` on the PORTALED [data-popover-content], not `data-size` on itself, and the guard only cycles `data-size`; the demo popover sits at md. Cycled by hand across the four picker-sizes 2026-08-21 → reaches (section/row/footer spacing follows the picker size)',
'header-font-size-xs':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (12/14/16/16px → 102px, each in its own picker-size)',
'header-font-size-sm':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (12/14/16/16px → 102px, each in its own picker-size)',
'header-font-size-md':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (12/14/16/16px → 102px, each in its own picker-size)',
'header-font-size-lg':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (12/14/16/16px → 102px, each in its own picker-size)',
'header-gap':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (gap 8→1234px, fg → rgb(4,5,6), weight 500→123, line-height 20→60.32px)',
'header-fg':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (gap 8→1234px, fg → rgb(4,5,6), weight 500→123, line-height 20→60.32px)',
'header-font-weight':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (gap 8→1234px, fg → rgb(4,5,6), weight 500→123, line-height 20→60.32px)',
'header-line-height':
'the date-picker demo renders no [data-picker-header] (0 nodes, counted) — picker-shell has no demo route of its own (404) and is measured inside a host picker; forced → reaches (gap 8→1234px, fg → rgb(4,5,6), weight 500→123, line-height 20→60.32px)',
'time-row-gap':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-row-padding-block-start':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-row-padding-inline':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-row-border-width':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-row-border':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-label-fg':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-label-font-size-xs':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-label-font-size-sm':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-label-font-size-md':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)',
'time-label-font-size-lg':
'the time row is CLASS-hooked (.picker-time-row) and the date-picker demo does not render it; the guard filters nodes by attribute, so it cannot see it either way (§13 class-hook debt). Forced → reaches (gap/padding → 1234px, border 1→9px + rgb(7,8,9), label → rgb(10,11,12) / 99px)'
},
'scroll-frames': {
'loader-inset-block-end':
'the loading caption only exists while frames are decoding (0 nodes once loaded, counted); forced → reaches (24 → 1234px)',
'loader-font-size':
'the loading caption only exists while frames are decoding (0 nodes once loaded, counted); forced → reaches (12 → 99px)',
'loader-letter-spacing':
'the loading caption only exists while frames are decoding (0 nodes once loaded, counted); forced → reaches (1.2 → 9px)',
'loader-fg':
'the loading caption only exists while frames are decoding (0 nodes once loaded, counted); forced → reaches (rgb(1,2,3))'
},
skeleton: {
'line-radius':
"only the `text` shape renders [data-skeleton-line]; the demo mounts `rect` (0 lines, counted). Forced shape='text' → reaches (4 → 1234px)"
},
'skin-media-player': {
'record-base-width':
'the width is `min(100%, base * scale)`, so the LARGE sentinel of the guard is capped by the container and proves nothing. Re-measured with SMALL values 2026-08-22, with data-skin=record forced (the demo mounts turntable) -> reaches (111px exactly)',
'cassette-base-width':
'the width is `min(100%, base * scale)`, so the LARGE sentinel of the guard is capped by the container and proves nothing. Re-measured with SMALL values 2026-08-22, data-skin=cassette forced -> reaches (122px exactly)',
'deck-base-width':
'the width is `min(100%, base * scale)`, so the LARGE sentinel of the guard is capped by the container and proves nothing. Re-measured with SMALL values 2026-08-22, data-skin=deck forced -> reaches (133px exactly)',
'scale-sm':
'the width is `min(100%, base * scale)`, so the LARGE sentinel of the guard is capped by the container and proves nothing. Re-measured with SMALL values 2026-08-22, with the data-size=sm of the PLAYER forced -> reaches (133 x 0.11 = 14.625px)',
'scale-lg':
'the width is `min(100%, base * scale)`, so the LARGE sentinel of the guard is capped by the container and proves nothing. Re-measured with SMALL values 2026-08-22, data-size=lg forced -> reaches (133 x 0.22 = 29.25px)',
'scale-xl':
'the width is `min(100%, base * scale)`, so the LARGE sentinel of the guard is capped by the container and proves nothing. Re-measured with SMALL values 2026-08-22, data-size=xl forced -> reaches (133 x 0.33 = 43.875px)',
'lamp-opacity':
'the lamp only dims while the player is paused and the deck still; forced -> reaches (0.18 -> 0.123)'
},
spinner: {
'bar-radius':
"the demo mounts the RING variant only (0 bars, 0 dots, counted); forced variant='bars' → reaches (1234px)",
'label-font-size':
'the label is optional and the demo mounts none (0 nodes, counted); forced → reaches (1234px)',
'label-fg': 'the label is optional and the demo mounts none; forced → reaches (rgb(1,2,3))',
'track-opacity':
'its only declaration lives inside `prefers-reduced-motion`; emulated reduce context → reaches (0.6 → 0.123)'
},
'card-group': {
'title-fg':
'the STATIC heading form is not mounted in the demo (0 [data-static] nodes vs 1 [data-button], counted); forced → reaches (rgb(1,2,3))',
'title-font-family':
'static heading not mounted in the demo; forced → reaches (Instrument Sans → Zapfino)',
'title-font-size': 'static heading not mounted in the demo; forced → reaches (16 → 1234px)',
'title-line-height': 'static heading not mounted in the demo; forced → reaches (20px → 3.77em)',
'title-padding-block-end':
'static heading not mounted in the demo; forced → reaches (8 → 1234px)'
},
clipboard: {
'indicator-gap':
'the “Copied!” indicator only exists for a moment after a copy (0 nodes at rest, counted); forced → reaches (4 → 1234px)',
'indicator-padding-block':
'the “Copied!” indicator only exists for a moment after a copy (0 nodes at rest, counted); forced → reaches (2 → 1235px)',
'indicator-padding-inline':
'the “Copied!” indicator only exists for a moment after a copy (0 nodes at rest, counted); forced → reaches (8 → 1236px)',
'indicator-radius':
'the “Copied!” indicator only exists for a moment after a copy (0 nodes at rest, counted); forced → reaches (9999 → 1237px)',
'indicator-font-size':
'the “Copied!” indicator only exists for a moment after a copy (0 nodes at rest, counted); forced → reaches (12 → 99px)',
'indicator-font-weight':
'the “Copied!” indicator only exists for a moment after a copy (0 nodes at rest, counted); forced → reaches (500 → 123)'
},
collapsible: {
// 2026-08-24. Its ONLY two silences, and both are the freeze the guard
// needs to read everything else. Measured unfrozen on the real trigger,
// which transitions `background` and `color` (two entries in the computed
// list, so the write shows up twice).
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen on [data-collapsible-trigger] -> reaches (0.18s, 0.18s -> 4.321s, 4.321s)',
'transition-ease':
'same freeze, same node -> reaches (cubic-bezier(0.4, 0, 0.2, 1) x2 -> steps(3) x2)'
},
code: {
radius:
'the DEMO HARNESS wins: `[data-uix-docs] code` (uix.css, 0-1-1) beats the recipe base rule `[data-code]` (0-1-0) and sets border-radius/padding/font on the inline code — confirmed with CDP matched-rules. The variant rules (0,2,0) DO win, which is why only this base-rule token reads dead. Same harness rule that hides the <pre> of code-block (next-features §13)',
'soft-bg':
"the demo mounts the `plain` variant only (no chrome); forced variant='soft' → reaches (rgb(1,2,3))",
'border-width': "the demo mounts `plain` only; forced variant='outline' → reaches (1 → 9px)",
border: "the demo mounts `plain` only; forced variant='outline' → reaches (rgb(4,5,6))",
'padding-inline':
'only the chromed variants pad; forced → reaches (4.12 → 77px), and the variant rule (0,2,0) beats the harness',
'padding-block': 'only the chromed variants pad; forced → reaches (1.29 → 66px)'
},
'code-block': {
'pre-padding':
'the DEMO HARNESS outweighs the component: `[data-uix-docs] pre` (uix.css:801, 0-1-1) beats `[data-code-block-pre]` (0-1-0) and paints padding/border/radius/bg/font on the <pre>. Forced with !important → reaches (16px 20px → 12px). Seven properties measured, registered in next-features §13'
},
toolbar: {
// 2026-08-24. Its ONLY two silences, and both are the freeze the guard
// needs to read everything else. Measured unfrozen on the real Link, which
// transitions FOUR properties (background, border-color, color, box-shadow)
// — hence four entries in the computed list.
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen on [data-toolbar-link] -> reaches (0.12s x4 -> 4.321s x4)',
'transition-ease':
'same freeze, same node -> reaches (cubic-bezier(0.4, 0, 0.2, 1) x4 -> steps(3) x4)'
},
'tree-view': {
'disabled-row-fg':
'no disabled row in the demo (0 mounted, counted); forced data-disabled → reaches (oklch(0.61 0 0) → rgb(1,2,3))'
},
'password-field': {
// The demo boots with an empty field: data-strength=0, so no segment is
// active and none of the four steps paints. Forced level by level
// 2026-08-22, transitions frozen.
'strength-1-bg': 'the meter sits at strength 0 (empty field); forced -> reaches (oklch(0.5787 0.1877 322.11) -> rgb(1,2,3))',
'strength-2-bg': 'same; forced -> reaches (oklch(0.6908 0.1909 45.02) -> rgb(1,2,3))',
'strength-3-bg': 'same; forced -> reaches (oklch(0.6406 0.1329 157.68) -> rgb(1,2,3))',
'strength-4-bg': 'same; forced -> reaches (oklch(0.6491 0.1136 181.96) -> rgb(1,2,3))',
// The visibility trigger owns both: the guard freezes transitions, and the
// demo boots enabled. Measured on it 2026-08-22.
'transition-duration': 'the guard freezes transitions; measured without the freeze on the visibility trigger -> reaches (0.12s -> 11.5s)',
'transition-ease': 'same freeze, same node -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(4))',
'disabled-opacity': 'only under [data-disabled] on the visibility trigger; forced -> reaches (0.4 -> 0.123)'
},
'context-menu': {
// Third measurement of the same finding: the overlay DEPTH PLANE imposes the
// panel font and beats the recipe (section 12.9, pending signature, 20
// components). Writing the token moves nothing while the plane does.
'item-disabled-opacity': 'no disabled item in the demo; forced data-disabled -> reaches (0.55 -> 0.123)'
},
'float-panel': {
// The demo mounts the DEFAULT variant and no generic action button (only the
// close control). Forced in place 2026-08-22, transitions frozen.
'outline-bg': 'the demo runs the default variant; set data-variant=outline -> reaches (oklch(0.9911 0 0) -> rgb(1,2,3))',
'outline-border': 'same variant; forced -> reaches (oklch(0.7921 0 0) -> rgb(1,2,3))',
'ghost-bg': 'same, variant ghost; forced -> reaches (oklch(0.9911 0 0) -> rgb(1,2,3))',
'ghost-border': 'same, variant ghost; forced -> reaches (oklch(0.931 0 0) -> rgb(1,2,3))',
'ghost-shadow': 'same, variant ghost; forced -> reaches (rgba(15,23,42,0.1) 0 4px 12px -> rgb(1,2,3) 0 0 0 7px)',
'action-fg': 'no generic action button in the demo (only the close control); mounted in place -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
'action-radius': 'same button; mounted -> reaches (4px -> 1234px)',
'action-font-size': 'same button; mounted -> reaches (16px -> 1234px)',
'hover-action-bg': 'same button, and only under :hover; same mounting pass',
'hover-action-fg': 'same button, and only under :hover; same mounting pass',
'resize-grip-radius': 'only under :focus-visible; focused the grip -> reaches (4px -> 1234px)',
// 2026-08-23. The twelve the 2026-08-22 commit left written as "rojo que
// queda" and nobody measured. Measured now, one by one, on the real panel.
//
// SIX are the depth plane, exactly as that commit predicted: the content
// carries `data-depth='overlay'`, and `[data-depth='overlay']` declares
// background / border / box-shadow / font-family / line-height at the SAME
// specificity (0,1,0) and LATER in the cascade. Verified by moving the
// plane's own tokens on this node: surface, border, font and leading
// repaint it, and the plane's `box-shadow` rule is in its matched list.
// Same adjudication as `tooltip`, same open decision (PLAN 12.9).
shadow:
PLANE_SUPERSEDED +
'; `shadow-topmost` DOES reach — its [data-topmost] rule is (0,2,0) and beats the plane (-> rgb(4,5,6))',
// Three states / parts the demo does not mount.
'active-shadow':
'only under [data-dragging] / [data-resizing]; forced -> reaches (rgba(15,23,42,0.22) 0 28px 72px -> rgb(1,2,3))',
'resize-size':
'the CORNER handles (se/ne/sw/nw) carry it and the demo mounts only the edge ones (e, s)',
'button-size':
'consumed by [data-float-panel-action] / [data-float-panel-stage-trigger], neither mounted in the demo — the only control is the close Button, which is a composed <Button> and sizes itself (same group as the action-* entries above)',
// The palette bridge (THM-2), not debt: with a colour stamped the forward
// redefines the private and this key is only the no-colour base.
accent:
'the content carries data-color, so --_float-panel-accent comes from the THM-2 forward (--_float-panel-palette-border -> rgb(7,8,9)); with data-color removed it reaches (-> rgb(1,2,3))',
// The known law: the guard freezes transitions to make everything else
// measurable. Unfrozen pass on the panel itself.
'transition-duration':
'frozen by the guard by design; unfrozen pass -> reaches (0.12s -> 11.5s)',
'transition-ease':
'frozen by the guard by design; unfrozen pass -> reaches (cubic-bezier(0.4,0,0.2,1) -> steps(7))'
},
drawer: {
// The guard OPENS the drawer before testing, and the overlay then covers the
// trigger: the hover pass cannot reach it (Playwright refuses to hover a
// node that does not receive the pointer). Hovered by hand with the drawer
// closed 2026-08-22 -> reaches.
'hover-trigger-bg': 'the open drawer overlay covers the trigger, so the hover pass cannot land on it; hovered by hand with the drawer closed -> reaches (oklch(0.931 0 0) -> rgb(1,2,3))',
// ── The 24 the component carried from before the axis, measured one by one
// 2026-08-22 (transitions frozen, drawer open, each state forced).
// The GRABBER is not mounted in this demo and its size swaps with the side:
// length is the inline axis for top/bottom and the block axis for left/right.
'handle-bg': 'no grabber in this demo; mounted in place -> reaches (oklch(0.9911 0 0) -> rgb(1,2,3))',
'active-handle-bg': 'same grabber, and only while dragging; forced -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
'handle-radius': 'same grabber; mounted -> reaches (9999px -> 1234px)',
'handle-length': 'same grabber, and only under side=top/bottom; forced -> reaches (36px -> 1234px)',
'handle-thickness': 'same grabber, same side; forced -> reaches (4px -> 1234px)',
'handle-active-scale': 'same grabber, only while dragging (transform, which the guard does not read)',
'handle-transition-duration': 'the guard freezes transitions; the grabber transitions background and transform on it',
'handle-transition-ease': 'same freeze, same pair',
// The dragging ring only exists while a pointer drags the panel.
'content-ring-dragging-fg': 'only under [data-dragging]; forced -> reaches (srgb 0.392 / 0.32 -> rgb(1,2,3))',
'content-ring-dragging-width': 'same state; forced -> reaches (2px -> 1234px)',
'content-ring-dragging-offset': 'same state, outline-offset (read set)',
'content-shadow-dragging': 'same state; forced -> the box-shadow changes',
// Sizes: the demo runs md on the right side, and soma writes the resolved
// axis INLINE (width for left/right, height for top/bottom), so the token of
// the axis in play cannot win from :root — a value channel, like carousel
// item-gap. The cross axis does reach: height-sm forced 260px -> 976px.
'content-width-sm': 'soma writes width INLINE on the content for a left/right drawer, so no cascade can beat it - value channel, registered in next-features 13',
'content-width-md': 'same inline width channel',
'content-width-lg': 'same inline width channel',
'content-height-sm': 'the demo runs a right drawer, where the height is not the axis in play; forced side=bottom -> reaches (260px -> 976px)',
'content-height-md': 'same cross axis, same pass',
'content-height-lg': 'same cross axis, same pass',
'content-padding-full': 'only under [data-size=full]; forced -> reaches (24px -> 1234px)',
// Header and footer are optional parts the demo does not render.
'header-gap': 'the demo mounts no header; mounted in place -> reaches (12px -> 1234px)',
'footer-gap': 'the demo mounts no footer; mounted in place -> reaches (12px -> 1234px)',
'footer-margin-top': 'same footer; mounted -> reaches (8px -> 1234px)',
'inline-z': 'only under [data-variant=inline]; forced -> reaches (50 -> 4321)',
// AND A REAL DEFECT, not an instrument limit: the veil paints NOTHING.
'overlay-bg': 'the veil paints nothing today: soma writes --drawer-overlay-opacity INLINE as the unitless 1 (its drag progress) and the CSS consumes it as a color-mix PERCENTAGE, so the mix is invalid and the background falls to transparent. Writing 80% on the node paints it. Registered in next-features 13 - it moves pixel, so it is not fixed here'
},
aura: {
// The six state tints and the halo paint the INDICATOR background, and the
// demo runs with the WebGL canvas mounted — the rule
// [data-aura-indicator]:has(canvas) sets background:none ON PURPOSE (the orb
// IS the presence; a disc behind it muddies the silhouette). Removed the
// canvas in place 2026-08-22: the gradient returns and all six follow.
'orb-color-idle': 'the canvas covers the disc by design; removed in place -> reaches (oklch(0.6434 0 0) -> rgb(1,2,3) inside the radial-gradient)',
'orb-color-offered': 'same disc, same pass',
'orb-color-planned': 'same disc, same pass',
'orb-color-reviewing': 'same disc, same pass',
'orb-color-acting': 'same disc, same pass',
'orb-color-escalated': 'same disc, same pass',
'orb-halo-alpha': 'the outer stop of the same gradient; removed the canvas -> the gradient changes',
// The arc and the halo are ring SLOTS that only exist in the working
// states; the demo sits on the track. Mounted as <circle data-aura-ring-slot>
// inside the real SVG 2026-08-22 — which is exactly what the CSS selects.
'ring-arc-width': 'the arc slot is not mounted in the idle demo; mounted in place -> reaches (2px -> 1234px)',
'ring-halo-width': 'the halo slot is not mounted; mounted in place -> reaches (1px -> 1234px)',
'ring-halo-opacity': 'same slot; mounted in place -> reaches (0.5 -> 0.123)',
'transition-duration': 'the guard freezes transitions on purpose; the orb tint and the arc stroke transition on it',
'transition-ease': 'same freeze, same pair of properties'
},
popover: {
// The demo renders neither Title nor Description. Mounted inside the OPEN
// panel with the attrs the CSS selects (2026-08-22): all nine reach; the two
// with a number are the sample that was read.
'title-fg': 'the demo mounts no Popover.Title; mounted in place -> reaches (oklch(0.2435 0 0) -> rgb(1,2,3))',
'title-font-size': 'same part; mounted in place -> reaches (16px -> 1234px)',
'title-font-family': 'same part, same measurement pass',
'title-font-weight': 'same part, same measurement pass',
'title-line-height': 'same part, same measurement pass',
'description-fg': 'the demo mounts no Popover.Description; mounted in place -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
'description-font-family': 'same part, same measurement pass',
'description-font-size': 'same part, same measurement pass',
'description-line-height': 'same part, same measurement pass',
// The overlay is opt-in (modal popovers) and the demo boots with it off.
'overlay-bg': 'the demo boots with showOverlay off; mounted in place -> reaches (rgba(28,25,23,0.42) -> rgb(1,2,3))',
'overlay-z': 'same; mounted in place -> reaches (60 -> 4321)',
// The two that are NOT about mounting: the depth plane wins over both.
},
'radio-cards': {
// All five forced by hand 2026-08-22, WITH transitions frozen: the card
// transitions `border-color`, and reading right after the write returns the
// starting value (the same trap the guard's own freeze exists for — the
// first measurement of invalid-border read "no effect" for that reason).
'invalid-border':
'only paints under [data-invalid] and the demo boots valid; forced -> reaches (oklch(0.9555 0.0207 13.86) -> rgb(1,2,3))',
'horizontal-basis':
'only under [data-orientation=horizontal]; forced -> reaches (192px -> 1234px of flex-basis)',
'disabled-opacity':
'only under [data-disabled] on the item; forced -> reaches (0.4 -> 0.123)',
'transition-duration':
'the guard freezes transitions on purpose; measured without the freeze -> reaches (0.12s -> 11.5s)',
'transition-ease':
'same freeze; measured without it -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(4))'
},
prose: {
// Prose styles bare HTML at ZERO specificity on purpose (`:where([data-prose] el)`,
// so an embedded component keeps its own look). That is exactly what the docs
// harness beats: `[data-uix-docs] code|pre` (0,2,0) wins over (0,0,0). Removing
// the harness attribute in place 2026-08-22 -> the five reach. Same §13 entry as
// code-block's, one floor down.
'code-bg': 'the harness rule [data-uix-docs] code (0,2,0) beats :where(…) (0,0,0); without it -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))',
'code-radius': 'same harness rule; without it -> reaches (4px -> 1234px)',
'code-font-family': 'same harness rule; without it -> reaches (Azeret Mono -> Zapfino)',
'pre-bg': 'the harness rule [data-uix-docs] pre (0,2,0) beats :where(…); without it -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))',
'pre-radius': 'same harness rule; without it -> reaches (6px -> 1234px)',
// Two elements the demo's sample HTML does not use. Mounted INSIDE the real
// [data-prose] container 2026-08-22 — and a bare <mark>/<dt> IS what this
// recipe styles (it selects raw HTML), so the node is faithful.
'mark-bg': 'the sample HTML has no <mark>; mounted in place -> reaches (oklch(0.9923 0.0025 48.72) -> rgb(1,2,3))',
'mark-radius': 'same; mounted in place -> reaches (4px -> 1234px)',
'dt-font-weight': 'the sample HTML has no <dl>; mounted in place -> reaches (600 -> 123)'
},
result: {
// All five measured on the demo's REAL nodes (its own controls drive them),
// not on a node built by hand — the drag-drop lesson: a "forced -> reaches"
// adjudication is worth what the forced node is worth.
'extra-margin-block-start':
'the extra block is optional and the demo boots without it; ticked its checkbox 2026-08-22 -> reaches (16px -> 1234px)',
'extra-measure':
'same optional block; ticked 2026-08-22 -> reaches (559.44px -> 1234px)',
'error-fg':
'only paints under [data-status=error] and the demo boots on success; clicked its chip 2026-08-22 -> reaches (oklch(0.6256 0.1933 23.03) -> rgb(1,2,3))',
'warning-fg':
'only paints under [data-status=warning]; clicked its chip 2026-08-22 -> reaches (oklch(0.6908 0.1909 45.02) -> rgb(1,2,3))',
'info-fg':
'only paints under [data-status=info]; clicked its chip 2026-08-22 -> reaches (oklch(0.5556 0.1829 305.86) -> rgb(1,2,3))',
'extra-font-size':
'same optional block; ticked its checkbox 2026-08-22 -> reaches (14px -> 1234px)',
'extra-fg': 'same optional block; ticked 2026-08-22 -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
'media-fg':
'the DEFAULT glyph ink: with a [data-status] the private wins by design (each status re-points --_result-media-fg to its accent) and the demo always sets one. Removed the attribute 2026-08-22 -> reaches (oklch(0.61 0 0) -> rgb(1,2,3))',
'code-font-family':
'the big HTTP code only renders for the http statuses and the demo boots on success; clicked the not-found chip 2026-08-22 -> reaches (Azeret Mono -> Zapfino)',
'code-font-weight': 'same http-only node; clicked not-found 2026-08-22 -> reaches (600 -> 123)',
'code-letter-spacing':
'same http-only node; clicked not-found 2026-08-22 -> reaches (3.36px -> 4.5px)',
'code-fg':
'same http-only node; clicked not-found 2026-08-22 -> reaches (oklch(0.61 0 0) -> rgb(1,2,3))'
},
chart: {
'transition-duration':
"the guard FREEZES transitions on purpose (a transitioned property returns its starting value), which is exactly what hides a token whose whole job IS the transition — same class as text-circular.char-transition. Measured without the freeze 2026-08-22 on [data-chart-line]: 0.12s -> 11.5s",
'transition-ease':
"same freeze, same measurement 2026-08-22 on [data-chart-line]: cubic-bezier(0, 0, 0.2, 1) -> steps(4)"
},
'text-circular': {
'char-transition':
"the guard FREEZES transitions on purpose (a transitioned property returns its starting value), which is exactly what hides a token whose whole job is the transition. Measured without the freeze 2026-08-22 -> reaches (0.5s cubic-bezier -> 9.5s linear)"
},
textarea: {
'focus-input-border':
'consumed only under [data-focused], which the guard blurs away ON PURPOSE (the click-focus poisoning fix); focused by hand with the pointer parked → reaches (rgb(4,5,6))',
'invalid-input-border':
'consumed only under [data-invalid]; the demo boots valid. Forced by hand 2026-08-21 → reaches (rgb(7,8,9))',
'overflow-count-fg':
'the count only carries [data-overflow] past maxLength (280 chars); forced → reaches (rgb(13,14,15))',
'overflow-count-font-weight':
'the count only carries [data-overflow] past maxLength (280 chars); forced → reaches (font-weight 333)'
},
'grid-list': {
'invalid-border':
'consumed only under [data-invalid]; the demo boots with its invalid control off, so the rule never matches at measurement. Toggled by hand 2026-08-21 → reaches (oklch(0.9555 0.0207 13.86) → rgb(1,2,3))'
},
metrics: {
// Measured one by one 2026-08-23 (transitions frozen, each condition forced).
// Every one of the 16 is ALIVE: the demo mounts neither the xxl step, nor the
// icon without a data-color, nor the actions row, nor an end-placed chart.
'gap-xxl': 'the size sweep of the guard does not reach the xxl step; forced data-size=xxl -> reaches (12px -> 1234px)',
'icon-gap-xxl': 'same xxl step, read on the padding-inline-start of an icon-start root; forced -> reaches (92px -> 1306px)',
'icon-box-xxl': 'same xxl step; forced -> reaches (72px -> 1234px)',
'label-font-size-xxl': 'same xxl step; forced -> reaches (28px -> 1234px)',
'value-font-size-xxl': 'same xxl step; forced -> reaches (80px -> 1234px)',
'description-font-size-xxl': 'same xxl step; forced -> reaches (28px -> 1234px)',
'icon-border-width': 'only the outline variant draws a stroke and the demo runs soft; forced data-variant=outline -> reaches (1px -> 1234px)',
'icon-bg': 'the no-data-color default, and every demo icon carries a colour that overrides the hook; removed data-color -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))',
'icon-fg': 'same no-data-color default; removed data-color -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
'actions-gap': 'the actions row is conditional and the demo mounts none; mounted in place -> reaches (12px -> 1234px)',
'actions-margin-block-start': 'same row; mounted -> reaches (12px -> 1234px)',
'actions-padding-block-start': 'same row; mounted -> reaches (12px -> 1234px)',
'actions-border-fg': 'same row; mounted -> reaches (oklch(0.931 0 0) -> rgb(1,2,3))',
'chart-right-width': 'only an end-placed chart reserves the gutter and the demo places them full; forced data-placement=end -> reaches (112px -> 1234px)',
'flash-duration': 'the flash rule needs the sema stamp of the hold (data-event-family=signal + phase=active), which is gone by the time the guard reads; stamped by hand -> reaches (0.32s -> 11.5s)',
'flash-ease': 'same stamp; forced -> reaches (cubic-bezier(0, 0, 0.2, 1) -> steps(7))',
'icon-circle-radius': 'the demo mounts only the rounded shape; forced data-shape=circle -> reaches (9999px -> 1234px)',
'icon-square-radius': 'same, the demo mounts only rounded; forced data-shape=square -> reaches (6px -> 1234px)'
},
'color-picker': {
// Measured one by one 2026-08-23 (picker open, transitions frozen unless the
// token IS the transition). 21 of the 23 are alive; the two width steps are a
// real reach defect, registered in next-features 13.
'content-width-sm': 'the private --_color-picker-content-width is declared three times and consumed ZERO times: the portalled panel hardwires calc(content-width-md + 2rem), so no sm step can reach it. Registered in next-features 13 - wiring or retiring it moves pixel',
'content-width-lg': 'same orphan private; the panel width has no size axis today. Registered in next-features 13',
'swatch-size-sm': 'inside the portalled content the private is pinned to swatch-size-md with no size variants; on a swatch outside the portal the step reaches (20px -> 1234px). Same entry in next-features 13',
'swatch-size-md': 'the demo mounts no swatch of any kind; mounted in place -> reaches (24px -> 1234px)',
'swatch-size-lg': 'same pinning inside the portal; outside it reaches (28px -> 1234px)',
'swatch-radius': 'presets and saved swatches are conditional and the demo mounts none; mounted -> reaches (4px -> 1234px)',
'swatch-border': 'same swatches; mounted -> reaches (oklch(0.931 0 0) -> rgb(1,2,3))',
'swatch-checked-ring': 'same swatches, and only under [data-checked]; mounted and checked -> reaches (the 3px ring turns rgb(1,2,3))',
'swatch-gap': 'the swatch group is conditional and the demo mounts none; mounted -> reaches (6px -> 1234px)',
'swatch-border-width': 'same swatches; mounted -> reaches (1px -> 1234px)',
'swatch-ring-gap': 'same swatches, and only under [data-checked] or :focus-visible; mounted and checked -> reaches (the 1px inner ring turns rgb(1,2,3))',
'transparency-cell-alt': 'the standalone transparency grid utility is not mounted in the demo; mounted -> reaches (oklch(0.9911 0 0) -> rgb(1,2,3))',
'eye-dropper-size': 'the DEMO route overrides the eye dropper with its own scoped rule (.cp-tools-row sets inline-size:auto + aspect-ratio); with the token consumption restored -> reaches (30px -> 1234px)',
'eye-dropper-bg': 'same demo override (background:transparent); restored and frozen -> reaches (transparent -> rgb(1,2,3))',
'hue-0': 'the rainbow ramp needs data-x-channel=hue and the demo area runs saturation/brightness; forced -> reaches (rgb(255,0,0) -> rgb(1,2,3))',
'hue-60': 'same hue ramp; forced data-x-channel=hue -> reaches',
'hue-120': 'same hue ramp; forced data-x-channel=hue -> reaches',
'hue-180': 'same hue ramp; forced data-x-channel=hue -> reaches',
'hue-240': 'same hue ramp; forced data-x-channel=hue -> reaches',
'hue-300': 'same hue ramp; forced data-x-channel=hue -> reaches',
'hue-360': 'same hue ramp; forced data-x-channel=hue -> reaches',
'saturation-floor': 'the ::before ramp needs x-channel=hue AND y-channel=saturation; forced -> reaches (rgb(128,128,128) -> rgb(1,2,3))',
'transition-duration': 'the guard freezes transitions before measuring (the forced-measurement fix) and these two tokens ARE the transition; measured unfrozen on the eye dropper -> reaches (0.12s -> 11.5s)',
'transition-ease': 'same instrument limit; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(7))',
'disabled-opacity': 'no disabled trigger or eye dropper in the demo; forced data-disabled -> reaches (0.4 -> 0.137)'
},
'dropdown-menu': {
'item-disabled-opacity':
'no disabled item in the demo menu; forced data-disabled 2026-08-23 -> reaches (0.55 -> 0.137)'
},
image: {
'fade-duration': 'the guard freezes transitions and this token IS the fade; measured unfrozen 2026-08-23 -> reaches (0.18s -> 11.5s)',
'fade-ease': 'same instrument limit; measured unfrozen -> reaches (cubic-bezier(0, 0, 0.2, 1) -> steps(7))',
'placeholder-base': 'consumed ONLY inside @media (prefers-reduced-motion: reduce), where the shimmer is replaced by a flat base; the guard runs with motion on. Measured with reducedMotion emulated -> reaches (oklch(0.9821 0 0) -> rgb(1,2,3))'
},
checkbox: {
// Measured one by one 2026-08-23. Two scoping traps of the instrument: the
// glyph only exists inside a CHECKED box, and the group label carries its
// own [data-disabled] (it is not inherited from the group).
'size-xs-indicator-stroke': 'the glyph exists only inside a CHECKED box and the first checkbox of the demo is empty; measured on a checked one with data-size forced -> reaches (2px -> 7px)',
'size-sm-indicator-stroke': 'same, forced -> reaches (2px -> 7px)',
'size-md-indicator-stroke': 'same, forced -> reaches (2px -> 7px)',
'size-lg-indicator-stroke': 'same, forced -> reaches (2px -> 7px)',
'size-xl-indicator-stroke': 'same, forced -> reaches (2px -> 7px)',
'invalid-border': 'only under [data-invalid]; forced -> reaches (oklch(0.9555 0.0207 13.86) -> rgb(1,2,3))',
'invalid-ring': 'the invalid focus ring: needs [data-invalid] AND :focus-visible, which the guard blurs on purpose; focused by hand -> reaches (the 4px ring turns rgb(1,2,3))',
'invalid-ring-gap': 'same double ring; forced -> reaches (the 2px gap turns rgb(4,5,6))',
'disabled-bg': 'only under [data-disabled]; forced -> reaches',
'disabled-border': 'only under [data-disabled]; forced -> reaches',
'disabled-opacity': 'only under [data-disabled]; forced -> reaches (0.4 -> 0.137)',
'disabled-indicator-fg': 'needs [data-disabled] AND a checked box (the glyph); forced on a checked one -> reaches',
'disabled-group-label-fg': 'the label carries its OWN [data-disabled] - it is not inherited from the group, so forcing the group does nothing; set on the label -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
'transition-duration': 'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s)',
'transition-ease': 'same instrument limit; measured unfrozen -> reaches',
'stroke-duration': 'same, on the check path dash animation; measured unfrozen -> reaches (0.12s -> 11.5s)',
'stroke-ease': 'same, measured unfrozen -> reaches'
},
'anchor-nav': {
'link-radius':
'the link only rounds under :focus-visible (the ring corner), and the guard blurs on purpose; focused from the keyboard 2026-08-23 -> reaches (4px -> 1234px)'
},
tooltip: {
// Measured 2026-08-23 with the demo's `open` switch (a hover-opened panel is
// not reliable enough to measure: it needs the pointer parked on the trigger
// for the whole pass).
'content-z': 'it lands on the floating WRAPPER, which carries no data-tooltip-* attr and so is outside the measured set; read on the wrapper -> reaches (90 -> 4321)',
'outline-arrow-bg': 'the arrow is painted through a SIBLING selector that needs the content carrying data-variant=outline AND the panel open; measured with the demo switch -> reaches (oklch(0.9911 0 0) -> rgb(1,2,3))',
'outline-arrow-border': 'same sibling rule; measured -> reaches (oklch(0.7921 0 0) -> rgb(1,2,3))'
},
section: {
// ONE STEP PER INSTANCE: the wrapper maps the `padding` prop to
// var(--section-padding-block-{k}) and writes it INLINE, so only the active
// step is reachable at a time. Forcing another step reaches (2026-08-23).
'padding-block-sm': 'one step per instance; the demo runs md. Forced the step inline -> reaches',
'padding-block-lg': 'same, one step per instance',
'padding-block-xl': 'same; forced -> reaches (96px -> 123px)'
},
'qr-code': {
'size-xs': 'one step per instance: the wrapper writes var(--qr-code-size-{k}) inline from the size prop and the demo runs lg. Forced -> reaches (96px -> 123px)',
'size-sm': 'same, one step per instance',
'size-md': 'same, one step per instance',
'size-xl': 'same, one step per instance',
'fg': 'painted as the SVG fill of the module path, not as color on the root; read on the path -> reaches (rgb(24,24,27) -> rgb(1,2,3))',
'bg': 'painted as the fill of the backing rect, not as background on the root; read on the rect -> reaches (white -> rgb(1,2,3))'
},
'toggle-group': {
gap: 'the demo group is ATTACHED (segmented), where the gap collapses to 0; removed data-attached -> reaches (4px -> 123px)'
},
'button-group': {
'divider-strength':
'the seam only draws between ATTACHED buttons of a filled variant (solid/soft/ghost/plain) and the demo runs surface; forced -> reaches (0.18 -> 0.9 alpha)'
},
'audio-player': {
'live-font-weight': 'the LIVE badge only exists while the provider reflects a live stream (display:none otherwise) and the demo plays a file; mounted with [data-live] 2026-08-23 -> reaches (600 -> 333)',
'live-letter-spacing': 'same badge; mounted -> reaches (1.28px -> 7px)'
},
button: {
// Measured one by one 2026-08-23. The icon scale needs a real <svg> child,
// the radius scale is an OPT-IN prop the demo does not set, and the four
// palette-* slots are RESOLVED names: a :root write loses by design.
'icon-size-xs': 'the demo button carries no icon; a real <svg> child mounted and the size forced -> reaches (14px -> 123px)',
'icon-size-sm': 'same, no icon in the demo; mounted -> reaches (16px -> 123px)',
'icon-size-md': 'same, no icon in the demo; mounted -> reaches (18px -> 123px)',
'icon-size-lg': 'same, no icon in the demo; mounted -> reaches (20px -> 123px)',
'icon-size-xl': 'same, no icon in the demo; mounted -> reaches (32px -> 123px)',
'radius-sm': 'the radius scale is an opt-in prop ([data-rounded]) and the demo does not set it; forced -> reaches (4px -> 1234px)',
'radius-lg': 'same opt-in attribute; forced -> reaches (10px -> 1234px)',
'radius-xl': 'same opt-in attribute; forced -> reaches (16px -> 1234px)',
'radius-full': 'same opt-in attribute; forced data-rounded=full -> reaches (9999px -> 1234px)',
'transition-duration': 'the guard freezes transitions to measure and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s, five properties)',
'transition-ease': 'same instrument limit; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(7))',
'disabled-opacity': 'no disabled button in the demo; forced data-disabled -> reaches (0.4 -> 0.137)',
'primary-track': 'the FALLBACK of the palette forward: it acts only on an instance with NO data-color, and the demo stamps data-color=primary. Removed the attribute -> reaches. See the pattern entry below for the other seven tones',
'primary-element': 'same fallback, same condition',
'primary-border': 'same fallback, same condition',
'primary-solid': 'same fallback: without data-color it repaints (oklch(0.5556 0.1829 305.86) -> rgb(1,2,3)); with data-color=primary the generic forward rule supersedes it',
'primary-solid-hover': 'same fallback, same condition',
'primary-text': 'same fallback, same condition',
'primary-contrast': 'same fallback, same condition',
'palette-track': 'a RESOLVED name, declared on [data-button] by the forward, so a :root write loses BY DESIGN - a theme moves the tone or the scale. Measured on a soft button: from :root nothing, from the node oklch(0.9932 0.0034 325.6) -> rgb(4,5,6)',
'palette-element': 'same resolved name; the theme moves its coordinate',
'palette-border': 'same resolved name; the theme moves its coordinate',
'palette-text': 'same resolved name; the theme moves its coordinate'
},
menubar: {
'disabled-trigger-fg': 'no disabled entry in the demo bar; forced data-disabled 2026-08-23 -> reaches (oklch(0.61 0 0) -> rgb(1,2,3))'
},
field: {
// Measured one by one 2026-08-23 on /field, /date-field, /date-picker and
// /time-picker. The 20 are alive; every one needed a state, a variant, a
// route or an instrument the guard does not reach on its own.
'invalid-label-fg': 'only under [data-invalid] and the demo boots valid; forced -> reaches (oklch(0.5855 0.1743 42.74) -> rgb(1,2,3))',
'disabled-label-fg': 'only under [data-disabled]; forced -> reaches (oklch(0.7921 0 0) -> rgb(1,2,3))',
'invalid-control-border': 'only under [data-invalid]; forced -> reaches (oklch(0.8059 0.1123 59.96) -> rgb(1,2,3))',
'disabled-control-bg': 'only under [data-disabled]; forced -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))',
'control-bg-readonly': 'only under [data-readonly]; forced -> reaches (oklch(0.9551 0 0) -> rgb(1,2,3))',
'disabled-opacity': 'it lives on the CONTROL, not on the field root, so the guard read the wrong node; forced data-disabled and read on the control -> reaches (0.4 -> 0.137)',
'control-ghost-border': 'the ghost variant and the demo boots surface; forced data-variant=ghost -> reaches (transparent -> rgb(1,2,3))',
'control-ghost-bg': 'same ghost variant; forced -> reaches (transparent -> rgb(1,2,3))',
'layout-column-gap': 'only in the horizontal orientation; forced data-orientation=horizontal -> reaches (16px -> 1234px)',
'focus-control-border': 'only under :focus-within, and the guard blurs ON PURPOSE (the click-focus poisoning fix); focused from the keyboard -> reaches (the focus ring colour -> rgb(1,2,3))',
'focus-control-trigger-fg': 'only under :focus-visible on the picker trigger, which the guard blurs; focused from the keyboard on /date-picker -> reaches (oklch(0.2435 0 0) -> rgb(1,2,3))',
'floating-label-top': 'floatingLabel is a demo switch that boots OFF, and the label must also be floated (focused or filled); switch on + focus -> reaches (0px -> 1234px)',
'floating-label-padding-inline': 'same switch; turned on -> reaches (4px -> 1234px)',
'error-fg': 'the error text only RENDERS when the field is invalid, and it is the demo switch that mounts it - forcing the data-invalid attribute does not make Svelte render the node; switch on -> reaches (oklch(0.5855 0.1743 42.74) -> rgb(1,2,3))',
'control-placeholder-fg': 'the ::placeholder box exists only when the input HAS a placeholder attribute, and the demo input has none: getComputedStyle then returns the ELEMENT style and the token reads dead. With a placeholder set -> reaches (oklch(0.61 0 0) -> rgb(1,2,3))',
'segment-active-bg': 'the ACTIVE segment being edited: no segment on the field route and none focused; measured on /date-field with the segment clicked -> reaches (the 40% mix -> rgb(1,2,3))',
'segment-active-text': 'same segment; measured on /date-field -> reaches (oklch(0.5168 0.1733 305.88) -> rgb(1,2,3))',
'segment-height': 'a FAMILY token that field OWNS and the pickers CONSUME - nothing on the field routes reads it - and it is RESOLVED (declared per [data-field][data-size]), so a :root write loses BY DESIGN: a theme moves the coordinate. Measured on /time-picker: from :root nothing, from the field host 28px -> 1234px, and moving --field-control-height-md 28px -> 992px',
'transition-duration': 'the guard freezes transitions to measure and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s)',
'transition-ease': 'same instrument limit; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(7))'
},
'onion-menu': {
// Measured 2026-08-23. The lift needs the transitions frozen; the four rim
// tokens belong to the `luminous` look, which the component demo does not
// render at all (it is a Svelte prop that emits DIFFERENT markup, so no
// attribute can be forced): measured on /active/docs/agnt, which uses it.
'trigger-lift': 'the lift TRANSITIONS, so an immediate read after the write returns the old value; hovered with transitions frozen -> reaches (translate 0 -2px -> 0 -123px)',
'rim-width': 'the luminous look is not rendered by the component demo; measured on /active/docs/agnt -> reaches (2px -> 17px)',
'rim-glow-width': 'same look, same route -> reaches (9px -> 17px)',
'rim-glow-blur': 'same look, same route -> reaches (blur(4px) -> blur(13px))',
'rim-glow-opacity': 'same look, and the rim is under an ANIMATION: with only the transitions frozen the read returns the animated value (0.482956) and the token looks dead. With animation frozen too it computes 0.45 and follows -> reaches (0.45 -> 0.137)'
},
'file-upload': {
// Measured one by one 2026-08-23 (`__fu-adj`). The demo mounts the WHOLE
// surface (two seeded files, so list, preview, name, size, progress, remove
// and clear all render): what is left is state the route cannot reach and
// the freeze the guard does on purpose.
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen on the dropzone -> reaches (0.12s -> 11.5s on its three properties)',
'transition-ease':
'same instrument limit; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(7))',
'disabled-opacity':
'only under [data-disabled]; forced on the provider -> reaches (0.4 -> 0.123)',
'invalid-dropzone-border':
'only under [data-invalid], and this component takes invalid from an enclosing Field, which the demo route does not mount; forced -> reaches (oklch(0.8059 0.1123 59.96) -> rgb(1,2,3))'
},
switch: {
// Measured one by one 2026-08-23 (`__sw-adj`). The demo stage boots
// UNCHECKED, VALID and ENABLED and the switch has no trigger to open, so
// every state rule of the recipe is off-stage for the guard; the travel adds
// an instrument gap of its own.
'size-xs-thumb-translate':
'the travel lands on `transform`, which the guard does not snapshot, and it is 0px until the thumb is checked; forced data-state=checked + data-size=xs -> reaches (translateX 12px -> 1234px)',
'size-sm-thumb-translate': 'same pair of reasons; forced -> reaches (14px -> 1234px)',
'size-md-thumb-translate': 'same pair of reasons; forced -> reaches (16px -> 1234px)',
'size-lg-thumb-translate': 'same pair of reasons; forced -> reaches (18px -> 1234px)',
'size-xl-thumb-translate': 'same pair of reasons; forced -> reaches (20px -> 1234px)',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s on all four properties)',
'transition-ease':
'same instrument limit; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(7))',
'disabled-track-bg':
'only under [data-disabled]; forced -> reaches (color(srgb 0.9332 0.9334 0.9334) -> rgb(1,2,3))',
'disabled-track-border': 'same state; forced -> reaches (color(srgb 0.8685 …) -> rgb(1,2,3))',
'disabled-thumb-bg':
'same state, on the thumb; forced -> reaches (color(srgb 0.9867 …) -> rgb(1,2,3))',
'disabled-thumb-border':
'same state, on the thumb; forced -> reaches (color(srgb 0.9097 …) -> rgb(1,2,3))',
'disabled-opacity': 'same state; forced -> reaches (0.4 -> 0.123)',
'invalid-track-border':
'only under [data-invalid], which no trigger reaches and the guard does not force; forced -> reaches (oklch(0.9555 0.0207 13.86) -> rgb(1,2,3))'
},
select: {
// 2026-08-24. Ten reasons, every one measured on the REAL nodes with
// transitions frozen (the 24 tone forwarders are the palette cascade and
// go by PATTERN below). Its panel is PORTALED, so the guard has to keep it
// OPEN for the ~30 tokens that live inside it — and the open state is what
// buries the two rest-state keys of the trigger.
'trigger-border':
'the guard must keep the panel OPEN (30 of its tokens live in it) and [data-select-trigger][data-state=open] re-points border-color to the palette accent at (0,2,0); measured with the panel CLOSED -> reaches (oklch(0.8853 0 0) -> rgb(1, 2, 3))',
'trigger-indicator-fg':
'same open-state shadowing, on the chevron: [data-state=open] [data-select-indicator] re-points its colour; measured with the panel CLOSED -> reaches (oklch(0.5032 0 0) -> rgb(1, 2, 3))',
'placeholder-fg':
'the demo boots WITH a value, so no node carries [data-placeholder]; forced on the real value span -> reaches (oklch(0.2435 0 0) -> rgb(1, 2, 3))',
'disabled-border':
'the demo mounts ONE select and switching `disabled` on closes the panel that carries 30 other tokens; forced [data-disabled] on the real trigger -> reaches (oklch(0.8853 0 0) -> rgb(1, 2, 3))',
'disabled-bg':
'same single instance; forced [data-disabled] on the real trigger -> reaches (oklch(0.9911 0 0) -> rgb(1, 2, 3))',
'invalid-border':
'minted 2026-08-24 (it was reading --color-risk-border raw); the demo boots VALID. Forced [data-invalid] on the real trigger -> reaches on BOTH halves: border-color oklch(0.8853 0 0) -> rgb(1, 2, 3), and with [data-state=open] the ring too (oklch(0.8059 0.1123 59.96) 0 0 0 1px -> rgb(1, 2, 3) 0 0 0 1px)',
'close-duration':
'it feeds --motion-duration-exit, a CUSTOM property the guard does not snapshot, and it only reaches animation-duration while the panel is LEAVING — measured while open, animation-duration is the ENTER pair (0.18s). Read on the real panel: --motion-duration-exit 120ms -> 11.5s',
'separator-size':
'ALIVE but crushed: the separator sits in the ScrollArea flex column with the default flex-shrink 1, and the panel overflows (scrollHeight 670 vs clientHeight 310), so its 1px block-size computes 0px and no value of the token changes it. With flex-shrink 0 on the same node the token follows (1px -> 9px). The separator therefore paints NOTHING in an overflowing panel — a pixel-moving defect registered in next-features §13, not a dead token',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen on the real trigger -> reaches (0.12s -> 11.5s on all four properties)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))'
},
calendar: {
// 2026-08-24. This entry is the FAMILY's vocabulary (calendar-surface.css),
// so the guard measures it across calendar + month-grid + range-calendar;
// with those three routes 68 of its 74 keys move. These six are what the
// family cannot show, each measured on the real node.
'invalid-border':
'no calendar surface of the three routes boots invalid; forced [data-invalid] on the real host -> reaches (oklch(0.8059 0.1123 59.96) -> rgb(1, 2, 3))',
'select-min-width':
'its ONLY consumer is [data-range-calendar-month-select] / -year-select, and NO demo in the repo mounts those parts (0 nodes on the range-calendar route, which renders a text heading instead; DateRangePicker imports the CALENDAR selectors, so its nodes carry data-calendar-month-select). A part no page mounts has no node to paint — demo gap, registered in next-features §13',
'range-start-solid-hover':
'the hover pass stops at the first 30 nodes and the range endpoints sit past them on the range-calendar route; hovered the real [data-range-start] day -> reaches (oklch(0.6193 0.1094 181.3) -> rgb(1, 2, 3))',
'range-end-solid-hover':
'same limit on the other endpoint; hovered the real [data-range-end] day -> reaches (oklch(0.5246 0.1755 305.39) -> rgb(1, 2, 3))',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen on a real day cell -> reaches (0.12s -> 11.5s on all five properties)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))'
},
'radio-group': {
// 2026-08-23. The guard already sweeps its four variants and both
// orientations and measures the disabled / invalid stages through the
// demo's URL switches; these are what is left, each measured on the REAL
// nodes. Three of them are DEFECTS, not instrument limits, and say so.
//
// (1) The dot's whole scale — a value channel written INLINE.
'dot-size':
'DEAD BY INLINE STYLE, not by the demo: <SvgDot> writes style="width: 1em; height: 1em" on the glyph, and an inline declaration beats any stylesheet rule. Measured 2026-08-23: the dot computes 13.3281px (1em of the button UA font) at EVERY step while the token says 5/6/7/9/11px, the sentinel value changes nothing, and removing the inline style makes the same token paint 1234px. The recipe scale has never painted — a pixel-moving fix (the `!important` shape recipe-contract §3 allows for exactly this, bypassing an inline style) that needs a signature; registered in next-features §13',
'dot-size-xs': 'same inline style; the step reads 5px and the dot paints 13.3281px',
'dot-size-sm': 'same inline style; the step reads 6px and the dot paints 13.3281px',
'dot-size-md': 'same inline style; the step reads 7px and the dot paints 13.3281px',
'dot-size-lg': 'same inline style; the step reads 9px and the dot paints 13.3281px',
'dot-size-xl': 'same inline style; the step reads 11px and the dot paints 13.3281px',
// (2) A rule whose selector no runtime ever matches.
'disabled-item-label-fg':
'DEAD SELECTOR: it is consumed by [data-radio-group-label][data-disabled], and soma never stamps data-disabled on the Label part (the morfo declares `data: []` for it). Measured 2026-08-23 with the group disabled through ?perm.disabled=true: the label carries [id, data-radio-group-label, data-archetype] and nothing else. Forced on the label by hand -> reaches (oklch(0.2435 0 0) -> rgb(1, 2, 3)), so the token is sound and the ATTRIBUTE is missing — a morfo decision (checkbox\'s twin label does carry its own), registered in next-features §13',
// (3) A declaration the variant rules out-rank in every variant.
'checked-disabled-indicator-bg':
'SUPERSEDED by the variant rules: [data-radio-group][data-variant=X] [data-radio-group-item][data-state=checked] is (0,4,0) and [data-radio-group-item][data-disabled][data-state=checked] only (0,3,0). Measured 2026-08-23 on a disabled+checked item with the sentinel value written: solid oklch(0.5556 0.1829 305.86) (the full accent), outline and segmented rgba(0,0,0,0), ghost the 18% mix — never rgb(1,2,3). And removing data-variant does not help: the `:not([data-variant])` twin is (0,4,0) too. So a disabled+checked radio shows the FULL accent today; raising the specificity moves pixels -> signature, registered in next-features §13',
// Instrument limits, measured.
'gap-horizontal':
'the row gap is a PAIR and only the half in force paints: the demo boots `vertical`, and the guard sweeps ONE axis (data-variant, where twelve of its keys live). Switched the real demo to horizontal -> reaches (column-gap 16px -> 1234px)',
'invalid-ring':
'needs [data-invalid] AND :focus-visible, and the guard blurs on purpose; on a button :focus-visible only latches with the keyboard modality, so measured 2026-08-23 with a Tab followed by focus() on the real item -> reaches (the 4px ring oklch(0.9555 0.0207 13.86) -> rgb(1, 2, 3))',
'invalid-ring-gap': 'same double ring; measured the same way -> reaches (the 2px gap oklch(0.9911 0 0) -> rgb(4, 5, 6))',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen on the real item -> reaches (0.12s -> 11.5s on all four transitioned properties)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))',
'segmented-transition-duration':
'same freeze, on the segmented pair; measured unfrozen with the real variant on -> reaches (segment 0.18s -> 11.5s, and the pill\'s --indicator-duration 180ms -> 11.5s)',
'segmented-transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.32, 0.72, 0, 1) -> steps(3))',
'segmented-pill-shadow':
'the sliding pill is a node the WRAPPER only renders under variant="segmented" (like Switch\'s default Thumb), so stamping data-variant while measuring cannot create it; measured with the demo\'s real segmented chip on -> reaches (rgba(15, 23, 42, 0.08) 0 1px 2px -> rgb(1, 2, 3) 0 0 0 7px)'
// `hover-segmented-segment-fg` had an entry here for one run and the guard
// reported it STALE on the next: it needs hover AND the segmented variant,
// which the hover pass does not sweep — yet the pointer's resting place is
// enough for the static pass to catch it. Verified alive twice before the
// entry was pruned (hovered segment: oklch(0.2435 0 0) -> rgb(1, 2, 3)).
},
'rating-group': {
// 2026-08-23. Six, each measured on the real nodes.
'partial-item-fg':
'only under [data-state=partial], which needs allowHalf AND a half value; forced on the real fifth item -> reaches (oklch(0.6406 0.1329 157.68) -> rgb(1, 2, 3))',
'invalid-item-fg':
'minted 2026-08-23 (the rule was reading --color-threat-element raw); the demo boots VALID, and switching `invalid` on would make its (0,3,0) rule out-rank item-fg / active-item-fg / partial-item-fg for the whole run. Forced [data-invalid] on the real root -> reaches (oklch(0.9555 0.0207 13.86) -> rgb(1, 2, 3))',
'item-hover-offset':
'the guard does not snapshot `transform`, and this is the only knob of the recipe that moves one (the 1px lift on hover); hovered the real item and read transform -> reaches (matrix(1, 0, 0, 1, 0, -1) -> matrix(1, 0, 0, 1, 0, -40)). Instrument gap, registered in next-features §13',
'focus-radius':
'the corner only rounds under :focus-visible on the provider and the guard blurs on purpose; focused from the keyboard -> reaches (6px -> 1234px)',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen on a real item -> reaches (0.12s -> 11.5s on colour and transform)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))'
},
toggle: {
// 2026-08-23. Eight, each forced on the REAL stage toggle. The forty-eight
// tone keys are the palette cascade, adjudicated BY PATTERN below; the
// twelve hover keys and the thirty variant keys stopped being dead when the
// guard learnt to sweep SEVERAL axes (variant x state x invalid) in both
// passes — they are not adjudicated, they are measured.
'radius-sm':
'only the step in force paints (the demo has no `rounded` control at all, so the resting corner is the only one mounted); forced data-rounded=sm -> reaches (4px -> 1234px)',
'radius-md': 'same scale; forced data-rounded=md -> reaches (6px -> 1234px)',
'radius-lg': 'same scale; forced data-rounded=lg -> reaches (10px -> 1234px)',
'radius-xl': 'same scale; forced data-rounded=xl -> reaches (16px -> 1234px)',
'radius-full': 'same scale; forced data-rounded=full -> reaches (9999px -> 1234px)',
'disabled-opacity':
'the demo boots enabled, and switching `disabled` on for the whole run would drop pointer-events and revert the hover pair, killing six other keys; forced data-disabled on the real toggle -> reaches (opacity 0.4 -> 0.123)',
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s on all four transitioned properties)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(4))'
},
card: {
// 2026-08-23. Nine, each forced on the REAL stage card (which already boots
// with data-interactive + data-lift), transitions frozen before reading.
// The forty tone keys are the palette cascade, adjudicated BY PATTERN below.
'radius-sm':
'only the step in force paints (the demo boots rounded=md); forced data-rounded=sm -> reaches (6px -> 1234px)',
'radius-lg': 'same scale; forced data-rounded=lg -> reaches (16px -> 1234px)',
// The three emerge keys share ONE cause, and it is not the demo being shy:
// the mount rule is `:not([data-animation-style])` on purpose (the motion
// system owns the single `animation` property when the card opts in), and
// the stage boots with motion=select-pop.
'emerge-duration':
'the mount rule yields to the motion system — [data-card]:not([data-animation-style]) — and the stage boots with data-animation-style=select-pop, so no node runs the emerge. Removed the attribute on the real card -> reaches (animation-duration 0.32s -> 11.5s on both keyframes)',
'emerge-ease':
'same yield; same removal -> reaches (cubic-bezier(0, 0, 0.2, 1) -> steps(4))',
'emerge-distance':
'same yield, PLUS a second cause the other two do not have: it feeds the channel hook --motion-distance-md, and the mount ends on translate 0 with fill-mode both, so `transform` at rest can never show it. Read the hook itself on the real card -> reaches (8px -> 1234px)',
// The guard does not snapshot `transform` (same instrument gap as
// rating-group.item-hover-offset, next-features §13).
'hover-lift':
'the guard does not snapshot `transform`; hovered the real card and read it -> reaches (matrix(1, 0, 0, 1, 0, -2) -> matrix(1, 0, 0, 1, 0, 1234)). Instrument gap, registered in next-features §13',
'press-scale':
'same `transform` gap AND :active, which no script can force; read the live rule instead — [data-card][data-interactive]:active…:not(:has(button:active, …)) { transform: scale(var(--card-press-scale)) } is in the sheet and consumes the token by name',
'press-duration':
'same :active rule, which also sets transition-duration: var(--card-press-duration); read in the live sheet next to press-scale',
'disabled-opacity':
'the card dims through `filter: opacity()` (not `opacity` — its own mount animation would outrank a plain one, the comment in card.css records the measurement), and the demo boots enabled; forced data-disabled on the real card -> reaches (filter opacity(0.4) -> opacity(0.123))'
},
'image-adjustments': {
// 2026-08-24. One, measured on the REAL stage reset, transitions frozen.
// Its sibling `hover-reset-fg` looked like the same class and was NOT: the
// reset boots disabled (nothing adjusted yet) so `:hover:not([disabled])`
// could not match, and the `disabled` sweep in COMPONENT_OVERRIDES makes it
// read live. Only the focus corner has no mechanical route.
'focus-reset-radius':
'the corner only rounds under :focus-visible and the guard blurs the active element on purpose (the F2-A fix for click-focus poisoning); focused the real reset from script and confirmed :focus-visible matched -> reaches (4px -> 1234px). Same cause and same shape as rating-group.focus-radius'
},
toast: {
// 2026-08-24. Thirty-four, and the biggest group is §12.9 with a face
// nobody had seen yet: on a PORTALED card the overlay plane does not only
// take the typography, it takes the whole CARD. Measured on the real item
// with transitions frozen (`scripts/__dbg-toast-plane.mjs`): writing the
// component's surface / border / accent / border-width / shadow moves
// NOTHING (bg stays oklch(0.931 0 0), border oklch(0.8853 0 0) 1px), while
// --depth-overlay-surface / -border / -shadow / --border-width on the same
// root repaint every one of them (rgb(4, 5, 6), 999px, the 9px ring). The
// tone keys ride the PATTERN entries below.
'transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s on the two transitioned properties of the card)',
'transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3))',
'closed-offset':
'TWO reasons: the rule is `[data-toast-item][data-state=closed]` and a card only wears that state on its way OUT (the guard measures a card it has just fired), and it paints through `transform`, which the guard does not snapshot (the blind spot already adjudicated on background / rating-group / card / fab). Measured 2026-08-24 forcing data-state=closed on the real card with transitions frozen -> reaches (matrix(0.98, 0, 0, 0.98, 0, 10) -> matrix(0.123, 0, 0, 0.123, 0, 1234))',
'closed-scale': 'same rule, same property, same measurement -> reaches (0.98 -> 0.123)',
'action-focus-ring-offset':
'the ring only paints under `[data-toast-action]:focus-visible` and the guard blurs the active element on purpose; walked the focus onto the real Undo button with the keyboard, confirmed :focus-visible matched -> reaches (the inner spread goes 1px -> 999px)',
'action-focus-ring-width':
'same focus ring; measured focused -> reaches (the outer spread follows offset + width)',
'action-focus-ring-color':
'same focus ring; measured focused -> reaches (color(srgb 0.745076 …) -> rgb(1, 2, 3))',
'provider-max-width':
'the card reads `inline-size: min(100%, var(--toast-provider-max-width))`, so the guard`s 1234px is CAPPED by the other half of the min() and nothing moves — the known blind spot of a sentinel value that is too big. Measured 2026-08-24 from the other side, which is the only side that can move it: 120px -> the card narrows from 420px to 280px (its min-inline-size floor), so the token reaches'
},
tabs: {
// 2026-08-24. Nine, and NOT ONE of them is a token that lies: four are the
// transition the guard freezes, three the focus ring the guard blurs, one
// the composition the demo happens to mount, one a property the guard does
// not read. All nine measured by hand on the real nodes of the demo. The
// variant sweep + the two URL surfaces in COMPONENT_OVERRIDES took the run
// from 40/79 to 70/79 first, so what is left here is the residue, not the
// bulk.
'trigger-bg':
"the demo mounts `<Tabs.Indicator>`, and `[data-tabs-list]:has([data-tabs-indicator]) [data-tabs-trigger] { background: transparent }` (0,2,0) out-ranks the trigger's own `[data-tabs-trigger]` (0,1,0) — by design, the label has to read above the sliding pill. Measured 2026-08-24 with transitions frozen: with the indicator mounted the write moves nothing (rgba(0, 0, 0, 0)); switch the demo's `render Indicator part` OFF — the DEFAULT composition, the indicator is opt-in — and the same write reaches (rgba(0, 0, 0, 0) -> rgb(1, 2, 3)). Turning it off for the whole run only trades this key for `indicator-line-thickness`",
'trigger-transition-duration':
'the guard freezes transitions and this token IS the transition; measured unfrozen -> reaches (0.12s -> 11.5s on all four transitioned properties of the trigger)',
'trigger-transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.4, 0, 0.2, 1) -> steps(3) on all four)',
'indicator-transition-duration':
'same freeze, on the sliding indicator; measured unfrozen -> reaches (0.18s -> 11.5s on translate / inline-size / block-size; the fourth slot is the opacity fade, which is system)',
'indicator-transition-ease':
'same freeze; measured unfrozen -> reaches (cubic-bezier(0.32, 0.72, 0, 1) -> steps(3) on the same three)',
'trigger-focus-ring-offset':
'the ring only paints under :focus-visible and the guard blurs the active element on purpose (the F2-A fix for click-focus poisoning); walked the focus onto a real trigger with the keyboard, confirmed :focus-visible matched (1 node) -> reaches (1px -> 1234px)',
'trigger-focus-ring-width': 'same focus ring; measured focused -> reaches (2px -> 1234px)',
'trigger-focus-ring-color':
'same focus ring; measured focused -> reaches (color(srgb 0.745076 0.576585 0.894185 / 0.48) -> rgb(1, 2, 3))',
'scrollable-fade':
'TWO reasons, and either alone would be enough: the edge fade only exists under `[data-scrollable]`, an opt-in switch the stage boots OFF, and it paints through `mask-image`, which is not in the guard read set. Measured 2026-08-24 with the demo switch on and transitions frozen -> reaches (the mask reads `linear-gradient(to right, transparent, black 16px, black calc(100% - 16px), transparent)` and the write moves both stops to 1234px)'
}
};
/**
* The one architectural fact behind every tone key that reads dead. Measured
* 2026-08-23 on button, badge and callout: the palette forward emits a block per
* tone AND, LAST, a generic `[data-{c}][data-color]` that resolves the palette
* slots from the GLOBAL `--palette-*` (which `[data-color={tone}]` fills from
* `--color-{tone}-*`). Equal specificity (0,2,0), so the last one wins: with any
* tone attribute present the per-tone keys are bypassed. On data-color=risk,
* `--{c}-risk-solid` moves nothing at :root NOR on the node, while
* `--palette-solid` and `--color-risk-solid` on the node repaint. The primary-*
* keys are that rule's FALLBACK and do act on an instance with no data-color.
* 49 recipes emit the generic block and the contract holds 419 tone keys —
* registered in next-features §13, where the fix (emission order) is proposed.
*/
const PALETTE_SUPERSEDED =
'SUPERSEDED, not missing: the generic [data-{c}][data-color] block of the palette forward is emitted LAST and wins by source order at equal specificity, so the tone keys are bypassed and the paint comes from the global --palette-* (see next-features 13, measured on button, badge and callout 2026-08-23)';
/**
* The same adjudication, written ONCE for a whole family of keys. Born with
* button: 56 of its 106 keys are the eight tones x seven slots, and the reason
* they move nothing is ONE architectural fact, not 56 accidents. Copying the
* sentence 56 times would bury it.
*
* Checked only AFTER the exact lookup above fails, so a single key can always
* carry its own, more precise reason.
*/
export const SENTINEL_PATTERN_EXCEPTIONS: Array<{
component: string;
pattern: RegExp;
reason: string;
}> = [
{
component: 'button',
pattern:
/^(secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|element|border|solid|solid-hover|text|contrast)$/,
reason: PALETTE_SUPERSEDED + ' — the seven primary-* keys carry their own entry above'
},
{
component: 'callout',
pattern: /^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|text|solid)$/,
reason: PALETTE_SUPERSEDED
},
{
component: 'checkbox',
pattern: /^(primary|secondary|neutral|affirm)-(solid|solid-hover)$/,
reason: PALETTE_SUPERSEDED
},
{
component: 'radio-group',
pattern: /^(primary|secondary|neutral|affirm)-(solid|solid-hover)$/,
reason:
PALETTE_SUPERSEDED +
' — the same four tones x two slots as its twin checkbox, and PRIMARY falls with them: the eidos wrapper always resolves a colour and stamps data-color, so the generic block matches on every instance and the fallback that names the component key never applies. Measured 2026-08-23 on an affirm instance: --radio-group-affirm-solid moves nothing (oklch(0.6491 0.1136 181.96) stays), --palette-solid on the same node repaints (rgb(4, 5, 6))'
},
{
component: 'badge',
pattern:
/^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|border|solid|text|contrast)$/,
reason: PALETTE_SUPERSEDED
},
{
component: 'form',
pattern: /^(action-|transition-|disabled-opacity$)/,
reason:
'SUPERSEDED by the composed Button: [data-form-submit] & co. also carry `data-button`, and `[data-button]` matches at the SAME specificity (0,1,0) but loads LATER, so button.css paints the whole action chrome. Measured 2026-08-23, eight properties one by one — height, padding-inline, font-size, font-weight, line-height, gap, radius, border-width — plus the transition pair and the disabled opacity: NOT ONE of them moves. Same defect gradient-picker documented (36 of its 45 keys) and emoji-picker found in its trigger; the answer there was to retire the dead declarations, and here that is 24 public keys — a decision for the author, so they are adjudicated meanwhile (next-features 13)'
},
{
component: 'editable',
pattern: /^(primary|secondary|neutral|affirm|risk|threat)-(solid|border)$/,
reason:
PALETTE_SUPERSEDED +
' — measured here 2026-08-23 with the mechanism in the open: the node carries --palette-solid (oklch(0.5556 …)) from the shared per-instance layer, the generic block reads it, and the fallback that names the component key never applies; strip data-color from the same instance and --editable-primary-solid paints again (rgb(1, 2, 3)). soma always stamps data-color, so no instance escapes'
},
{
component: 'surface',
pattern: /^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|solid|contrast)$/,
reason: PALETTE_SUPERSEDED
},
{
component: 'file-upload',
pattern:
/^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(solid|solid-hover|track|border|text)$/,
reason:
PALETTE_SUPERSEDED +
' — the eight tones x five slots, 40 of its 97 keys. Measured 2026-08-23 on the trigger (solid) and on the hovered dropzone (track) for the eight tones: not one moves, while --palette-solid on the node repaints (oklch(0.6908 …) -> rgb(4,5,6)). Its host default is `primary`, and the demo passes color explicitly, so the fallback never applies either'
},
{
component: 'switch',
pattern: /^(primary|secondary|neutral|affirm|risk|threat)-(solid|solid-hover)$/,
reason:
PALETTE_SUPERSEDED +
' — and here NEUTRAL falls with the rest: soma always stamps data-color (it is the resolved colour, neutral by default), so the generic block matches on every instance and the fallback the other recipes keep alive never applies. Measured checked 2026-08-23: --switch-neutral-solid moves nothing, --palette-solid on the node repaints (oklch(0.5556 …) -> rgb(4,5,6))'
},
{
component: 'toggle',
pattern:
/^(primary|secondary|neutral|affirm|risk|threat)-(track|element|hover|border|solid|solid-hover|text|contrast)$/,
reason:
PALETTE_SUPERSEDED +
' — the six tones toggle forwards x eight slots, 48 of its 126 keys (it excludes fulfill/loss by doctrine: a toggle is neither completion nor irreversible loss). Measured 2026-08-23 on the real pressed toggle with transitions frozen: with data-color=primary, --toggle-primary-solid moves NOTHING (the fill stays oklch(0.5556 0.1829 305.86)) while --palette-solid on the same node repaints it (rgb(1, 2, 3)); strip data-color and --toggle-neutral-solid paints again (oklch(0.6434 0 0) -> rgb(1, 2, 3)). The neutral eight fall with the rest for a second reason worth writing down: the guard STAMPS data-color=neutral to test them, which is exactly what turns the generic block on'
},
{
component: 'card',
pattern:
/^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|border|solid|text|contrast)$/,
reason:
PALETTE_SUPERSEDED +
' — the eight tones x five slots, 40 of its 98 keys. Measured 2026-08-23 on the real stage card with transitions frozen: with data-color=primary, --card-primary-track moves NOTHING (the surface stays oklch(0.9932 0.0034 325.6)) while --palette-track on the same node repaints it (rgb(1, 2, 3)); strip data-color and --card-neutral-track paints again (oklch(0.9911 0 0) -> rgb(1, 2, 3)). The wrapper stamps data-color on every instance, so the named fallback never applies'
},
{
component: 'tags-input',
pattern: /^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|border|text)$/,
reason:
PALETTE_SUPERSEDED +
' — the eight tones x three slots, 24 of its 91 keys. Measured 2026-08-24 on the real tag forced into data-state=active with transitions frozen: with data-color=primary (the wrapper resolves `color` and stamps it on EVERY instance, default included) --tags-input-primary-border moves NOTHING (the tag border stays oklch(0.8043 0.0918 309.69)) while --palette-border on the same node repaints it (rgb(4, 5, 6)); strip data-color and --tags-input-primary-border paints again (rgb(1, 2, 3)). The generic `[data-tags-input][data-color], [data-tags-input][data-color-custom]` block is emitted LAST at the same (0,2,0) as the eight per-tone blocks. The three `*-text` slots carry a SECOND cause on top: even unsuperseded they cannot tint the item, because the archetype ink beats them (see the item-fg entry above)'
},
{
component: 'toast',
pattern: /^(default|affirm|fulfill|risk|threat|loss)-(surface|border)$/,
reason:
PLANE_SUPERSEDED +
' — the six intents x two slots, 12 of its 85 keys, and this is §12.9 on a PORTALED card: the item carries data-depth=overlay and the plane declares `background` and the `border` shorthand at the same (0,1,0) and later, so the whole per-intent CARD is painted by the plane. Measured 2026-08-24 on the real item with transitions frozen: --toast-risk-surface / -border move nothing (bg stays oklch(0.931 0 0)) while --depth-overlay-surface / -border on the same root repaint it (rgb(4, 5, 6)). Visible consequence, registered in next-features §12.9 and NOT fixed from this axis: a risk toast and a fulfill toast wear the same grey card; only the status disc and the action ink carry the intent'
},
{
component: 'toast',
pattern: /^(default|affirm|fulfill|risk|threat|loss)-accent$/,
reason:
'SUPERSEDED by the depth plane AT REST (the accent is a `border-inline-start` longhand and the plane`s later `border` shorthand overwrites all four sides — §12.9, same measurement as the surface/border pattern), but NOT dead: under `[data-toast-item][data-loading]` the pulse rule is (0,2,0) and its @keyframes outranks every normal declaration. Measured 2026-08-24 over 100 frames of the real pulse: without the write the interpolated border-inline-start-color runs oklab L 0.5032..0.8514; with --toast-default-accent=rgb(1, 2, 3) it runs 0.0823..0.5032 — the token reaches, in the one state where the plane cannot reach it'
},
{
component: 'toast',
pattern: /^(affirm|fulfill|risk|threat|loss)-action-hover-bg$/,
reason:
'the tone is what the guard cannot combine with the hover: its static pass stamps data-intent to test a tone key, and its hover pass does not — so only `default-action-hover-bg` (the untinted card, which needs no stamp) reads alive. Measured 2026-08-24 with the demo`s own `risk` chip and a real pointer on the Undo button, transitions frozen -> reaches (oklch(0.9923 0.0025 48.72) -> rgb(1, 2, 3))'
},
{
component: 'select',
pattern: /^(primary|secondary|neutral|affirm|fulfill|risk|threat|loss)-(track|border|text)$/,
reason:
PALETTE_SUPERSEDED +
' — the eight tones x three slots, 24 of its 103 keys, and here the cascade is the TSC v2.2 MULTI-PART one (parts trigger + content, because the panel portals out): the last block emitted is `[data-select-trigger][data-color], [data-select-content][data-color], …` reading `var(--palette-track, var(--select-primary-track))`. Measured 2026-08-24 on the open trigger, which carries data-color=primary: --select-primary-border moves NOTHING (border stays oklch(0.8043 0.0918 309.69)) while --palette-border on the same node repaints it (rgb(4, 5, 6)). soma always stamps data-color, so the named fallback never applies on any instance'
}
];

Powered by TurnKey Linux.