/* ===========================================================================
   Hedge — the deck.
   ===========================================================================

   A night-shift instrument deck, not a dark-mode website. The farm this system
   was written on is read at four in the morning: weights, counts, feed issues,
   a mortality board. That hour is the palette.

   Two accents, both carrying meaning, because one decorative accent on
   near-black is the house style of every generated "futuristic" page:
     brass    — the institution. Headings, rules, the brand.
     phosphor — live telemetry, and nothing else. If it glows, it is a reading.

   The display face stays Fraunces. A high-contrast serif over glass reads
   institutional rather than start-up, which is the correct register for a
   ledger a bank has to accept.

   CSP NOTE: style-src is 'self' with no 'unsafe-inline'. Nothing in this site
   may use a <style> block or a style="" attribute. Per-element colour is
   resolved through [data-sp] custom-property inheritance instead — see
   "species" below.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. Tokens
   --------------------------------------------------------------------------- */

:root {
  /* Base. Never pure black — these keep chlorophyll in them, which is what
     stops the page reading as a generic tech template. */
  --void:   #04100C;
  --deep:   #071913;
  --deep2:  #0A241B;
  --pine:   #123A2C;

  /* Ink on dark */
  --ivory:  #F4F0E6;
  --mute:   #9DB3A6;
  --faint:  #6A8377;

  /* The accents. Three, and each one means something — a decorative accent is
     how a dark page turns into a template.
       brass    the institution: headings, rules, the brand, the chrome.
       phosphor a live or measured reading. If it glows, it is telemetry.
       ember    a loss, or the gap between what is and what the breed sheet
                says. This is the only colour the product exists to shrink, so
                it never appears anywhere that is not a shortfall. */
  --brass:    #C6A15B;
  --brass-l:  #E7D2A0;
  --phosphor: #7FE3B0;
  --ember:    #E08A55;

  /* The two colours the logotype already owns. The "E"s in EDGE are three green
     bars and three amber bars — they have been in the mark since before this
     site existed, and they were the only saturated colour anywhere on the page.
     Naming them promotes the brand's own palette into the system rather than
     inventing a decorative one, which is what "more colour" has to mean here. */
  --leaf:     #43A047;
  --leaf-l:   #6FC46F;
  --amber:    #F2B01E;
  --amber-l:  #FFCB4D;

  /* Glass. Kept as separate tokens so a panel can be tuned in one place —
     several of these are used inside gradients and cannot be var()'d inline. */
  --glass-hi:  rgba(255, 255, 255, .058);
  --glass-lo:  rgba(255, 255, 255, .014);
  --glass-brd: rgba(255, 255, 255, .085);
  --glass-lip: rgba(255, 255, 255, .055);
  --glass-sh:  0 26px 70px -34px rgba(0, 0, 0, .95);

  /* Species accents. Each is still drawn from the animal itself, but they now
     run at daylight saturation rather than at the old instrument-phosphor
     wash. The earlier set sat within a few points of each other in chroma, so
     on a near-black ground a pig section and a broiler section were the same
     grey-brown to anyone not comparing them side by side — the colour was
     carrying meaning it was too quiet to deliver. These are far enough apart to
     be read at a glance and still sit inside one family.

     They are the only colour with a job on this page: a section, its plate, its
     charts and its badges all key off the species being discussed, so colour is
     navigation, not decoration. --sp-d is the same hue pulled down for washes
     and fills where the bright value would fight the type. */
  --sp-pig:     #E08A72;  --sp-pig-d:     #7A3A2C;
  --sp-layer:   #F5B324;  --sp-layer-d:   #7A560D;
  --sp-broiler: #B9D04E;  --sp-broiler-d: #4E6018;
  --sp-cattle:  #93B4C9;  --sp-cattle-d:  #35586E;
  --sp-fish:    #45B8D6;  --sp-fish-d:    #12566A;
  --sp-rabbit:  #D8B27E;  --sp-rabbit-d:  #6B4C25;
  --sp-bee:     #F4C21C;  --sp-bee-d:     #6E5306;
  /* Crops are the one enterprise here that is not an animal. Jade rather than
     another leaf green, because it has to be told apart from broiler chartreuse
     at glyph size and the two sections sit next to each other. */
  --sp-crop:    #4FC28E;  --sp-crop-d:    #1B5A41;
  --sp: var(--brass);
  --sp-d: #4A3A17;

  --serif: 'Fraunces', Georgia, serif;
  --ui:    'Hanken Grotesk', system-ui, sans-serif;
  --label: 'Schibsted Grotesk', system-ui, sans-serif;
  --mono:  'IBM Plex Mono', ui-monospace, monospace;

  --gut:  clamp(20px, 5vw, 64px);
  --max:  1280px;
  --r:    18px;
  --r-sm: 12px;
}

/* The species resolver. Every component reads var(--sp); the ancestor with
   [data-sp] decides what that is. One rule per species, and nothing downstream
   has to know which species it is rendering. */
[data-sp='pig']     { --sp: var(--sp-pig);     --sp-d: var(--sp-pig-d); }
[data-sp='layer']   { --sp: var(--sp-layer);   --sp-d: var(--sp-layer-d); }
[data-sp='broiler'] { --sp: var(--sp-broiler); --sp-d: var(--sp-broiler-d); }
[data-sp='cattle']  { --sp: var(--sp-cattle);  --sp-d: var(--sp-cattle-d); }
[data-sp='fish']    { --sp: var(--sp-fish);    --sp-d: var(--sp-fish-d); }
[data-sp='rabbit']  { --sp: var(--sp-rabbit);  --sp-d: var(--sp-rabbit-d); }
[data-sp='bee']     { --sp: var(--sp-bee);     --sp-d: var(--sp-bee-d); }
[data-sp='crop']    { --sp: var(--sp-crop);    --sp-d: var(--sp-crop-d); }

/* ---------------------------------------------------------------------------
   2. Reset and page frame
   --------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--void);
  color: var(--ivory);
  font-family: var(--ui);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  /* DO NOT set overflow here. Any value other than visible makes <body> a
     backdrop root, and every backdrop-filter on the page silently flattens —
     the glass stops being glass and nothing reports an error. */
}

img, svg, video { display: block; max-width: 100%; }

a { color: inherit; }

/* One focus ring for the whole site. It deliberately does NOT set border-radius:
   that used to be here, and because border-radius is the element's own property
   rather than the outline's, tabbing onto a pill button or an 18px card squared
   its corners off for as long as it held focus. An outline already follows
   whatever radius the element has, so there was nothing to fix and a visible
   glitch to cause. */
:focus-visible {
  outline: 2px solid var(--brass-l);
  outline-offset: 3px;
}

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gut); }

.vh {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  padding: 12px 18px; background: var(--brass); color: var(--void);
  font-family: var(--label); font-weight: 600; text-decoration: none;
}
.skip:focus { left: 12px; top: 12px; }

/* ---------------------------------------------------------------------------
   3. The atmosphere — a fixed field the whole document floats above.
   Two layers: a contour wash and a slow aurora. Both are painted once, behind
   everything, so the glass has something worth refracting. Without a textured
   backdrop, backdrop-filter is invisible and the glass looks like flat grey.
   --------------------------------------------------------------------------- */

