/* GENERATED from src/styles/tokens.css by scripts/help-build.mjs.
 * Never edit by hand: the deploy gate fails when this is stale.
 * It exists so a page we render on the edge can wear the same brand the console does. */
/* SiteLaunch brand tokens: the one place a color, a face or a distance is
   decided. Everything else reads from here or copies these values by name:
   home.css (the root domain), the Tailwind theme in index.css (the console),
   the email shell (supabase/functions/_shared/sl-brand.ts, since email cannot
   read CSS variables) and the kit bar (kit/customizer.css). BRAND.md explains
   each choice and carries the contrast table; src/test/brand.test.ts holds the
   copies in step with this file.

   THE FOUR THE BRAND IS
     mist    #EAEFEF   the paper
     gray    #BFC9D1   the quiet line
     slate   #25343F   the ink
     apricot #FF9B51   the one accent

   Everything else is derived from those four and certified against every
   ground it is allowed to sit on. Three rules the palette itself imposes, and
   none of them is a preference:

   1. THE APRICOT IS A FILL ON LIGHT, NEVER TEXT. At 1.80 against the paper it
      fails even the 3:1 large-text floor. It fills a button, draws a rule, and
      carries the SLATE on top of it at 6.13. Where the accent has to BE text
      on a light ground, that is --sl-apricot-deep.
   2. THE GRAY IS DECORATION. At 1.45 on the paper it cannot carry a word and
      cannot bound a control. --sl-field-line bounds controls; --sl-muted is
      the quietest rung allowed to hold text.
   3. ON THE DARK PLANE THE SEEDS DO THE WORK DIRECTLY: the mist reads at
      11.02, the gray at 7.61 and the apricot at 6.13 against the slate. This
      palette is least compromised on ink, which is why the console's rail and
      the marketing site both run there.

   TWO PLANES, ONE COMPONENT. The semantic block at the foot is the mechanism:
   wrap a region in .sl-ink or .sl-paper and everything inside switches, so a
   card written once sits on either without knowing which it is on. */
