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

729 lines
58 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.
*/
export const SENTINEL_EXCEPTIONS: Record<string, Record<string, string>> = {
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': {
'font-family':
"declared but out-ranked: the panel stamps `data-depth='overlay'`, whose plane declares font-family too at an EQUAL (0,1,0) — the generated sheet loads later, so it wins. Kept on purpose: retiring it would fix that tie in the plane's favour, a pixel decision pending signature (next-features §12.9). Measured with CDP matched-rules 2026-08-21, stable across 5 dev reloads",
'line-height':
'same load-order tie with the `overlay` plane, which imposes 1.25 where this recipe asks for --leading-normal (1.5). Declared and kept until the signature resolves who owns overlay typography',
'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)'
},
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'
},
'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)'
},
metrics: {
// The demo's icon runs the `rounded` shape; the other two only paint under
// their own data-shape value. Forced in place 2026-08-22.
'icon-circle-radius': 'the demo icon is data-shape=rounded; forced circle -> reaches (9999px -> 1234px)',
'icon-square-radius': 'same; forced square -> reaches (6px -> 1234px)'
},
'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)'
},
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'
},
'color-picker': {
// The demo mounts no swatch TRIGGER: its presets render as <ColorSwatch>
// components, so the two parts these paint never enter the panel. Mounted
// inside the OPEN panel 2026-08-22 with the attrs the CSS selects.
'swatch-border-width': 'no swatch trigger in the demo panel; mounted in place -> reaches (1px -> 1234px)',
'swatch-ring-gap': 'the ring gap of the checked swatch and of its indicator; mounted in place -> reaches (oklch(0.9911 0 0) 0 0 0 1px -> rgb(1,2,3) 0 0 0 1px)'
},
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.
'font-family':
'the overlay DEPTH PLANE imposes font-family on the panel and beats the recipe: the section 12.9 finding, pending signature (20 components). Measured 2026-08-22, writing the token moves nothing while the plane does.',
'line-height':
'same plane, same finding: the token cannot win until the plane stops owning typography'
},
'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)'
},
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'
},
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)'
}
};
/**
* 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
},
];

Powered by TurnKey Linux.