.field {
  position: fixed; inset: 0; z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(120% 80% at 78% -10%, rgba(18, 58, 44, .85), transparent 60%),
    radial-gradient(90%  70% at 8%  105%, rgba(12, 44, 34, .75), transparent 62%),
    var(--void);
}

.field-lines { position: absolute; inset: 0; width: 100%; height: 100%; opacity: .5; }
.field-lines path { fill: none; stroke: rgba(198, 161, 91, .16); stroke-width: 1; vector-effect: non-scaling-stroke; }
.field-lines path.lit { stroke: rgba(127, 227, 176, .32); stroke-width: 1.4; }

/* A single slow drift. One ambient motion on the page, not five. */
.field-glow {
  position: absolute; inset: -30%;
  background: radial-gradient(38% 30% at 50% 50%, rgba(127, 227, 176, .07), transparent 70%);
  animation: drift 34s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(-8%, -4%, 0) scale(1); }
  to   { transform: translate3d(10%,  6%, 0) scale(1.18); }
}
@media (prefers-reduced-motion: reduce) {
  .field-glow { animation: none; }
}

/* Fine grain. Stops the large dark gradients from banding on cheap panels,
   which is the single most common way a dark site looks amateur. */
.field-grain {
  position: absolute; inset: 0; opacity: .5; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------------
   4. Glass primitives
   --------------------------------------------------------------------------- */

.glass {
  position: relative;
  background: linear-gradient(158deg, var(--glass-hi), var(--glass-lo));
  border: 1px solid var(--glass-brd);
  border-radius: var(--r);
  box-shadow: var(--glass-sh);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  /* Badges deliberately break the bounds, so this must not clip. */
  overflow: visible;
}

/* The lip — a one-pixel highlight along the top edge only. This is what makes
   a translucent rectangle read as a physical pane rather than a div with
   opacity, and it costs one pseudo-element. */
.glass::before {
  content: '';
  position: absolute; inset: 0 0 auto 0; height: 1px;
  border-radius: var(--r) var(--r) 0 0;
  background: linear-gradient(90deg, transparent, var(--glass-lip) 18%, var(--glass-lip) 82%, transparent);
}

.glass-lift { transition: transform .4s cubic-bezier(.2, .7, .3, 1), border-color .4s ease; }
.glass-lift:hover { transform: translateY(-4px); border-color: rgba(198, 161, 91, .3); }

/* Backdrop-filter is the most expensive thing on this page. Below the tablet
   breakpoint the panels fall back to a solid tint — visually near-identical at
   that size, and it keeps a mid-range Android at sixty frames. */
@media (max-width: 860px) {
  .glass {
    backdrop-filter: none; -webkit-backdrop-filter: none;
    background: linear-gradient(158deg, rgba(18, 58, 44, .5), rgba(7, 25, 19, .62));
  }
}

/* ---------------------------------------------------------------------------
   5. Badges — overlapping, breaking their container's edge
   --------------------------------------------------------------------------- */

.badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px;
  border: 1px solid rgba(198, 161, 91, .34);
  border-radius: 999px;
  background: rgba(7, 25, 19, .82);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--brass-l);
  white-space: nowrap;
}

/* Pinned so it straddles the panel edge. The panel must not clip (see .glass). */
.badge-pin { position: absolute; top: -13px; left: 22px; z-index: 3; }
.badge-pin-r { left: auto; right: 22px; }
.badge-pin-b { top: auto; bottom: -13px; }

.badge-sp { border-color: color-mix(in srgb, var(--sp) 55%, transparent); color: var(--sp); }

.badge-live { border-color: rgba(127, 227, 176, .4); color: var(--phosphor); }
.badge-live .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--phosphor);
  box-shadow: 0 0 0 0 rgba(127, 227, 176, .6);
  animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(127, 227, 176, .55); }
  70%  { box-shadow: 0 0 0 7px rgba(127, 227, 176, 0); }
  100% { box-shadow: 0 0 0 0 rgba(127, 227, 176, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .badge-live .dot { animation: none; }
}

.badge-off { border-color: rgba(157, 179, 166, .24); color: var(--faint); border-style: dashed; }

/* ---------------------------------------------------------------------------
   6. Type
   --------------------------------------------------------------------------- */

.eyebrow {
  margin: 0 0 14px;
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--brass);
}

h1, h2, h3 { font-family: var(--serif); font-weight: 400; letter-spacing: -.018em; }

.h1 {
  margin: 0 0 22px;
  font-size: clamp(2.5rem, 6.4vw, 5rem);
  line-height: 1.02;
}
.h1 em { font-style: italic; color: var(--brass-l); }

.h2 {
  margin: 0 0 18px;
  font-size: clamp(1.85rem, 3.6vw, 3rem);
  line-height: 1.1;
}

.h3 { margin: 0 0 10px; font-size: 1.2rem; line-height: 1.25; }

.lede {
  margin: 0 0 34px; max-width: 62ch;
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  line-height: 1.68; color: var(--mute);
}

p { margin: 0 0 16px; }
p:last-child { margin-bottom: 0; }

.rule {
  width: 54px; height: 0; margin: 0 0 20px;
  border: 0; border-top: 1px solid var(--brass);
}

/* Data. Everything numeric is mono and tabular so columns of figures line up —
   the whole product is a ledger, and proportional digits in a ledger look wrong
   to exactly the audience this page is for. */
.num, .fig, .money { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* Added by hedge.js only once a figure has actually been replaced from
   /api/market.json. Phosphor is the telemetry accent everywhere else on this
   site — if it glows, it is a reading — so a refreshed number lights up and a
   hard-coded one does not, without a badge having to announce it. The class is
   never added when the fetch fails, which is the point: the colour is the claim,
   so it cannot outlive the thing it claims. */
.money.is-live { color: var(--phosphor); }

.fig {
  display: block;
  font-size: clamp(2rem, 4.4vw, 3.1rem);
  font-weight: 500; line-height: 1;
  color: var(--ivory);
}

.src {
  display: block; margin-top: 5px;
  font-family: var(--mono); font-size: 10.5px; line-height: 1.45;
  letter-spacing: .04em; color: var(--faint);
}

/* ---------------------------------------------------------------------------
   7. Sections
   --------------------------------------------------------------------------- */

.section { padding-block: clamp(72px, 11vw, 140px); position: relative; }
.section-head { max-width: 74ch; margin-bottom: clamp(38px, 5vw, 62px); }

/* A section that is about one species is lit by that species. The wash is the
   deep value of the accent, not the bright one, and it tops out at a few per
   cent — enough that scrolling from pigs to layers to broilers is a change of
   light rather than a change of label, and not so much that the glass panels
   stop reading as glass. Sits at z-index -1, above the fixed contour field and
   below every panel. */
.section[data-sp] { isolation: isolate; }
.section[data-sp]::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(80% 52% at 12% 0%,  color-mix(in srgb, var(--sp-d) 62%, transparent), transparent 68%),
    radial-gradient(64% 46% at 92% 88%, color-mix(in srgb, var(--sp-d) 42%, transparent), transparent 70%);
  opacity: .5;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
}

/* The eyebrow and the rule take the species key too, so the label at the top of
   a section names its colour before the reader meets a single chart in it. */
