/*
 * R01 — the design tokens. ONE definition, four properties.
 *
 * Before this file the "Soil & Sage" palette existed in four copies — the
 * website, the grower portal, the sales portal and the HR portal — and they had
 * already drifted:
 *
 *   • --sage-dark was #556047 in the grower portal and #637154 in the other two
 *   • the divider was --hair in one place and --hairline in three
 *   • muted text was --muted in one place and --ink-muted in three
 *   • --low and --info existed only in the grower portal
 *
 * That is what a copied palette always does. The values below started as the
 * website's, because that copy was the most carefully reasoned — it is the only
 * one that recorded measured contrast ratios next to its choices — extended with
 * the semantic tokens the staff portals need.
 *
 * ── SURFACES ARE NEUTRAL, THE BRAND IS NOT ───────────────────────────────────
 * Surfaces and inks are white and black; the greens and clays are untouched.
 * Editing this file re-themes all four properties at once — the point of R01, and
 * also how one edit could walk away from the brand. SOURCE OF TRUTH for the brand
 * hues is the Android app's theme (android-app/.../ui/theme/Color.kt, from
 * docs/ARCHITECTURE.md §3): the web must look like the same company, so those hex
 * values are copied, never re-picked. Surfaces and inks are the web's own
 * business; --sage, --clay and --status-* are not.
 *
 * TYPE is light by design — --weight-body 300, --weight-display 200 — which is why
 * --ink is black rather than a soft charcoal: a thin stroke loses apparent
 * contrast, so light weights need more tonal separation, not less.
 *
 * ── THE RULE THAT MATTERS ────────────────────────────────────────────────────
 * A brand hue and a legible text colour are NOT the same value. Sage #7c8b6a is
 * the brand green; as small text on these surfaces it measures under WCAG AA,
 * which is what the grower portal shipped before R01. So every status colour
 * appears twice:
 *
 *   --status-*        the brand hue. Decorative only — chart lines, dots,
 *                     borders, fills. Never small text.
 *   --status-*-ink    the darkened, hue-preserving variant that clears 4.5:1 on
 *                     all four surfaces with margin. Use this for text.
 *
 * Ratios below are MEASURED against beige / beige-alt / cream / cream-muted, not
 * estimated. scripts/ops/check-design-tokens.js re-measures them in CI, so a
 * future edit that dips under AA fails the build rather than shipping.
 */

