feat(design): the scheme set, the colour contract and the token utilities (E28 S3a)
Four schemes (Midnight; Forest cyan, Slate fuchsia, Matrix lime), YouTube and Starship retired with no data migration: normalizeTheme maps a stored retired scheme to Midnight. A vitest contract measures every scheme x mode (text 4.5:1, control edge 3:1, status text, the accent's 30-degree hue gap); it caught light-mode danger at 4.43:1, now red-700. The state layers, the strong edge, the touch target and the fades are index.css tokens and utilities the lab now reads. Backdrops recoloured to the new accents, with a grey overlay grain that actually breaks the banding (longest flat run 15-26px -> 4-8px). The glass tuner is retired.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
// The decided values the lab's reference renderings share (batches A and B, 2026-09-24). They are
|
||||
// the lab's stand-ins until S3 moves each into index.css / the ui/ primitives; then these go.
|
||||
// The decided values the lab's reference renderings share (batches A and B, 2026-09-24). The colour
|
||||
// rules are real now (E28 S3a): each constant below names the index.css utility or token that holds
|
||||
// it, so the lab renders what the app ships. The height ladder moves into ui/Button in S3b.
|
||||
|
||||
/** B1 compact ladder: explicit heights, so one toolbar row lines up at 28. */
|
||||
export const H = {
|
||||
@@ -12,25 +13,15 @@ export const H = {
|
||||
bar: "h-7",
|
||||
} as const;
|
||||
|
||||
/** A4: the input edge, ≥ 3:1 against the page in every scheme and mode. */
|
||||
export const STRONG = "color-mix(in srgb, var(--fg) 55%, var(--bg))";
|
||||
/** A4: the input edge, ≥ 3:1 against the page in every scheme and mode (index.css --edge-strong). */
|
||||
export const STRONG = "var(--edge-strong)";
|
||||
|
||||
/** B3 state layers: the text colour at 10% (hover) / 16% (pressed) over whatever is underneath;
|
||||
* a filled control mixes its own text colour into the fill at 14% / 24%. */
|
||||
export const LAYER =
|
||||
"hover:bg-[color-mix(in_srgb,var(--fg)_10%,transparent)] active:bg-[color-mix(in_srgb,var(--fg)_16%,transparent)]";
|
||||
export const FILLED =
|
||||
"bg-accent text-accent-fg hover:bg-[color-mix(in_srgb,var(--accent-fg)_14%,var(--accent))] active:bg-[color-mix(in_srgb,var(--accent-fg)_24%,var(--accent))]";
|
||||
export const DANGER =
|
||||
"bg-danger text-danger-fg hover:bg-[color-mix(in_srgb,var(--danger-fg)_14%,var(--danger))] active:bg-[color-mix(in_srgb,var(--danger-fg)_24%,var(--danger))]";
|
||||
/** B3 state layers (index.css utilities). */
|
||||
export const LAYER = "state-layer";
|
||||
export const FILLED = "state-filled";
|
||||
export const DANGER = "state-danger";
|
||||
|
||||
/** B9: the header + fade edge — a crisp band and a 1rem gradient of the colour it sits on. Literal
|
||||
* strings per colour: Tailwind only generates classes it can read whole. */
|
||||
export const FADE_BELOW =
|
||||
"after:pointer-events-none after:absolute after:inset-x-0 after:top-full after:h-4 after:bg-[linear-gradient(to_bottom,var(--bg),transparent)] after:content-['']";
|
||||
export const FADE_BELOW_PANEL =
|
||||
"after:pointer-events-none after:absolute after:inset-x-0 after:top-full after:h-4 after:bg-[linear-gradient(to_bottom,var(--surface),transparent)] after:content-['']";
|
||||
export const FADE_ABOVE_PANEL =
|
||||
"before:pointer-events-none before:absolute before:inset-x-0 before:bottom-full before:h-4 before:bg-[linear-gradient(to_top,var(--surface),transparent)] before:content-['']";
|
||||
export const FADE_EDGES_X =
|
||||
"linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent)";
|
||||
/** B9: the header + fade edge (index.css utilities; the host is positioned). */
|
||||
export const FADE_BELOW = "fade-below";
|
||||
export const FADE_BELOW_PANEL = "fade-below-panel";
|
||||
export const FADE_ABOVE_PANEL = "fade-above-panel";
|
||||
|
||||
Reference in New Issue
Block a user