.section[data-sp] .section-head .eyebrow { color: var(--sp); }
.section[data-sp] .section-head .rule { border-top-color: var(--sp); width: 96px; }

/* ---------------------------------------------------------------------------
   8. Buttons
   --------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 13px 24px;
  border: 1px solid transparent; border-radius: 999px;
  font-family: var(--label); font-size: .9rem; font-weight: 600;
  letter-spacing: .01em; text-decoration: none; cursor: pointer;
  transition: transform .3s cubic-bezier(.2,.7,.3,1), background-color .3s ease, border-color .3s ease, color .3s ease;
}
.btn:hover { transform: translateY(-2px); }

.btn-primary { background: var(--brass); color: #1A1206; }
.btn-primary:hover { background: var(--brass-l); }

.btn-ghost { border-color: rgba(255,255,255,.16); color: var(--ivory); }
.btn-ghost:hover { border-color: var(--brass); color: var(--brass-l); background: rgba(198,161,91,.08); }

.btn-arrow { transition: transform .3s cubic-bezier(.2,.7,.3,1); }
.btn:hover .btn-arrow { transform: translateX(4px); }

@media (prefers-reduced-motion: reduce) {
  .btn, .btn-arrow, .glass-lift { transition: none; }
  .btn:hover, .glass-lift:hover { transform: none; }
}

/* ---------------------------------------------------------------------------
   9. Header and navigation
   --------------------------------------------------------------------------- */

.head {
  position: sticky; top: 0; z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background-color .35s ease, border-color .35s ease, backdrop-filter .35s ease;
}
.head-in {
  display: flex; align-items: center; gap: 22px;
  min-height: 68px;
}

/* Only frosts once the page has scrolled — over the hero it stays invisible so
   the contour field reads full-bleed. site.js adds .is-stuck. */
.head.is-stuck {
  background: rgba(4, 16, 12, .72);
  border-bottom-color: rgba(255,255,255,.07);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
}

/* The lockup's proportion is declared here because the mark and the logotype
   have to read as one object.

   PROPORTION, and this is the one that was actually wrong on the live site.
   The two brand PNGs are each trimmed tight to their own ink — mark ink 225×287
   of a 238×300 file, logotype ink 943×181 of 952×190 — so their native sizes
   carry NO information about how big one should be beside the other. Anyone
   deriving the lockup from the file dimensions is deriving it from the crop.
   The header shipped at mark 35px against word 17px: 2.06×, a monogram towering
   over its own name. Measured off the delivered lockup and checked at render
   size, the monogram wants to be roughly a third again the height of the
   logotype block — 26 against 19, 1.37× — which is what is set below. Change
   these two numbers together or not at all. */
.brandlink {
  --lock:  .95s;   /* how long the emblem takes to come up */
  --globe: 16s;    /* one full turn of the emblem */

  /* The emblem's two strokes. BOTH sampled from the delivered artwork, neither
     chosen: hedge-mark-green.png is solid #4AA742, and the logotype's amber bars
     are solid #F5BA21. The monogram and the word therefore carry byte-identical
     colour, which is the only way a lockup stays a lockup.

     Deliberately NOT the deck's --phosphor and --amber. Phosphor means "this is
     a live reading" everywhere else on this site, and a logo is not a reading.
     An earlier pass here used #EFA63C, eyeballed from a reference image; it was
     four points off the artwork's own amber and put the two halves of the lockup
     in slightly different golds. Sample, do not match by eye. */
  --mark-green: #4AA742;
  --mark-gold:  #F5BA21;

  display: inline-flex; align-items: center; gap: 9px; text-decoration: none;
}
.brandlink .word { height: 19px; width: auto; }

/* ---------------------------------------------------------------------------
   9b. The emblem turns. Nothing else moves.

   WHAT WAS HERE BEFORE. Both halves of the lockup used to animate together: a
   "signal lock" of chromatic separations that converged out of misregistration
   while a beam read down each piece, then re-read itself every eleven seconds.
   It was built around a white monogram, and it is gone for two reasons. The
   monogram is no longer white — it carries its own green and amber now, and
   dragging a phosphor ghost and a multiply beam across coloured artwork tints
   what is already tinted and turns the amber stroke brown. And a lockup with two
   competing motions has no focal point: the eye is asked to watch a word
   flickering and a monogram turning at the same time and settles on neither.

   So the word is still. It is the delivered PNG, painted once, and it never
   moves again. Everything that used to drive it — the --scan, --rest and --split
   clocks, the --sep-a/--sep-b separations, the --beam gradient, and the
   sig-sep-a/b, amb-sep-a/b, sig-scan, amb-scan, live-a and live-b keyframes —
   was deleted with it rather than left switched off, because CSS that nothing
   selects is indistinguishable from CSS that is about to be needed again.

   THE EMBLEM keeps one movement, and it is the only movement in the header: a
   constant turn on its vertical axis, the way a broadcast station's globe turns.
   The argument is the same one the separations were making, said once instead of
   continuously — this is an instrument, and instruments are in motion whether or
   not you are looking at them.
   --------------------------------------------------------------------------- */

/* The symbol library — the species glyphs of section 24. Present in the
   document, painted nowhere. */
.svgdefs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* 21 × 26 keeps the artwork's own 238:300. Paired with .brandlink .word at 19px
   — see the note on proportion above before touching either. */
.hmark {
  position: relative; display: inline-flex; flex: none;
  width: 21px; height: 26px;
  /* .hmark-globe is transformed inside this, so the perspective has to live on
     the parent: an element cannot both establish a perspective and be moved
     within it. */
  perspective: 320px;
}
.wordwrap { position: relative; display: inline-flex; }

/* ── the emblem: two strokes, two colours, one axis ──────────────────────────
   The H is two interlocking strokes and they are two separate shapes in the
   artwork — 20,190 and 20,092 pixels, sharing none — so each gets its own mask
   over its own solid colour. Nothing is traced or redrawn: hedge-mark-left.png
   and hedge-mark-right.png carry the original anti-aliased alpha split by
   stroke, and recombining them reproduces the delivered file exactly. The
   letterform stays the designer's to the pixel, and at 5 KB each the pair is a
   quarter the weight of the white PNG it replaces. */
.hmark-globe {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  animation: sig-resolve var(--lock) cubic-bezier(.16, .84, .28, 1) .10s 1,
             hmark-globe var(--globe) linear 1.1s infinite;
}

/* TWO FACES. Spin a single flat mark and it shows its own mirror for half of
   every turn: the hooks curl the wrong way and the green stroke lands on the
   right. That is not a stylised back, it is the logo printed backwards, on
   screen, half the time. So the emblem is built the way a broadcast ident is —
   double-sided, with the back pre-rotated 180° so that when the turn brings it
   round it reads correctly. Each face hides its own backface, so exactly one is
   ever painted and they cannot z-fight. */
.hmark-face {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.hmark-back { transform: rotateY(180deg); }

.hmark-l, .hmark-r {
  position: absolute; inset: 0;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}
.hmark-l {
  background: var(--mark-green);
  -webkit-mask-image: url('/assets/hedge-mark-left.png');
          mask-image: url('/assets/hedge-mark-left.png');
}
.hmark-r {
  background: var(--mark-gold);
  -webkit-mask-image: url('/assets/hedge-mark-right.png');
          mask-image: url('/assets/hedge-mark-right.png');
}

/* Constant speed, no easing, never resting on the face — a station globe turns,
   it does not present. The 1.1s delay lets the mark come up and be read first. */
@keyframes hmark-globe {
  from { transform: rotateY(0deg); }
  to   { transform: rotateY(360deg); }
}

/* The emblem arriving: up from nothing, over-exposed, settling. A display coming
   on, not a fade-in. It carries no fill-mode on purpose — its last keyframe is
   already the resting state, and a fill would pin the animated values forever
   and silently outrank the hover rule below. */
@keyframes sig-resolve {
  0%   { opacity: 0; filter: brightness(2.6) saturate(.4); }
  45%  { opacity: 1; }
  100% { opacity: 1; filter: brightness(1) saturate(1); }
}

/* ── the answer ──────────────────────────────────────────────────────────────
   Hover and keyboard focus speed the turn up rather than lighting anything up.
   An instrument being addressed looks busier, not louder — and since the word no
   longer moves, this is the lockup's whole response, so it has to stay legible
   as a change of state rather than read as a glitch. */
.brandlink:hover .hmark-globe,
.brandlink:focus-visible .hmark-globe {
  animation: hmark-globe calc(var(--globe) / 2.6) linear infinite;
}

/* The turn stops facing forward. A continuously rotating logo is precisely the
   kind of unrequested motion this query exists to silence, and the emblem still
   says everything it needs standing still — the two colours are in the artwork,
   not in the animation. */
@media (prefers-reduced-motion: reduce) {
  .hmark-globe,
  .brandlink:hover .hmark-globe,
  .brandlink:focus-visible .hmark-globe {
    animation: none;
    transform: none;
  }
  .hmark { perspective: none; }
}
.nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav a {
  padding: 8px 14px; border-radius: 999px;
  font-family: var(--label); font-size: .845rem; font-weight: 600;
  color: var(--mute); text-decoration: none;
  transition: color .25s ease, background-color .25s ease;
}
.nav a:hover { color: var(--ivory); background: rgba(255,255,255,.05); }
.nav a[aria-current='page'] { color: var(--brass-l); background: rgba(198,161,91,.1); }

.nav .signin {
  margin-left: 8px;
  border: 1px solid rgba(198,161,91,.4); color: var(--brass-l);
}
.nav .signin:hover { background: rgba(198,161,91,.14); border-color: var(--brass); }

.navtoggle {
  display: none; margin-left: auto;
  padding: 9px 14px; border: 1px solid rgba(255,255,255,.16);
  border-radius: 999px; background: transparent; color: var(--ivory);
  font-family: var(--label); font-size: .82rem; font-weight: 600; cursor: pointer;
}

@media (max-width: 900px) {
  .navtoggle { display: block; }
  .nav {
    display: none;
    position: absolute; left: var(--gut); right: var(--gut); top: 100%;
    flex-direction: column; align-items: stretch; gap: 2px;
    margin: 8px 0 0; padding: 10px;
    background: rgba(7, 25, 19, .95);
    border: 1px solid var(--glass-brd); border-radius: var(--r);
    backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
    box-shadow: var(--glass-sh);
  }
  .nav.is-open { display: flex; }
  .nav a { padding: 12px 14px; }
  .nav .signin { margin: 6px 0 0; text-align: center; }
}

/* ---------------------------------------------------------------------------
   10. Footer
   --------------------------------------------------------------------------- */

.foot {
  margin-top: clamp(60px, 9vw, 110px);
  border-top: 1px solid rgba(255,255,255,.07);
  padding-block: clamp(44px, 6vw, 72px);
  background: rgba(4, 16, 12, .6);
}
.foot-grid {
  display: grid; gap: 34px;
  grid-template-columns: minmax(220px, 1fr) 2fr;
}
.foot-nav { display: flex; flex-wrap: wrap; gap: 8px 30px; align-items: flex-start; }
.foot-col { display: flex; flex-direction: column; gap: 9px; min-width: 130px; }
.foot-col h4 {
  margin: 0 0 4px; font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--brass);
}
.foot-col a { font-size: .88rem; color: var(--mute); text-decoration: none; }
.foot-col a:hover { color: var(--ivory); }
.tagline { margin: 14px 0 0; font-size: .88rem; color: var(--faint); }
.legal {
  margin: 34px 0 0; padding-top: 22px;
  border-top: 1px solid rgba(255,255,255,.06);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .05em; color: var(--faint);
}