:root {
  /* ---- the four seeds, by name ---- */
  --sl-mist: #eaefef;
  --sl-gray: #bfc9d1;
  --sl-slate: #25343f;
  --sl-apricot: #ff9b51;

  /* ---- the light plane: grounds ---- */
  --sl-paper-0: #f4f7f7;
  --sl-paper: #eaefef;
  --sl-paper-2: #dee5e5;
  --sl-white: #ffffff;

  /* ---- lines and decoration. NON-TEXT, all of them: the number beside each
         is what it measures against the paper, and none clears 3. ---- */
  --sl-sand: #cfd8dc;       /* 1.25  the line between rows */
  --sl-stone: #bfc9d1;      /* 1.45  the seed, decoration only */
  --sl-paper-dim: #9aa6ad;  /* 2.15  a disabled mark on light */

  /* ---- a CONTROL's own edge. WCAG 1.4.11 asks 3:1 of the boundary of a thing
         you have to find and operate, which a grouping line does not meet.
         3.28 on the paper, 3.03 on the deepest ground. ---- */
  --sl-field-line: #7a8186;

  /* ---- the ink ladder. Every rung carries body text on every ground above:
         16.5 / 12.4 / 8.7 / 5.1 against the paper. ---- */
  --sl-ink: #25343f;
  --sl-ink-2: #1f2c36;
  --sl-graphite: #3a4750;
  --sl-muted: #5f6468;
  --sl-obsidian: #141d23;

  /* The ground behind anything modal. Named because four files write `bg-black/40` for
     this and the gate counts each one: black IS the color for a scrim, but a repeated
     literal is still the same decision typed five times. It carries its own alpha, so it
     is used bare as bg-sl-scrim, and it is the same in both planes on purpose, because a
     scrim that lightens in dark mode stops separating the dialog from the page. */
  --sl-scrim: rgb(0 0 0 / 0.45);

  /* ---- the dark plane: grounds from the same slate ---- */
  --sl-ink-0: #161f26;
  --sl-ink-1: #1c272f;
  --sl-ink-3: #33434f;

  /* ---- the apricot, in its jobs ---- */
  --sl-apricot-hover: #f08a3c;
  --sl-apricot-deep: #9e4a10;   /* the accent AS text on light: 4.78 worst */
  --sl-apricot-tint: #ffbd8c;   /* lifted, for quiet uses on ink */
  --sl-apricot-wash: #ffe9d9;   /* a tint behind a callout: ink on it 10.9 */

  /* status: text on paper, a wash behind it, and the lighter pair on ink */
  --sl-ok: #12705a;
  --sl-ok-tint: #dcefe9;
  --sl-ok-on-ink: #5fd3b4;
  --sl-warn: #8a5a00;
  --sl-warn-tint: #faeed6;
  --sl-warn-on-ink: #f0c470;
  --sl-bad: #b02418;
  --sl-bad-tint: #fbe3e0;
  --sl-bad-on-ink: #ff8f83;
  --sl-info: #1b5f86;
  --sl-info-tint: #e0edf5;
  --sl-info-on-ink: #8ac8e8;

  /* ---- the four meanings, each with its three roles ----------------------
   *
   * The VALUES above already existed and are already certified. What was
   * missing was the recipe: a meaning is not a color, it is three roles, and a
   * component that has to pick one of them by hand picks differently each time.
   *
   *   --success            the ink. Text, an icon, a border that carries it.
   *   --success-foreground what reads ON the solid fill.
   *   --success-surface    the tint a callout sits on.
   *
   * MEASURED, not chosen. Every pair below, against #eaefef paper and #25343f
   * ink, on 2026-09-09:
   *
   *              ink on paper   white on solid   slate on solid   ink on tint
   *   success        5.18            6.02             2.13           5.03
   *   warning        5.11            5.93             2.16           5.16
   *   danger         5.81            6.75             1.90           5.52
   *   info           5.98            6.94             1.84           5.81
   *
   * SO THE FOREGROUND IS WHITE, on all four, and slate would fail all four.
   * That is the OPPOSITE of the apricot rule two blocks up, where white is 2.09
   * and slate is required. Two accents, two answers, and the only way to know
   * which is to measure: this is exactly the pair of facts somebody guesses
   * wrong when they reach for --sl-on-accent because it worked last time.
   *
   * The tints sit at 1.01 to 1.05 against paper, so they are a HUE difference
   * and not a lightness one. That is fine for a callout and fatal for anything
   * that carries meaning by itself, which is why every Pill in this product
   * pairs its tint with a word.
   *
   * Deliberately NOT tied to the brand accent. Danger has to stay red when the
   * apricot changes, or a warning reads as decoration.
   */
  --success: var(--sl-ok);
  --success-foreground: #ffffff;
  --success-surface: var(--sl-ok-tint);

  --warning: var(--sl-warn);
  --warning-foreground: #ffffff;
  --warning-surface: var(--sl-warn-tint);

  --danger: var(--sl-bad);
  --danger-foreground: #ffffff;
  --danger-surface: var(--sl-bad-tint);

  --info: var(--sl-info);
  --info-foreground: #ffffff;
  --info-surface: var(--sl-info-tint);

  /* lines and shade, with alpha so they sit on any surface */
  --sl-line-on-paper: rgba(37, 52, 63, 0.16);
  --sl-line-on-ink: rgba(234, 239, 239, 0.18);
  --sl-shade: rgba(20, 29, 35, 0.55);

  /* the same colors as HSL triplets, for Tailwind's hsl(var()) colors that
     need alpha */
  --sl-hsl-paper-0: 180 16% 96%;
  --sl-hsl-paper: 180 14% 93%;
  --sl-hsl-paper-2: 180 12% 88%;
  --sl-hsl-sand: 198 16% 84%;
  --sl-hsl-stone: 207 16% 78%;
  --sl-hsl-field-line: 204 5% 50%;
  --sl-hsl-muted: 207 5% 39%;
  --sl-hsl-graphite: 205 16% 27%;
  --sl-hsl-ink-2: 206 27% 17%;
  --sl-hsl-ink: 205 26% 20%;
  --sl-hsl-obsidian: 204 27% 11%;
  --sl-hsl-ink-0: 206 27% 12%;
  --sl-hsl-ink-1: 205 25% 15%;
  --sl-hsl-slate: 205 26% 20%;
  --sl-hsl-apricot: 26 100% 66%;
  --sl-hsl-apricot-deep: 25 82% 34%;
  --sl-hsl-bad: 5 76% 39%;

  /* type */
  --sl-font-sans: "Albert Sans", "Inter", system-ui, -apple-system, sans-serif;
  --sl-font-serif: "Fraunces", "Georgia", "Times New Roman", serif;
  --sl-font-mark: "Archivo Black", "Albert Sans", sans-serif;
  --sl-font-mono: "JetBrains Mono", ui-monospace, Menlo, monospace;
  --sl-serif-soft: 60;
  --sl-track-eyebrow: 0.18em;
  --sl-track-display: -0.025em;

  /* The wordmark.

     THE NAME WAS SET THREE DIFFERENT WAYS. The console rail used the body face
     at semibold, the marketing mark used --sl-font-mark (Archivo Black) at
     19px, and both legal pages shouted SITELAUNCH in Archivo Black. Three
     faces, two weights and two capitalisations for one word, which reads as
     three brands rather than one.

     The face, the weight and the tracking are settled here and applied through
     .sl-wordmark below. SIZE IS NOT HERE ON PURPOSE: a rail, a hero and a
     footer legitimately want different sizes of the same mark, and pinning that
     centrally would only force every caller to override it back. */
  --sl-font-wordmark: var(--sl-font-sans);
  --sl-weight-wordmark: 600;
  --sl-track-wordmark: -0.02em;

  /* space, radius, shadow, motion */
  --sl-gutter: clamp(20px, 5vw, 72px);
  --sl-measure: 58ch;
  --sl-wrap: 1240px;
  --sl-radius-pill: 999px;
  --sl-radius-card: 6px;
  --sl-radius-field: 4px;
  --sl-shadow-card: 0 30px 60px rgba(20, 29, 35, 0.18);
  --sl-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --sl-dur-fast: 0.2s;
  --sl-dur-reveal: 0.9s;
  --sl-dur-photo: 1.8s;
}

/* semantic names, the same on paper and on ink, so a component written once
   sits on either: wrap a region in .sl-ink and everything inside switches.

   Note where the two planes differ and why. On PAPER the accent cannot carry
   a word, so --sl-accent-text is the deep burnt tone and the accent itself is
   only ever a fill. On INK the apricot reads at 6.13 and is the text color
   directly, which is the whole reason this palette prefers the dark plane. */
:root,
.sl-paper {
  --sl-surface: var(--sl-paper);
  --sl-surface-2: var(--sl-paper-2);
  --sl-surface-raised: var(--sl-white);
  --sl-text: var(--sl-ink);
  --sl-text-muted: var(--sl-muted);
  --sl-line: var(--sl-line-on-paper);
  --sl-accent: var(--sl-apricot);
  --sl-accent-text: var(--sl-apricot-deep);
  --sl-on-accent: var(--sl-slate);
  --sl-focus: var(--sl-apricot-deep);
}
/* The one way the name is set.
 *
 * text-transform is the belt and braces: the name is lowercase, and a caller
 * who types it any other way still renders it correctly rather than shipping a
 * fourth spelling. src/test/brand.test.ts catches the source; this catches the
 * pixels. Deliberately a plain class at 0,1,0 and not :where(), which
 * contributes zero specificity and is how the dark theme died. */
.sl-wordmark {
  font-family: var(--sl-font-wordmark);
  font-weight: var(--sl-weight-wordmark);
  letter-spacing: var(--sl-track-wordmark);
  text-transform: lowercase;
}

.sl-ink {
  --sl-surface: var(--sl-ink-1);
  --sl-surface-2: var(--sl-ink-0);
  --sl-surface-raised: var(--sl-ink-3);
  --sl-text: var(--sl-paper);
  --sl-text-muted: var(--sl-stone);
  --sl-line: var(--sl-line-on-ink);
  --sl-accent: var(--sl-apricot);
  --sl-accent-text: var(--sl-apricot);
  --sl-on-accent: var(--sl-slate);
  --sl-focus: var(--sl-apricot);
}

