4.6 KiB
Audit: radio-cards
audit-version: 1
audited-at: 2026-06-26
scope: eidos (eidos-only primitive)
method: theming-coherence category sweep (composite-and-service), adversarially verified; roles + :Morfo lead-verified CLEAN across all eidos (no success/warning/danger/info; only alert-dialog uses :Morfo).
Summary
Counts (post-verification): CRITICAL 0 · HIGH 0 · MEDIUM 1 · LOW 2. conformance: Contract: 'as const satisfies Morfo' ✓ | Scope: eidos ✓ | Roles: reuses radio-group (none new) ✓ | Variants: data-size, data-orientation, data-columns, data-invalid ✓ | Sizing: via recipe (padding/gap/icon-size/title-font-size) ✓ | Color: reused --_radio-group-palette-* inlined (documented) ✓ as-const: true · roles clean: true · variants clean: true · has-recipe: true
Findings
MEDIUM: one-off easing literal where --ease-* scale exists — radio-cards-easing-001
- dimension: MAGIC_LITERAL, NO_OVERLAP
- location: src/uix/eidos/components/radio-cards/radio-cards.css:252
- evidence: transition: transform var(--radio-cards-transition-duration) cubic-bezier(0.4, 0, 0.2, 1);
- impact: Bespoke Material-standard easing curve inlined where the canonical --ease-* token scale exists. Sibling split-button.css:22 correctly uses var(--ease-default). The duration here correctly uses a recipe token (--radio-cards-transition-duration); only the easing bypasses the scale, so a theme that retunes --ease-default won't reach this indicator transition.
- proposed-fix: Replace cubic-bezier(0.4, 0, 0.2, 1) with var(--ease-default) (or the appropriate registered --ease-* token) to keep the indicator pop on the canonical easing scale.
- verify: [verifier-added] added by adversarial verify pass
- fix-status: open
LOW: bare percentages in color-mix() — radio-cards-001
- dimension: MAGIC_LITERAL
- location: src/uix/eidos/components/radio-cards/radio-cards.css:98, 117
- evidence: color-mix(in srgb, var(--_radio-group-palette-solid) 12%, var(--color-surface-default)); (line 98) color-mix(in srgb, var(--_radio-group-palette-solid) 7%, var(--color-surface-default)); (line 117)
- impact: Hardcoded tint opacity (12% for hover, 7% for checked) — these are interaction opacity values that bypass --opacity-* scale; however, they are documented in the recipe comments and locked to the card presentation logic
- proposed-fix: Document or add --radio-cards-*-opacity tokens if cross-component theming consistency is desired, but the current inlining is acceptable given the component-specific palette context
- verify: [downgraded] Confirmed css:98 (12%) and css:117 (7%) color-mix proportions tinting --_radio-group-palette-solid over --color-surface-default. These are color-mix tint ratios, not element opacity; a :root token referencing the palette would be invalid-at-computed-value (comment css:106-113). No canonical token applies to a mix proportion. LOW, not MEDIUM.
- fix-status: open
LOW: bare percentage / em in pseudo-element — radio-cards-002
- dimension: MAGIC_LITERAL
- location: src/uix/eidos/components/radio-cards/radio-cards.css:247-248, 252
- evidence: inline-size: 46%; block-size: 46%; (line 247-248) transform: scale(0); ... cubic-bezier(0.4, 0, 0.2, 1); (line 252)
- impact: 46% is the inner dot radius (fixed ratio to the outer ring); scale(0) is a keyframe/initial state; cubic-bezier is acceptable easing (not a one-off deviation from standard preset)
- proposed-fix: No fix — 46% is a fixed geometry ratio, scale(0) is structural, and cubic-bezier(0.4, 0, 0.2, 1) is a standard animation easing
- verify: [downgraded] Confirmed css:247-248 46% (fixed inner-dot geometry ratio) and css:252 scale(0) (structural initial state) — both LOW physical/structural, not drift. HOWEVER css:252 also carries a bespoke easing cubic-bezier(0.4, 0, 0.2, 1) where --ease-* tokens exist and split-button.css:22 correctly uses var(--ease-default); that easing sliver is the real MEDIUM (see new finding radio-cards-easing-001). The 46%
- fix-status: open
Theming facts (E-bis)
- magic literals: 12% @ src/uix/eidos/components/radio-cards/radio-cards.css:98 -> hover tint opacity (component-specific, documented in recipe comments) | 7% @ src/uix/eidos/components/radio-cards/radio-cards.css:117 -> checked tint opacity (component-specific, documented) | 46% @ src/uix/eidos/components/radio-cards/radio-cards.css:247-248 -> inner dot geometry ratio (fixed, acceptable) | cubic-bezier(0.4, 0, 0.2, 1) @ src/uix/eidos/components/radio-cards/radio-cards.css:252 -> standard easing preset (acceptable)
- magic z-index: none
- non-canonical names: none
- roles clean: true · variants clean: true