Skip to content

Bundles of joy#24

Draft
nschneble wants to merge 7 commits into
mainfrom
harder-better-faster-stronger
Draft

Bundles of joy#24
nschneble wants to merge 7 commits into
mainfrom
harder-better-faster-stronger

Conversation

@nschneble
Copy link
Copy Markdown
Owner

@nschneble nschneble commented Jun 8, 2026

Features added:

  • Bundle architecture for theme color tokens (base / mount / orbit / alert / warn / info / success, each with bg / border / text / alt-text / highlight)
  • school-of-rock pilot: full bundle palette for both light and dark modes, WCAG 2.2 SC 1.4.3 + 1.4.11 verified per-pair against bundle-bg AND page-bg
  • Alert component default branch wired through bundle tokens; Apollo + Nouvelle Vague keep their bespoke variants until each gets a CVD-aware bundle palette of its own
  • AppShell email-verification banner migrated to the warn bundle — first consumer of --warn-* tokens. Nouvelle Vague keeps its grayscale overrides (Alert.tsx pattern); Apollo falls through to the default bundle until it gets its own warn palette.
  • Eight additional component sites migrated to bundle tokens. Each site swaps a hardcoded Tailwind utility (rose-*, emerald-*, amber-*) for the corresponding bundle var. Default bundle was already tuned to mirror the legacy hue, so un-migrated themes stay visually equivalent. Nouvelle Vague + Apollo per-theme branches preserved where they existed:
    • SettingsGroup.tsx danger variant (4 class constants) → --alert-*
    • BookmarkletRegenerateButton.tsx, DangerZone.tsx, ApiTokenRow.tsx confirmation alt-text → --alert-text
    • TokenInput.tsx validation error → --alert-text
    • TokenVerificationPage.tsx success check icon → --success-highlight
    • StatusBadge.tsx success + warning default: branches → --success-* / --warn-* (info default deferred — see below)