/* ── Fallbacks for the variables Radix sets at runtime ────────────────────
 *
 * shadcn's navigation-menu, select, toast and accordion size themselves from
 * `--radix-*` custom properties that Radix writes onto the ELEMENT while it
 * measures. Until that happens the property is undefined, and a class naming an
 * undefined custom property generates no rule at all: the element takes
 * whatever size it inherited and nothing errors.
 *
 * These are declared here as the value each one should degrade to before Radix
 * has measured. An inline style on the element beats `:root`, so Radix still
 * wins the moment it has a real number. Found by `npx @bigsteele/wiremap`,
 * which counts a token used but defined nowhere as a defect rather than an
 * unfinished migration, and is right to: it is shipping.
 */
:root {
  --radix-navigation-menu-viewport-height: auto;
  --radix-navigation-menu-viewport-width: auto;
  --radix-select-trigger-height: auto;
  --radix-select-trigger-width: auto;
  --radix-toast-swipe-end-x: 0px;
  --radix-toast-swipe-move-x: 0px;
  --radix-accordion-content-height: auto;
}

/* ---- the four meanings on the dark plane -------------------------------
 *
 * ONE RULE, TWO SELECTORS, because the dark plane is reached two ways: the
 * whole app under [data-theme='dark'], and the console rail under .sl-ink,
 * which is dark whatever the theme. Writing it twice is how one of them drifts.
 *
 * THE FOREGROUND FLIPS HERE, and this is the point of defining it at all. On
 * the light plane the fill is the deep color and white reads on it at 5.93 to
 * 6.94. On the dark plane the fill is the LIGHT color, and white on it is 1.64
 * to 2.21, which fails outright: obsidian is 7.73 to 10.44. A token defined
 * only in :root would have shipped white-on-mint at 1.83 and looked fine to
 * whoever wrote it on a light screen.
 *
 * Measured 2026-09-09, against #161f26 and #1c272f grounds:
 *
 *            ink on ground   obsidian on solid   ink on its surface
 *   success      9.11               9.32                5.97
 *   warning     10.20              10.44                6.54
 *   danger       7.56               7.73                5.23
 *   info         9.15               9.36                5.98
 *
 * The surface is DERIVED with color-mix rather than being a fifth hex to keep
 * in step by hand: a wash of the ink over the raised ground is what a tint is,
 * and deriving it means it cannot disagree with the ink it belongs to.
 *
 * NOT `:where(...)`, AND THAT ONE WORD COST THE WHOLE BLOCK. `:where()`
 * contributes ZERO specificity by definition, so this rule scored 0,0,0 while
 * the `:root` above scores 0,1,0. Both match the same `<html>` element once the
 * theme attribute is on it, so `:root` won every single declaration here and
 * every number measured in the table above has never painted. In dark mode
 * `--warning-surface` stayed `#faeed6`, a cream, under a near-white
 * `--foreground`: about 1.1 to 1, which is what a merchant reported as an
 * unreadable Publish banner.
 *
 * `.sl-ink` hid it. That selector matches a DESCENDANT, and a declaration on the
 * element itself beats one inherited from `:root` whatever the specificity, so
 * the rail painted correctly and only the pages were wrong. A fault that is
 * invisible in the one place everybody looks.
 *
 * `src/test/tokens-specificity.test.ts` now refuses any override of a `:root`
 * token that cannot outrank `:root`, which is the rule rather than the spelling.
 */
[data-theme='dark'], .sl-ink {
  --success: var(--sl-ok-on-ink);
  --success-foreground: var(--sl-obsidian);
  --success-surface: color-mix(in srgb, var(--sl-ok-on-ink) 15%, var(--sl-ink-1));

  --warning: var(--sl-warn-on-ink);
  --warning-foreground: var(--sl-obsidian);
  --warning-surface: color-mix(in srgb, var(--sl-warn-on-ink) 15%, var(--sl-ink-1));

  --danger: var(--sl-bad-on-ink);
  --danger-foreground: var(--sl-obsidian);
  --danger-surface: color-mix(in srgb, var(--sl-bad-on-ink) 15%, var(--sl-ink-1));

  --info: var(--sl-info-on-ink);
  --info-foreground: var(--sl-obsidian);
  --info-surface: color-mix(in srgb, var(--sl-info-on-ink) 15%, var(--sl-ink-1));
}