@media (max-width: 760px) {
  .foot-grid { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------
   11. Reveal — one shared entrance. site.js adds .js-anim to <html> only when
   motion is allowed, so a JS failure or a reduced-motion preference leaves
   every element visible rather than permanently transparent.
   --------------------------------------------------------------------------- */

.js-anim .rv { opacity: 0; transform: translateY(18px); }
.js-anim .rv.in {
  opacity: 1; transform: none;
  transition: opacity .7s ease, transform .7s cubic-bezier(.2,.7,.3,1);
}
.js-anim .rv.d1.in { transition-delay: .06s; }
.js-anim .rv.d2.in { transition-delay: .12s; }
.js-anim .rv.d3.in { transition-delay: .18s; }
.js-anim .rv.d4.in { transition-delay: .24s; }

/* ---------------------------------------------------------------------------
   12. Grids and small utilities
   --------------------------------------------------------------------------- */

.grid  { display: grid; gap: 20px; }

/* A grid item's min-width defaults to auto, so it refuses to shrink below its
   own content. That defeats .tablewrap: the .ledger inside it declares
   min-width: 560px to stay readable, and rather than scrolling in place the
   whole column grows to 560 and pushes the page sideways. Evidence overflowed
   at both 375 and 1280 for exactly this reason. Opt every grid item out, and
   the scroll container does the job it was added for.
   .stack is listed separately because it is a grid without the .grid class. */
.grid > *, .stack > * { min-width: 0; }

.g2    { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3    { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4    { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gauto { grid-template-columns: repeat(auto-fit, minmax(min(100%, 292px), 1fr)); }
.g-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(24px, 4vw, 48px); }

@media (max-width: 1000px) { .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px)  { .g-split { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 860px)  { .g3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .g2, .g3, .g4 { grid-template-columns: 1fr; } }

.actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.stack   { display: grid; gap: 14px; }
.mt-l    { margin-top: clamp(30px, 4vw, 52px); }
.mt-s    { margin-top: 18px; }

/* A quiet hairline between stacked sections. Structure without decoration. */
.section + .section { border-top: 1px solid rgba(255, 255, 255, .05); }

/* ---------------------------------------------------------------------------
   13. Hero
   --------------------------------------------------------------------------- */

.hero { padding-block: clamp(56px, 8vw, 108px) clamp(52px, 7vw, 96px); }
.hero-grid {
  display: grid; align-items: center;
  gap: clamp(34px, 5vw, 58px);
  grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
}
@media (max-width: 1000px) { .hero-grid { grid-template-columns: 1fr; } }

/* Keeps "every franc —" from breaking mid-phrase on a narrow column. */
.nb { display: inline-block; }

.hero-sub {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: 26px 0 0;
}

/* ---------------------------------------------------------------------------
   14. The instrument — the signature panel.

   Every figure on this site is a reading taken off something: a survey, a breed
   manual, a price feed, the farm's own ledger. The instrument is the frame that
   says so. A mono readout, a calibration label underneath, and a hairline scan
   grid behind it. It carries the hero, and it recurs wherever a number needs to
   be shown as measured rather than asserted.
   --------------------------------------------------------------------------- */

.inst { padding: 24px 22px 20px; }

.inst-h {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 6px; padding-bottom: 14px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.inst-t {
  margin: 0;
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
}

.inst-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline; gap: 2px 16px;
  padding: 13px 0;
  border-bottom: 1px dashed rgba(255, 255, 255, .07);
}
.inst-row:last-child { border-bottom: 0; padding-bottom: 2px; }
.inst-k { font-size: .875rem; color: var(--mute); }
.inst-v {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 1.06rem; color: var(--ivory); text-align: right; white-space: nowrap;
}
.inst-v.is-gap  { color: var(--ember); }
.inst-v.is-live { color: var(--phosphor); }
.inst-note { grid-column: 1 / -1; margin: 0; }

/* The scan grid — a faint ruled backdrop, so the panel reads as a gauge face
   rather than a card. Drawn as a gradient pair; no extra element, no image. */
.inst-face {
  position: relative; overflow: hidden;
  border-radius: var(--r-sm);
}
.inst-face::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, .028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .028) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: radial-gradient(120% 100% at 50% 0%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(120% 100% at 50% 0%, #000 30%, transparent 78%);
}

/* ---------------------------------------------------------------------------
   15. Cards, stats, modules
   --------------------------------------------------------------------------- */

.card { padding: clamp(22px, 2.4vw, 30px); }
.card > :last-child { margin-bottom: 0; }
.card p { color: var(--mute); font-size: .94rem; }

.card-t {
  margin: 0 0 9px;
  font-family: var(--serif); font-size: 1.16rem; font-weight: 400;
  letter-spacing: -.012em; color: var(--ivory);
}

.tag {
  display: inline-block; margin-bottom: 13px;
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--brass);
}

.stat { padding: 26px 22px 22px; }
.stat .fig { margin-bottom: 8px; }
.stat .cap { display: block; font-size: .86rem; line-height: 1.45; color: var(--mute); }

/* ---------------------------------------------------------------------------
   16. Charts

   All geometry is written as SVG presentation attributes rather than inline
   style, because style-src has no 'unsafe-inline' — a style="" attribute here
   would be silently dropped by the browser and every bar would collapse to
   zero. Colour comes from the classes below.
   --------------------------------------------------------------------------- */

.chart { display: block; width: 100%; height: auto; overflow: visible; }

.cx-grid  { stroke: rgba(255, 255, 255, .07); stroke-width: 1; }
.cx-axis  { stroke: rgba(255, 255, 255, .16); stroke-width: 1; }

.cx-bar   { fill: rgba(255, 255, 255, .085); }
.cx-bar-a { fill: var(--sp); }                    /* what the farm has today */
.cx-bar-b { fill: rgba(198, 161, 91, .8); }       /* what the standard says   */
.cx-bar-x { fill: rgba(224, 138, 85, .78); }      /* the shortfall between    */

.cx-lab {
  fill: var(--faint); font-family: var(--mono); font-size: 10px;
  letter-spacing: .09em; text-transform: uppercase;
}
.cx-val { fill: var(--ivory); font-family: var(--mono); font-size: 13px; font-weight: 500; }
.cx-val-x { fill: var(--ember); }

.cx-line   { fill: none; stroke: var(--phosphor); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cx-line-b { stroke: var(--brass); }
.cx-line-x { stroke: var(--ember); }
.cx-line-i { stroke-dasharray: 5 6; opacity: .75; }  /* endpoints cited, path indicative */
.cx-dot    { fill: var(--phosphor); }
.cx-dot-b  { fill: var(--brass-l); }
.cx-dot-x  { fill: var(--ember); }

/* Schematic nodes, for the architecture drawing. */
.cx-node   { fill: rgba(255, 255, 255, .045); stroke: rgba(255, 255, 255, .11); stroke-width: 1; }
.cx-node-b { fill: rgba(198, 161, 91, .1);   stroke: rgba(198, 161, 91, .42);  stroke-width: 1; }
.cx-node-l { fill: rgba(127, 227, 176, .07); stroke: rgba(127, 227, 176, .32); stroke-width: 1; }
.cx-flow   { fill: none; stroke: rgba(198, 161, 91, .45); stroke-width: 1.2; }
.cx-arrow  { fill: rgba(198, 161, 91, .7); }
.cx-t      { fill: var(--ivory); font-family: var(--ui); font-size: 13px; }
.cx-ts     { fill: var(--mute);  font-family: var(--ui); font-size: 11.5px; }

/* A legend that sits under a chart rather than inside it — inside it would need
   per-swatch colour, and per-element colour cannot be an inline style here. */
.legend { display: flex; flex-wrap: wrap; gap: 8px 20px; margin-top: 14px; }
.legend span {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--faint);
}
.legend i { width: 14px; height: 3px; border-radius: 2px; background: currentColor; }
.legend .is-std  { color: var(--brass); }
.legend .is-here { color: var(--ember); }
.legend .is-live { color: var(--phosphor); }
.legend .is-sp   { color: var(--sp); }

/* Radial gauge. The arc length is set with stroke-dasharray as an attribute on
   the element — also a presentation attribute, also CSP-safe. */
.gauge { display: grid; place-items: center; gap: 12px; }
.gauge svg { width: 128px; height: 128px; }
.g-track { fill: none; stroke: rgba(255, 255, 255, .08); stroke-width: 7; }
.g-val   { fill: none; stroke: var(--phosphor); stroke-width: 7; stroke-linecap: round; }
.g-val-x { stroke: var(--ember); }
.g-num   { fill: var(--ivory); font-family: var(--mono); font-size: 21px; font-weight: 500; text-anchor: middle; }
.g-cap   { display: block; font-size: .84rem; line-height: 1.45; color: var(--mute); text-align: center; max-width: 22ch; }

/* ---------------------------------------------------------------------------
   17. Tables — the ledger
   --------------------------------------------------------------------------- */

.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.ledger { width: 100%; min-width: 560px; border-collapse: collapse; font-size: .9rem; }
.ledger caption {
  margin-bottom: 14px; text-align: left;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint);
}
.ledger th, .ledger td {
  padding: 15px 16px; text-align: left; vertical-align: top;
  border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.ledger thead th {
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--brass);
  border-bottom-color: rgba(198, 161, 91, .3);
}
.ledger tbody th { max-width: 34ch; font-weight: 500; color: var(--ivory); }
.ledger td { color: var(--mute); }
.ledger .num { text-align: right; white-space: nowrap; }
.ledger tfoot th, .ledger tfoot td {
  border-bottom: 0; border-top: 1px solid rgba(198, 161, 91, .34);
  color: var(--ivory); font-weight: 500;
}
.ledger .total { color: var(--brass-l); }

.why { display: block; margin-top: 7px; font-size: .8rem; line-height: 1.5; color: var(--faint); }

.up   { color: var(--ember); font-family: var(--mono); }
.down { color: var(--phosphor); font-family: var(--mono); }
.flat { color: var(--faint); font-family: var(--mono); }
.gapv { color: var(--ember); font-family: var(--mono); }

/* ---------------------------------------------------------------------------
   18. The gap calculator
   --------------------------------------------------------------------------- */

.calc-controls {
  display: grid; align-items: end; gap: 18px;
  grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr);
  padding: 22px; margin-bottom: 26px;
}
@media (max-width: 820px) { .calc-controls { grid-template-columns: 1fr; } }

.segs {
  display: inline-flex; gap: 4px; padding: 4px;
  border: 1px solid var(--glass-brd); border-radius: 999px;
  background: rgba(4, 16, 12, .5);
}
.seg {
  padding: 9px 20px; border: 0; border-radius: 999px;
  background: transparent; color: var(--mute);
  font-family: var(--label); font-size: .85rem; font-weight: 600; cursor: pointer;
  transition: color .25s ease, background-color .25s ease;
}
.seg[aria-selected='true'] {
  background: color-mix(in srgb, var(--sp) 20%, transparent);
  color: var(--sp);
}

.ctl { display: flex; flex-direction: column; gap: 8px; }
.ctl > span,
.fld > span {
  font-family: var(--mono); font-size: 10px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.ctl > span em, .fld > span em { font-style: normal; }

.ctl input, .fld input, .fld select, .fld textarea {
  width: 100%; padding: 12px 14px;
  border: 1px solid var(--glass-brd); border-radius: var(--r-sm);
  background: rgba(4, 16, 12, .58); color: var(--ivory);
  font-family: var(--ui); font-size: .95rem;
  transition: border-color .25s ease;
}
.ctl input { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.ctl input:hover, .fld input:hover, .fld select:hover, .fld textarea:hover { border-color: rgba(198, 161, 91, .34); }
.fld textarea { resize: vertical; }
::placeholder { color: rgba(157, 179, 166, .42); }
/* Native dropdown lists paint with the page's own colours in most engines only
   if the option carries them explicitly. */
option { background: #071913; color: #F4F0E6; }

.dag { color: var(--brass); }

.calc-sum {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: 10px;
  margin: 0 0 20px; padding: 16px 20px; border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--sp) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--sp) 24%, transparent);
}
.calc-sum > span { font-size: .87rem; color: var(--mute); }
.calc-sum b {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: clamp(1.3rem, 2.6vw, 1.85rem); color: var(--ivory);
}

.calc-panel { padding: clamp(20px, 2.4vw, 28px); }
.calc-scale { margin-top: 18px; font-size: .88rem; color: var(--mute); }
.calc-scale b, .calc-sum b { color: var(--brass-l); }
.calc-legend { margin-top: 20px; font-size: .84rem; line-height: 1.6; color: var(--faint); }

/* ---------------------------------------------------------------------------
   19. Forms
   --------------------------------------------------------------------------- */

.form { display: grid; gap: 16px; padding: clamp(22px, 2.6vw, 30px); }
.form .row { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }
@media (max-width: 620px) { .form .row { grid-template-columns: 1fr; } }
.fld { display: flex; flex-direction: column; gap: 8px; }

/* Bots fill every input they can find; a person never sees this one. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.formmsg {
  margin: 0; padding: 12px 15px; border-radius: var(--r-sm);
  font-size: .89rem; border: 1px solid transparent;
}
.formmsg[data-tone='ok']  { border-color: rgba(127, 227, 176, .34); color: var(--phosphor); background: rgba(127, 227, 176, .07); }
.formmsg[data-tone='err'] { border-color: rgba(224, 138, 85, .38);  color: var(--ember);    background: rgba(224, 138, 85, .07); }
.formnote { font-size: .82rem; color: var(--faint); }
.formnote a { color: var(--brass-l); }

.kv { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.kv li {
  display: grid; grid-template-columns: 128px minmax(0, 1fr); gap: 14px;
  padding: 14px 0; border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.kv li:last-child { border-bottom: 0; }
.kv .k {
  font-family: var(--mono); font-size: 10px; letter-spacing: .13em;
  text-transform: uppercase; color: var(--faint); padding-top: 4px;
}
.kv a { color: var(--brass-l); text-decoration: none; }
.kv a:hover { color: var(--ivory); }
@media (max-width: 520px) { .kv li { grid-template-columns: 1fr; gap: 4px; } }

/* ---------------------------------------------------------------------------
   20. The sequence — numbered because it genuinely is one.

   Paper is written, then photographed, then read, then posted, then reported.
   Reorder those and the record is wrong, so the numbers carry information the
   reader needs rather than decorating a list of features.
   --------------------------------------------------------------------------- */

.tl { display: grid; }
.tl-step { position: relative; padding: 0 0 34px 52px; }
.tl-step:last-child { padding-bottom: 0; }
.tl-step::before {
  content: ''; position: absolute; left: 16px; top: 36px; bottom: 2px; width: 1px;
  background: linear-gradient(180deg, rgba(198, 161, 91, .45), rgba(198, 161, 91, .05));
}
.tl-step:last-child::before { display: none; }
.tl-n {
  position: absolute; left: 0; top: 0;
  display: grid; place-items: center; width: 33px; height: 33px;
  border: 1px solid rgba(198, 161, 91, .42); border-radius: 50%;
  background: rgba(7, 25, 19, .92);
  font-family: var(--mono); font-size: 11px; color: var(--brass-l);
}
.tl-step h3 { margin: 5px 0 8px; font-size: 1.1rem; }
.tl-step p { color: var(--mute); font-size: .93rem; }

/* ---------------------------------------------------------------------------
   21. Prose blocks — quotes, checklists, absences, legal documents
   --------------------------------------------------------------------------- */

.pull {
  margin: 0; padding: clamp(24px, 3vw, 36px);
  border-left: 2px solid var(--brass);
  font-family: var(--serif); font-size: clamp(1.16rem, 2vw, 1.5rem);
  line-height: 1.45; color: var(--ivory);
}
.pull cite {
  display: block; margin-top: 20px;
  font-family: var(--mono); font-size: 10.5px; font-style: normal;
  letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
}

.checks { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }
.checks li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 14px; font-size: .94rem; color: var(--mute); }
.checks .tick { color: var(--brass); font-family: var(--mono); line-height: 1.6; }
.checks b { color: var(--ivory); font-weight: 500; }

.absence {
  margin: 0; padding: clamp(22px, 2.6vw, 30px);
  border: 1px dashed rgba(198, 161, 91, .34); border-radius: var(--r);
  font-size: .95rem; color: var(--mute); background: rgba(198, 161, 91, .035);
}
.absence b { color: var(--brass-l); font-weight: 500; }

.asof {
  margin: 16px 0 0;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; color: var(--faint);
}

/* The species strip. Four of these have no customer behind them, and the dashed
   state says so rather than implying a roadmap. */
.band-list { list-style: none; margin: 0 0 22px; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
.band-list li {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 16px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--sp) 42%, transparent);
  background: color-mix(in srgb, var(--sp) 8%, transparent);
  font-size: .88rem; color: var(--ivory);
}
.band-list li.off { border-style: dashed; border-color: rgba(157, 179, 166, .22); background: none; color: var(--faint); }
.band-list .key { width: 8px; height: 8px; border-radius: 50%; background: var(--sp); }
.band-list li.off .key { background: rgba(157, 179, 166, .35); }
.band-list em {
  font-style: normal; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--faint);
}
.band-note { font-size: .92rem; color: var(--mute); max-width: 78ch; }