Wave 2 (this push):

  • bundles.css default border palettes hardened to clear WCAG 2.2 SC 1.4.11 cross-theme. Light :root borders move from soft tints to dark stops (rose-800 #9f1239 / amber-800 #92400e / blue-800 #1e40af / emerald-700 #15803d). Dark [data-mode='dark'] borders shift from 50%-alpha-on-page to solid (rose-400 / amber-500 / blue-400 / emerald-400). Verified worst-case against before-midnight light --bg (#ccc095) and before-sunset dark --bg (#050404). Preamble comment updated to drop the "DO NOT meet 1.4.11" warning — defaults are now compliance-bearing. --success-border light uses emerald-700 (not emerald-800, which collides with --success-text).
  • IconButton.tsx danger variant migrated off the hardcoded rose-100/rose-400/rose-700 + dark-mode rose-900/rose-700/rose-300 stack to --alert-bg / --alert-border / --alert-text. Nouvelle Vague per-theme block preserved verbatim (Alert.tsx discipline). With the wave-2 defaults hardening, the dark-mode rose fork is no longer load-bearing.
  • FOCUS_RING_DANGER migrated off ring-rose-400 to ring-[var(--alert-highlight)]. Tracks per-theme palettes alongside the rest of the alert surface. styles.test.ts + JSDoc updated.
  • StatusBadge.info annotation refreshed with the 2026-06-08 verification note. --info-border (#1e40af light / #60a5fa dark) now clears 3:1 against --bg in every un-migrated theme — migration is unblocked but bundled separately to keep this commit's scope tight to alert-bundle work.

Deferred to follow-up PRs (intentional):

  • The other 9 themes — each needs its own bundle palette + contrast pass
  • Apollo CVD migration onto bundles — requires distinguishability under protanopia / deuteranopia / tritanopia
  • Day-for-night --asset-filter / .themed-asset utility (PRD-specified but separate slice)
  • Theme editor (ContrastChecker, useThemeOverrides, ComponentShowcase) keyed off the legacy 11 flat variables; will need updating once bundles are fully adopted
  • Remaining hardcoded color sites — each requires a palette decision:
    • IconButton.tsx danger-filled variant: solid saturated rose (bg-rose-600 + text-rose-50). Bundle has no "filled-button on alert" pattern. Awaits a --{bundle}-highlight-fg foreground slot across all state bundles. Deferral comment landed in the source.

Next wave (unblocked, scheduled separately):

  • StatusBadge.tsx info default: migrate off bg-blue-100 / border-blue-300 / text-blue-700 (light) and bg-blue-950/20 / border-blue-800/40 / text-blue-400 (dark) to --info-*. Unblocked by the wave-2 defaults hardening.

Dark-surface follow-ups:

  • warn bundle: consumed by AppShell (email-verification banner) + StatusBadge warning default. Wave-2 defaults clear SC 1.4.11 across un-migrated themes; per-theme bundle palettes still encouraged for theme-fitting hue.
  • info bundle: defined in bundles.css for both default + school-of-rock, zero consumers in components. Awaits component migration in a follow-up. The school-of-rock info palette was re-hued to a brown/cream family (away from green) so it stays hue-distinct from success under all four CVD simulations.
  • success bundle: consumed by Alert, StatusBadge (success default), TokenVerificationPage (highlight only).
  • alert bundle: consumed by Alert, SettingsGroup danger, IconButton danger, and the four small alt-text sites listed above.

Notes for review:

  • index.css import order is load-bearing: bundles.css must come AFTER all per-theme flat-token stylesheets, so the default-branch var(--bg) / var(--bg-surface) references in the bundle defaults can resolve against the active theme. Reordering breaks the cascade silently. (Comment now lives in index.css next to the import.)
  • The default-branch --alert-* / --warn-* / --info-* / --success-* palettes intentionally DO NOT meet WCAG 2.2 SC 1.4.11landed in wave 2. Defaults now clear >=3:1 border-vs-bg in every un-migrated theme. Per-theme overrides still encouraged for theme-fitting hue, not for compliance.
  • school-of-rock-dark --base-border lands at exactly 3.01:1 against --base-bg. Passes WCAG 1.4.11 but is right at the threshold; consider tightening before promoting school-of-rock as the canonical bundle example.
  • Apollo + Nouvelle Vague per-theme branches preserved verbatim across all wave-2 changes — only default-branch behavior moved.
  • AppShell banner migration accepts an alpha drift on dark --warn-bg (legacy inline used bg-amber-950/25 = 0.25 alpha; bundle uses 0.40). A11y-lead approved the drift in favor of bundle consistency.
  • Wave-2 dark-mode border alpha → solid shift: un-migrated themes' dark-mode --warn-border / --info-border / --success-border move from 50%-alpha-on-page to solid hex stops. Borders pop slightly more in dark mode; a11y-lead accepted the tradeoff given the contrast headroom (all four clear 5:1 minimum). --alert-border was already solid pre-wave.
  • StatusBadge success-text shade drift: pre-migration text-emerald-700 = #047857; post-migration --success-text default light = #065f46 (closer to emerald-800). Same family, one shade darker.
  • SettingsGroup icon mapping: the danger variant's icon uses --alert-highlight (the closest bundle slot for "accent inside alert surface"). On default-branch themes the icon stays brighter than the heading (rose-500 vs rose-700-ish); on school-of-rock the icon equals the border hue rather than being brighter than the heading.

🤖 Generated with Claude Code

nschneble and others added 2 commits June 8, 2026 00:25
Introduce a color-bundle layer alongside the existing 11 flat tokens.
Ship the bundle palette for school-of-rock (both modes) and migrate the
Alert component's default branch to consume the new tokens. Apollo and
Nouvelle Vague keep their bespoke variants until each gets a CVD-aware
bundle palette of its own.

7 bundles x 5 vars x light/dark, WCAG 2.2 SC 1.4.3 + 1.4.11 verified
per-pair for school-of-rock against bundle-bg AND page-bg.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- school-of-rock info bundle re-hued to brown/cream for CVD hue-separation
  vs success (green) under all four CVD simulations (a11y-lead values)
- bundles.css default block annotated: defaults intentionally below SC 1.4.11,
  per-theme overrides enforce the contract
- index.css import-order comment: bundles.css must follow per-theme files
- Alert.test.tsx now pins Apollo + Nouvelle Vague variant branches across
  both modes, not just the default branch

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@nschneble nschneble self-assigned this Jun 8, 2026
nschneble and others added 5 commits June 8, 2026 10:53
First consumer of the --warn-* bundle tokens. Swaps inline amber Tailwind
classes for var(--warn-bg) / var(--warn-border) / var(--warn-text) on the
default branch; drops the dark-mode amber overrides (the bundle handles
[data-mode='dark']). Nouvelle Vague keeps its grayscale overrides per the
Alert.tsx pattern; Apollo falls through to the default bundle.

Accepts an alpha drift on dark --warn-bg (0.25 -> 0.40) in favor of
bundle consistency; a11y-lead approved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Continues PR #24's rolling migration. Each site swaps Tailwind
utilities (rose-*, emerald-*, amber-*) for bundle vars where
the default bundle was deliberately tuned to mirror the legacy
hue. Nouvelle Vague inline overrides preserved. Apollo continues
to fall through to defaults.

Sites: SettingsGroup danger variant; "Sure?" alt-text in
BookmarkletRegenerateButton / DangerZone / ApiTokenRow;
TokenInput validation error; TokenVerificationPage success
icon; StatusBadge success + warning defaults.

Deferred (palette decision required): StatusBadge info default,
IconButton danger / danger-filled, lib/styles.ts FOCUS_RING_DANGER
(+ test), ContrastChecker PassBadge.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Move text-xs before color tokens in ApiTokenRow + BookmarkletRegenerateButton (Tailwind class order per CLAUDE.md, flagged by the-stickler)
- Clarify StatusBadge info-variant deferral comment: bundle defaults exist, hold is a WCAG-compliance checkpoint not a missing palette (flagged by the-diamantaire)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The default `:root` and `[data-mode='dark']` palettes in bundles.css now
clear SC 1.4.11 (>=3:1 border-vs-bg) against every un-migrated theme,
verified worst-case against `before-midnight` light --bg (#ccc095) and
`before-sunset` dark --bg (#050404).

Light defaults shift the border slot from soft tints (rose-200,
amber-300, blue-300, emerald-300) to dark stops:
- --alert-border:   #fecdd3 -> #9f1239 (rose-800)
- --warn-border:    #fcd34d -> #92400e (amber-800)
- --info-border:    #93c5fd -> #1e40af (blue-800)
- --success-border: #6ee7b7 -> #15803d (emerald-700; emerald-800 #065f46
  was rejected because it collides with --success-text)

Dark borders shift from 50%-alpha-on-page to solid hex stops. Borders
will pop slightly more in dark mode for un-migrated themes; the
accessibility-lead review accepted the tradeoff given the contrast
headroom (all four clear 5:1 minimum):
- --alert-border:   #9f1239              -> #fb7185 (rose-400)
- --warn-border:    rgb(146 64 14 / 0.5) -> #f59e0b (amber-500)
- --info-border:    rgb(30 58 138 / 0.5) -> #60a5fa (blue-400)
- --success-border: rgb(6 95 70 / 0.5)   -> #34d399 (emerald-400)

Preamble comment updated to drop the "DO NOT meet SC 1.4.11" warning;
defaults are now compliance-bearing, with per-theme palettes still
encouraged for theme-fitting hue.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`IconButton`'s `danger` variant now reads its hover-bg, ring, and text
from the alert bundle (`--alert-bg`, `--alert-border`, `--alert-text`)
instead of the hardcoded rose-100/rose-400/rose-700 stack plus dark-mode
rose-900/rose-700/rose-300 fork. With the wave-2 defaults hardening,
every un-migrated theme inherits a >=3:1 border against the page, so the
rose dark-mode fork is no longer load-bearing.

`FOCUS_RING_DANGER` migrates from `ring-rose-400` to
`ring-[var(--alert-highlight)]`, tracking per-theme palettes alongside
the rest of the alert surface. Test assertion + JSDoc updated to match.

`danger-filled` stays on the legacy Tailwind rose-600 saturation; a
deferral comment documents why. The bundle architecture lacks a
`--{bundle}-highlight-fg` foreground slot, and the only candidate
(`--alert-bg`) is alpha-on-page in dark mode, so a deterministic
foreground-vs-fill contrast can't be guaranteed yet.

`StatusBadge.info` annotation updated with the 2026-06-08 verification
note: `--info-border` now clears 3:1 against `--bg` in every un-migrated
theme, so migration is unblocked. The migration itself ships in a later
wave to keep this commit's scope tight to alert-bundle work.

Nouvelle Vague + Apollo per-theme overrides preserved verbatim. NV's
`focus-visible:ring-[var(--accent)]` still wins against
`FOCUS_RING_DANGER` via the higher-specificity `[data-theme=...]`
attribute selector.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant