/* ══════════════════════════════════════════════════════════════════════════
   animalsss — one palette, two themes, five colours to choose from.

   The site had grown four unrelated colour schemes: an amber-on-navy
   marketplace, a light-grey blog, seventy-six farm-manager screens that were
   dark by default and seventy that were light, and a community feed on its own
   warm greys. Nothing agreed, and "dark mode" was a navbar that turned navy
   while the page under it stayed white — because :root in marketplace.css held
   *light* values and the class named theme-light repainted the components,
   which is backwards.

   So this file is the only place a colour is given a *meaning*. Everything else
   in the codebase either already used a token or was rewritten to (see
   scripts/recolor_css.py), and every legacy token name — --amber, --bg-card,
   --cf-line, --mph-primary, --pf-page, --detail-surface, all 199 of them — is
   re-pointed here.

   ── Where the colours come from ──
   This file holds no hex of its own. The paint lives in palette.css, which is
   @generated by scripts/make_palette.py: five palettes (plum, orchid, berry,
   clay, ink), and each one emits a full light set (--l-*) and a full dark set
   (--d-*) whose every ratio the script *measures* before it will write the
   file. This file turns those into the named roles the components read —
   --primary is var(--l-primary) in light and var(--d-primary) in dark, and so
   on down — and adds nothing but the shapes, the shadows and the motion, which
   carry no hue.

   Pick the palette with `data-accent` on <html> (palette.css explains that end).
   The light block and the dark block below draw from the *same* palette, so one
   choice re-tints both themes at once — there is no second place to keep in
   step, which is the whole point of the split.

   ── Why html:root and not :root ──
   Eighty-seven farm templates open their own <style> with `:root{--bg:#0f172a}`
   inside {% block extra_css %}, which is *later in the document* than this
   file's <link>. A plain :root here would lose every one of those. `html:root`
   is a type selector plus a pseudo-class — specificity (0,1,1) against their
   (0,1,0) — so it wins on weight rather than on order, and none of those
   eighty-seven templates had to be touched.

   ── The theme switch ──
   `data-theme` on <html> is the state. The legacy `theme-light` class stays on
   it in light mode because ~460 rules in marketplace.css hang off it, and it is
   in the served markup so a browser with JavaScript off still gets the light
   theme rather than a half-painted dark one. The inline script in each shell
   flips both before first paint; see pages/jscript/theme-fx.js for the rest.

   Dark is not "light with the lightness inverted". Shadows do almost nothing on
   a dark ground, so depth there comes from a lighter surface plus a hairline
   border, and the accent gets brighter to hold its contrast against near-black.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── LIGHT (the default, and what a no-JS browser gets) ─────────────────── */
