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/audit/THEMING_COHERENCE.md

8.4 KiB

Theming coherence — consolidated (E-bis roll-up)

updated-at: 2026-06-26 batches-complete: 1 canon refs: THEMING §4 (9 roles), §5 (sizes + 1:1 font), §6 (naming/slots), §16 (anti-patterns A–H), §19 (EIDOS_VARIANTS), §35 (scales — z/opacity/border)

(a) Hardcoded-where-canonical values (the consolidation)

Value (literal) Canonical token it should be Components hardcoding it Severity
content-z / overlay-z integers (80/75/70/60) --z-index-{overlay-ladder} (THEMING §35-C) select(80), dialog(70), popover(75/60), combobox(80), dropdown-menu(80) — 5/5 SYSTEMIC
item-disabled-opacity: '0.55' var(--opacity-disabled) dropdown-menu MEDIUM
item-description-font-size: '0.85em' var(--font-size-*) (escapes the px/rem guard) select MEDIUM
group-heading-letter-spacing: '0.04em' var(--tracking-caps) select LOW
item-description-mt: '0.125rem' var(--space-0-5) select LOW
item-height: '2rem' --list-item-height-* / --control-height-* (list-surface layer) dropdown-menu LOW

dialog.overlay-opacity: '62%' is left as recipe-legitimate (scrim opacity is a recipe knob, not on the --opacity-* step scale) — noted, not flagged.

(b) Near-duplicate tokens (same resolved value, different name)

  • content-z: '80' appears identically in select, combobox, dropdown-menu — three names, one value, no shared source. Folds into SYS-2 (MAGIC-Z).
  • No other near-duplicate token pairs surfaced in Batch 1 (the recipes alias --color-*/--space-*/--radius-* consistently).

(c) Non-canonical role / variant / size / slot names found

  • Roles: NONE. All 5 use only the 9 canonical roles (primary/secondary/tertiary/neutral + affirm/fulfill/risk/threat/loss). No success/warning/danger/info. ✓ (THEMING §16-C clean.)
  • Variants: NONE invented. SelectVariant = ControlVariant, dialog uses position/size data-attrs (visual, eidos-owned, not "variants"). ✓
  • Sizes: NONE invented (xs..xl subsets). One raw-rem size (dropdown-menu.item-height: 2rem) that should bridge the list-surface scale — drift, not an invented name.
  • Slots: NONE invented; recipes use track/border/text/bg/hover/... from the fixed vocabulary. ✓

(d) Per-component canon-conformance

Component roles sizes variants naming no-overlap
select ✓ ✓ ✓ ✓ ✗ (em-font literal escapes guard; magic-z; subset type=all-9 vs 8 accents)
dialog ✓ ✓ ✓ ✓ ✗ (dead [data-dialog-trigger] envelope overlaps composed Button; magic-z)
popover ✓ ✓ ✓ ✓ ⚠ (magic-z only)
combobox ✓ ✓ ✓ ✓ ⚠ (magic-z only)
dropdown-menu ✓ ⚠ (item-height 2rem) ✓ ✓ ⚠ (magic-z + magic opacity)

Legend: ✓ clean · ⚠ minor drift · ✗ real overlap/violation.

(e) Systemic theming finding (≥3 components → one structural fix)

THEME-SYS-1 · Overlay z-index is an ad-hoc parallel scale; a canonical --z-index-* ladder already exists

  • recurs in (B1+B2): select 80 · dialog overlay 70 · popover content 75 / overlay 60 · combobox 80 · dropdown-menu 80 · tooltip 76 · drawer overlay 72 / inline 64 · link-preview preview-z 99 · navigation-menu content-z (token, value hardcoded) · toast toaster-z 1200. ~10 overlay recipes.
  • lead-verified ground truth: the canonical scale STATIC_Z_INDEX (lib/primitives/static.ts:291) EXISTS: base 0 · raised 1 · sticky 100 · dropdown 300 · popover 400 · tooltip 500 · modal 700 · toast 900, exposed as --z-index-{key} and consumed by the depth planes (overlay → var(--z-index-popover), modal → var(--z-index- modal)) AND by menu-dial (var(--z-index-sticky, 1100)). So the overlay recipes hardcode an ad-hoc 60–99/ 1200 scale that (a) duplicates a scale that already exists and (b) doesn't even match its ordering — e.g. ad-hoc tooltip 76 < dropdown 80, but canonical tooltip 500 > dropdown 300.
  • precise fix mapping (one sweep): dropdown-menu/context-menu → --z-index-dropdown; select/combobox/popover/ link-preview content → --z-index-popover; tooltip → --z-index-tooltip; dialog/drawer overlay → --z-index- modal (content = +1 or a --z-index-modal-content); toast → --z-index-toast. menu-dial already does it right.
  • fix-status: open