.prose { max-width: 74ch; }
.prose h2 { margin: 44px 0 14px; font-size: clamp(1.3rem, 2.2vw, 1.6rem); }
.prose h3 { margin: 28px 0 10px; font-size: 1.1rem; }
.prose p, .prose li { color: var(--mute); font-size: .95rem; }
.prose ul, .prose ol { margin: 0 0 18px; padding-left: 22px; }
.prose li { margin-bottom: 9px; }
.prose a { color: var(--brass-l); }
.prose strong { color: var(--ivory); font-weight: 500; }
.doc-meta {
  margin: 0 0 34px; padding-bottom: 22px;
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; color: var(--faint);
}

/* ---------------------------------------------------------------------------
   22. Plates — the photographs.

   A dark instrument deck and a bright stock photograph are natural enemies: drop
   one in untreated and the page stops being a deck and becomes a brochure with a
   dark theme. So a photograph never appears as a photograph here. It appears as
   a PLATE — a field observation pinned into the record, numbered, captioned, and
   pulled toward the palette until it sits at the same colour temperature as
   everything around it.

   Three things do that work:
     the filter   desaturates and darkens until the photo reads as ground rather
                  than as figure, so the type and the data stay the subject;
     the scrim    a bottom-weighted gradient in --void, so the image dissolves
                  into the page instead of ending at a hard rectangle edge;
     the chip     one glass tile of real data laid over the image, which is the
                  whole thesis of the site in miniature — the photograph is the
                  farm, the chip is what the farm actually knows about itself.

   Every plate carries a badge that straddles its top edge, so it is bound into
   the same overlapping-glass language as the panels rather than sitting apart
   from them.
   --------------------------------------------------------------------------- */