html:root,
html[data-theme="light"] {
  color-scheme: light;

  /* ── Brand ──
     One value has to serve as both a button fill with --primary-ink on it and
     as link text on a card, because that is how the existing CSS uses
     var(--amber). make_palette.py walks the accent ramp for the darkest step
     that still clears 4.5:1 as link text on the page and the surface, and
     --primary-ink is the label colour that clears 4.5:1 sitting on that fill;
     both are measured. The brighter steps are the gradient's top stop and the
     badge tints, never small text. */
  --primary:        var(--l-primary);
  --primary-strong: var(--l-primary-strong);
  --primary-bright: var(--l-primary-bright);
  --primary-soft:   var(--l-primary-soft);
  --primary-wash:   var(--l-primary-wash);
  /* The unfilled part of a meter — the ring on the profile cockpit, the track
     behind a bar. Not --primary-wash, which is a tint for a page and measures
     ~1.05:1 against a card: on light that track was a rumour, and on dark
     --primary-wash sits at 1.00:1 against --surface, so the ring rendered as an
     arc floating in nothing and there was no circle left to judge 20% against.
     A meter with no track is not a meter. make_palette.py scans for a track
     that reads against the card (>=1.15:1) and still lets the fill read against
     it (>=3:1), and measures both, so the meter carries the same weight in
     either theme. */
  --meter-track:    var(--l-meter-track);
  --primary-ink:    var(--l-primary-ink);    /* text that sits on --primary */
  --primary-rgb:    var(--l-primary-rgb);    /* for rgba(var(--primary-rgb),.12) */
  --primary-glow:   rgba(var(--l-primary-rgb),.16);
  /* The accent used as TEXT on an ordinary page surface — a badge label on
     --primary-soft, a "read more" link, a metric number in an --primary-glow
     chip. It is not --primary-bright, and the difference is the whole point:
     "bright" moves away from the ground in DARK (#e5af7b, 7.7:1 on
     --primary-soft) and toward it in LIGHT (#cb9b6c, 2.4:1 on white) because a
     tint ramp only has one direction. Every rule that reached for
     --primary-bright as a colour rather than a fill therefore read fine in dark
     and vanished in light — that is 20 rules in the health templates alone,
     which is what made /health/ the worst light-theme page on the site. So the
     polarity gets its own token: the accent as ink flips, the accent as fill
     does not.
     --l-primary-STRONG, not --l-primary. The dark side of this alias already
     stepped away from the fill (it takes --d-primary-bright); the light side did
     not, and --l-primary as ink measures 4.32 worst-case over the six neutral
     grounds plus --primary-soft across the nine palettes — under the 4.5 an alias
     literally named "ink" has to hold. --l-primary-strong is 6.05 on the same
     sweep. The fill role is unaffected: nothing named --accent-ink fills anything. */
  --accent-ink:     var(--l-primary-strong);

  /* ── Triplets, for the colours that get used with an alpha ──
     --primary-rgb was the only one of these for a long time, and the gap is why
     414 uses of a literal rgba() are still scattered through the templates: a
     frosted navbar, a hairline border at 30%, a danger wash at 10% all need a
     channel list rather than a colour, and without a token there was nothing to
     reach for. A hardcoded one cannot follow the theme — the health landing nav
     is rgba(10,15,26,.88), pre-redesign navy, in the light theme as much as the
     dark one.

     Only the colours that are actually used with alpha are listed. A triplet
     nobody composes with is a value to keep in step for no reason. */
  --header-rgb:  var(--l-header-rgb);
  --line-rgb:    var(--l-line-rgb);
  --surface-rgb: var(--l-surface-rgb);
  --ink-rgb:     var(--l-ink-rgb);
  --bad-rgb:     var(--l-bad-rgb);
  --ok-rgb:      var(--l-ok-rgb);
  --info-rgb:    var(--l-info-rgb);
  --warn-rgb:    var(--l-warn-rgb);
  /* Muted. There is a state between good/warn/bad that none of those describe —
     offline, private, unscheduled — and it was being drawn in slate-400 on three
     health badges, a grey borrowed from the pre-redesign palette that sat cold
     against everything around it. --dim is the muted the palette already uses for
     secondary text; this is its channels, so a 15% wash of "nothing to report"
     can follow the theme like the other four. */
  --dim-rgb:     var(--l-dim-rgb);

  /* ── The activity heatmap ramp ──
     Sequential, so one hue getting darker as the count rises — never a second
     hue, which would read as a different kind of thing rather than more of the
     same one.

     The steps are not the ramp's pale end. make_palette.py starts the scale at
     the first step that clears 2:1 against the card, because a filled cell under
     that floor looks identical to an empty one — and the single-post week, the
     most common non-empty value on the grid, is exactly that cell. Dark is
     stepped separately rather than flipped: on a dark card the scale has to run
     the other way, dim up to bright, and both directions are checked against
     their own surface. */
  --hm-0: var(--l-hm-0);      /* nothing posted — a track, not a value */
  --hm-1: var(--l-hm-1);      /* one thing */
  --hm-2: var(--l-hm-2);      /* two or three */
  --hm-3: var(--l-hm-3);      /* four or more */

  /* ── Ground and surfaces ──
     The page is a tint of the accent rather than white or grey: it is the whole
     point of the redesign, and it makes a plain card read as raised without a
     shadow doing all the work. */
  --page:      var(--l-page);
  --page-2:    var(--l-page-2);
  --surface:   var(--l-surface);
  --surface-2: var(--l-surface-2);
  --surface-3: var(--l-surface-3);
  --line:      var(--l-line);
  --line-2:    var(--l-line-2);

  --ink:    var(--l-ink);
  --ink-2:  var(--l-ink-2);
  --ink-3:  var(--l-ink-3);
  /* --dim aliases --ink-3 rather than the palette's --l-dim/--d-dim. Every use of
     --dim in this file is a muted-TEXT role (--text-muted, --muted, --cf-muted,
     --pf-muted, --mph-text-muted and the five per-page *-text-muted tokens), and
     the raw dim value is a tier too dark to read: --d-dim #8a8077 is 4.14:1 on
     --surface, under the 4.5 small-text floor before any opacity is applied on
     top of it. There is no room for a passing tier below --ink-3 when the ground
     can be --surface, so the bottom two tiers collapse into one. The raw
     --l-dim/--d-dim are still defined in palette.css for anything that genuinely
     wants a non-text grey. */
  --dim:    var(--l-ink-3);

  /* Header/footer ground. A deep tint of the accent rather than the old navy,
     so the nav belongs to the same family as everything under it. */
  --header:      var(--l-header);
  --header-ink:  var(--l-header-ink);
  --header-dim:  rgba(var(--l-header-ink-rgb),.70);

  /* ── Status ──
     Kept semantic and kept apart from the brand: success borrows a fixed green
     and carries an icon in the components, danger stays warm-red and warning
     amber, and the generator rotates danger/warning off the accent hue when a
     warm palette would collide with them (see make_palette.py, rotate_away).

     Each family has four steps, not two. `soft` is the wash behind an alert and
     `soft-2` is the same wash one shade deeper; `strong` is the pressed and hovered
     state, and it exists because without it a hover has nowhere to go — a danger
     button whose hover repeats --bad stops answering the pointer. `soft-2` is there
     for the same reason one level quieter: the pale buttons and the wash gradients
     hover and shade within the wash, and going to full --bad would turn a hint into
     an alarm. On a light page both deeper steps are darker, on a dark page both are
     brighter: in either theme, each is the more emphatic of its pair. */
  --ok:      var(--l-ok);
  --ok-soft: var(--l-ok-soft);
  --ok-soft-2: var(--l-ok-soft-2);
  --ok-strong: var(--l-ok-strong);
  --warn:      var(--l-warn);
  --warn-soft: var(--l-warn-soft);
  --warn-soft-2: var(--l-warn-soft-2);
  --warn-strong: var(--l-warn-strong);
  --bad:      var(--l-bad);
  --bad-soft: var(--l-bad-soft);
  --bad-soft-2: var(--l-bad-soft-2);
  --bad-strong: var(--l-bad-strong);
  --info:      var(--l-info);
  --info-soft: var(--l-info-soft);
  --info-soft-2: var(--l-info-soft-2);
  --info-strong: var(--l-info-strong);
  --link:      var(--l-link);
  --link-strong: var(--l-link-strong);

  /* ── Shape ── */
  --radius-xs: 8px;
  --radius-sm: 12px;
  --radius:    16px;
  --radius-lg: 22px;
  --radius-xl: 28px;
  --radius-pill: 999px;

  /* ── Depth ──
     Four steps, plus a top inset highlight. The tint is --l-shade-rgb — the
     palette's darkest step, a near-black *of the accent* rather than neutral
     black — so a lift on a coloured page keeps the family. The highlight is
     what actually makes a surface read as three-dimensional: light from above,
     shadow below. */
  --shade-rgb: var(--l-shade-rgb);
  --ring:  inset 0 1px 0 rgba(255,255,255,.85);
  --ring-2: inset 0 1px 0 rgba(255,255,255,.6), inset 0 -1px 0 rgba(var(--shade-rgb),.04);
  --e1: 0 1px 2px rgba(var(--shade-rgb),.05), 0 1px 3px rgba(var(--shade-rgb),.04);
  --e2: 0 2px 4px rgba(var(--shade-rgb),.05), 0 6px 16px rgba(var(--shade-rgb),.07);
  --e3: 0 4px 8px rgba(var(--shade-rgb),.06), 0 14px 32px rgba(var(--shade-rgb),.10);
  --e4: 0 10px 20px rgba(var(--shade-rgb),.08), 0 28px 64px rgba(var(--shade-rgb),.14);
  --e-press: inset 0 2px 6px rgba(var(--shade-rgb),.12);
  --e-glow:  0 10px 30px rgba(var(--l-primary-rgb),.22);

  /* ── Gradients ──
     Two stops, top lighter, a couple of ramp steps apart. Any more and it stops
     looking like a lit surface and starts looking like a 2014 web page. The
     accent stops come straight off the shared --a-* ramp, so they re-tint with
     the palette; the surface, header and page washes come from the light set.

     Except --grad-primary and --grad-primary-h, which carry TEXT. Those two used
     to open on --a-500 and --a-400, and --primary-ink is #ffffff in every light
     palette, so white sat on the 400/500 steps and measured 2.46-3.36:1 — a
     pixel audit found it on .mph-btn--primary, .mph-pop-price, .mph-card-badge,
     .mph-pop-ribbon, .mph-blog-tab, .mph-cat-name and every submit button on the
     site, because they all fill with one of these two tokens.
     --primary-lift and --primary-sink exist for exactly this: make_palette.py
     walks one step either side of --primary and KEEPS the step only if
     --primary-ink still clears 4.5 on it, then asserts both ends. In light that
     leaves lift == --primary (#846444 for brown; white cannot survive the 600
     step) and sink one darker, so the light button is a quieter gradient than it
     was. That is the price of a legible label, and the lit look is still there
     in dark, where the ink is near-black and the ramp can open on --a-300.
     Use the verified stops; do not go back to raw ramp steps. */
  --grad-primary: linear-gradient(180deg, var(--l-primary-lift) 0%, var(--l-primary-sink) 100%);
  --grad-primary-h: linear-gradient(135deg, var(--l-primary-lift) 0%, var(--l-primary) 55%, var(--l-primary-sink) 100%);
  --grad-surface: linear-gradient(180deg, var(--l-surface) 0%, var(--l-surface-2) 100%);
  --grad-header:  linear-gradient(180deg, var(--l-header-2) 0%, var(--l-header) 100%);
  --grad-page:    radial-gradient(1200px 520px at 12% -8%, var(--l-glow-1) 0%, transparent 60%),
                  radial-gradient(900px 420px at 92% 4%, var(--l-glow-2) 0%, transparent 55%);
  --grad-sheen:   linear-gradient(115deg, rgba(255,255,255,0) 30%, rgba(255,255,255,.55) 48%, rgba(255,255,255,0) 62%);

  /* ── Motion ──
     --t for anything the finger causes, --t-slow for anything the scroll
     causes, --spring for the one overshoot a press is allowed. */
  --t:      .2s cubic-bezier(.4,0,.2,1);
  --t-fast: .12s cubic-bezier(.4,0,.2,1);
  --t-slow: .45s cubic-bezier(.16,1,.3,1);
  --spring: cubic-bezier(.34,1.56,.64,1);
  --easing: cubic-bezier(.4,0,.2,1);

  --sidebar-width: 260px;
}