:root {
  /* --- Surfaces ---
     Neutral white. The NAMES are kept because several hundred rules across four
     properties use them; they now mean "page" and "card", not literal beige.
     Steps chosen to preserve the old hierarchy, not merely to be white: measured
     page->card 1.101 (was 1.099), page->alt 1.105 (1.114), card->inset 1.130
     (1.139). All-#ffffff would flatten cards into the page, because this design
     separates surfaces with hairlines and tone rather than shadow. */
  --beige: #f4f4f2; /* page background */
  --beige-alt: #e9e9e6; /* alternating sections, scrims, header */
  --cream: #ffffff; /* cards / raised surfaces */
  --cream-muted: #f2f1ee; /* inset fields */

  /* --- Brand --- */
  --sage: #7c8b6a; /* primary — plant / health-good. DECORATIVE */
  --sage-dark: #637154; /* pressed / emphasis */
  --clay: #c08457; /* secondary — soil / warm accent */
  --clay-dark: #a96f45;

  /* --- Ink. See the type note in the header for why this is black. --- */
  --ink: #0a0a0a; /* primary text. 17.98 / 16.27 / 19.80 / 17.53 */
  /* Neutral grey, not the old warm #6a6358: that still cleared AA here, but a
     warm-brown caption on neutral white reads as a mistake, not a choice. */
  --ink-muted: #5a5a56; /* captions, hints. 6.29 / 5.69 / 6.93 / 6.13 */
  --hairline: #dededa; /* 1px outlines / dividers */

  /* Link colours, derived from sage/clay but darkened to clear AA as text.
     5.14 / 4.62 / 5.65 on beige / beige-alt / cream. An earlier value (#5c694e)
     computed as 4.51 on beige-alt but renders at 4.479 — under AA. */
  --link: #5a674c;
  --link-hover: #885938; /* clay-derived, 5.05 / 4.53 */

  /* --- Status: decorative hues (charts, dots, fills, borders) --- */
  --status-good: #7c8b6a;
  --status-low: #c9a227;
  --status-bad: #b4573b;
  --status-info: #5e7c8b;

  /* --- Status: text-safe inks. Measured, all four surfaces, AA with margin ---
     good 5.68 / 5.10 / 6.24 / 5.48   — the HR portal's in-use value, kept
     warn 5.57 / 5.00 / 6.13 / 5.38   — derived; the old #9a7a16 was 3.11–3.80
     bad  6.40 / 5.74 / 7.03 / 6.17   — the HR portal's in-use value, kept
     info 5.57 / 5.00 / 6.13 / 5.38   — derived; the old #5e7c8b was 3.39–4.16 */
  --status-good-ink: #556047;
  --status-warn-ink: #715b16;
  --status-bad-ink: #8f3a22;
  --status-info-ink: #49616c;

  /* --- Type --- */
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", "Noto Sans Devanagari", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Fluid scale. clamp() means one value serves a 320 px phone and a desktop,
     so there are no layout-shifting breakpoints on the type. */
  --step-display: clamp(2.25rem, 1.6rem + 3.2vw, 4rem);
  --step-h1: clamp(1.75rem, 1.35rem + 2vw, 2.75rem);
  --step-h2: clamp(1.35rem, 1.15rem + 1vw, 1.85rem);
  --step-h3: clamp(1.1rem, 1rem + 0.5vw, 1.3rem);
  --step-body: clamp(1rem, 0.97rem + 0.15vw, 1.075rem);
  --step-small: 0.875rem;
  --step-tiny: 0.78rem;

  --weight-display: 200; /* ExtraLight — matches app displayLarge */
  --weight-heading: 300; /* Light — matches app headline/title */
  --weight-body: 300; /* Light — matches app bodyLarge */
  --weight-ui: 400; /* Normal — labels, buttons, dense data */

  --tracking-display: 0.01em;
  --tracking-label: 0.06em; /* letter-spacing carries emphasis instead of bold */

  /* --- Space (8 px base, matching the app's Dimens) --- */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-6: 1.5rem;
  --s-8: 2rem;
  --s-12: 3rem;
  --s-16: 4rem;
  --s-24: 6rem;

  --radius: 14px; /* app cards are generously rounded */
  --radius-sm: 9px;
  --measure: 65ch; /* readable line length */
  --page-max: 1140px;

  /* Shadows stay almost invisible — the app separates surfaces with hairlines
     and tone, not elevation. */
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04), 0 8px 24px rgba(0, 0, 0, 0.05);

  /* Minimum interactive target. WCAG 2.2 AA (2.5.8) asks for 24px; the portals
     already used 44px and there is no reason to go backwards on a field device. */
  --tap: 44px;

  /* --- Tints and scrims (R07) ---
     Translucent fills used for selected states and dialog backdrops. They are
     tokens rather than literal rgba() because the alpha that reads correctly
     over a light surface disappears over a dark one — the grower portal had
     rgba(124,139,106,0.16) hard-coded in two places, which is invisible in dark
     mode. */
  --tint-sage: rgba(124, 139, 106, 0.16);
  --tint-bad: rgba(180, 87, 59, 0.10);
  --scrim: rgba(0, 0, 0, 0.42);

  /* ── Compatibility aliases ───────────────────────────────────────────────
     The three staff portals were written against shorter names. Aliasing here
     rather than rewriting several hundred rules across three stylesheets keeps
     the adoption diff small and reviewable. New code should prefer the
     canonical names above; these are not deprecated, just narrower. */
  --font: var(--font-sans);
  --mono: var(--font-mono);
  --hair: var(--hairline); /* grower portal's spelling */
  --muted: var(--ink-muted); /* grower portal's spelling */
  --good: var(--status-good-ink);
  --warn: var(--status-warn-ink);
  --bad: var(--status-bad-ink);
  --low: var(--status-low);
  --info: var(--status-info-ink);
}

/*
 * The dark counterpart, neutral to match. It was warm brown ("Night field") when
 * the light surfaces were warm beige; leaving it warm while the light theme went
 * white would make the two look like two different products. Brand hues are
 * untouched here as above — what changed is the paper, not the brand.
 *
 * Scoped to opt OUT rather than opt in, so the website keeps behaving exactly as
 * it does today. The staff portals set `data-theme="light-only"` on <html> until
 * R07 lands, because their stylesheets still carry light-only assumptions (the
 * enrolment QR on white, for one) and a half-converted dark mode is worse than
 * none. Removing that attribute is the last step of R07, not a side effect of
 * adopting these tokens.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light-only"]) {
    --beige: #101010;
    --beige-alt: #0a0a0a;
    --cream: #1b1b1b;
    --cream-muted: #242424;
    --sage: #9dac88;
    --sage-dark: #b3c0a1;
    --clay: #d59b71;
    --clay-dark: #e0ac87;
    --ink: #f2f2f2; /* 17.00 / 17.68 / 15.39 / 13.87 */
    --ink-muted: #a6a6a2; /* 7.79 / 8.11 / 7.05 / 6.36 */
    /* On the dark surfaces the app's own light tints already clear AA. */
    --link: #b3c0a1;
    --link-hover: #e0ac87;
    --hairline: #303030;
    --status-good: #9dac88;
    --status-low: #d8b85a;
    --status-bad: #d98a72;
    --status-info: #8fa9b6;
    /* Inks invert: on dark surfaces the LIGHT tint is the legible one. */
    --status-good-ink: #9dac88;
    --status-warn-ink: #d8b85a;
    --status-bad-ink: #d98a72;
    --status-info-ink: #8fa9b6;
    /* Tints lift rather than darken on a dark surface, and the scrim goes
       heavier because the dialog behind it is no longer bright. */
    --tint-sage: rgba(157, 172, 136, 0.22);
    --tint-bad: rgba(217, 138, 114, 0.16);
    --scrim: rgba(0, 0, 0, 0.62);
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.22);
  }
}