.plate { margin: 0 0 clamp(26px, 3vw, 42px); }

/* The frame, not the figure, is the positioning context. The figure also holds
   the caption, so anchoring the chip and the accent bar to it puts them below
   the text instead of on the image — which is exactly what happened first try. */
.plate-frame {
  position: relative;
  border-radius: var(--r);
  border: 1px solid var(--glass-brd);
  box-shadow: var(--glass-sh);
  /* The badge and the chip both break these bounds. */
  overflow: visible;
}

.plate img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 7;
  object-fit: cover;
  border-radius: var(--r);
  /* Held back, not drained. The original grade sat at saturate(.58) and pulled
     brightness to .74, which reduced a layer house to a grey rectangle — the
     photograph was carrying the shape and nothing else, and a page about
     livestock had no livestock visible in it. This keeps the deck's single
     exposure while letting the birds, the litter and the terraces read as what
     they are; the scrim below still guarantees the caption and chip their
     contrast. */
  filter: saturate(.92) contrast(1.04) brightness(.86);
  transition: filter .6s ease, transform .6s cubic-bezier(.2, .7, .3, 1);
}

/* On approach the photograph comes fully up. A plate is evidence, and evidence
   rewards looking at it. */
.plate-frame:hover img { filter: saturate(1.06) contrast(1.02) brightness(.98); }

/* One knob for photographs that arrive hot. A green plantation in full sun is a
   different exposure problem from a shed interior, and left alone it sits a
   whole stop above every other plate and reads as stock. Applied per image
   rather than by loosening the default, so the deck keeps one exposure. */
.plate-hot img { filter: saturate(.62) contrast(1.0) brightness(.62); }
.plate-hot .plate-frame:hover img { filter: saturate(.8) contrast(1.0) brightness(.76); }

/* The scrim. Two stops, both in --void: one along the bottom so the caption and
   the chip always have something to sit on regardless of what the photograph is
   doing there, and a light wash over the whole frame to seat it in the page. */
.plate-frame::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: var(--r);
  background:
    linear-gradient(to top, rgba(4, 16, 12, .88) 0%, rgba(4, 16, 12, .34) 34%, rgba(4, 16, 12, 0) 62%),
    linear-gradient(145deg, rgba(4, 16, 12, .30), rgba(4, 16, 12, .06));
  pointer-events: none;
}

/* A hairline of the governing accent along the bottom edge — the same key the
   charts and badges use, so the photograph is filed under the same species as
   the data beside it. --sp inherits from the section and falls back to brass at
   :root, so a plate outside any species section is simply brass. */
.plate-frame::before {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  border-radius: 0 0 var(--r) var(--r);
  background: linear-gradient(90deg, transparent, var(--sp) 22%, var(--sp) 78%, transparent);
  opacity: .55;
  z-index: 2;
}

/* The data chip. Deliberately overlapping the image's lower edge rather than
   inset within it, so it reads as laid on top of the record, not printed in it. */
.plate-chip {
  position: absolute; z-index: 3;
  right: clamp(16px, 2.4vw, 28px); bottom: -18px;
  display: grid; gap: 1px;
  padding: 13px 20px 14px;
  border-radius: calc(var(--r) - 6px);
  text-align: right;
}
.plate-k {
  font-family: var(--mono); font-size: 9.5px; font-weight: 500;
  letter-spacing: .15em; text-transform: uppercase; color: var(--faint);
}
.plate-v {
  font-family: var(--serif); font-size: clamp(1.25rem, 2.4vw, 1.7rem);
  font-weight: 400; line-height: 1.05; color: var(--sp);
  font-variant-numeric: tabular-nums;
}

/* The caption sits below the frame in the site's source voice, because that is
   what it is — a note on the record, not a slogan over a picture. The top margin
   has to clear the chip hanging 18px out of the frame above it. */
.plate-cap {
  margin: clamp(30px, 3vw, 38px) 0 0;
  max-width: 62ch;
  font-size: .93rem; color: var(--mute);
}
.plate-cap b { font-weight: 400; color: var(--ivory); }

/* Portrait sources (the layer house, the banana stand, Kigali) are cropped hard
   by object-fit at this ratio, which is intended — the plate is a horizontal
   band across the deck and the crop is part of the treatment. On a phone the
   band would leave nothing legible, so it opens up toward the source ratio. */
@media (max-width: 700px) {
  .plate img { aspect-ratio: 5 / 4; }
  .plate-chip { right: 14px; bottom: -16px; padding: 11px 16px 12px; }
}

/* One photograph is allowed to be atmosphere rather than evidence: the hills
   behind the front-page hero. It carries no chip and no caption, only the same
   filter and a far heavier scrim, because anything more would compete with the
   headline sitting on it. */
.plate-band { margin-bottom: 0; }
.plate-band .plate-frame { border: 0; box-shadow: none; border-radius: 0; }
.plate-band .plate-frame::before { display: none; }
.plate-band img { aspect-ratio: 21 / 6; border-radius: 0; filter: saturate(.42) contrast(1.05) brightness(.42); }
.plate-band .plate-frame::after {
  border-radius: 0;
  background:
    linear-gradient(to top, var(--void) 2%, rgba(4, 16, 12, .55) 46%, rgba(4, 16, 12, .82) 100%);
}
@media (max-width: 700px) { .plate-band img { aspect-ratio: 16 / 9; } }

/* ---------------------------------------------------------------------------
   23. Not found
   --------------------------------------------------------------------------- */