/* ── DARK ────────────────────────────────────────────────────────────────
   Same weight as the light selector above (one type + one attribute), so this
   wins by being second — and beats the legacy html.theme-light token block in
   marketplace.css for the same reason. Only the tokens that change with the
   theme are here; the shapes and motion inherit from the light block through
   html:root, which matches whatever the data-theme. */
html[data-theme="dark"] {
  color-scheme: dark;

  /* Brighter fill than light mode: on a near-black ground the light --primary
     reads as a hole rather than a button. make_palette.py takes the brighter
     step link text needs and puts the ramp's near-black on it for the label —
     white-on-fill and fill-on-near-black cannot both clear 4.5:1, so the ink is
     dark here, not white. */
  --primary:        var(--d-primary);
  --primary-strong: var(--d-primary-strong);
  --primary-bright: var(--d-primary-bright);
  --primary-soft:   var(--d-primary-soft);
  --primary-wash:   var(--d-primary-wash);
  --meter-track:    var(--d-meter-track);
  --primary-ink:    var(--d-primary-ink);
  --primary-rgb:    var(--d-primary-rgb);
  --primary-glow:   rgba(var(--d-primary-rgb),.20);
  --accent-ink:     var(--d-primary-bright);  /* see the --accent-ink note in the light block above */

  /* The dark half of the triplets. Every one of these has to be here or the
     colour it belongs to stops changing with the theme, which is the whole
     fault they were added to fix. */
  --header-rgb:  var(--d-header-rgb);
  --line-rgb:    var(--d-line-rgb);
  --surface-rgb: var(--d-surface-rgb);
  --ink-rgb:     var(--d-ink-rgb);
  --bad-rgb:     var(--d-bad-rgb);
  --ok-rgb:      var(--d-ok-rgb);
  --info-rgb:    var(--d-info-rgb);
  --warn-rgb:    var(--d-warn-rgb);
  --dim-rgb:     var(--d-dim-rgb);

  /* Brighter = more, because the card underneath is dark. Checked against this
     block's own surface, not inherited from the light one. */
  --hm-0: var(--d-hm-0);
  --hm-1: var(--d-hm-1);
  --hm-2: var(--d-hm-2);
  --hm-3: var(--d-hm-3);

  --page:      var(--d-page);
  --page-2:    var(--d-page-2);
  --surface:   var(--d-surface);
  --surface-2: var(--d-surface-2);
  --surface-3: var(--d-surface-3);
  --line:      var(--d-line);
  --line-2:    var(--d-line-2);

  --ink:    var(--d-ink);
  --ink-2:  var(--d-ink-2);
  --ink-3:  var(--d-ink-3);
  --dim:    var(--d-ink-3);   /* see the --dim note in the light block above */

  --header:     var(--d-header);
  --header-ink: var(--d-header-ink);
  --header-dim: rgba(var(--d-header-ink-rgb),.68);

  /* Strong goes *brighter* here, not darker — on a dark ground, emphasis is
     light. Same names, opposite direction, so a component asking for
     --bad-strong on hover is right in both themes without a media query. */
  --ok:      var(--d-ok);
  --ok-soft: var(--d-ok-soft);
  --ok-soft-2: var(--d-ok-soft-2);
  --ok-strong: var(--d-ok-strong);
  --warn:      var(--d-warn);
  --warn-soft: var(--d-warn-soft);
  --warn-soft-2: var(--d-warn-soft-2);
  --warn-strong: var(--d-warn-strong);
  --bad:      var(--d-bad);
  --bad-soft: var(--d-bad-soft);
  --bad-soft-2: var(--d-bad-soft-2);
  --bad-strong: var(--d-bad-strong);
  --info:      var(--d-info);
  --info-soft: var(--d-info-soft);
  --info-soft-2: var(--d-info-soft-2);
  --info-strong: var(--d-info-strong);
  --link:      var(--d-link);
  --link-strong: var(--d-link-strong);

  /* Depth on a dark ground: the shadow is still there for the lift but it is
     the hairline border and the lighter surface that do the reading. The top
     inset highlight drops to 6% — at light-mode strength it looks like a
     scratch on the glass. --d-shade-rgb is near-pure black, so these read as
     ordinary dark-mode shadows. */
  --shade-rgb: var(--d-shade-rgb);
  --ring:   inset 0 1px 0 rgba(255,255,255,.06);
  --ring-2: inset 0 1px 0 rgba(255,255,255,.05), inset 0 -1px 0 rgba(var(--shade-rgb),.35);
  --e1: 0 1px 2px rgba(var(--shade-rgb),.5);
  --e2: 0 2px 6px rgba(var(--shade-rgb),.45), 0 8px 20px rgba(var(--shade-rgb),.4);
  --e3: 0 6px 14px rgba(var(--shade-rgb),.5), 0 18px 40px rgba(var(--shade-rgb),.45);
  --e4: 0 12px 28px rgba(var(--shade-rgb),.55), 0 34px 70px rgba(var(--shade-rgb),.5);
  --e-press: inset 0 2px 8px rgba(var(--shade-rgb),.5);
  --e-glow:  0 10px 34px rgba(var(--d-primary-rgb),.35);

  --grad-primary: linear-gradient(180deg, var(--a-400) 0%, var(--a-600) 100%);
  --grad-primary-h: linear-gradient(135deg, var(--a-300) 0%, var(--a-500) 55%, var(--a-600) 100%);
  --grad-surface: linear-gradient(180deg, var(--d-surface-2) 0%, var(--d-surface) 100%);
  --grad-header:  linear-gradient(180deg, var(--d-header-2) 0%, var(--d-header) 100%);
  --grad-page:    radial-gradient(1100px 520px at 10% -10%, var(--d-glow-1) 0%, transparent 62%),
                  radial-gradient(900px 420px at 94% 2%, var(--d-glow-2) 0%, transparent 55%);
  --grad-sheen:   linear-gradient(115deg, rgba(255,255,255,0) 30%, rgba(255,255,255,.10) 48%, rgba(255,255,255,0) 62%);
}

