/** * The design tokens (milestone 23, ruling 2). * * Values are the Tailwind 4 zinc/blue/red ramps the app rendered before the * StyleX conversion, carried over verbatim so the palette does not shift. * Each token holds its dark value under `prefers-color-scheme: dark` — the * same media strategy Tailwind 4 defaulted to. There is no theme toggle and * no `data-theme` attribute; the scheme follows the operating system. * * Name tokens by role, never by shade: a call site asks for `border`, not for * zinc-200. */ import * as stylex from "@stylexjs/stylex"; const DARK = "@media (prefers-color-scheme: dark)"; export const colors = stylex.defineVars({ /** The page ground. */ surface: { default: "oklch(98.5% 0 none)", [DARK]: "oklch(14.1% 0.005 285.823)" }, /** Cards, dialogs and inputs sitting on top of the ground. */ surfaceRaised: { default: "#fff", [DARK]: "oklch(21% 0.006 285.885)" }, /** The fill under a pointer on a nav item or a menu row. */ surfaceHover: { default: "oklch(96.7% 0.001 286.375)", [DARK]: "oklch(27.4% 0.006 286.033)" }, /** Hairlines between rows and around cards. */ border: { default: "oklch(92% 0.004 286.32)", [DARK]: "oklch(27.4% 0.006 286.033)" }, /** Control outlines, which need more contrast than a row divider. */ borderStrong: { default: "oklch(87.1% 0.006 286.286)", [DARK]: "oklch(37% 0.013 285.805)" }, text: { default: "oklch(21% 0.006 285.885)", [DARK]: "oklch(96.7% 0.001 286.375)" }, /** * Secondary text. Most call sites were a flat zinc-500 before the conversion, * with no dark override, which measured 4.12:1 on the dark ground and so * failed WCAG AA; the dark value here is zinc-400, which measures 7.56:1. */ textMuted: { default: "oklch(55.2% 0.016 285.938)", [DARK]: "oklch(70.5% 0.015 286.067)" }, /** * Secondary text that already adapted before the conversion: zinc-600 on the * light ground, zinc-400 on the dark one. It is a separate token because * `textMuted`'s lighter light value measures 4.62:1 against 7.40:1 here, and * these call sites are small text — table headers, an inactive nav item, a * chart legend — where that loss shows. */ textSecondary: { default: "oklch(44.2% 0.017 285.786)", [DARK]: "oklch(70.5% 0.015 286.067)" }, /** * The accent (ui-visual-redesign.md): blue at hue 258 for nav, links, primary * actions and the total-queries series. Identical in both schemes. */ primary: { default: "oklch(55% 0.16 258)", [DARK]: "oklch(55% 0.16 258)" }, primaryText: { default: "#fff", [DARK]: "#fff" }, /** * Primary as foreground text. Darker than `primary` in light because the * active nav label sits on `primarySurface`, where the accent itself * measures 4.39:1; this value measures 5.43:1 there. Lightened in dark so it * clears the ground (5.87:1 on its wash). */ primaryOnSurface: { default: "oklch(50% 0.16 258)", [DARK]: "oklch(72% 0.13 258)" }, /** The accent as a wash: the active nav item's fill. */ primarySurface: { default: "oklch(96% 0.02 258)", [DARK]: "oklch(28% 0.05 258)" }, /** * Warnings: a degraded condition the operator can still act on, as against * `danger`, which is a failure or a destructive action. The amber ramp. */ warnSurface: { default: "oklch(98.7% 0.022 95.277)", [DARK]: "oklch(27.9% 0.077 45.635)" }, warnBorder: { default: "oklch(87.9% 0.169 91.605)", [DARK]: "oklch(47.3% 0.137 46.201)" }, /** A control's outline inside a warning banner, which the banner border would swallow. */ warnBorderStrong: { default: "oklch(82.8% 0.189 84.429)", [DARK]: "oklch(55.5% 0.163 48.998)" }, warnText: { default: "oklch(41.4% 0.112 45.904)", [DARK]: "oklch(96.2% 0.059 95.617)" }, danger: { default: "oklch(57.7% 0.245 27.325)", [DARK]: "oklch(70.4% 0.191 22.216)" }, dangerSurface: { default: "oklch(97.1% 0.013 17.38)", [DARK]: "oklch(25.8% 0.092 26.042)" }, dangerBorder: { default: "oklch(80.8% 0.114 19.571)", [DARK]: "oklch(44.4% 0.177 26.899)" }, dangerText: { default: "oklch(44.4% 0.177 26.899)", [DARK]: "oklch(88.5% 0.062 18.334)" }, /** * The softer red the charts and the blocked stat numeral wear: 3.54:1 on * white, which clears the 3:1 floor for non-text and large text and nothing * else. Small text keeps `dangerText`. */ chartRed: { default: "oklch(65% 0.19 25)", [DARK]: "oklch(65% 0.19 25)" }, /** Cache and success: fixed semantics, never derived from the accent. */ chartGreen: { default: "oklch(62% 0.14 150)", [DARK]: "oklch(62% 0.14 150)" }, chartGreenSurface: { default: "oklch(93% 0.05 150)", [DARK]: "oklch(30% 0.06 150)" }, /** * The categorical series palette (ui-visual-redesign.md): eight hues spread * round the wheel, clear of the reserved red at hue 25, the same in both * schemes. `seriesOther` is the aggregated tail, a flat gray that never * competes with a named client. SVG attributes take these vars directly. */ seriesBlue: { default: "oklch(60% 0.14 258)", [DARK]: "oklch(60% 0.14 258)" }, seriesTeal: { default: "oklch(68% 0.12 190)", [DARK]: "oklch(68% 0.12 190)" }, seriesViolet: { default: "oklch(62% 0.15 300)", [DARK]: "oklch(62% 0.15 300)" }, seriesAmber: { default: "oklch(75% 0.13 80)", [DARK]: "oklch(75% 0.13 80)" }, seriesGreen: { default: "oklch(65% 0.13 150)", [DARK]: "oklch(65% 0.13 150)" }, seriesMagenta: { default: "oklch(66% 0.14 340)", [DARK]: "oklch(66% 0.14 340)" }, seriesOrange: { default: "oklch(70% 0.14 55)", [DARK]: "oklch(70% 0.14 55)" }, seriesOlive: { default: "oklch(72% 0.11 120)", [DARK]: "oklch(72% 0.11 120)" }, seriesOther: { default: "oklch(80% 0.01 260)", [DARK]: "oklch(80% 0.01 260)" }, /** * The query-types ring: the accent's hue stepped in lightness and chroma from * the busiest type outward. Six steps cover every ring the API answers with * in practice; in dark the ramp runs the other way so the busiest stays the * most saturated against the ground. */ ramp1: { default: "oklch(55% 0.15 258)", [DARK]: "oklch(72% 0.14 258)" }, ramp2: { default: "oklch(63% 0.13 258)", [DARK]: "oklch(64% 0.12 258)" }, ramp3: { default: "oklch(71% 0.10 258)", [DARK]: "oklch(56% 0.10 258)" }, ramp4: { default: "oklch(78% 0.075 258)", [DARK]: "oklch(48% 0.08 258)" }, ramp5: { default: "oklch(85% 0.05 258)", [DARK]: "oklch(41% 0.06 258)" }, ramp6: { default: "oklch(91% 0.035 258)", [DARK]: "oklch(35% 0.04 258)" }, /** The focus ring colour. The ring itself is a floor, not a variant. */ focus: { default: "oklch(55% 0.16 258)", [DARK]: "oklch(55% 0.16 258)" }, }); /** * The stacking order. Three layers is the whole app: a chart tooltip floats * over its own panel, a dialog overlay covers the page, and a confirmation sits * over the dialog that opened it. Values are strings because a StyleX var holds * a CSS token, not a number. */ export const layers = stylex.defineVars({ tooltip: "10", overlay: "50", confirm: "60", }); /** * Values that are shared but are not theme: they never vary by colour scheme, * and they are the same number wherever they appear. * * `defineConsts` rather than a plain exported constant, and in this module * rather than in `ui/styles`, because of how the compiler reads a * `stylex.create` body. A constant imported from an ordinary module is rejected * outright, and a plain export from a `.stylex.ts` module is read as a variable * object rather than a literal — so neither can be shared. `defineConsts` is * the one mechanism that inlines a literal across module boundaries, which is * why these are strings with their units baked in. */ export const metrics = stylex.defineConsts({ /** WCAG 2.5.5's enhanced 44px target, applied where layout permits; some inline controls stop at 40px or above 2.5.8's 24px minimum. */ hitTarget: "44px", /** One corner radius for every surface: cards, controls, tooltips, nav items. */ radius: "4px", /** The inset of a card's content from its border. */ cardPadding: "1.75rem", /** The press and hover settle shared by every control that styles its own states. */ transitionProperty: "background-color, color, border-color, transform", transitionDuration: "120ms", });