.nf-wrap { min-height: 76vh; display: grid; align-content: center; max-width: 62ch; }
.nf-links { display: flex; flex-wrap: wrap; gap: 10px 26px; margin-top: 30px; }
.nf-links a { font-family: var(--label); font-size: .9rem; font-weight: 600; color: var(--brass-l); text-decoration: none; }
.nf-links a:hover { color: var(--ivory); }

@media (max-width: 620px) {
  .hide-sm { display: none; }
}

/* ---------------------------------------------------------------------------
   24. Glyphs — the species marks, and the four things done about them.

   Drawn, not photographed, and drawn in the same hand as the icons inside the
   Hedge system: 24-unit box, 1.7 stroke, round caps, no fill. That is the
   deliberate reason there is no icon library here. A farmer who meets the pig
   glyph on this page meets the same pig glyph in the sidebar after signing in,
   and an illustration set bought in would have broken that on the first screen.

   They take currentColor, and every place they are used sets that to var(--sp),
   so a glyph is never a decoration floating free of the species it belongs to.
   --------------------------------------------------------------------------- */

.glyph { width: 24px; height: 24px; flex: none; color: var(--sp); }
.glyph svg { width: 100%; height: 100%; display: block; }

/* The disc a glyph sits in when it is doing structural work — a section marker
   or the head of a solve panel — rather than sitting inline in a list. */
.glyph-disc {
  display: inline-grid; place-items: center; flex: none;
  width: 46px; height: 46px; border-radius: 14px;
  color: var(--sp);
  background: color-mix(in srgb, var(--sp) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--sp) 34%, transparent);
}
.glyph-disc .glyph { width: 24px; height: 24px; }

/* Section heads on the species sections lead with the mark, so the reader knows
   what they are looking at before they read the label. */
.head-mark { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.head-mark .eyebrow { margin: 0; }

/* ---------------------------------------------------------------------------
   25. Solve — what the system does about it.

   Every other panel on this site is glass: a reading, held up to the light,
   deliberately provisional. These are not. A solve panel is opaque, keyed hard
   to the species colour, and sits at the end of each section as the one thing
   on the page making a claim rather than reporting a figure. The change of
   material is the argument — the evidence is behind glass, the answer is not.
   --------------------------------------------------------------------------- */

.solve {
  position: relative;
  margin-top: clamp(34px, 4vw, 54px);
  padding: clamp(26px, 3.4vw, 42px);
  border-radius: var(--r);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--sp) 30%, transparent);
  background:
    linear-gradient(152deg, color-mix(in srgb, var(--sp-d) 46%, transparent), transparent 62%),
    linear-gradient(180deg, var(--deep2), var(--deep));
  box-shadow: var(--glass-sh);
}

/* A hairline of the accent down the leading edge — the same device the plate
   uses along its bottom, so the two read as the same filing system. */
.solve::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: linear-gradient(180deg, transparent, var(--sp) 18%, var(--sp) 82%, transparent);
}

.solve-head { display: flex; align-items: center; gap: 16px; margin-bottom: 8px; }
.solve-t {
  margin: 0;
  font-family: var(--serif); font-size: clamp(1.3rem, 2.4vw, 1.85rem);
  font-weight: 400; line-height: 1.14; letter-spacing: -.018em;
  color: var(--ivory);
}
.solve-lede { margin: 0 0 clamp(24px, 3vw, 34px); max-width: 68ch; color: var(--mute); }
.solve-lede b { font-weight: 400; color: var(--ivory); }

.solve-steps { display: grid; gap: 18px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.solve-step {
  padding-top: 16px;
  border-top: 1px solid color-mix(in srgb, var(--sp) 26%, transparent);
}
.solve-step h4 {
  margin: 0 0 7px;
  font-family: var(--label); font-size: .82rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--sp);
}
.solve-step p { margin: 0; font-size: .95rem; color: var(--mute); }

@media (max-width: 860px) { .solve-steps { grid-template-columns: 1fr; gap: 22px; } }

/* ---------------------------------------------------------------------------
   26. Gains — what a farm actually walks away with.

   The four tiles under the hero. They are the only place on the site that
   addresses the reader in the second person, and they exist because the page
   spent its whole length proving a gap and never once said plainly what
   arrives. Each names a capability that has a section elsewhere on the site
   backing it, and links to it — nothing here is a claim this page invents.
   --------------------------------------------------------------------------- */

.gains { display: grid; gap: 16px; grid-template-columns: repeat(4, minmax(0, 1fr)); }

.gain {
  position: relative; display: block;
  padding: 26px 24px 24px;
  border-radius: var(--r);
  border: 1px solid var(--glass-brd);
  background: linear-gradient(158deg, var(--glass-hi), var(--glass-lo));
  text-decoration: none; color: inherit;
  overflow: hidden;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1), border-color .34s ease;
}
/* The wash is painted on a child layer so it can be faded on hover without
   animating the panel's own background, which would repaint the blur. */
.gain::after {
  content: '';
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(120% 90% at 8% 0%, color-mix(in srgb, var(--sp-d) 55%, transparent), transparent 64%);
  opacity: .5; transition: opacity .34s ease;
}
.gain > * { position: relative; z-index: 1; }
.gain:hover, .gain:focus-visible {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--sp) 46%, transparent);
}
.gain:hover::after, .gain:focus-visible::after { opacity: .95; }

.gain-t {
  margin: 16px 0 8px;
  font-family: var(--serif); font-size: 1.16rem; font-weight: 400;
  line-height: 1.24; color: var(--ivory);
}
.gain p { margin: 0; font-size: .91rem; line-height: 1.6; color: var(--mute); }
.gain-more {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 16px;
  font-family: var(--label); font-size: .78rem; font-weight: 600;
  letter-spacing: .04em; color: var(--sp);
}
.gain-more span { transition: transform .3s cubic-bezier(.2, .7, .3, 1); }
.gain:hover .gain-more span { transform: translateX(4px); }

@media (max-width: 1020px) { .gains { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .gains { grid-template-columns: 1fr; } }

@media (prefers-reduced-motion: reduce) {
  .gain, .gain::after, .gain-more span, .plate img { transition: none; }
  .gain:hover, .gain:focus-visible { transform: none; }
}

/* ---------------------------------------------------------------------------
   27. The species key — a legend for the colour system.

   Colour is only navigation if the reader is told what it keys to once. This is
   that one telling: seven swatches, each in its own accent, live ones filled
   and unbuilt ones outlined. It replaces the flat text list that was doing this
   job before, which named the species but showed none of their colours.
   --------------------------------------------------------------------------- */

.spkey { list-style: none; margin: 0 0 26px; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
.spkey li {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 16px 9px 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--sp) 40%, transparent);
  background: color-mix(in srgb, var(--sp-d) 34%, transparent);
  font-family: var(--label); font-size: .84rem; font-weight: 600;
  color: var(--ivory);
}
.spkey .glyph { width: 19px; height: 19px; }
.spkey em {
  font-family: var(--mono); font-style: normal; font-size: 9.5px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--sp);
}
.spkey li.off {
  border-style: dashed;
  border-color: rgba(157, 179, 166, .24);
  background: none;
  color: var(--faint);
}
.spkey li.off .glyph, .spkey li.off em { color: var(--faint); }