/* The OS preference decides only when the visitor has not: the pre-paint
   script writes data-theme="light" the moment they pick, and that attribute is
   what this guard checks for. Without the guard, choosing light on a
   dark-set phone would fight the media query forever.

   This block must stay a mirror of the dark block above — same tokens, same
   right-hand sides — or an OS-dark visitor and a click-dark visitor would see
   two different sites. scripts/check_palette.py asserts the two are identical. */
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]):not(.theme-light) {
    color-scheme: dark;
    --primary:        var(--d-primary);
    --primary-strong: var(--d-primary-strong);
    --primary-bright: var(--d-primary-bright);
    --primary-soft:   var(--d-primary-soft);
    --primary-wash:   var(--d-primary-wash);
    --meter-track:    var(--d-meter-track);
    --primary-ink:    var(--d-primary-ink);
    --primary-rgb:    var(--d-primary-rgb);
    --primary-glow:   rgba(var(--d-primary-rgb),.20);
    --accent-ink:     var(--d-primary-bright);  /* see the --accent-ink note in the light block above */
    --header-rgb:  var(--d-header-rgb);
    --line-rgb:    var(--d-line-rgb);
    --surface-rgb: var(--d-surface-rgb);
    --ink-rgb:     var(--d-ink-rgb);
    --bad-rgb:     var(--d-bad-rgb);
    --ok-rgb:      var(--d-ok-rgb);
    --info-rgb:    var(--d-info-rgb);
    --warn-rgb:    var(--d-warn-rgb);
    --dim-rgb:     var(--d-dim-rgb);
    --hm-0: var(--d-hm-0);
    --hm-1: var(--d-hm-1);
    --hm-2: var(--d-hm-2);
    --hm-3: var(--d-hm-3);
    --page:      var(--d-page);
    --page-2:    var(--d-page-2);
    --surface:   var(--d-surface);
    --surface-2: var(--d-surface-2);
    --surface-3: var(--d-surface-3);
    --line:      var(--d-line);
    --line-2:    var(--d-line-2);
    --ink:    var(--d-ink);
    --ink-2:  var(--d-ink-2);
    --ink-3:  var(--d-ink-3);
    --dim:    var(--d-ink-3);   /* see the --dim note in the light block above */
    --header:     var(--d-header);
    --header-ink: var(--d-header-ink);
    --header-dim: rgba(var(--d-header-ink-rgb),.68);
    --ok:      var(--d-ok);
    --ok-soft: var(--d-ok-soft);
    --ok-soft-2: var(--d-ok-soft-2);
    --ok-strong: var(--d-ok-strong);
    --warn:      var(--d-warn);
    --warn-soft: var(--d-warn-soft);
    --warn-soft-2: var(--d-warn-soft-2);
    --warn-strong: var(--d-warn-strong);
    --bad:      var(--d-bad);
    --bad-soft: var(--d-bad-soft);
    --bad-soft-2: var(--d-bad-soft-2);
    --bad-strong: var(--d-bad-strong);
    --info:      var(--d-info);
    --info-soft: var(--d-info-soft);
    --info-soft-2: var(--d-info-soft-2);
    --info-strong: var(--d-info-strong);
    --link:      var(--d-link);
    --link-strong: var(--d-link-strong);
    --shade-rgb: var(--d-shade-rgb);
    --ring:   inset 0 1px 0 rgba(255,255,255,.06);
    --ring-2: inset 0 1px 0 rgba(255,255,255,.05), inset 0 -1px 0 rgba(var(--shade-rgb),.35);
    --e1: 0 1px 2px rgba(var(--shade-rgb),.5);
    --e2: 0 2px 6px rgba(var(--shade-rgb),.45), 0 8px 20px rgba(var(--shade-rgb),.4);
    --e3: 0 6px 14px rgba(var(--shade-rgb),.5), 0 18px 40px rgba(var(--shade-rgb),.45);
    --e4: 0 12px 28px rgba(var(--shade-rgb),.55), 0 34px 70px rgba(var(--shade-rgb),.5);
    --e-press: inset 0 2px 8px rgba(var(--shade-rgb),.5);
    --e-glow:  0 10px 34px rgba(var(--d-primary-rgb),.35);
    --grad-primary: linear-gradient(180deg, var(--a-400) 0%, var(--a-600) 100%);
    --grad-primary-h: linear-gradient(135deg, var(--a-300) 0%, var(--a-500) 55%, var(--a-600) 100%);
    --grad-surface: linear-gradient(180deg, var(--d-surface-2) 0%, var(--d-surface) 100%);
    --grad-header:  linear-gradient(180deg, var(--d-header-2) 0%, var(--d-header) 100%);
    --grad-page:    radial-gradient(1100px 520px at 10% -10%, var(--d-glow-1) 0%, transparent 62%),
                    radial-gradient(900px 420px at 94% 2%, var(--d-glow-2) 0%, transparent 55%);
    --grad-sheen:   linear-gradient(115deg, rgba(255,255,255,0) 30%, rgba(255,255,255,.10) 48%, rgba(255,255,255,0) 62%);
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   LEGACY TOKEN NAMES
   Every custom property the codebase already reads, pointed at the roles
   above. This is the whole reason a four-scheme site can change colour in one
   file: --amber is read by 144 farm templates, --bg-card by 165, --cf-line by
   the community feed, --mph-primary by the 56KB marketplace home stylesheet.
   None of them had to learn a new name.
   ══════════════════════════════════════════════════════════════════════════ */
html:root,
html[data-theme="light"],
html[data-theme="dark"] {
  /* the eleven-step accent ramp under its old name. It is theme-independent —
     the same eleven --a-* steps in light and dark — because 39 gradients across
     the farm, marketplace and mandi sheets still read --g-200 / --g-800 / --g-900
     directly, and a gradient stop does not want to move when the theme flips. */
  --g-50:  var(--a-50);
  --g-100: var(--a-100);
  --g-200: var(--a-200);
  --g-300: var(--a-300);
  --g-400: var(--a-400);
  --g-500: var(--a-500);
  --g-600: var(--a-600);
  --g-700: var(--a-700);
  --g-800: var(--a-800);
  --g-900: var(--a-900);
  --g-950: var(--a-950);

  /* the amber that was the site's accent — now the brand accent */
  --amber:        var(--primary);
  --amber-light:  var(--primary-bright);
  --amber-glow:   var(--primary-glow);
  --accent:       var(--primary);
  --accent-light: var(--primary-bright);
  --accent-strong: var(--primary-strong);
  --accent-hover: var(--primary-strong);
  --accent-glow:  var(--primary-glow);
  --accent2:      var(--primary-strong);
  --brand:        var(--primary);
  --brand-dark:   var(--primary-strong);
  --brand-light:  var(--primary-soft);
  --brand-gradient: var(--grad-primary);
  --primary-light: var(--primary-soft);
  --primary-dark:  var(--primary-strong);

  /* grounds */
  --bg:            var(--page);
  --bg-dark:       var(--page-2);
  --bg-primary:    var(--page);
  --bg-secondary:  var(--page-2);
  --bg-card:       var(--surface);
  --bg-card-hover: var(--surface-2);
  --surface2:      var(--surface-2);
  --border:        var(--line);
  --border-light:  var(--line);

  /* type */
  --text:           var(--ink);
  --text2:          var(--ink-2);
  --text-primary:   var(--ink);
  --text-secondary: var(--ink-2);
  --text-muted:     var(--dim);
  --text-dim:       var(--dim);
  --muted:          var(--dim);

  /* status, and the named hues the farm screens use for chart series and
     category chips. They keep their identity — a blue is still a blue — but
     they are the one blue, not nine. */
  --green:       var(--ok);
  --green-light: var(--ok-soft);
  --green-glow:  var(--primary-glow);
  --success:     var(--ok);
  --red:       var(--bad);
  --red-light: var(--bad-soft);
  --red-glow:  rgba(var(--bad-rgb),.18);
  --danger:    var(--bad);
  --rose:      var(--bad);
  --rose-glow: rgba(var(--bad-rgb),.18);
  --orange:  var(--warn);
  --warning: var(--warn);
  --yellow:       var(--warn);
  --yellow-light: var(--warn-soft);
  --blue:       var(--info);
  --blue-light: var(--info-soft);
  --blue-glow:  rgba(var(--info-rgb),.18);
  --teal:       var(--info);
  --teal-light: var(--info-soft);
  --teal-glow:  rgba(var(--info-rgb),.18);
  --purple:       var(--primary-strong);
  --purple-light: var(--primary-soft);
  --purple-glow:  var(--primary-glow);

  /* shape and depth under their old names */
  --radius:    16px;
  --radius-sm: 12px;
  --radius-lg: 22px;
  --radius-xl: 28px;
  --shadow:       var(--e2);
  --shadow-sm:    var(--e1);
  --shadow-lg:    var(--e3);
  --shadow-hover: var(--e3);
  --transition: var(--t);
  --t: .2s cubic-bezier(.4,0,.2,1);
  --w: 1200px;

  /* the community feed */
  --cf-page:    var(--page);
  --cf-surface: var(--surface);
  --cf-line:    var(--line);
  --cf-ink:     var(--ink);
  --cf-ink-2:   var(--ink-2);
  --cf-muted:   var(--dim);
  --cf-accent:  var(--primary);
  --cf-blue:    var(--info);
  --cf-like:    var(--bad);
  --cf-ok:      var(--ok);

  /* the account area */
  --pf-page:      var(--page);
  --pf-surface:   var(--surface);
  --pf-line:      var(--line);
  --pf-ink:       var(--ink);
  --pf-ink-2:     var(--ink-2);
  --pf-muted:     var(--dim);
  --pf-accent:    var(--primary);
  --pf-accent-dark: var(--primary-strong);
  --pf-accent-soft: var(--primary-soft);
  --pf-blue:      var(--info);
  --pf-like:      var(--bad);
  --pf-good:      var(--ok);
  --pf-good-soft: var(--ok-soft);
  --pf-warn:      var(--warn);
  --pf-warn-soft: var(--warn-soft);
  --pf-bad:       var(--bad);
  --pf-bad-soft:  var(--bad-soft);

  /* the marketplace home page */
  --mph-primary:       var(--primary);
  --mph-primary-hover: var(--primary-strong);
  --mph-primary-light: var(--primary-soft);
  --mph-primary-glow:  var(--primary-glow);
  --mph-accent:        var(--primary-bright);
  --mph-accent-light:  var(--primary-soft);
  --mph-surface:       var(--surface);
  --mph-surface-card:  var(--surface);
  --mph-surface-hover: var(--surface-2);
  --mph-bg-subtle:     var(--page-2);
  --mph-bg-stats:      var(--surface-2);
  --mph-bg-glass:      color-mix(in srgb, var(--surface) 72%, transparent);
  --mph-bg-glass-hover: color-mix(in srgb, var(--surface) 86%, transparent);
  --mph-badge-bg:      var(--primary-soft);
  --mph-cta-badge-bg:  var(--primary-soft);
  --mph-border:        var(--line);
  --mph-border-light:  var(--line);
  --mph-grid-line:     var(--line);
  --mph-text:          var(--ink);
  --mph-text-secondary: var(--ink-2);
  --mph-text-muted:    var(--dim);
  /* the scrim over a hero photo — a dark tint of the palette, dark in both
     themes so white caption text keeps its contrast on top of any image */
  --mph-overlay:       rgba(var(--shade-rgb),.45);
  --mph-overlay-dark:  rgba(var(--shade-rgb),.70);
  --mph-overlay-gradient: linear-gradient(180deg, rgba(var(--shade-rgb),0) 0%, rgba(var(--shade-rgb),.72) 100%);
  --mph-gradient-1:    var(--grad-primary-h);
  --mph-gradient-2:    var(--grad-primary);
  --mph-gradient-card: var(--grad-surface);
  --mph-gradient-dark: var(--grad-header);
  --mph-shadow-sm:     var(--e1);
  --mph-shadow-md:     var(--e2);
  --mph-shadow-lg:     var(--e3);
  --mph-shadow-glow:   var(--e-glow);
  --mph-radius-sm:     var(--radius-xs);
  --mph-radius-md:     var(--radius-sm);
  --mph-radius-lg:     var(--radius);
  --mph-radius-xl:     var(--radius-lg);
  --mph-radius-full:   var(--radius-pill);
  --mph-transition:      var(--t);
  --mph-transition-fast: var(--t-fast);
  --mph-container:   1200px;
  --mph-section-gap: 64px;

  /* market rates */
  --mandi-primary:       var(--primary);
  --mandi-primary-dark:  var(--primary-strong);
  --mandi-primary-light: var(--primary-soft);
  --mandi-green:         var(--ok);
  --mandi-green-light:   var(--ok-soft);
  --mandi-red:           var(--bad);
  --mandi-red-light:     var(--bad-soft);
  --mandi-blue:          var(--info);
  --mandi-blue-light:    var(--info-soft);
  --mandi-radius:        var(--radius-sm);
  --mandi-shadow:        var(--e2);
  --mandi-shadow-hover:  var(--e3);
  --mandi-transition:    var(--t);
  --mandi-max-width:     1200px;

  /* the four one-off families: listing detail, delete confirms, the forms and
     the tips pages each shipped with their own five-token set */
  --detail-bg: var(--page); --detail-surface: var(--surface);
  --detail-text: var(--ink); --detail-text-muted: var(--dim);
  --detail-border: var(--line); --detail-primary: var(--primary);
  --detail-primary-light: var(--primary-soft);
  --detail-radius: var(--radius); --detail-radius-sm: var(--radius-sm);
  --detail-shadow: var(--e2); --detail-shadow-lg: var(--e3);
  --detail-transition: var(--t);
  --del-bg: var(--page); --del-surface: var(--surface);
  --del-text: var(--ink); --del-text-muted: var(--dim);
  --del-border: var(--line); --del-primary: var(--primary);
  --del-radius: var(--radius); --del-radius-sm: var(--radius-sm);
  --del-transition: var(--t);
  --form-bg: var(--page); --form-surface: var(--surface);
  --form-text: var(--ink); --form-text-muted: var(--dim);
  --form-border: var(--line); --form-primary: var(--primary);
  --form-primary-light: var(--primary-soft);
  --form-radius: var(--radius); --form-radius-sm: var(--radius-sm);
  --form-transition: var(--t);
  --tips-bg: var(--page); --tips-surface: var(--surface);
  --tips-text: var(--ink); --tips-text-muted: var(--dim);
  --tips-border: var(--line); --tips-primary: var(--primary);
  --tips-primary-light: var(--primary-soft);
  --tips-radius: var(--radius); --tips-radius-sm: var(--radius-sm);
  --tips-shadow: var(--e2); --tips-shadow-lg: var(--e3);
  --tips-transition: var(--t);
}

/* ══════════════════════════════════════════════════════════════════════════
   THE GROUND
   Set on both html and body: the old sheets paint one or the other, and a
   half-painted background is how you get a white band under a dark footer.
   ══════════════════════════════════════════════════════════════════════════ */
html { background: var(--page); }
body {
  background-color: var(--page);
  background-image: var(--grad-page);
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--ink);
  /* Both shells fought over the font stack — Inter here, -apple-system in the
     inline styles, Poppins in the farm screens. One stack, and it starts with
     what the device already has so nothing waits on a webfont. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Selection and focus in the brand colour rather than the browser's blue. */
::selection { background: var(--primary-soft); color: var(--ink); }
:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Scrollbars, so a dark page does not come with a light-grey gutter. */
* { scrollbar-color: var(--line-2) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line-2);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--primary); background-clip: content-box; }