THEME-SYS-2 · Recipe opacity decimals where a numeric --opacity-* scale exists

  • recurs in: dropdown-menu item-disabled-opacity 0.55, context-menu item-disabled-opacity 0.55, onion-menu muted-opacity 0.85/hover-ring-opacity 0.65, calendar day-outside-opacity 0.62 (B3). The --opacity-* scale is a 0.05 step (static.ts:255-275: --opacity-60=0.6, --opacity-65=0.65) — 0.62 maps to NO step, and the same off-scale 0.62/62% recurs as overlay-opacity in dialog (base.ts:729) + drawer (:895): an unnamed brand value. Dialog uses var(--opacity-disabled) for disabled — the positive model.
  • one fix: map disabled opacities to var(--opacity-disabled), snap decimals to the nearest --opacity-* step, and give the recurring 0.62 scrim value ONE named token (--opacity-scrim?) instead of three literals.
  • fix-status: open

B3 theming note — calendar 8ch select-min-width is LEGIT (not drift)

  • The verify correctly ruled 'select-min-width': '8ch' (calendar recipe) a non-violation: ch is the right unit for a text-box min-width (tracks glyph width of the month/year label), there is no canonical ch-scale to reference, and it's already a named component token. Token-naming nit at most (LOW). Recorded so the next sweep doesn't re-flag it.

Batch-8 closing — eidos primitives (44) are theming-clean

The final batch swept all eidos-only primitives (layout · typography · visual · composite+service · infra) for E-bis. Result: the eidos theming layer is in excellent shape.

  • (c) NON-CANONICAL ROLES — CLEAN across all 124 components (authoritative). Lead grep + the B8 category sweep + verify agree: NO recipe / type union / data-color enum / token name anywhere uses success/warning/danger/ info/error/brand. The only occurrences are COMMENTS that correctly document the mapping (badge/types.ts:22: "success → affirm, warning → risk, error → threat"). The B8 agents' "TextColor/HeadingColor must use ColorRole" flags were all REFUTED: typography color uses the content-color slots (content-primary/secondary/muted/disabled/ on-solid), which are valid content roles, NOT the 9 hierarchy/intent roles. THEMING §16-C is fully satisfied.
  • VARIANTS / SIZES / NAMING — CLEAN. No invented data-variant, no invented size, no --eidos-/--soma-/--air- prefix, no redundant color- segment found in any primitive.
  • RAW HEX — only the physically-fixed ones. qr-code's #fff/#000 (scanability) is the sole raw-hex, correctly ruled legitimate (refuted).
  • The residual literals are minor (3 MEDIUM, 12 LOW), no systemic class:
    • code/kbd/mark inline-pill padding in em (0.1–0.4em) — there is NO canonical em-padding scale, so this is borderline-acceptable LOW (a candidate for a future --inline-pad-* token if it ever recurs more).
    • scroll-frames layout + opacity literals (2 MEDIUM) — should reference --space-* / --opacity-*.
    • radio-cards one-off easing literal (MEDIUM) — should reference --ease-*.
    • section calc(--space-16 * 1.5) (LOW) — composes the canonical token for an off-scale xl=96px (no --space-24).
    • container 80rem defensive fallback, group 1px border-collapse — physically-fixed/defensive (LOW, accept).
  • No new systemic theming finding from B8. The two systemic theming issues remain THEME-SYS-1 (overlay z-ladder, ~10 overlay recipes — the only structural theming fix worth a sweep) and THEME-SYS-2 (magic opacity decimals).

Notes for the full sweep

  • The biggest theming wins are E-bis structural (tokenize z-ladder), not per-recipe. Batch 8 (eidos-only primitives) will add the most distinct hardcoded-value data — re-run this roll-up after each batch and promote any value hardcoded in ≥3 components to a systemic entry here.
  • The px/rem font-size coherence guard has an em/% hole (select-008) — tracked in VALIDATOR_GAPS.

Powered by TurnKey Linux.