/* GENERATED by build-css.py from css/NN-*.css: do not edit. */

/* ════ 00-foundation.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Foundation: tokens, reset, type, layout, buttons, links.
   Spec: design/DESIGN.md. Coordinator-owned; components consume, never redefine.
   ───────────────────────────────────────────────────────────────────────── */
:root{
  /* colour: her brand, Committed strategy (DESIGN.md §2) */
  --forest:#174226; --forest-2:#1F5232;
  --field:#457D57;  --sage:#CCDDB8;
  /* the primary action (DESIGN.md §2, §5): the strongest fill its ground allows, in her own two greens.
     On light grounds a forest button; on forest (.on-forest grounds below) a sage one. Was gold until 7 Oct. */
  --cta:var(--forest); --cta-ink:var(--white); --cta-hover:var(--forest-2); --cta-hover-ink:var(--white);
  --soil:#52311D;
  --ink:#14201A; --body:#2A3630; --muted:#4F5D55;
  --ground:#F3F6F3; --ground-2:#E7EDE8; --white:#FFFFFF;
  --line:#D5DED7; --line-strong:#AFBDB3;
  --on-forest:#E4ECE5; --on-forest-muted:#B6C7BA;
  --input-edge:#86978B;  /* form-control borders: 3.1:1 on white (--line-strong is decorative only) */
  --error:#9B2C1F; --error-bg:#FBEEEB;  /* 7.6:1 on white */
  --rule-on-forest:rgb(228 236 229 / .16);  /* hairlines on forest */
  --focus:var(--field);

  /* type: Archivo, one family on width + weight (DESIGN.md §3) */
  --sans:"Archivo","Helvetica Neue",Arial,sans-serif;
  --fs-display:clamp(2.6rem,1.6rem + 3.6vw,4.75rem);
  --fs-h2:clamp(1.9rem,1.3rem + 2vw,3rem);
  --fs-h3:clamp(1.25rem,1.1rem + .5vw,1.5rem);
  --fs-lead:clamp(1.125rem,1rem + .4vw,1.3rem);
  --fs-body:1.125rem; --fs-small:.9375rem; --fs-label:.78rem;

  /* space, shape, depth (DESIGN.md §4) */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px; --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px;
  --sec-pad:clamp(72px,9vw,128px);
  --wrap:1240px; --gutter:clamp(20px,4vw,40px);
  --r-sm:3px; --r:6px;
  --shadow-float:0 12px 32px -12px rgb(20 32 26 / .28);
  --ease:cubic-bezier(.16,1,.3,1);
  --z-base:1; --z-sticky:20; --z-header:30; --z-overlay:40; --z-sheet:50; --z-toast:60;

  /* legacy names, kept so untouched components still resolve. Do not use in new CSS. */
  --mint:var(--ground); --mint-2:var(--ground-2); --green:var(--field);
}

/* reset */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;scroll-padding-top:96px}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--ground);color:var(--body);font-family:var(--sans);font-size:var(--fs-body);line-height:1.6;font-stretch:100%;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;overflow-x:clip}
img,svg,video{display:block;max-width:100%;height:auto}
button,input,select,textarea{font:inherit;color:inherit}
p{margin:0;text-wrap:pretty}
ul,ol{margin:0}

/* type */
h1,h2,h3,h4{font-family:var(--sans);color:var(--ink);margin:0;text-wrap:balance}
h1{font-size:var(--fs-display);font-stretch:118%;font-weight:760;letter-spacing:-.025em;line-height:1.02}
h2{font-size:var(--fs-h2);font-stretch:114%;font-weight:720;letter-spacing:-.02em;line-height:1.08}
h3{font-size:var(--fs-h3);font-stretch:104%;font-weight:680;letter-spacing:-.01em;line-height:1.2}
h4{font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;line-height:1.2}
.lead{font-size:var(--fs-lead);line-height:1.5;font-weight:420;max-width:56ch;color:var(--body)}
.small{font-size:var(--fs-small);line-height:1.5}
/* The one kicker system: data labels only (DESIGN.md §3). Never an eyebrow above a section heading. */
.label{font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;line-height:1.2;color:var(--muted)}
.num{font-variant-numeric:tabular-nums lining-nums}
strong,b{font-weight:650}

/* links */
a{color:var(--field);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;transition:color .15s,text-decoration-thickness .15s}
a:hover{color:var(--forest);text-decoration-thickness:2px}
:focus-visible{outline:3px solid var(--focus);outline-offset:3px;border-radius:var(--r-sm)}

/* layout */
.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:var(--gutter);position:relative}
.sec{padding-block:var(--sec-pad);position:relative}
.sec--tight{padding-block:clamp(48px,6vw,80px)}
.sec--white{background:var(--white)}
.sec--forest{background:var(--forest);color:var(--on-forest)}
.sec--forest h2,.sec--forest h3{color:var(--white)}
.sec-head{max-width:62ch;margin-bottom:clamp(32px,4vw,56px)}
.sec-head p{margin-top:var(--s-4);font-size:var(--fs-lead);line-height:1.5;color:var(--muted)}
.sec--forest .sec-head p{color:var(--on-forest-muted)}

/* buttons (DESIGN.md §5): square-shouldered, one primary action */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:52px;padding:0 26px;border-radius:var(--r-sm);font-family:var(--sans);font-size:1rem;font-stretch:106%;font-weight:620;letter-spacing:.005em;line-height:1;text-decoration:none;cursor:pointer;border:1.5px solid transparent;transition:background-color .18s var(--ease),color .18s var(--ease),border-color .18s var(--ease);touch-action:manipulation;white-space:nowrap}
.btn svg{width:18px;height:18px;flex:none;transition:transform .2s var(--ease)}
.btn:hover svg{transform:translateX(3px)}
.btn:hover{text-decoration:none}
.btn--primary{background:var(--cta);color:var(--cta-ink)}
.btn--primary:hover{background:var(--cta-hover);color:var(--cta-hover-ink)}
/* forest grounds flip the primary to sage with forest text (7.9:1); hover lifts to white */
.sec--forest,.hero,.ctaband,.site-foot{--cta:var(--sage);--cta-ink:var(--forest);--cta-hover:var(--white);--cta-hover-ink:var(--forest)}
.btn--ghost{background:transparent;color:var(--forest);border-color:var(--forest)}
.btn--ghost:hover{background:var(--forest);color:var(--white)}
.sec--forest .btn--ghost,.btn--ghostlight{background:transparent;color:var(--white);border-color:var(--sage)}
.sec--forest .btn--ghost:hover,.btn--ghostlight:hover{background:var(--white);color:var(--forest);border-color:var(--white)}
.btn--onforest{background:var(--white);color:var(--forest)}
.btn--onforest:hover{background:var(--sage);color:var(--forest)}
.btn[disabled]{opacity:.6;cursor:progress}
@media (prefers-reduced-motion:reduce){.btn,.btn svg{transition:none}.btn:hover svg{transform:none}}

/* utilities */
[hidden]{display:none !important}
.visually-hidden{position:absolute !important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.skip{position:absolute;left:-999px;top:8px;background:var(--forest);color:#fff;padding:10px 14px;border-radius:var(--r-sm);z-index:var(--z-toast)}
.skip:focus{left:8px}

/* ════ 10-header.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Header: white bar, the real lockup, five-page nav, quiet phone, one primary action.
   Mobile: phone + Menu buttons open a full-height modal sheet (<dialog>).
   One header for every page: these sizes are the single source of truth.
   ───────────────────────────────────────────────────────────────────────── */
.site-head{
  /* local tokens (header only) */
  --head-h:84px;
  --head-logo:64px;          /* lockup height: the "AGRI SOIL" caps sit at about the nav's cap height */
  --head-shadow:0 1px 0 var(--line),0 14px 28px -22px rgb(20 32 26 / .32);
  position:sticky;top:0;z-index:var(--z-header);
  background:var(--white);
  box-shadow:0 1px 0 transparent;
  transition:box-shadow .25s var(--ease);
}
.site-head[data-stuck="true"]{box-shadow:var(--head-shadow)}
.site-head > .wrap{display:flex;align-items:center;min-height:var(--head-h)}

/* brand */
.brand{display:flex;align-items:center;flex:none;min-height:44px;margin-left:-3px;border-radius:var(--r-sm)}
.brand img{height:var(--head-logo);width:auto}

/* desktop nav: Archivo 106% / 620, a 2px forest rule under the active page */
.site-nav{display:flex;align-items:center;gap:var(--s-1);margin-left:clamp(28px,3.4vw,56px)}
.site-nav a{
  position:relative;display:inline-flex;align-items:center;min-height:44px;padding:0 14px;
  font-size:1rem;font-stretch:106%;font-weight:620;letter-spacing:.005em;line-height:1;
  color:var(--ink);text-decoration:none;border-radius:var(--r-sm);
  transition:color .15s var(--ease);
}
.site-nav a::after{
  content:"";position:absolute;left:14px;right:14px;bottom:6px;height:2px;
  background:var(--field);transform:scaleX(0);transform-origin:left center;
  transition:transform .25s var(--ease),background-color .15s;
}
.site-nav a:hover{color:var(--forest)}
.site-nav a:hover::after{transform:scaleX(1)}
.site-nav a[aria-current="page"]{color:var(--forest)}
.site-nav a[aria-current="page"]::after{transform:scaleX(1);background:var(--forest)}

/* right cluster */
.head-right{margin-left:auto;display:flex;align-items:center;gap:var(--s-5)}
.head-phone{
  display:inline-flex;align-items:center;gap:10px;min-height:44px;padding:0 4px;
  color:var(--ink);text-decoration:none;white-space:nowrap;border-radius:var(--r-sm);
  font-size:1rem;font-stretch:106%;font-weight:620;letter-spacing:.01em;line-height:1;
  font-variant-numeric:tabular-nums lining-nums;
}
.head-phone svg{width:18px;height:18px;flex:none;color:var(--field);transition:color .15s}
.head-phone span{text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:1px;text-underline-offset:5px;transition:text-decoration-color .15s,color .15s}
.head-phone:hover{color:var(--forest)}
.head-phone:hover svg{color:var(--forest)}
.head-phone:hover span{text-decoration-color:currentColor}
.head-cta{min-height:48px;padding:0 22px}

/* menu button (hidden on desktop) */
.menu-btn,.menu-close{
  display:none;align-items:center;gap:10px;min-height:44px;padding:0 14px;
  background:var(--white);color:var(--forest);border:1px solid var(--line-strong);border-radius:var(--r-sm);
  font-size:1rem;font-stretch:106%;font-weight:620;letter-spacing:.005em;line-height:1;cursor:pointer;
  touch-action:manipulation;transition:border-color .15s,background-color .15s;
}
.menu-btn svg,.menu-close svg{width:20px;height:20px;flex:none}
.menu-btn:hover,.menu-close:hover{border-color:var(--forest);background:var(--ground)}

/* tight desktop: keep the number from crowding the nav */
@media (max-width:1180px){
  .site-nav a{padding:0 11px}
  .site-nav a::after{left:11px;right:11px}
  .head-right{gap:var(--s-4)}
}

/* ── tablet + phone ─────────────────────────────────────────────────── */
@media (max-width:1040px){
  .site-head{--head-h:72px;--head-logo:50px}
  .site-nav{display:none}
  .head-right{gap:var(--s-2)}
  .head-phone{
    justify-content:center;width:44px;height:44px;padding:0;
    border:1px solid var(--line-strong);border-radius:var(--r-sm);color:var(--forest);
  }
  .head-phone svg{color:var(--forest)}
  .head-phone span{display:none}
  .head-phone:hover{border-color:var(--forest);background:var(--ground)}
  .head-cta{min-height:44px;padding:0 18px;margin-right:var(--s-1)}
  .menu-btn{display:inline-flex}
}
/* Below 821px the home page's sticky bar (24-home-variants.css) carries "Get a price"; on a phone the sheet does. */
@media (max-width:820px){body:has(.sticky-cta) .head-cta{display:none}}
@media (max-width:560px){.head-cta{display:none}}
@media (max-width:400px){
  .site-head{--head-logo:46px}
  .menu-btn{padding:0 12px}
}
@media (max-width:350px){.site-head{--head-logo:40px}}

/* ── the sheet ──────────────────────────────────────────────────────── */
.menu-sheet{
  position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0;border:0;
  background:var(--white);color:var(--body);
  display:none;flex-direction:column;overflow-y:auto;overscroll-behavior:contain;
}
.menu-sheet[open]{display:flex;animation:sheet-in .32s var(--ease)}
.menu-sheet::backdrop{background:var(--white)}
@keyframes sheet-in{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
html.menu-open{overflow:hidden}
html.menu-open body{overflow:hidden}

.menu-sheet__bar{
  display:flex;align-items:center;justify-content:space-between;flex:none;
  min-height:72px;padding-inline:var(--gutter);border-bottom:1px solid var(--line);
}
.menu-sheet__bar img{height:50px;width:auto;margin-left:-3px}
.menu-close{display:inline-flex}

.menu-sheet__nav{display:flex;flex-direction:column;padding:var(--s-3) var(--gutter) 0}
.menu-sheet__nav a{
  display:flex;align-items:center;justify-content:space-between;min-height:68px;
  border-bottom:1px solid var(--line);
  font-size:1.75rem;font-stretch:112%;font-weight:700;letter-spacing:-.015em;line-height:1.1;
  color:var(--ink);text-decoration:none;
}
.menu-sheet__nav a::after{
  content:"";width:10px;height:10px;flex:none;margin-right:6px;
  border-top:2px solid var(--line-strong);border-right:2px solid var(--line-strong);transform:rotate(45deg);
  transition:border-color .15s,transform .2s var(--ease);
}
.menu-sheet__nav a:hover{color:var(--forest)}
.menu-sheet__nav a:hover::after{border-color:var(--forest);transform:translateX(3px) rotate(45deg)}
.menu-sheet__nav a[aria-current="page"]{color:var(--forest);text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:8px}
.menu-sheet__nav a[aria-current="page"]::after{border-color:var(--forest)}
.menu-sheet__nav a:focus-visible{outline-offset:-3px}

.menu-sheet__acts{display:grid;gap:var(--s-3);margin-top:auto;padding:var(--s-6) var(--gutter) max(var(--s-6),env(safe-area-inset-bottom))}
.menu-sheet__acts .btn{width:100%}
.menu-sheet__acts .btn--ghost svg{transform:none}
.menu-sheet__acts p{margin-top:var(--s-3);font-size:var(--fs-small);line-height:1.6;color:var(--muted)}
.menu-sheet__acts p a{font-weight:620}

@media (prefers-reduced-motion:reduce){
  .site-head,.site-nav a,.site-nav a::after,.menu-sheet__nav a::after{transition:none}
  .menu-sheet[open]{animation:none}
}

/* ════ 20-hero.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Hero: the split Francesca chose (21 Sep). Words on forest, set on the page
   grid so the headline's left edge is the logo's left edge; the photograph
   runs from the split to the viewport edge. One load sequence (DESIGN.md §7).
   Mobile: words first (the promise and the button inside the first screen in
   a cab), then the photograph as a landscape band that closes the hero.

   Her method is the drawing. One real field in the photograph (the pasture below
   the river) is plotted: a sampling grid in its perspective, clipped to its
   hedges, with one cell selected (its point and the twelve cores that make the
   sample). Left alone, it runs a draw every few seconds like a roulette wheel
   (Luke, 7 Oct): a light runs cell to cell from the field's top-left down to the
   bottom, snaking row by row with a fading trail (.hero__plot-trail), slows, and
   stops on a random cell, which builds itself. Point at a cell and it is selected at once;
   move away and it stays there until the draw resumes. The page script runs it,
   paused while the hero is off screen or the tab is hidden. With no JS, reduced
   motion or in a render, the default cell simply stays selected.
   The panel is forest with a slight lift toward the photograph, over a faint
   contour sheet (an OS-map cue, low contrast, thinning behind the headline). With
   motion allowed, the page script swaps the static svg for a canvas tracing the same
   hills plus slow 3D noise, so the terrain morphs over ~30s (~1ms a frame at 15fps).
   The seam is a map neatline with edge ticks; the caption plate sits across it
   clear of the bottom edge, so the halves read as one sheet.
   Drawings: tools/hero-plot.py (the grid), tools/hero-contours.py (the contours).
   ───────────────────────────────────────────────────────────────────────── */
.hero{
  /* local tokens (hero only) */
  --hero-head:84px;                                   /* the sticky header above (10-header.css) */
  --hero-side:max(var(--gutter),calc((100% - var(--wrap)) / 2 + var(--gutter)));   /* % = the hero's own width */
  --hero-pad:clamp(40px,4.2vw,64px);
  --hero-rule:rgb(204 221 184 / .22);                  /* --sage at 22% on forest: hairlines inside the panel */
  --hero-seam:rgb(204 221 184 / .42);                  /* the neatline and its ticks */
  --hero-h1:clamp(2.55rem,1.2rem + 3.4vw,4.35rem);
  --hero-plot-rest:.52;                                /* the field grid after it has drawn */
  --hero-in:cubic-bezier(.16,1,.3,1);

  position:relative;isolation:isolate;overflow:hidden;
  display:grid;
  grid-template-columns:[full-start] var(--hero-side) [copy-start] minmax(0,58fr) [split] minmax(0,42fr) var(--hero-side) [full-end];
  min-height:clamp(540px,calc(100svh - var(--hero-head) - 96px),780px);   /* the notice band peeks in on a laptop */
  /* forest, lifting a touch toward the photograph so the panel has depth, not a flat fill */
  background:var(--forest) linear-gradient(98deg,var(--forest) 38%,#1B4A2C 100%);
  color:var(--on-forest);
}

.hero__panel{grid-column:copy-start / split;grid-row:1;display:flex;align-items:center;padding:var(--hero-pad) clamp(32px,4.4vw,72px) var(--hero-pad) 0}
.hero__copy{max-width:640px}

/* the panel's ground: contours in sage, barely there, thinning out behind the headline (top-left)
   and strongest low on the panel near the seam, where there are no words */
.hero__contours{position:absolute;z-index:-1;grid-column:full-start / split;grid-row:1;inset:0;width:100%;height:100%;
  fill:none;stroke:var(--sage);stroke-width:1;stroke-opacity:.13;pointer-events:none;
  -webkit-mask:linear-gradient(160deg,rgb(0 0 0 / .25) 18%,#000 72%);mask:linear-gradient(160deg,rgb(0 0 0 / .25) 18%,#000 72%)}
.hero__contours path{vector-effect:non-scaling-stroke}
.hero__contours .hero__contours-index{stroke-width:1.5;stroke-opacity:.2}

/* headline: two set lines ("Know what's in your soil" / "before you spend on it."), each balanced */
.hero h1{color:var(--white);font-size:var(--hero-h1);line-height:1;letter-spacing:-.028em}
.hero__line{display:block}
.hero h1 .accent{color:var(--sage)}
.hero .lead{margin-top:clamp(20px,2vw,28px);max-width:50ch;color:var(--on-forest)}

/* actions: the primary (sage on forest, DESIGN.md §5), sage-ruled secondary */
.hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(28px,3vw,40px)}
.hero__cta .btn--ghostlight svg{width:17px;height:17px}
.hero__cta .btn--ghostlight span{font-variant-numeric:tabular-nums lining-nums}
.hero__cta .btn--ghostlight:hover svg{transform:none}

/* proof line: three facts from the copy, on a hairline. Not badges. Two and one, in two
   columns that size to their words (Luke, 7 Oct: on one row they looked crammed), one column on a phone. */
.hero__proof{list-style:none;margin:clamp(24px,2.6vw,36px) 0 0;padding:18px 0 0;border-top:1px solid var(--hero-rule);display:flex;flex-wrap:nowrap;gap:10px clamp(16px,1.7vw,26px)}   /* one row on desktop (Luke, 7 Oct) */
@media (max-width:1100px){.hero__proof{flex-wrap:wrap}}
.hero__proof li{display:flex;align-items:center;gap:8px;white-space:nowrap;font-size:var(--fs-small);font-weight:500;line-height:1.3;color:var(--on-forest-muted)}
.hero__proof li::before{content:"";flex:none;width:15px;height:15px;background:var(--sage);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/contain no-repeat}

/* ── photograph: split → viewport edge, no frame, no shadow (DESIGN.md §6) ── */
.hero__photo{grid-column:split / full-end;grid-row:1;position:relative;margin:0;background:var(--forest-2)}
/* the frame crops; the plate keeps the photo's own 16:9 and covers the frame the way
   object-fit:cover would (anchored 56% across), so the grid drawn in photo coordinates
   stays registered to the land at any size */
.hero__frame{position:absolute;inset:0;overflow:hidden;container-type:size}
.hero__plate{position:absolute;left:56%;top:50%;width:max(100cqw,177.778cqh);aspect-ratio:16 / 9;translate:-56% -50%;transform-origin:50% 100%}
.hero__plate img{display:block;width:100%;height:100%}
@supports not (width:1cqw){
  .hero__plate{inset:0;width:auto;translate:none}
  .hero__plate img{object-fit:cover;object-position:56% 50%}
  .hero__plot{display:none}
}

/* the plotted field: hairlines in the field's own perspective, clipped to its hedges */
.hero__plot{position:absolute;inset:0;width:100%;height:100%;fill:none;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.hero__plot-grid{opacity:var(--hero-plot-rest)}
.hero__plot-grid path{stroke:#fff;stroke-opacity:.6;stroke-width:1;vector-effect:non-scaling-stroke}
/* the selected cell: its outline, its point, and the twelve cores that make the sample.
   Four layers, so a slow draw can overlap the one or two still fading out.
   The draw (idle) is slow and eased both ways; pointing is quick (.is-pointing). */
.hero{--cell-fade:2.2s;--cell-ease:cubic-bezier(.45,.05,.35,1)}
.hero__plot-cell{opacity:0;transition:opacity var(--cell-fade) var(--cell-ease)}
.hero__plot-cell.is-on{opacity:1}
.hero__photo.is-pointing{--cell-fade:.35s;--cell-ease:var(--hero-in)}
.hero__plot-edge{stroke:#fff;stroke-opacity:.9;stroke-width:1.5;vector-effect:non-scaling-stroke}
.hero__plot-cores{stroke:#fff}
.hero__plot-mark{stroke:var(--sage)}
@media (hover:hover) and (pointer:fine){.hero__photo.is-live{cursor:crosshair}}
/* the draw's running light: each cell it passes lights (a faint fill and a bright edge) and
   fades behind it like a trail. Drawn by the page script into .hero__plot-trail. */
.hero__plot-trail path{fill:#fff;fill-opacity:.18;stroke:#fff;stroke-opacity:.9;stroke-width:1.5;vector-effect:non-scaling-stroke;opacity:0}
.hero__plot-trail path.is-lit{animation:hero-trail .95s linear both}
@keyframes hero-trail{0%{opacity:1}15%{opacity:.8}100%{opacity:0}}
/* a drawn cell builds itself: outline, then the point, then the twelve cores */
@media (prefers-reduced-motion:no-preference){
  .hero__plot-cell.is-drawn .hero__plot-edge{animation:hero-fade 1.4s var(--cell-ease) both}
  .hero__plot-cell.is-drawn .hero__plot-mark{animation:hero-fade 1.2s var(--cell-ease) .45s both}
  .hero__plot-cell.is-drawn .hero__plot-cores{animation:hero-fade 1.5s var(--cell-ease) .8s both}
}
@media (prefers-reduced-motion:reduce){.hero__plot-cell{transition:none}}

/* the seam: a neatline with ticks every 48px (a longer one every fourth), pointing into the panel like an OS sheet edge */
.hero__photo::before{content:"";position:absolute;z-index:var(--z-base);top:0;bottom:0;left:0;width:15px;translate:-100% 0;pointer-events:none;
  background:
    linear-gradient(var(--hero-seam),var(--hero-seam)) 100% 0 / 1px 100% no-repeat,
    repeating-linear-gradient(180deg,var(--hero-seam) 0 1px,transparent 1px 48px) 100% 24px / 7px 100% no-repeat,
    repeating-linear-gradient(180deg,var(--hero-seam) 0 1px,transparent 1px 192px) 100% 24px / 15px 100% no-repeat}

/* caption: a plate across the seam near the bottom, part on the panel, part on the land (Luke, 5 Oct).
   It floats clear of the bottom edge in a full hairline frame (Luke, 7 Oct: flush on the edge, its
   frame was cut off and it looked clipped). A real caption, in the label voice. */
.hero__caption{--cap-in:clamp(28px,2.6vw,44px);--cap-low:clamp(20px,2.4vw,36px);
  position:absolute;z-index:calc(var(--z-base) + 1);left:calc(-1 * var(--cap-in));bottom:var(--cap-low);
  display:flex;flex-direction:column;gap:6px;max-width:calc(100% + var(--cap-in) - 24px);
  padding:14px 22px 15px;background:var(--forest);border:1px solid var(--hero-seam);border-radius:var(--r-sm)}
.hero__caption .label{color:var(--sage)}
.hero__caption-sub{font-size:var(--fs-small);line-height:1.2;color:var(--on-forest-muted)}

/* ── load: one sequence, ≤1.6s. The lines rise, the photo settles, the grid
   draws across the field near → far, the cell is plotted,
   the caption slides in, and the grid rests. CSS only; every end state is the
   resting style above, so no JS, a headless render or reduced motion all show it. ── */
@media (prefers-reduced-motion:no-preference){
  .hero__plate img{animation:hero-settle 1.1s var(--hero-in) both}
  .hero__line,.hero .lead,.hero__cta,.hero__proof{animation:hero-rise .9s var(--hero-in) both}
  .hero__line:nth-child(1){animation-delay:60ms}
  .hero__line:nth-child(2){animation-delay:140ms}
  .hero .lead{animation-delay:220ms}
  .hero__cta{animation-delay:300ms}
  .hero__proof{animation-delay:380ms}
  /* the field is plotted from its near hedge to its far one (a clip sweep: the lines are 1px at any size), then the default cell */
  .hero__plot-grid{animation:hero-sweep .8s cubic-bezier(.5,0,.2,1) .45s both,hero-plot-rest .4s var(--hero-in) 1.2s both}
  .hero__plot-cell--first .hero__plot-edge{animation:hero-fade .45s var(--hero-in) .95s both}
  .hero__plot-cell--first .hero__plot-mark{animation:hero-fade .4s var(--hero-in) 1s both}
  .hero__plot-cell--first .hero__plot-cores{animation:hero-fade .45s var(--hero-in) 1.1s both}
  .hero__caption{animation:hero-slide .6s var(--hero-in) .95s both}
  .hero__contours{animation:hero-fade 1.6s ease-out .2s both}
}
@keyframes hero-fade{from{opacity:.001}}
@keyframes hero-settle{from{opacity:.001;transform:scale(1.04)}to{opacity:1;transform:none}}
@keyframes hero-rise{from{opacity:.001;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes hero-sweep{from{clip-path:inset(100% 0 0 0)}to{clip-path:inset(0)}}
@keyframes hero-plot-rest{from{opacity:1}to{opacity:var(--hero-plot-rest)}}
@keyframes hero-slide{from{opacity:.001;transform:translateX(-14px)}to{opacity:1;transform:none}}

/* ── depth: as the page scrolls, the photograph drifts slower than the page (it is
   scaled 1.06 from its bottom edge, so the drift never shows an edge).
   Scroll-driven CSS only; static elsewhere. ── */
@supports (animation-timeline:scroll()){
  @media (prefers-reduced-motion:no-preference) and (min-width:901px){
    .hero__plate{transform:scale(1.06);animation:hero-drift-photo linear both;animation-timeline:scroll(root);animation-range:0 100vh}
  }
}
@keyframes hero-drift-photo{from{transform:scale(1.06)}to{transform:translateY(5%) scale(1.06)}}

@media (max-width:1040px){.hero{--hero-head:72px}}
@media (max-width:1100px) and (min-width:901px){
  .hero__panel{padding-right:40px}
}
/* short laptop screens: a smaller headline so the notice still peeks in */
@media (min-width:901px) and (max-height:820px){
  .hero{--hero-h1:clamp(2.4rem,1.1rem + 3vw,3.75rem);--hero-pad:clamp(36px,3.6vw,52px)}
  .hero .lead{margin-top:18px}
  .hero__cta{margin-top:26px}
  .hero__proof{margin-top:26px;padding-top:16px}
}

/* stacked: words, then the photograph as a band; the seam turns horizontal */
@media (max-width:900px){
  .hero{grid-template-columns:[full-start] var(--gutter) [copy-start] minmax(0,1fr) [split] var(--gutter) [full-end];min-height:0;
    background:var(--forest) linear-gradient(180deg,var(--forest) 40%,#1B4A2C 100%)}
  .hero__panel{grid-column:copy-start / split;grid-row:1;padding:clamp(40px,8vw,64px) 0 clamp(40px,8vw,56px)}
  .hero__copy{max-width:640px}
  .hero__photo{grid-column:full-start / full-end;grid-row:2;height:clamp(220px,58vw,460px)}
  .hero__photo::before{top:0;bottom:auto;left:0;right:0;width:auto;height:15px;translate:0 -100%;
    background:
      linear-gradient(var(--hero-seam),var(--hero-seam)) 0 100% / 100% 1px no-repeat,
      repeating-linear-gradient(90deg,var(--hero-seam) 0 1px,transparent 1px 48px) var(--gutter) 100% / 100% 7px no-repeat,
      repeating-linear-gradient(90deg,var(--hero-seam) 0 1px,transparent 1px 192px) var(--gutter) 100% / 100% 15px no-repeat}
  .hero__caption{left:var(--gutter);bottom:16px;max-width:calc(100% - 2 * var(--gutter))}
  .hero__caption::before{display:none}
}
@media (max-width:560px){
  .hero{--hero-h1:clamp(2.3rem,1.2rem + 5.4vw,2.75rem)}
  .hero h1{letter-spacing:-.03em}
  .hero__cta{flex-direction:column;gap:10px}
  .hero__cta .btn{width:100%;min-height:56px}
  .hero__proof{flex-direction:column;gap:10px}
  /* the caption moves under the photograph so it never covers a third of a small crop */
  .hero__photo{height:auto;background:var(--forest)}
  .hero__frame{position:relative;inset:auto;aspect-ratio:4 / 3}
  .hero__caption{position:static;max-width:none;padding:14px var(--gutter) 18px;border:0;border-radius:0;animation:none}
}

/* ════ 21-due.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Five-year notice: the statutory hook, set like an official notice. A soil-
   brown "5 year rule" plate (the plate on a gate or a Defra leaflet), the rule
   in plain words, one ruled action. --soil is the notice's colour (DESIGN.md §2).
   Also used on the About page, so it carries no home-only assumptions.
   ───────────────────────────────────────────────────────────────────────── */
.due{
  /* local tokens (notice only) */
  --due-plate:clamp(76px,7vw,92px);
  background:var(--white);border-bottom:1px solid var(--line);
}
.due__inner{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:clamp(20px,3vw,40px);padding-block:clamp(24px,2.6vw,32px)}

/* the plate */
.due__mark{width:var(--due-plate);aspect-ratio:1;display:grid;place-content:center;justify-items:center;gap:6px;border:2px solid var(--soil);border-radius:var(--r-sm);color:var(--soil)}
.due__num{font-size:calc(var(--due-plate) * .5);font-stretch:118%;font-weight:760;line-height:.8;letter-spacing:-.04em}
.due__unit{font-size:.62rem;font-stretch:125%;font-weight:680;letter-spacing:.14em;line-height:1.15;text-transform:uppercase;text-align:center}

/* the rule */
.due__body{padding-left:clamp(20px,3vw,40px);border-left:1px solid var(--line);min-height:var(--due-plate);display:flex;flex-direction:column;justify-content:center;gap:6px}
.due__head{font-size:var(--fs-h3);font-stretch:108%;font-weight:720;letter-spacing:-.01em;line-height:1.15;color:var(--soil)}
.due__text{max-width:70ch;font-size:1.0625rem;line-height:1.5;color:var(--body)}
.due__text b{font-weight:700;color:var(--ink)}

/* the action: ruled, not filled (the filled primary is the hero's one action in this viewport) */
.due__act{white-space:nowrap}

@media (max-width:900px){
  .due__inner{grid-template-columns:auto minmax(0,1fr);row-gap:20px}
  .due__act{grid-column:1 / -1;justify-self:start}
}
@media (max-width:560px){
  .due{--due-plate:64px}
  .due__inner{column-gap:16px;align-items:start}
  .due__body{padding-left:16px;min-height:0}
  .due__text{font-size:1rem}
  .due__act{justify-self:stretch;width:100%}
}
/* narrowest phones: the plate sits beside the question; the rule takes the full width beneath */
@media (max-width:420px){
  .due{--due-plate:58px}
  .due__inner{align-items:center;row-gap:16px}
  .due__body{display:contents}
  .due__text{grid-column:1 / -1}
}

/* Entrance, once, as it comes into view (the page script sets .is-armed, then .is-in):
   the plate settles, the 5 rolls up into it like a counter turning over, then the
   question, the rule and the action follow. Under a second; a peek on load waits for
   the hero (--due-d). No JS, reduced motion or a render: no .is-armed, all static. */
@media (prefers-reduced-motion:no-preference){
  .due.is-armed .due__mark{overflow:hidden;opacity:.001;transform:scale(.94);
    transition:opacity .5s var(--ease) var(--due-d,0ms),transform .7s var(--ease) var(--due-d,0ms)}
  .due.is-armed .due__num{transform:translateY(var(--due-plate));transition:transform .9s var(--ease) calc(var(--due-d,0ms) + .12s)}
  .due.is-armed .due__unit{opacity:.001;transition:opacity .5s var(--ease) calc(var(--due-d,0ms) + .5s)}
  .due.is-armed :is(.due__head,.due__text,.due__act){opacity:.001;transform:translateY(10px);
    transition:opacity .6s var(--ease) var(--d),transform .8s var(--ease) var(--d)}
  .due.is-armed .due__head{--d:calc(var(--due-d,0ms) + .2s)}
  .due.is-armed .due__text{--d:calc(var(--due-d,0ms) + .3s)}
  .due.is-armed .due__act{--d:calc(var(--due-d,0ms) + .45s)}
  .due.is-armed.is-in :is(.due__mark,.due__num,.due__unit,.due__head,.due__text,.due__act){opacity:1;transform:none}
}

/* ════ 22-audience.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Who it's for: three photo cards (Francesca's pick). Not boxed tiles: the
   photograph carries the card, the words sit on the ground beneath it, and
   every row (tag, words, action) lines up across the three via subgrid.
   Photos are stand-ins: the frame fixes the ratio, object-fit does the crop,
   so any replacement drops in without moving a baseline.
   ───────────────────────────────────────────────────────────────────────── */
#for{
  /* local tokens (audience only) */
  --path-ratio:5 / 4;
  --path-gap:clamp(20px,2.6vw,36px);
}

/* head: the h2 and its line share a row, line set to the h2's last baseline */
.for-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px var(--path-gap);align-items:last baseline;margin-bottom:clamp(36px,4.4vw,64px)}
.for-head h2{max-width:14ch}
.for-head p{max-width:44ch;justify-self:end;font-size:var(--fs-lead);line-height:1.5;color:var(--muted)}

.paths{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));column-gap:var(--path-gap);row-gap:0}
.path{position:relative;display:grid;grid-row:span 4;grid-template-rows:subgrid;align-content:start;row-gap:0}

.path__img{position:relative;overflow:hidden;aspect-ratio:var(--path-ratio);border-radius:var(--r);background:var(--ground-2)}
.path__img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}

.path__tag{margin-top:22px;color:var(--field)}
.path__body{margin-top:10px}
.path h3{font-size:clamp(1.45rem,1.15rem + .8vw,1.9rem);font-stretch:112%;font-weight:720;letter-spacing:-.018em;line-height:1.1}
.path__text{margin-top:12px;color:var(--body);max-width:40ch}

/* the action row: a hairline, the words, the arrow at the far edge. The whole card is the target. */
.path__link{margin-top:24px;display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:56px;border-top:1px solid var(--line-strong);
  font-size:1rem;font-stretch:106%;font-weight:620;letter-spacing:.005em;color:var(--forest);text-decoration:none;transition:border-color .2s var(--ease),color .2s var(--ease)}
.path__link svg{width:20px;height:20px;flex:none;transition:transform .25s var(--ease)}
.path__link::after{content:"";position:absolute;inset:0;z-index:var(--z-base)}   /* stretched link */
.path__link:hover{text-decoration:none}
.path__link:focus-visible{outline:none}
.path:has(.path__link:focus-visible){outline:3px solid var(--focus);outline-offset:6px;border-radius:var(--r)}
.path:hover .path__link{border-top-color:var(--forest)}
.path:hover .path__link svg{transform:translateX(4px)}
.path:hover .path__img img{transform:scale(1.035)}

@media (prefers-reduced-motion:reduce){.path__img img,.path__link svg{transition:none}.path:hover .path__img img,.path:hover .path__link svg{transform:none}}

/* tablet: three rows, photograph left, words right */
@media (max-width:960px){
  .for-head{grid-template-columns:1fr}
  .for-head p{justify-self:start}
  .paths{grid-template-columns:1fr;row-gap:clamp(28px,4vw,40px)}
  .path{grid-row:auto;grid-template-rows:auto 1fr auto;grid-template-columns:minmax(0,5fr) minmax(0,6fr);column-gap:clamp(24px,4vw,40px)}
  .path__img{grid-column:1;grid-row:1 / span 3;align-self:start}
  .path > :not(.path__img){grid-column:2}
  .path__tag{margin-top:4px}
}
/* phone: stacked, a slightly wider crop so three cards don't become a long scroll */
@media (max-width:600px){
  #for{--path-ratio:3 / 2}
  .paths{row-gap:44px}
  .path{grid-template-columns:1fr;grid-template-rows:none}
  .path__img{grid-row:auto}
  .path > :not(.path__img){grid-column:1}
  .path__tag{margin-top:18px}
  .path__link{margin-top:18px}
}

/* ════ 23-frames.css ════ */
/* Framed figures (report maps, documents): a hairline and the --r corner. No white mat,
   no shadow (DESIGN.md §6): the report's own page is the frame. */
.frame{margin:0;background:var(--white);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.frame img{width:100%}

/* ════ 24-home-variants.css ════ */
/* Home-page section variants (Francesca's picks are hero 1, for 2, teasers 1, proof 1, cta 1, enq 1, sticky 1) */
/* ── hero, notice, who it's for: one layout each now (picked 21 Sep); styles live in 20-hero.css, 21-due.css, 22-audience.css ── */

/* ─────────────────────────────────────────────────────────────────────────
   Start here: four routes on a diagonal. Each row pairs a wide tile with a
   narrow one (7 + 5 of 12 columns), swapped on the second row, and every
   photograph in a row shares one height, so the widths differ and the
   baselines don't. Same card grammar as the audience cards above (photo,
   words on the ground, a ruled action row), so the page reads as one system.
   ───────────────────────────────────────────────────────────────────────── */
.starts{
  /* local tokens (start-here only) */
  --tile-img-h:clamp(240px,23vw,330px);
  --tile-gap-x:clamp(24px,3vw,44px);
  --tile-gap-y:clamp(48px,5vw,72px);
  border-bottom:1px solid var(--line);   /* the report proof follows on white */
}
.more-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px var(--tile-gap-x);align-items:last baseline;margin-bottom:clamp(36px,4.4vw,64px)}
.more-head p{max-width:44ch;justify-self:end;font-size:var(--fs-lead);line-height:1.5;color:var(--muted)}

.tiles{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--tile-gap-y) var(--tile-gap-x)}
.tile{position:relative;display:grid;grid-template-rows:auto auto 1fr auto;align-content:start}
.tile--wide{grid-column:span 7}
.tile--narrow{grid-column:span 5}

.tile__img{position:relative;height:var(--tile-img-h);overflow:hidden;border-radius:var(--r);background:var(--ground-2)}
.tile__img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease)}
/* the report tile: the page itself on the table, whole, with a hairline edge. Never cropped. */
.tile--doc .tile__img{display:grid;place-items:center;padding:clamp(16px,1.8vw,26px)}
.tile--doc .tile__img img{position:static;width:100%;height:100%;object-fit:contain;background:var(--white);outline:1px solid var(--line);transform-origin:50% 50%}

.tile__head{margin-top:clamp(20px,2vw,26px);font-size:clamp(1.4rem,1.15rem + .7vw,1.8rem);font-stretch:112%;font-weight:720;letter-spacing:-.018em;line-height:1.1}
.tile__text{margin-top:10px;max-width:46ch;color:var(--body)}

.tile__link{margin-top:22px;display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:56px;border-top:1px solid var(--line-strong);
  font-size:1rem;font-stretch:106%;font-weight:620;letter-spacing:.005em;color:var(--forest);text-decoration:none;transition:border-color .2s var(--ease)}
.tile__link svg{width:20px;height:20px;flex:none;transition:transform .25s var(--ease)}
.tile__link::after{content:"";position:absolute;inset:0;z-index:var(--z-base)}   /* the whole tile is the target */
.tile__link:hover{text-decoration:none}
.tile__link:focus-visible{outline:none}
.tile:has(.tile__link:focus-visible){outline:3px solid var(--focus);outline-offset:6px;border-radius:var(--r)}
.tile:hover .tile__link{border-top-color:var(--forest)}
.tile:hover .tile__link svg{transform:translateX(4px)}
.tile:hover .tile__img img{transform:scale(1.035)}
.tile--doc:hover .tile__img img{transform:scale(1.02)}
@media (prefers-reduced-motion:reduce){.tile__img img,.tile__link svg{transition:none}.tile:hover .tile__img img,.tile:hover .tile__link svg{transform:none}}

@media (max-width:960px){
  .more-head{grid-template-columns:1fr}
  .more-head p{justify-self:start}
  .tile--wide,.tile--narrow{grid-column:span 6}
}
/* phone: the two big routes keep their photographs; Report and Blog become
   compact rows (thumbnail beside the words) so four tiles aren't four screens */
@media (max-width:640px){
  .starts{--tile-gap-y:40px}
  .tiles{grid-template-columns:1fr}
  .tile--wide,.tile--narrow{grid-column:auto}
  .tile--wide .tile__img{height:auto;aspect-ratio:3 / 2}
  .tile--narrow{grid-template-columns:112px minmax(0,1fr);grid-template-rows:auto 1fr auto;column-gap:18px}
  .tile--narrow .tile__img{grid-row:1 / span 2;height:auto;aspect-ratio:1}
  .tile--narrow.tile--doc .tile__img{padding:10px}
  .tile--narrow .tile__head{margin-top:0}
  .tile--narrow .tile__text{margin-top:6px;font-size:1rem}
  .tile--narrow .tile__link{grid-column:1 / -1;margin-top:16px}
  .tile__head{margin-top:18px}
  .tile__link{margin-top:16px}
}

/* ─────────────────────────────────────────────────────────────────────────
   Mid-page call to action: a forest band with presence. Her line at near-
   display size, the reason and the one gold action beside it on a hairline,
   the phone set as a number you can read from across a kitchen. A faint
   contour sheet (sage) runs off the right edge: an OS-map cue, not decoration
   for its own sake.
   ───────────────────────────────────────────────────────────────────────── */
.ctaband{
  /* local tokens (band only) */
  --cta-h2:clamp(2.4rem,1.4rem + 3.4vw,4.4rem);
  position:relative;isolation:isolate;overflow:hidden;background:var(--forest);color:var(--on-forest);padding-block:clamp(64px,8vw,112px)}
.ctaband__lines{position:absolute;inset:0;z-index:-1;width:100%;height:100%;fill:none;stroke:var(--sage);stroke-width:1;opacity:.13;vector-effect:non-scaling-stroke}
.ctaband__lines path{vector-effect:non-scaling-stroke}
.ctaband__in{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(32px,5vw,80px);align-items:center}
.ctaband h2{color:var(--white);font-size:var(--cta-h2);font-stretch:118%;font-weight:760;letter-spacing:-.028em;line-height:1;max-width:9ch}
.ctaband__side{padding-left:clamp(24px,3vw,48px);border-left:1px solid var(--rule-on-forest)}
.ctaband__side p{max-width:38ch;font-size:var(--fs-lead);line-height:1.5;color:var(--on-forest)}
.ctaband__acts{display:flex;flex-wrap:wrap;align-items:center;gap:20px 32px;margin-top:clamp(24px,2.6vw,32px)}
.ctaband__tel{display:inline-flex;align-items:center;gap:14px;min-height:52px;color:var(--white);text-decoration:none}
.ctaband__tel svg{width:22px;height:22px;flex:none;color:var(--sage)}
.ctaband__tel > span{display:grid;gap:5px}
.ctaband__tel .label{color:var(--on-forest-muted)}
.ctaband__num{font-size:1.375rem;font-stretch:110%;font-weight:680;letter-spacing:-.005em;line-height:1;text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:1px;text-underline-offset:5px;transition:text-decoration-color .15s}
.ctaband__tel:hover{color:var(--white)}
.ctaband__tel:hover .ctaband__num{text-decoration-color:var(--sage)}
@media (max-width:900px){
  .ctaband__in{grid-template-columns:1fr;align-items:start}
  .ctaband h2{max-width:none}
  .ctaband__side{padding-left:0;padding-top:clamp(24px,4vw,32px);border-left:0;border-top:1px solid var(--rule-on-forest)}
}
@media (max-width:560px){
  .ctaband{--cta-h2:clamp(2.3rem,1.4rem + 5vw,2.8rem)}
  .ctaband__acts{flex-direction:column;align-items:stretch;gap:16px}
  .ctaband__acts .btn{width:100%;min-height:56px}
}

/* ── enquiry variant (enquiry form's agent) ── */
.enq--stack{grid-template-columns:1fr;max-width:760px}
.enq--stack .enq__side{text-align:center}.enq--stack .enq__side .lead,.enq--stack .enq__side p{margin-inline:auto}
.enq--stack .enq__contact{justify-content:center;display:flex;flex-wrap:wrap;gap:24px}

/* ─────────────────────────────────────────────────────────────────────────
   Sticky bar (phones): a flat white shelf on the bottom edge, square-shouldered,
   a hairline above, clear of the home indicator. Gold "Get a price" takes the
   width; Call is the ruled secondary. It slides away while the hero's button,
   the form or the footer is on screen (.is-away, set by its script), and while
   the cookie bar is asking, so the two never stack.
   ───────────────────────────────────────────────────────────────────────── */
.sticky-cta{display:none}
@media (max-width:820px){
  .sticky-cta{
    position:fixed;left:0;right:0;bottom:0;z-index:var(--z-sticky);
    display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s-2);
    padding:10px var(--gutter) max(10px,env(safe-area-inset-bottom));
    background:var(--white);border-top:1px solid var(--line);box-shadow:0 -10px 24px -18px rgb(20 32 26 / .35);
    transition:transform .32s var(--ease),visibility 0s linear 0s}
  .sticky-cta .btn{min-height:50px;padding-inline:20px}
  .sticky-cta__call{background:transparent;color:var(--forest);border-color:var(--forest)}
  .sticky-cta__call:hover{background:var(--forest);color:var(--white)}
  .sticky-cta__call svg{width:17px;height:17px}
  .sticky-cta__call:hover svg{transform:none}
  .sticky-cta.is-away,body:has(.cookie-bar:not([hidden])) .sticky-cta{transform:translateY(calc(100% + 2px));visibility:hidden;transition:transform .32s var(--ease),visibility 0s linear .32s}
}
@media (prefers-reduced-motion:reduce){.sticky-cta{transition:none !important}}

/* ════ 30-report.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Report proof (home + Services). The strongest thing she owns is a page of
   a real report, so it is shown as a document: a hairline sheet, the
   report's own heading and column heads in the label voice, the maps, the
   ADAS key in the report's own colours, and a title block underneath
   (hectares · fields · samples) with the PDF. Four plain claims beside it,
   ruled, no ticks.
   Layout: sheet left (7 of 12), heading + claims right. Phone: heading,
   sheet, claims.
   ───────────────────────────────────────────────────────────────────────── */
#report{
  /* local tokens: the ADAS soil index colours exactly as the report prints them
     (sampled from its routine-results key). Data colours, used here only. */
  --adas-0:#FF0000; --adas-1:#FFB500; --adas-2a:#8ACD44; --adas-2b:#009F2B;
  --adas-3:#009FEC; --adas-4:#0053B3; --adas-5:#000043;
  /* the four maps' widths in the source image (px), so the heads sit over their maps */
  --map-cols:535fr 476fr 475fr 479fr;
}
.report{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);grid-template-areas:"head head" "sheet claims";column-gap:clamp(36px,5.6vw,88px);row-gap:clamp(36px,4vw,56px);align-items:start}
.report__h{grid-area:head;max-width:21ch}
.sheet{grid-area:sheet;margin:0}
.claims{grid-area:claims}

/* the sheet: white page, hairline edge, --r corners, no mat, no shadow */
.sheet__page{background:var(--white);border:1px solid var(--line-strong);border-radius:var(--r);padding:clamp(16px,2vw,28px) clamp(16px,2vw,28px) clamp(14px,1.6vw,22px)}
.sheet__title{color:var(--ink);padding-bottom:12px;border-bottom:1px solid var(--line)}
.sheet__cols{list-style:none;margin:14px 0 8px;padding:0;display:grid;grid-template-columns:var(--map-cols);gap:0}
.sheet__cols li{font-size:var(--fs-small);font-weight:650;line-height:1.2;color:var(--ink);padding-left:2px}
.sheet__cols span{font-weight:450;color:var(--muted)}
/* the maps without their tiny printed legends (the key below says it legibly) */
.sheet__maps{overflow:hidden;aspect-ratio:1965 / 492;background:var(--ground-2)}
.sheet__maps img{width:100%;height:100%;object-fit:cover;object-position:50% 0}
.sheet__key{display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.sheet__key .label{color:var(--muted)}
.sheet__key ol{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:4px 12px}
.sheet__key li{display:flex;align-items:center;gap:6px;font-size:.875rem;font-weight:600;line-height:1;color:var(--ink);font-variant-numeric:tabular-nums lining-nums}
.sheet__key li::before{content:"";width:14px;height:14px;border-radius:2px;background:var(--k);box-shadow:inset 0 0 0 1px rgb(20 32 26 / .18)}

/* the title block under the sheet: what the page is from, in figures */
.sheet__cap{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"from from" "spec pdf";align-items:end;gap:12px clamp(20px,3vw,40px);margin-top:20px}
.sheet__from{grid-area:from}
.sheet__spec{grid-area:spec}
.sheet__pdf{grid-area:pdf}
.sheet__from .label{color:var(--field)}
.sheet__spec{display:flex;gap:clamp(20px,2.6vw,36px);margin:0}
.sheet__spec div{display:flex;flex-direction:column-reverse;gap:4px}
.sheet__spec dd{margin:0;font-size:clamp(1.5rem,1.2rem + .8vw,1.9rem);font-stretch:112%;font-weight:720;letter-spacing:-.02em;line-height:1;color:var(--ink)}
.sheet__spec dt{font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;line-height:1.2;color:var(--muted)}
.sheet__pdf{display:inline-flex;align-items:center;gap:10px;min-height:44px;font-size:var(--fs-small);font-weight:620;color:var(--forest);text-decoration:underline;text-decoration-color:var(--line-strong);text-underline-offset:4px}
.sheet__pdf svg{width:20px;height:20px;flex:none;color:var(--field)}
.sheet__pdf:hover{text-decoration-color:var(--forest)}
.sheet__fmt{color:var(--muted);font-weight:500}

/* the claims: a ruled list, the lead words in ink */
.claims{list-style:none;margin:0;padding:0;border-bottom:1px solid var(--line)}
.claims li:first-child{border-top-color:var(--ink)}
.claims li{padding:18px 0;border-top:1px solid var(--line);font-size:1.0625rem;line-height:1.5;color:var(--body);max-width:44ch}
.claims b{font-weight:680;color:var(--ink)}

@media (max-width:900px){
  .report{grid-template-columns:1fr;grid-template-areas:"head" "sheet" "claims";grid-template-rows:none}
  .report__h{max-width:20ch}
}
@media (max-width:560px){
  .sheet__page{padding:14px 12px 12px}
  .sheet__cols li{font-size:.8125rem}
  .sheet__cols span{display:block;font-size:.75rem}
  .sheet__key ol{gap:6px 10px}
  .sheet__cap{grid-template-columns:1fr;grid-template-areas:"from" "spec" "pdf";gap:14px}
  .sheet__pdf{justify-self:start}
  .claims li{padding:16px 0;font-size:1rem}
}

/* ════ 31-tests.css ════ */
/* What we test: her price list, set as a technical schedule (DESIGN.md §3, §4).
   Hairline rows under a forest head rule; prices in tabular figures with the unit as a label. */
.tests{display:grid;grid-template-columns:minmax(0,8fr) minmax(0,4fr);gap:clamp(32px,5vw,64px);align-items:start}

.schedule{border-top:2px solid var(--forest)}
.schedule__head,.schedule__row{display:grid;grid-template-columns:minmax(0,11rem) minmax(0,1fr) minmax(0,10.5rem);column-gap:var(--s-6)}
.schedule__head{padding:var(--s-3) 0;border-bottom:1px solid var(--line)}
.schedule__head .label:last-child{text-align:right}
.schedule__rows{list-style:none;margin:0;padding:0}
.schedule__row{padding:var(--s-5) 0;border-bottom:1px solid var(--line);align-items:baseline}
.schedule__name{font-size:1.1875rem;font-stretch:108%;font-weight:680;letter-spacing:-.005em;line-height:1.25;color:var(--ink)}
.schedule__desc{font-size:1rem;line-height:1.55;color:var(--body);max-width:52ch}

.schedule__price{text-align:right;color:var(--forest);line-height:1.2}
.schedule__from,.schedule__unit{display:block;font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.schedule__from{display:inline;margin-right:6px}
.schedule__unit{margin-top:var(--s-2)}
.schedule__fig{display:inline;font-size:1.75rem;font-stretch:112%;font-weight:720;letter-spacing:-.015em;line-height:1;color:var(--forest)}
.schedule__note{display:block;margin-top:var(--s-2);margin-left:auto;max-width:22ch;font-size:.875rem;line-height:1.45;color:var(--muted);text-wrap:pretty}
.schedule__price--job{font-size:1rem;font-stretch:106%;font-weight:600;color:var(--body);padding-top:2px}

/* aside: the map she sends, and the route for the unsure */
.tests__aside{display:grid;gap:var(--s-6);position:sticky;top:112px}
.tests__fig{margin:0}
.tests__fig img{width:100%;border-radius:var(--r);border:1px solid var(--line)}
.tests__fig figcaption{margin-top:var(--s-3);font-size:var(--fs-small);line-height:1.45;color:var(--muted)}
.tests__note{background:var(--forest);color:var(--on-forest);border-radius:var(--r);padding:var(--s-5) var(--s-5) var(--s-5)}
.tests__note-h{font-size:var(--fs-h3);font-stretch:104%;font-weight:680;letter-spacing:-.01em;line-height:1.2;color:var(--white);margin-bottom:var(--s-2)}
.tests__note p:not(.tests__note-h){color:var(--on-forest);font-size:1rem;line-height:1.55}
.tests__note-link{display:inline-flex;align-items:center;gap:var(--s-2);margin-top:var(--s-4);min-height:44px;color:var(--white);font-size:1rem;font-stretch:106%;font-weight:620;text-decoration:underline;text-decoration-color:var(--sage);text-underline-offset:5px}
.tests__note-link:hover{color:var(--sage);text-decoration-thickness:2px}
.tests__note-link svg{width:18px;height:18px;transition:transform .2s var(--ease)}
.tests__note-link:hover svg{transform:translateX(3px)}
.tests__note-link:focus-visible{outline-color:var(--sage)}

/* medium: name and description stack, price stays right */
@media (max-width:1180px){
  .schedule__head,.schedule__row{grid-template-columns:minmax(0,1fr) minmax(0,9.5rem);column-gap:var(--s-5)}
  .schedule__head .label:nth-child(2){display:none}
  .schedule__name{grid-column:1;grid-row:1}
  .schedule__desc{grid-column:1;grid-row:2;margin-top:var(--s-2)}
  .schedule__price{grid-column:2;grid-row:1 / span 2;align-self:start}
}
@media (max-width:960px){
  .tests{grid-template-columns:1fr}
  .tests__aside{position:static;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);align-items:start}
}
@media (max-width:640px){
  .tests__aside{grid-template-columns:1fr}
  .schedule__head{display:none}
  .schedule__row{grid-template-columns:minmax(0,1fr);padding:22px 0 var(--s-5)}
  .schedule__name,.schedule__desc,.schedule__price{grid-column:1;grid-row:auto}
  .schedule__name{font-size:1.125rem}
  .schedule__price{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s-1) 10px;margin-top:var(--s-3);text-align:left}
  .schedule__from,.schedule__unit{display:inline;margin:0}
  .schedule__fig{display:inline;font-size:1.5rem}
  .schedule__note{flex-basis:100%;margin:var(--s-1) 0 0;max-width:40ch}
  .schedule__price--job{display:block;font-size:.9375rem}
}
@media (prefers-reduced-motion:reduce){.tests__note-link svg{transition:none}.tests__note-link:hover svg{transform:none}}

/* Worked price example under the price list */
.schedule__example{margin:var(--s-5) 0 0;padding:var(--s-4) var(--s-5);background:var(--ground-2);border-left:3px solid var(--field);border-radius:var(--r-sm);font-size:1rem;line-height:1.55;color:var(--ink);max-width:62ch;text-wrap:pretty}
.schedule__example b{font-weight:680}

/* ════ 32-how.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   How it works (Services; markup in index.html). Plan → Sample → Analyse →
   Report is a real sequence, so it is numbered (DESIGN.md §4) and drawn as a
   ruled track: a hairline runs through four stops, each stop a tick on the
   line, the step number set in the wide display cut like a survey station.
   Below, the field photographs as one strip: the rig wide, two details.
   Phone: the track turns vertical, numbers on the line.
   ───────────────────────────────────────────────────────────────────────── */
#how{
  /* local tokens (how only) */
  --step-gap:clamp(24px,3vw,44px);
  --track-tick:9px;
  --how-img-h:clamp(220px,24vw,360px);
}
.how-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:24px 40px;margin-bottom:clamp(40px,5vw,72px)}
.how-head h2{max-width:18ch}

/* the track */
.steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));column-gap:var(--step-gap);position:relative}
.step{position:relative;padding-top:clamp(28px,3vw,40px);border-top:2px solid var(--forest)}
.step::before{content:"";position:absolute;left:0;top:calc(-1 * var(--track-tick) - 1px);width:2px;height:calc(var(--track-tick) * 2);background:var(--forest)}   /* the station tick */
.step__n{display:block;font-size:clamp(2.6rem,1.8rem + 2.2vw,3.75rem);font-stretch:125%;font-weight:300;letter-spacing:-.04em;line-height:.9;color:var(--field)}
.step h3{margin-top:clamp(16px,1.6vw,22px);font-size:clamp(1.35rem,1.15rem + .6vw,1.65rem);font-stretch:112%;font-weight:720;letter-spacing:-.015em}
.step p{margin-top:10px;max-width:34ch;color:var(--body)}
/* the gaps between steps keep the line continuous: the rule bridges each column gap */
.step:not(:last-child)::after{content:"";position:absolute;top:-2px;left:100%;width:var(--step-gap);border-top:2px solid var(--forest)}

/* the photographs: one strip, the rig given the width it deserves */
.how-media{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,1fr);column-gap:var(--step-gap);row-gap:24px;margin-top:clamp(56px,6vw,88px)}
.how-media figure{margin:0}
.how-media__img{position:relative;height:var(--how-img-h);overflow:hidden;border-radius:var(--r);background:var(--ground-2)}
.how-media__img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.how-media__main img{object-position:50% 62%}
.how-media figcaption{margin-top:12px;padding-top:10px;border-top:1px solid var(--line);font-size:var(--fs-small);line-height:1.4;color:var(--muted)}

@media (max-width:1000px){
  .steps{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:clamp(40px,5vw,56px)}
  .step:nth-child(2)::after{display:none}
  .how-media{grid-template-columns:repeat(2,minmax(0,1fr))}
  .how-media__main{grid-column:1 / -1}
}
/* phone: a vertical track, the number on the line, the words beside it */
@media (max-width:640px){
  #how{--how-img-h:auto}
  .how-head{margin-bottom:36px}
  .how-head .btn{width:100%;min-height:56px}
  .steps{grid-template-columns:1fr;row-gap:0;border-left:2px solid var(--forest);margin-left:4px}
  .step{border-top:0;padding:0 0 32px 26px;display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:14px;align-items:baseline}
  .step:last-child{padding-bottom:4px}
  .step::before{left:-2px;top:.55em;width:14px;height:2px}
  .step:not(:last-child)::after{display:none}
  .step__n{font-size:1.75rem;font-weight:400;letter-spacing:-.02em}
  .step h3{margin-top:0}
  .step p{grid-column:1 / -1;margin-top:8px}
  .how-media{margin-top:44px;column-gap:12px;row-gap:20px}
  .how-media__img{height:auto;aspect-ratio:4 / 3}
  .how-media__main .how-media__img{aspect-ratio:3 / 2}
  .how-media figcaption{font-size:.875rem}
}

/* ════ 33-about.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   About (About page; markup in index.html). Her words lead: the quote set
   large, attributed on a hairline; the story and the four facts sit beneath
   it as two columns; the portrait slot stands beside, a plain photograph
   with --r corners, no mat. The stand-in is a field, never a person.
   .who__ask is the review build's "your photograph goes here" overlay;
   build-live.py strips it, so production shows the photograph alone.
   ───────────────────────────────────────────────────────────────────────── */
#about{
  /* local tokens (about only) */
  --about-quote:clamp(1.55rem,1.15rem + 1.3vw,2.3rem);
}
.about{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(40px,6vw,96px);align-items:start}

/* the quote: no decorative marks hanging in space, just her sentence, set */
.quote{margin:0}
.quote p{font-size:var(--about-quote);font-stretch:108%;font-weight:560;letter-spacing:-.018em;line-height:1.22;color:var(--forest);text-wrap:balance;text-indent:-.42em}
.quote p::before{content:"\201C"}
.quote p::after{content:"\201D"}
.quote footer{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;margin-top:clamp(20px,2vw,28px);padding-top:16px;border-top:1px solid var(--line-strong);max-width:34rem}
.quote footer b{font-size:1.0625rem;font-stretch:106%;font-weight:680;color:var(--ink)}
.quote footer span{font-size:var(--fs-small);color:var(--muted)}

/* the story and the facts */
.about__body{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:clamp(28px,4vw,56px);margin-top:clamp(40px,4.6vw,64px)}
.about__story{display:grid;gap:16px;max-width:60ch}
.about__story p{color:var(--body)}
.about__facts{align-self:start;list-style:none;margin:0;padding:0;border-bottom:1px solid var(--line)}
.about__facts li{padding:13px 0;border-top:1px solid var(--line);font-size:var(--fs-small);font-weight:600;line-height:1.4;color:var(--forest)}

/* the portrait slot */
.who{margin:0;border-radius:var(--r);overflow:hidden;background:var(--ground-2);aspect-ratio:4 / 5;position:sticky;top:120px}
.who img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:42% 50%}
.who__ask{position:absolute;inset:0;display:grid;place-content:center;justify-items:center;gap:12px;padding:clamp(24px,3vw,40px);text-align:center;background:rgb(243 246 243 / .93);border:1.5px dashed var(--input-edge);border-radius:var(--r)}
.who__ask svg{width:72px;height:72px;color:var(--field);fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}
.who__ask p{max-width:30ch;font-size:var(--fs-small);line-height:1.5;color:var(--body)}
.who__ask b{display:block;margin-bottom:6px;font-size:1.125rem;font-stretch:106%;font-weight:680;color:var(--forest)}

@media (max-width:1000px){
  .about__body{grid-template-columns:1fr}
}
@media (max-width:820px){
  .about{grid-template-columns:1fr}
  .who{position:relative;top:auto;order:-1;aspect-ratio:3 / 2;max-width:none}
}
@media (max-width:560px){
  .who{aspect-ratio:4 / 3}
  .quote p{text-indent:0}
}

/* ════ 34-kits.css ════ */
/* Postal kits: one product moment. The bag, two kits side by side, the gold action. */
.kits{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(32px,6vw,96px);align-items:center}
.kits__img{margin:0;border-radius:var(--r);overflow:hidden;background:var(--ground-2)}
.kits__img img{width:100%;aspect-ratio:1;object-fit:cover}
.kits__lead{margin-top:var(--s-4)}

.kitlist{list-style:none;margin:var(--s-7) 0 0;padding:0;display:grid;grid-template-columns:1fr 1fr;border-top:2px solid var(--forest);border-bottom:1px solid var(--line)}
.kit{display:grid;grid-row:span 3;grid-template-rows:subgrid;row-gap:var(--s-2);padding:var(--s-5) var(--s-6) var(--s-6) 0}
.kit + .kit{padding-left:var(--s-6);padding-right:0;border-left:1px solid var(--line)}
.kit__name{font-size:var(--fs-h3);font-stretch:106%;font-weight:680;letter-spacing:-.01em;line-height:1.2;color:var(--ink)}
.kit__desc{font-size:1rem;line-height:1.55;color:var(--body);max-width:34ch}
.kit__price{margin-top:var(--s-4)}
.kit__fig{font-size:clamp(2rem,1.6rem + 1.2vw,2.6rem);font-stretch:112%;font-weight:720;letter-spacing:-.02em;line-height:1;color:var(--forest)}

.kits__cta{margin-top:var(--s-6);display:flex;flex-wrap:wrap;gap:var(--s-3)}

@media (max-width:960px){
  .kits{grid-template-columns:1fr}
  .kits__img{max-width:460px}
}
@media (max-width:560px){
  .kitlist{grid-template-columns:1fr}
  .kit{padding:var(--s-5) 0}
  .kit + .kit{padding-left:0;border-left:0;border-top:1px solid var(--line)}
  .kit__price{margin-top:var(--s-2)}
  .kits__cta .btn{width:100%}
}

/* ════ 35-faq.css ════ */
/* FAQ: a plain disclosure list. Hairlines, a drawn +/−, smooth where the browser can. */
.faq-wrap{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:clamp(32px,5vw,80px);align-items:start}
.faq-head{margin:0;position:sticky;top:112px}
.faq-head .faq-head__aside{margin-top:var(--s-5);font-size:1rem;line-height:1.6;color:var(--muted);max-width:30ch}

.faq{border-top:2px solid var(--forest);interpolate-size:allow-keywords}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{list-style:none;cursor:pointer;display:grid;grid-template-columns:minmax(0,1fr) 28px;gap:var(--s-5);align-items:center;padding:var(--s-5) 0;min-height:44px;border-radius:0}
.faq summary::-webkit-details-marker{display:none}
.faq__q{font-size:clamp(1.125rem,1.05rem + .3vw,1.3125rem);font-stretch:104%;font-weight:640;letter-spacing:-.005em;line-height:1.3;color:var(--ink);text-wrap:balance;transition:color .15s}
.faq summary:hover .faq__q{color:var(--forest)}
.faq summary:focus-visible{outline:3px solid var(--focus);outline-offset:4px;border-radius:var(--r-sm)}

/* +/−: two 1.5px bars in a hairline square; the vertical one folds away when open */
.faq__icon{position:relative;width:28px;height:28px;border:1px solid var(--line-strong);border-radius:var(--r-sm);color:var(--forest);transition:background-color .2s var(--ease),border-color .2s var(--ease)}
.faq__icon::before,.faq__icon::after{content:"";position:absolute;left:50%;top:50%;width:12px;height:1.5px;margin:-.75px 0 0 -6px;background:currentColor;transition:transform .3s var(--ease)}
.faq__icon::after{transform:rotate(90deg)}
.faq summary:hover .faq__icon{border-color:var(--forest)}
.faq details[open] .faq__icon{background:var(--forest);border-color:var(--forest);color:var(--white)}
.faq details[open] .faq__icon::after{transform:rotate(0deg)}

.faq__a{padding:0 calc(28px + var(--s-5)) var(--s-6) 0}
.faq__a p{max-width:64ch;font-size:1.0625rem;line-height:1.65;color:var(--body)}

/* smooth open/close where ::details-content is supported; instant elsewhere */
.faq details::details-content{block-size:0;overflow:hidden;transition:block-size .35s var(--ease),content-visibility .35s allow-discrete}
.faq details[open]::details-content{block-size:auto}

@media (max-width:900px){
  .faq-wrap{grid-template-columns:1fr}
  .faq-head{position:static}
}
@media (max-width:560px){
  .faq summary{gap:var(--s-4);padding:var(--s-4) 0 18px}
  .faq__a{padding-right:0}
}
@media (prefers-reduced-motion:reduce){
  .faq details::details-content,.faq__icon,.faq__icon::before,.faq__icon::after{transition:none}
}

/* ════ 40-enquire.css ════ */
/* Enquiry: the conversion surface. A forest panel; the pitch and the direct
   routes on the left, a white form on the right. Every hook the submit JS uses
   (.form__err, .form__ref, [data-ref], [data-continue], [data-sent], .form__done) is styled here. */
.enq{
  /* local tokens (candidates for 00-foundation.css) */
  --input-edge:#86978B;   /* input border: 3.1:1 on white, meets WCAG 1.4.11 (line-strong is 1.95:1) */
  --error:#9B2C1F;        /* 7.6:1 on white */
  --error-bg:#FBEEEB;     /* error text on this: 6.7:1 */
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(32px,5vw,80px);align-items:start;
  background:var(--forest);color:var(--on-forest);border-radius:var(--r);
  padding:clamp(28px,5vw,72px) clamp(24px,5vw,72px);
}
.enq h2{color:var(--white);max-width:16ch}
.enq__lead{margin-top:var(--s-5);color:var(--on-forest);max-width:38ch}

/* direct routes: strong secondaries, set as data (label + value) */
.enq__contact{list-style:none;margin:var(--s-7) 0 0;padding:0;border-top:1px solid rgb(204 221 184 / .28)}
.enq__contact li{display:grid;gap:6px;padding:var(--s-5) 0;border-bottom:1px solid rgb(204 221 184 / .28)}
.enq__contact .label{color:var(--sage)}
.enq__route{justify-self:start;display:inline-flex;align-items:center;min-height:44px;color:var(--white);font-size:clamp(1.375rem,1.2rem + .6vw,1.75rem);font-stretch:110%;font-weight:680;letter-spacing:-.01em;line-height:1.1;text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:2px;text-underline-offset:6px;transition:text-decoration-color .15s,color .15s;overflow-wrap:anywhere}
.enq__route:hover{color:var(--white);text-decoration-color:var(--sage)}
.enq__route:focus-visible{outline-color:var(--sage)}
.enq__contact small{display:block;font-size:var(--fs-small);line-height:1.5;color:var(--on-forest-muted)}

/* the form */
.form{background:var(--white);border-radius:var(--r);padding:clamp(24px,3.4vw,44px);color:var(--body)}
.form__head{margin-bottom:var(--s-6);padding-bottom:var(--s-5);border-bottom:1px solid var(--line)}
.form__head h3{font-size:clamp(1.5rem,1.3rem + .6vw,1.875rem);font-stretch:110%;font-weight:720;letter-spacing:-.015em}
.form__head p{margin-top:var(--s-2);font-size:1rem;color:var(--muted)}
.form .stack{display:grid;gap:22px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:22px var(--s-5)}

.field{display:grid;gap:var(--s-2);align-content:start}
.field label{font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;line-height:1.3;color:var(--body)}
.field label small{font-size:.8125rem;font-stretch:100%;font-weight:450;letter-spacing:0;text-transform:none;color:var(--muted);margin-left:var(--s-1)}
.field label small::before{content:"· "}
.field input,.field select,.field textarea{
  display:block;width:100%;min-height:52px;padding:0 var(--s-4);
  font:inherit;font-size:1.0625rem;line-height:1.4;color:var(--ink);
  background:var(--white);border:1px solid var(--input-edge);border-radius:var(--r-sm);
  transition:border-color .15s var(--ease),box-shadow .15s var(--ease);
  -webkit-appearance:none;appearance:none;
}
.field textarea{min-height:120px;padding:14px var(--s-4);resize:vertical;line-height:1.5}
.field ::placeholder{color:var(--muted);opacity:.85}
.field input:hover,.field select:hover,.field textarea:hover{border-color:var(--forest)}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--forest);box-shadow:0 0 0 1px var(--forest)}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
.field__select{position:relative}
.field__select::after{content:"";position:absolute;right:18px;top:50%;width:8px;height:8px;margin-top:-6px;border-right:1.5px solid var(--forest);border-bottom:1.5px solid var(--forest);transform:rotate(45deg);pointer-events:none}
.field select{padding-right:44px;cursor:pointer}
.field select:invalid{color:var(--muted)}
.field select option{color:var(--ink)}

/* inline errors: after the visitor has left a field, or after a submit attempt */
.field__msg{display:none;font-size:.9375rem;line-height:1.4;font-weight:500;color:var(--error)}
.field__msg::before{content:"";display:inline-block;width:6px;height:6px;margin:0 8px 2px 0;background:var(--error);transform:rotate(45deg)}
.field:has(:user-invalid) .field__msg,.form[data-tried] .field:has(:invalid) .field__msg{display:block}
.field:has(:user-invalid) :is(input,select,textarea),.form[data-tried] .field:has(:invalid) :is(input,select,textarea){border-color:var(--error);box-shadow:0 0 0 1px var(--error)}

.form__err{margin:0;padding:14px var(--s-4);border:1px solid rgb(155 44 31 / .35);border-radius:var(--r-sm);background:var(--error-bg);color:var(--error);font-size:var(--fs-small);line-height:1.5;font-weight:500}

.form__submit{display:grid;gap:var(--s-3);margin-top:var(--s-2)}
.form__submit .btn{width:100%;min-height:56px;font-size:1.0625rem}
.form .fine{font-size:.875rem;line-height:1.5;color:var(--muted);text-align:center}

/* sent: calm, left-set, the reference as data */
.form__done{display:none;padding:var(--s-3) 0 var(--s-2)}
.form__done svg{width:44px;height:44px;color:var(--field);margin-bottom:var(--s-5)}
.form__done h3{font-size:clamp(1.5rem,1.3rem + .6vw,1.875rem);font-stretch:110%;font-weight:720;letter-spacing:-.015em;margin-bottom:var(--s-3)}
.form__done p{color:var(--body);max-width:44ch;font-size:1.0625rem}
.form__ref{margin-top:var(--s-5) !important;padding-top:var(--s-4);border-top:1px solid var(--line);font-size:var(--fs-small) !important;color:var(--muted) !important}
.form__ref b{font-size:1.125rem;font-stretch:110%;font-weight:700;letter-spacing:.02em;color:var(--ink);font-variant-numeric:tabular-nums lining-nums}
.form__more{margin-top:var(--s-6)}
.form[data-sent="true"] .form__body{display:none}
.form[data-sent="true"] .form__done{display:block}
.form[data-sent="true"] .form__done svg{animation:enq-done .5s var(--ease) both}
@keyframes enq-done{from{opacity:0;transform:scale(.9)}to{opacity:1;transform:none}}

@media (max-width:960px){
  .enq{grid-template-columns:1fr}
  .enq h2{max-width:20ch}
  .enq__contact{display:grid;grid-template-columns:1fr 1fr;column-gap:var(--s-5);margin-top:var(--s-6)}
}
@media (max-width:640px){
  /* full-bleed panel on phones: the form gets the width, not the frame */
  .enq{border-radius:0;padding:var(--s-7) var(--gutter) var(--gutter);gap:var(--s-6)}
  .enq__contact{grid-template-columns:1fr}
  .grid2{grid-template-columns:1fr}
  .form{padding:var(--s-5) 20px var(--s-6)}
  .form__head{margin-bottom:var(--s-5)}
}
@media (prefers-reduced-motion:reduce){
  .form[data-sent="true"] .form__done svg{animation:none}
  .field input,.field select,.field textarea,.enq__route{transition:none}
}
.field__hint{font-size:.875rem;line-height:1.4;color:var(--muted)}

/* Form 1 → Form 2 hand-off (live build, 7 Oct 2026): a short confirmation and two choices
   (add field details, or leave it); no timed redirect. */
.form__next{margin-top:var(--s-5);padding-top:var(--s-5);border-top:1px solid var(--line)}
.form__next-msg{font-size:1rem !important;font-weight:520;color:var(--ink) !important;max-width:46ch}
.form__next-acts{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3) var(--s-5)}
.form__next .form__more{margin-top:0}
.form__done .form__next .btn svg{width:18px;height:18px;margin:0;color:currentColor;animation:none}
.form__skip{min-height:44px;padding:0 var(--s-1);background:none;border:0;font:inherit;font-size:var(--fs-small);font-weight:560;color:var(--forest);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.form__skip:hover{text-decoration-thickness:2px}
.form__next.is-skipped .form__next-msg{margin-bottom:var(--s-4)}

/* ── Form 1 in two screens (funnel optimisation, 7 Oct 2026) ─────────────────────
   A: land type as big cards + a rough size as chips. B: contact details. The JS sets
   data-screen="a"|"b"; with no JS it stays "all" and the two show as one form. The
   radios are real inputs (arrow keys, required, form.elements), drawn over by the label. */
.form__progress{display:flex;align-items:center;gap:var(--s-4);margin-bottom:var(--s-4)}
.form__progress .label{flex:none}
.form__progress-bar{flex:1;max-width:160px;height:4px;background:var(--ground-2);border-radius:2px;overflow:hidden}
.form__progress-bar span{display:block;height:100%;width:50%;background:var(--field);transition:width .4s var(--ease)}
.form[data-screen="a"] .form__progress-bar span{width:25%}
.form__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.form[data-screen="a"] [data-screen-b],.form[data-screen="b"] [data-screen-a]{display:none}
.form[data-screen="all"] .form__go{display:none}
.form[data-screen="all"] [data-screen-a]{margin-bottom:var(--s-6);padding-bottom:var(--s-6);border-bottom:1px solid var(--line)}
.form__screen[data-screen-a]{display:grid;gap:var(--s-6)}

.choice{margin:0;padding:0;border:0;min-width:0;display:grid;gap:var(--s-3)}
.choice__q{padding:0;margin-bottom:var(--s-1);font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;line-height:1.3;color:var(--body)}
.choice__q:focus{outline:none}
.choice__q:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
.choice__cards{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-3)}
.choice__cards .pick:last-child{grid-column:1 / -1}
.choice__chips{display:flex;flex-wrap:wrap;gap:var(--s-2)}

.pick{position:relative;display:flex;cursor:pointer;-webkit-tap-highlight-color:transparent}
.pick input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.pick > span{display:flex;align-items:center;gap:var(--s-3);width:100%;border:1px solid var(--input-edge);border-radius:var(--r-sm);background:var(--white);color:var(--ink);font-weight:600;line-height:1.25;transition:border-color .15s var(--ease),background-color .15s var(--ease),box-shadow .15s var(--ease),color .15s var(--ease)}
.pick:hover > span{border-color:var(--forest)}
.pick:has(input:focus-visible) > span{outline:3px solid var(--focus);outline-offset:2px}
.pick--card > span{min-height:64px;padding:12px var(--s-4);font-size:1.0625rem;font-stretch:104%}
/* the radio mark: a ring that fills, so "chosen" never rests on colour alone */
.pick--card > span::before{content:"";flex:none;width:20px;height:20px;border-radius:50%;border:1.5px solid var(--input-edge);background:var(--white);transition:border-color .15s,box-shadow .15s}
.pick--card input:checked + span{border-color:var(--forest);box-shadow:inset 0 0 0 1px var(--forest);background:var(--ground)}
.pick--card input:checked + span::before{border-color:var(--forest);box-shadow:inset 0 0 0 5px var(--forest)}
.pick--chip > span{min-height:48px;padding:0 var(--s-4);font-size:1rem;font-variant-numeric:tabular-nums lining-nums}
.pick--chip input:checked + span{background:var(--forest);border-color:var(--forest);color:var(--white)}
.choice .field__msg{display:none}
.form[data-tried-a] .choice:has(input[name="landType"]:invalid) .field__msg,
.form[data-tried][data-screen="all"] .choice:has(input:invalid) .field__msg{display:block}
.form[data-tried-a] .choice:has(input[name="landType"]:invalid) .pick--card > span{border-color:var(--error)}

.form__go{justify-self:start;min-width:160px}
.form__b-head{display:grid;gap:var(--s-2)}
.form__b-h{font-size:1.1875rem;font-stretch:106%;font-weight:680;letter-spacing:-.005em;text-transform:none;line-height:1.25;color:var(--ink)}
.form__b-h:focus{outline:none}
.form__b-h:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
.form__recap{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-1) var(--s-4);margin:0 0 var(--s-1);font-size:var(--fs-small);color:var(--muted)}
.form__recap-text{font-weight:560;color:var(--body)}
.form__back,.form__note-add{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0;background:none;border:0;font:inherit;font-size:var(--fs-small);font-weight:600;color:var(--forest);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.form__back svg{width:16px;height:16px}
.form__back:hover,.form__note-add:hover{text-decoration-thickness:2px}
.form__note-add{justify-self:start;margin-top:-6px}
.form__promise{font-size:var(--fs-small);line-height:1.5;color:var(--muted)}
.form .fine a{color:var(--forest);font-weight:600}
@media (max-width:640px){
  /* a phone: two cards a row and chips that fill their row, so screen A fits one screen */
  .choice__cards{gap:var(--s-2)}
  .pick--card > span{min-height:58px;padding:10px var(--s-3);gap:var(--s-2);font-size:1rem}
  .pick--card > span::before{width:18px;height:18px}
  .pick--card input:checked + span::before{box-shadow:inset 0 0 0 4px var(--forest)}
  .form__go{justify-self:stretch;min-height:56px}
  .pick--chip{flex:1 1 auto}
  .pick--chip > span{justify-content:center;padding:0 var(--s-3)}
  .form[data-screen="a"] [data-screen-a]{gap:var(--s-5)}
}
@media (prefers-reduced-motion:reduce){.pick > span,.form__progress-bar span{transition:none}}

/* Acre equivalents on the size chips (Form 1) */
.pick__ac{font-style:normal;font-weight:500;font-size:.875em;opacity:.78;white-space:nowrap}

/* ════ 50-pages.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Sub-page heads: one title block for every page that isn't Home
   (Services, About, Contact, Blog, the posts, the two policies).
   Light, deliberately: under the white header the page ground starts the page
   like the first sheet of her report, and forest is kept for the panels that
   close every sub-page (the enquiry band, the footer), so forest = "act now".
   Crumbs, then h1 left and lede right on the 12-column grid; the forest rule
   is the block's bottom edge, the same 2px head rule as the price list, FAQ
   and contact list. Built by pagehead() in build-five.py.
   ───────────────────────────────────────────────────────────────────────── */
.pagehead-sec{
  /* local tokens */
  --ph-top:clamp(28px,4.4vw,64px);       /* header → crumbs: the 84px bar already gives air */
  --ph-gap:clamp(28px,3.6vw,52px);       /* crumbs → h1 */
  --ph-foot:clamp(32px,4vw,56px);        /* last line → rule */
  padding-block:var(--ph-top) 0;
  background:var(--ground);
}
.pagehead{
  display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gutter);
  align-items:end;padding-bottom:var(--ph-foot);border-bottom:2px solid var(--forest);
}
.pagehead h1{grid-column:1 / span 8;max-width:17ch;font-size:clamp(2.6rem,1.55rem + 3.1vw,4.25rem)}
.pagehead__lede{
  grid-column:9 / -1;max-width:44ch;
  font-size:var(--fs-lead);line-height:1.5;font-weight:420;color:var(--body);
  padding-bottom:.35em;                  /* sits on the h1's last baseline, not its descender box */
}

/* crumbs: wayfinding, quiet; the current page in ink */
.crumbs{grid-column:1 / -1;margin-bottom:var(--ph-gap)}
.crumbs ol{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;align-items:center;font-size:var(--fs-small);line-height:1.4;color:var(--muted)}
.crumbs li{display:flex;align-items:center}
.crumbs li+li::before{content:"/";margin:0 10px;color:var(--line-strong)}
.crumbs a{display:inline-flex;align-items:center;min-height:32px;color:var(--muted);text-decoration:underline;text-decoration-color:transparent;text-underline-offset:4px}
.crumbs a:hover{color:var(--forest);text-decoration-color:currentColor;text-decoration-thickness:1px}
.crumbs [aria-current]{color:var(--ink);font-weight:500}

/* the section straight after a head: the rule already separates, so start close */
.sec--tight{padding-top:clamp(40px,5vw,72px)}

/* post head: tag, title and dek left; the cover takes the lede's column */
.pagehead--post{align-items:end}
.pagehead__main{grid-column:1 / span 7;display:grid;gap:var(--s-4);align-content:end;padding-bottom:.35em}
.pagehead--post h1{max-width:18ch;font-size:clamp(2.4rem,1.55rem + 2.9vw,4rem);margin-top:var(--s-1)}
.pagehead--post .pagehead__lede{grid-column:auto;max-width:50ch;padding:0}
.pagehead__cover{grid-column:8 / -1;margin:0;align-self:end}
.pagehead__cover img{width:100%;aspect-ratio:4 / 3;object-fit:cover;border-radius:var(--r)}

@media (max-width:900px){
  .pagehead{grid-template-columns:minmax(0,1fr)}
  .pagehead h1,.pagehead__lede,.pagehead__main,.pagehead__cover{grid-column:1 / -1}
  .pagehead h1{max-width:16ch}
  .pagehead__lede{margin-top:var(--s-5);max-width:52ch;padding:0}
  .pagehead__cover{margin-top:var(--s-6)}
  .pagehead--post .pagehead__lede{margin-top:0}
  .pagehead__cover img{aspect-ratio:3 / 2}
}
@media (max-width:560px){
  .pagehead-sec{--ph-gap:20px}
  .pagehead__cover{margin-inline:calc(var(--gutter) * -1)}
  .pagehead__cover img{border-radius:0}
  .pagehead--post{padding-bottom:0;border-bottom:0}  /* the full-bleed cover is the edge */
}

/* ════ 51-services.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Services page polish (7 Oct 2026, "the same care as the home page").
   Services only: every rule is scoped to an id that exists only on /services
   (#tests, #how, #kits, #faq) or to the page head straight before #tests,
   so Home, About, Contact and the blog are untouched.

   One motion idea, used throughout: every forest head rule on the page draws
   itself left to right (the price list on load; the steps track, the kit list
   and the FAQ as they scroll in), the way the hero's plotted grid sweeps in.
   The rest rides the shared reveal (css/95-motion.css + the page script).
   Reduced motion: none of it. A headless render: the reveal never arms, and
   the load sequence has finished before anything is captured.
   ───────────────────────────────────────────────────────────────────────── */

/* ── price list ─────────────────────────────────────────────────────────── */
/* the variable-rate panel ("Not sure what you need?"): a faint contour sheet in
   sage, the same OS-map cue as the hero and the home CTA band, strongest
   bottom-right where there are no words */
#tests .tests__note{position:relative;isolation:isolate;overflow:hidden}
#tests .tests__note::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300' preserveAspectRatio='xMaxYMax slice'%3E%3Cpath d='M389 250L391 256L389 261L386 267L381 271L376 275L371 279L365 283L359 286L352 287L344 288L337 287L330 286L324 284L317 283L311 283L303 284L294 283L286 282L278 278L274 273L272 267L273 261L275 255L277 250L279 245L281 241L282 236L284 231L287 227L292 223L297 219L303 216L309 214L315 211L322 208L330 206L338 205L346 206L354 209L359 214L362 220L365 225L367 230L371 233L375 237L381 240L386 245L389 250ZM444 250L448 261L446 272L439 282L427 290L414 296L400 300L388 304L377 309L367 313L355 317L343 320L330 321L317 320L304 318L292 316L278 314L264 312L249 308L236 301L227 292L223 282L224 270L230 259L237 250L243 242L246 234L247 226L248 216L249 206L254 196L262 187L274 181L287 176L302 174L316 173L330 173L344 173L358 175L371 180L382 186L390 194L396 203L401 211L407 218L414 225L424 232L435 240L444 250ZM495 250L500 266L498 282L489 297L472 308L450 316L429 321L410 324L394 329L379 335L365 344L349 353L330 360L309 363L288 362L268 357L250 349L233 340L218 330L203 319L192 307L184 293L182 278L185 264L192 250L200 238L206 226L209 214L210 200L210 184L215 168L225 153L242 142L264 136L287 135L310 139L330 144L349 149L366 153L384 157L401 162L417 169L432 177L443 188L453 199L463 211L474 222L485 235L495 250ZM539 250L539 270L535 289L525 308L508 323L486 335L460 343L436 348L414 354L395 362L376 373L355 386L330 399L301 407L271 408L243 401L219 387L202 369L189 351L178 333L168 317L158 301L148 285L143 268L142 250L145 233L151 216L158 199L164 181L170 162L179 142L194 123L215 108L243 99L273 99L303 105L330 115L353 126L374 134L395 138L418 141L444 144L470 150L494 160L512 175L525 192L533 211L537 231L539 250ZM581 250L569 272L557 294L546 314L533 334L516 352L495 368L470 380L444 390L417 400L390 411L362 423L330 436L294 445L256 446L221 439L191 421L171 398L160 371L153 347L147 326L136 307L121 290L104 271L89 250L81 227L81 202L91 179L106 158L125 138L147 119L170 101L197 86L228 75L263 71L298 74L330 84L358 96L384 106L409 113L438 117L471 118L508 123L544 133L573 150L591 173L597 199L592 225L581 250ZM625 250L600 275L578 298L563 319L552 342L543 367L530 393L510 417L481 437L447 451L409 461L370 467L330 471L289 472L247 470L207 462L172 445L146 421L129 394L120 365L113 339L103 317L86 297L62 275L37 250L17 221L10 189L19 158L43 132L77 111L114 96L152 84L187 73L222 63L257 55L293 50L330 51L366 56L400 64L432 73L466 81L504 88L545 97L586 109L623 129L647 156L654 188L645 220L625 250ZM668 250L641 279L614 304L593 328L580 353L573 383L564 417L548 453L519 484L478 506L430 516L379 515L330 507L285 495L243 483L202 470L164 455L129 437L99 415L77 389L60 361L46 334L30 307L9 280L-15 250L-36 216L-46 178L-38 141L-12 109L31 86L81 72L132 66L178 61L217 55L253 45L290 31L330 19L374 11L420 11L464 19L506 33L545 50L582 70L619 92L652 117L677 147L690 181L686 217L668 250Z' fill='none' stroke='%23CCDDB8' stroke-width='1' stroke-opacity='.16' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") right bottom / cover no-repeat;
  -webkit-mask:linear-gradient(150deg,transparent 22%,#000 78%);mask:linear-gradient(150deg,transparent 22%,#000 78%)}

/* phone: the column heads are hidden, so the list's own forest rule sat 40px under
   the page head's, a doubled line. The page head's rule is the list's top edge. */
@media (max-width:640px){
  #tests .schedule{border-top:0}
  #tests .schedule::before{display:none}
  #tests .schedule__row:first-child{padding-top:var(--s-1)}
}

/* ── postal kits ────────────────────────────────────────────────────────── */
#kits .kits__cta{align-items:center;column-gap:var(--s-6)}
#kits .kits__alt{font-size:var(--fs-small);line-height:1.5;color:var(--muted)}
#kits .kits__alt a{color:var(--field);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
#kits .kits__alt a:hover{color:var(--forest);text-decoration-thickness:2px}
#kits .kitlist{position:relative}
@media (max-width:560px){
  #kits .kit__desc{max-width:none}
  #kits .kits__alt{width:100%;text-align:center}
}

#faq .faq{position:relative}

/* ── motion ─────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion:no-preference){
  /* load: the page head and the price list are the first screen, so they get the
     hero's treatment, not a scroll reveal. Head lines rise; the list's rule draws;
     the rows step in under it, 70ms apart. Over in about a second. */
  .pagehead-sec:has(+ #tests) h1{animation:svc-rise .9s var(--ease) 60ms both}
  .pagehead-sec:has(+ #tests) .pagehead__lede{animation:svc-rise .9s var(--ease) 160ms both}
  #tests .schedule__head{animation:svc-fade .5s var(--ease) .4s both}
  #tests .schedule__row{animation:svc-rise .7s var(--ease) both}
  #tests .schedule__row:nth-child(1){animation-delay:.36s}
  #tests .schedule__row:nth-child(2){animation-delay:.43s}
  #tests .schedule__row:nth-child(3){animation-delay:.5s}
  #tests .schedule__row:nth-child(4){animation-delay:.57s}
  #tests .schedule__row:nth-child(n+5){animation-delay:.64s}

  /* forest head rules that draw: the border goes clear and a 2px bar scales in over it */
  #tests .schedule{position:relative;border-top-color:transparent}
  #tests .schedule::before{content:"";position:absolute;left:0;right:0;top:-2px;height:2px;background:var(--forest);
    transform-origin:0 50%;animation:svc-draw .9s cubic-bezier(.65,0,.35,1) .2s both}

  #kits .kits__body.rv .kitlist,#faq .faq.rv{border-top-color:transparent}
  #kits .kits__body.rv .kitlist::before,#faq .faq.rv::before{content:"";position:absolute;left:0;right:0;top:-2px;height:2px;background:var(--forest);
    transform:scaleX(0);transform-origin:0 50%;transition:transform .9s cubic-bezier(.65,0,.35,1) calc(var(--rd,0ms) + 100ms)}
  #kits .kits__body.rv.in .kitlist::before,#faq .faq.rv.in::before{transform:none}

  /* the kits: the two prices follow their rule in */
  #kits .kits__body.rv .kit{opacity:.001;transform:translateY(12px);transition:opacity .55s var(--ease),transform .75s var(--ease)}
  #kits .kits__body.rv.in .kit{opacity:1;transform:none;transition-delay:calc(var(--rd,0ms) + 200ms)}
  #kits .kits__body.rv.in .kit + .kit{transition-delay:calc(var(--rd,0ms) + 290ms)}

  /* the variable-rate map prints like the report's maps when it scrolls in (phone and tablet;
     on a desktop it is on the first screen) */
  #tests .rise.rv .tests__fig img{clip-path:inset(0 100% 0 0);
    transition:clip-path 1.1s cubic-bezier(.65,0,.35,1) calc(var(--rd,0ms) + 120ms),scale 1.4s var(--ease) var(--rd,0ms)}
  #tests .rise.rv.in .tests__fig img{clip-path:inset(0)}
}

/* the steps track draws as the four stations come in, each station arriving as the line reaches it */
@media (prefers-reduced-motion:no-preference) and (min-width:1001px){
  #how .steps.rv .step,#how .steps.rv .step::after{border-top-color:transparent}
  #how .steps.rv::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--forest);
    transform:scaleX(0);transform-origin:0 50%;transition:transform .8s cubic-bezier(.65,0,.35,1) var(--rd,0ms)}
  #how .steps.rv.in::before{transform:none}
  #how .steps.rv.in .step:nth-child(2){transition-delay:160ms}
  #how .steps.rv.in .step:nth-child(3){transition-delay:320ms}
  #how .steps.rv.in .step:nth-child(4){transition-delay:480ms}
}
/* phone: the track is vertical, so it draws downwards */
@media (prefers-reduced-motion:no-preference) and (max-width:640px){
  #how .steps.rv{border-left-color:transparent}
  #how .steps.rv::before{content:"";position:absolute;left:-2px;top:0;bottom:0;width:2px;background:var(--forest);
    transform:scaleY(0);transform-origin:50% 0;transition:transform 1s cubic-bezier(.65,0,.35,1) var(--rd,0ms)}
  #how .steps.rv.in::before{transform:none}
}
@keyframes svc-rise{from{opacity:.001;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes svc-fade{from{opacity:.001}}
@keyframes svc-draw{from{transform:scaleX(0)}}


/* ════ 60-blog.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Blog: the index (a lead post + the rest), the free-guides shelf, the post
   pages, and the review build's guide dialog. Flat: hairlines and her photos
   do the work, no card shadows (DESIGN.md §4, §6).
   ───────────────────────────────────────────────────────────────────────── */

/* tag: a legend key, the way an OS sheet keys its symbols. Square swatch + label voice.
   Compliance takes the soil note (it IS the five-year notice); guides the field green. */
.tag{
  --tag-c:var(--field);
  display:inline-flex;align-items:center;gap:10px;
  font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;line-height:1.2;
  color:var(--ink);
}
.tag::before{content:"";width:10px;height:10px;flex:none;background:var(--tag-c)}
.tag[data-tag="compliance"]{--tag-c:var(--soil)}
.tag[data-tag="example-report"]{--tag-c:var(--forest)}

/* "Read the post →": a text link with the button arrow */
.readmore{display:inline-flex;align-items:center;gap:var(--s-2);font-size:1rem;font-stretch:106%;font-weight:620;color:var(--forest);text-decoration:underline;text-decoration-color:var(--field);text-decoration-thickness:1px;text-underline-offset:5px}
.readmore svg{width:18px;height:18px;transition:transform .2s var(--ease)}

/* ── index ── */
.blog-index{padding-top:clamp(40px,5vw,72px)}

/* the lead: the post that matters most this season, given the room */
.lead-post__link{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:var(--gutter);align-items:center;color:inherit;text-decoration:none}
.lead-post__img{overflow:hidden;border-radius:var(--r);background:var(--ground-2)}
.lead-post__img img{width:100%;aspect-ratio:3 / 2;object-fit:cover}
.lead-post__body{display:grid;gap:var(--s-4);justify-items:start;padding-block:var(--s-5)}
.lead-post__h{font-size:var(--fs-h2);max-width:14ch;margin-top:var(--s-1)}
.lead-post__dek{font-size:var(--fs-lead);line-height:1.5;color:var(--body);max-width:40ch}
.lead-post .readmore{margin-top:var(--s-3)}
.lead-post__link:hover .lead-post__h{color:var(--forest)}
.lead-post__link:hover .readmore{text-decoration-thickness:2px}
.lead-post__link:hover .readmore svg{transform:translateX(3px)}

/* the rest: three across, under a hairline */
.post-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(32px,3.4vw,48px) var(--gutter);margin-top:clamp(48px,6vw,80px);padding-top:clamp(32px,4vw,48px);border-top:1px solid var(--line)}
.post-card__link{display:grid;gap:var(--s-3);align-content:start;color:inherit;text-decoration:none}
.post-card__img{overflow:hidden;border-radius:var(--r);background:var(--ground-2);margin-bottom:var(--s-3)}
.post-card__img img{width:100%;aspect-ratio:3 / 2;object-fit:cover}
.post-card__h{font-size:var(--fs-h3);font-stretch:104%;font-weight:680;letter-spacing:-.01em;line-height:1.2;text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:2px;text-underline-offset:5px;transition:text-decoration-color .15s}
.post-card__dek{font-size:1rem;line-height:1.55;color:var(--body);max-width:44ch}
.post-card__link:hover .post-card__h{color:var(--forest);text-decoration-color:var(--field)}
/* the guide page and the report cover are documents: keep their top edge, where the title is */
.post-card__img img[src*="field-guide"],.post-card__img img[src*="report-cover"]{object-position:50% 20%}

@media (max-width:1000px){
  .lead-post__link{grid-template-columns:minmax(0,1fr);gap:var(--s-5)}
  .lead-post__body{padding:0}
  .post-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .lead-post__img{margin-inline:calc(var(--gutter) * -1);border-radius:0}
  .post-grid{grid-template-columns:minmax(0,1fr)}
  /* phone: the rest become a compact list, thumbnail left */
  .post-card__link{grid-template-columns:7.5rem minmax(0,1fr);column-gap:var(--s-4);row-gap:var(--s-2)}
  .post-card__img{grid-row:1 / span 3;margin:0;align-self:start}
  .post-card__img img{aspect-ratio:1}
  .post-card__h{font-size:1.1875rem}
  .post-card__dek{font-size:.9375rem}
}

/* ── free guides: a downloads shelf, set like the price list ── */
.shelf{list-style:none;margin:0;padding:0;border-top:2px solid var(--forest)}
.shelf__item{
  display:grid;grid-template-columns:minmax(0,3fr) minmax(0,6fr) minmax(0,3fr);grid-template-rows:auto 1fr;
  column-gap:var(--gutter);padding:var(--s-6) 0;border-bottom:1px solid var(--line);
}
.shelf__cover{grid-column:1;grid-row:1 / span 2}
.shelf__cover img{width:100%;aspect-ratio:4 / 3;object-fit:cover;border-radius:var(--r);border:1px solid var(--line)}
.shelf__cover img[src*="report-cover"]{object-position:50% 20%}
.shelf__cover img[src*="field-guide"]{object-position:0 0}
.shelf__title{grid-column:2;grid-row:1;display:grid;gap:var(--s-3);justify-items:start}
.shelf__title h3{font-size:clamp(1.375rem,1.2rem + .6vw,1.75rem);font-stretch:108%;font-weight:700;letter-spacing:-.012em}
.shelf__body{grid-column:2;grid-row:2;margin-top:var(--s-3)}
.shelf__body p{color:var(--body);max-width:56ch}
.shelf__list{list-style:none;margin:var(--s-4) 0 0;padding:0;display:grid;gap:6px;font-size:1rem;line-height:1.45;color:var(--body)}
.shelf__list li{display:grid;grid-template-columns:14px minmax(0,1fr);gap:var(--s-2)}
.shelf__list li::before{content:"";width:6px;height:6px;margin-top:.55em;background:var(--field)}

.shelf__act{grid-column:3;grid-row:1 / span 2;display:flex;flex-direction:column;align-items:flex-end;text-align:right}
.shelf__size{display:flex;align-items:baseline;gap:var(--s-2)}
.shelf__fig{font-size:2.25rem;font-stretch:112%;font-weight:720;letter-spacing:-.02em;line-height:1;color:var(--forest)}
.shelf__time{margin-top:var(--s-2);font-size:var(--fs-small);color:var(--muted)}
.shelf__btn{margin-top:auto;width:100%;max-width:17rem}
.shelf__btn svg{width:18px;height:18px}
.shelf__btn:hover svg{transform:translateY(2px)}
.shelf__btn[href^="mailto"]:hover svg{transform:none}

.shelf__note{
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s-5) var(--s-6);align-items:center;
  margin-top:var(--s-7);padding:var(--s-5) var(--s-6);background:var(--ground);border-radius:var(--r);
}
.shelf__note p{color:var(--body);max-width:70ch}
.shelf__note b{color:var(--ink)}
.shelf__note p a{font-weight:600;white-space:nowrap}

@media (max-width:1000px){
  .shelf__item{grid-template-columns:minmax(0,4fr) minmax(0,8fr);grid-template-rows:auto auto auto;row-gap:0}
  .shelf__cover{grid-row:1 / span 2}
  .shelf__body{grid-column:2}
  .shelf__act{grid-column:2;grid-row:3;flex-direction:row;flex-wrap:wrap;align-items:center;gap:var(--s-2) var(--s-4);text-align:left;margin-top:var(--s-5)}
  .shelf__time{margin:0}
  .shelf__btn{margin:0 0 0 auto;width:auto}
}
@media (max-width:640px){
  .shelf__item{grid-template-columns:6.5rem minmax(0,1fr);column-gap:var(--s-4);padding:var(--s-5) 0}
  .shelf__cover{grid-row:1}
  .shelf__title{align-self:center;gap:var(--s-2)}
  .shelf__title h3{font-size:1.25rem}
  .shelf__body,.shelf__act{grid-column:1 / -1}
  .shelf__body{grid-row:2;margin-top:var(--s-4)}
  .shelf__act{grid-row:3}
  .shelf__btn{flex-basis:100%;max-width:none;margin:var(--s-2) 0 0}
  .shelf__note{grid-template-columns:minmax(0,1fr);padding:var(--s-5)}
  .shelf__note .btn{justify-self:start}
}

/* ── post pages ── */
.post-sec{padding-block:clamp(48px,6vw,88px) clamp(56px,6vw,96px)}
.post-layout{display:grid;grid-template-columns:minmax(0,8fr) minmax(0,4fr);column-gap:clamp(40px,6vw,96px);align-items:start}

.post__body{
  --post-fs:clamp(1.125rem,1.06rem + .25vw,1.1875rem);
  max-width:66ch;font-size:var(--post-fs);line-height:1.65;color:var(--body);
}
.post__body > *+*{margin-top:1.1em}
/* the opening paragraph is the answer: set it as a standfirst */
.post__body > p:first-of-type{font-size:clamp(1.25rem,1.1rem + .55vw,1.5rem);line-height:1.45;font-weight:440;color:var(--ink);letter-spacing:-.003em}
.post__body h2{margin-top:2.1em;font-size:clamp(1.5rem,1.3rem + .8vw,2rem);font-stretch:110%;font-weight:700;letter-spacing:-.015em;line-height:1.15}
.post__body h2+*{margin-top:.75em}
.post__body h3{margin-top:1.8em;font-size:var(--fs-h3)}
.post__body ul,.post__body ol{padding:0;list-style:none}
.post__body li{position:relative;padding-left:1.6em}
.post__body li+li{margin-top:.6em}
.post__body ul > li::before{content:"";position:absolute;left:.15em;top:.66em;width:7px;height:7px;background:var(--field)}
.post__body ol{counter-reset:li}
.post__body ol > li::before{counter-increment:li;content:counter(li);position:absolute;left:0;font-variant-numeric:tabular-nums;font-weight:650;color:var(--field)}
.post__fig{margin:2em 0}
.post__fig img{width:100%;border:1px solid var(--line);border-radius:var(--r)}
.post__fig figcaption{margin-top:var(--s-3);font-size:var(--fs-small);color:var(--muted)}
/* the end of every post: what to do next */
.post__body > .post__cta{display:flex;flex-wrap:wrap;gap:var(--s-3);margin-top:2.6em;padding-top:var(--s-6);border-top:2px solid var(--forest)}

/* "More from the blog": beside the article on a wide screen, after it on a narrow one */
.more{position:sticky;top:112px;padding-top:var(--s-1)}
.more__h{font-size:var(--fs-h3);font-stretch:104%;font-weight:680;letter-spacing:-.01em;line-height:1.2;padding-bottom:var(--s-4);border-bottom:2px solid var(--forest)}
.more__list{list-style:none;margin:0;padding:0}
.more__list li{border-bottom:1px solid var(--line)}
.more__link{display:grid;grid-template-columns:6rem minmax(0,1fr);gap:var(--s-4);align-items:center;padding:var(--s-4) 0;color:inherit;text-decoration:none}
.more__img{overflow:hidden;border-radius:var(--r-sm);background:var(--ground-2)}
.more__img img{width:100%;aspect-ratio:1;object-fit:cover}
.more__img img[src*="field-guide"],.more__img img[src*="report-cover"]{object-position:30% 20%}
.more__txt{display:grid;gap:var(--s-2);justify-items:start}
.more__txt .tag{font-size:.6875rem}
.more__t{font-size:1.0625rem;font-stretch:104%;font-weight:650;line-height:1.3;color:var(--ink);text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:2px;text-underline-offset:4px;transition:text-decoration-color .15s}
.more__link:hover .more__t{color:var(--forest);text-decoration-color:var(--field)}
.more__all{display:inline-flex;align-items:center;gap:var(--s-2);min-height:44px;margin-top:var(--s-3);font-size:1rem;font-stretch:106%;font-weight:620;color:var(--forest);text-underline-offset:5px;text-decoration-color:var(--field)}
.more__all svg{width:18px;height:18px;transition:transform .2s var(--ease)}
.more__all:hover svg{transform:translateX(3px)}

@media (max-width:1000px){
  .post-layout{grid-template-columns:minmax(0,1fr)}
  .more{position:static;margin-top:clamp(56px,8vw,88px)}
  .more__list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));column-gap:var(--gutter)}
  .more__list li{border-bottom:0}
  .more__link{grid-template-columns:minmax(0,1fr);align-items:start;padding:var(--s-5) 0 0}
  .more__img img{aspect-ratio:3 / 2}
}
@media (max-width:640px){
  .more__list{grid-template-columns:minmax(0,1fr)}
  .more__list li{border-bottom:1px solid var(--line)}
  .more__link{grid-template-columns:5.5rem minmax(0,1fr);align-items:center;padding:var(--s-4) 0}
  .more__img img{aspect-ratio:1}
  .post__body > .post__cta .btn{flex:1 1 100%}
}

@media (prefers-reduced-motion:reduce){
  .readmore svg,.more__all svg,.post-card__h,.more__t{transition:none}
  .lead-post__link:hover .readmore svg,.more__all:hover svg,.shelf__btn:hover svg{transform:none}
}

/* ════ 65-contact-legal.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Legal pages: her policies as long-form documents. Contents list left (sticky
   on a wide screen), the text at a reading measure right. Her sections ARE
   numbered, so the number is set as a hanging tabular figure.
   ───────────────────────────────────────────────────────────────────────── */
.legal-copy{padding-top:clamp(48px,6vw,88px)}
.legal-doc{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,9fr);column-gap:clamp(40px,6vw,96px);align-items:start}

.legal-toc{position:sticky;top:112px}
.legal-toc__h{padding-bottom:var(--s-3);border-bottom:2px solid var(--forest)}
.legal-toc ol{list-style:none;margin:0;padding:0}
.legal-toc li{border-bottom:1px solid var(--line)}
.legal-toc a{display:grid;grid-template-columns:1.75rem minmax(0,1fr);align-items:baseline;padding:10px 0;min-height:44px;font-size:.9375rem;line-height:1.35;color:var(--body);text-decoration:none}
.legal-toc a .num{font-size:.8125rem;font-weight:620;color:var(--muted)}
.legal-toc a:hover{color:var(--forest)}
.legal-toc a:hover .num{color:var(--field)}

.legal-copy .prose{max-width:68ch;font-size:var(--fs-body);line-height:1.65;color:var(--body)}
.legal-copy .prose > *+*{margin-top:1em}
/* "Effective Date: …": the document's own data line */
.legal-copy .prose > p:first-child{padding-bottom:var(--s-5);border-bottom:1px solid var(--line);color:var(--muted)}
.legal-copy .prose > p:first-child b{font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;margin-right:var(--s-2);color:var(--muted)}
.legal-copy .prose h2{position:relative;margin-top:2.4em;font-size:clamp(1.375rem,1.2rem + .6vw,1.75rem);font-stretch:108%;font-weight:700;letter-spacing:-.012em;line-height:1.2;scroll-margin-top:112px}
.legal-copy .prose h2+*{margin-top:.7em}
.legal-doc__n{display:inline-block;min-width:1.7em;color:var(--field);font-weight:700}
.legal-copy .prose h3{margin-top:1.8em;font-size:1.1875rem;font-stretch:104%;font-weight:680;line-height:1.3}
.legal-copy .prose h3+*{margin-top:.4em}
.legal-copy .prose ul{padding:0;list-style:none}
.legal-copy .prose li{position:relative;padding-left:1.5em}
.legal-copy .prose li+li{margin-top:.5em}
.legal-copy .prose li::before{content:"";position:absolute;left:.1em;top:.68em;width:6px;height:6px;background:var(--field)}
.legal-copy .prose b{color:var(--ink)}
.legal-copy .prose a{overflow-wrap:anywhere}

/* wide screens: the section number hangs in the gutter so the titles align with the text */
@media (min-width:1101px){
  .legal-doc__n{position:absolute;right:100%;min-width:0;margin-right:.6em}
}
@media (max-width:1100px){
  .legal-doc{grid-template-columns:minmax(0,1fr)}
  .legal-toc{position:static;margin-bottom:var(--s-7);max-width:68ch}
  .legal-toc ol{columns:2;column-gap:var(--s-6)}
  .legal-toc li{break-inside:avoid}
}
@media (max-width:640px){
  .legal-toc ol{columns:1}
  .legal-toc a{padding:8px 0}
}

/* Contact: "Find us". A composed block, set like a letterhead: label, value, note. */
.contact-find{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:clamp(32px,5vw,80px);align-items:start}
.contact-find__head p{margin-top:var(--s-4);font-size:var(--fs-lead);line-height:1.5;color:var(--muted);max-width:26ch}
.contact-find__list{margin:0;border-top:2px solid var(--forest)}
.contact-find__row{display:grid;grid-template-columns:minmax(0,9rem) minmax(0,1fr);gap:var(--s-2) var(--s-6);padding:var(--s-6) 0;border-bottom:1px solid var(--line);align-items:baseline}
.contact-find__row dt{color:var(--muted)}
.contact-find__row dd{margin:0}
.contact-find__big{display:inline-flex;align-items:center;min-height:44px;color:var(--forest);font-size:clamp(1.5rem,1.25rem + 1vw,2.25rem);font-stretch:112%;font-weight:700;letter-spacing:-.015em;line-height:1.1;text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:2px;text-underline-offset:7px;transition:text-decoration-color .15s;overflow-wrap:anywhere}
.contact-find__big:hover{color:var(--forest);text-decoration-color:var(--field)}
.contact-find__row dd p{margin-top:var(--s-2);font-size:1rem;color:var(--muted)}
.contact-find address{font-style:normal;font-size:var(--fs-lead);line-height:1.5;color:var(--ink)}
@media (max-width:900px){.contact-find{grid-template-columns:1fr}}
@media (max-width:560px){
  .contact-find__row{grid-template-columns:1fr;padding:var(--s-5) 0}
}
@media (prefers-reduced-motion:reduce){.contact-find__big{transition:none}}

/* ════ 66-magnet.css ════ */
/* Lead magnets (js/magnet.js, live build): the "send me the guide" dialog and the one
   site-wide nudge card. Built from the form's own pieces (.field, .btn, .label), so it
   reads as the same site. Square-shouldered, forest rule on top, gold for the one action. */

dialog.magnet{border:0;border-top:3px solid var(--forest);padding:0;width:min(560px,calc(100vw - 2 * var(--s-4)));max-height:calc(100dvh - 2 * var(--s-4));overflow:auto;background:var(--white);color:var(--body);box-shadow:var(--shadow-float)}
dialog.magnet::backdrop{background:rgb(20 32 26 / .6)}
dialog.magnet[open]{animation:mg-in .28s var(--ease) both}
@keyframes mg-in{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.magnet-open{overflow:hidden}
.magnet__in{position:relative;padding:var(--s-6) var(--s-6) var(--s-6)}
.magnet__close{position:absolute;right:var(--s-2);top:var(--s-2);display:grid;place-items:center;width:44px;height:44px;background:none;border:0;border-radius:var(--r-sm);color:var(--muted);cursor:pointer}
.magnet__close:hover{background:var(--ground-2);color:var(--ink)}
.magnet__close svg{width:20px;height:20px}
.magnet__head{display:flex;gap:var(--s-4);align-items:center;margin:0 var(--s-7) var(--s-4) 0}
.magnet__head img{flex:none;width:96px;aspect-ratio:4/3;object-fit:cover;border:1px solid var(--line);border-radius:var(--r-sm)}
.magnet__head .label{margin-bottom:var(--s-2)}
.magnet__head h2{font-size:clamp(1.3rem,1.15rem + .5vw,1.6rem);font-stretch:108%;font-weight:720;letter-spacing:-.015em;line-height:1.15;color:var(--ink)}
.magnet__lede{margin-bottom:var(--s-5);font-size:1rem;line-height:1.55;color:var(--body);max-width:48ch}
.magnet form{display:grid;gap:var(--s-4)}
.magnet__grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-4)}
.magnet .field input{min-height:52px}
.magnet__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.magnet__who{border:0;padding:0;margin:0;display:grid;grid-template-columns:1fr 1fr;gap:var(--s-2)}
.magnet__who legend{grid-column:1 / -1;padding:0;margin-bottom:var(--s-2);font-size:var(--fs-label);font-stretch:125%;font-weight:620;letter-spacing:.14em;text-transform:uppercase;line-height:1.3;color:var(--body)}
.magnet__opt{position:relative;display:flex;align-items:center;gap:var(--s-3);min-height:52px;padding:var(--s-2) var(--s-4);border:1px solid var(--input-edge);border-radius:var(--r-sm);background:var(--white);font-size:1rem;font-weight:520;line-height:1.25;color:var(--ink);cursor:pointer;transition:border-color .15s var(--ease),background-color .15s var(--ease)}
.magnet__opt:hover{border-color:var(--forest)}
.magnet__opt input{flex:none;width:18px;height:18px;margin:0;accent-color:var(--forest)}
.magnet__opt:has(input:checked){border-color:var(--forest);background:var(--ground);box-shadow:0 0 0 1px var(--forest)}
.magnet__opt:has(input:focus-visible){outline:3px solid var(--focus);outline-offset:2px}
.magnet__who .field__msg{grid-column:1 / -1}
.magnet form[data-tried] .magnet__who:has(:invalid) .field__msg{display:block}
.magnet form[data-tried] .magnet__who:has(:invalid) .magnet__opt{border-color:var(--error)}
.magnet form[data-tried] .field:has(:invalid) .field__msg{display:block}
.magnet form[data-tried] .field:has(:invalid) input{border-color:var(--error);box-shadow:0 0 0 1px var(--error)}

.magnet__err a{color:inherit;font-weight:620}
.magnet__go{width:100%;min-height:56px;font-size:1.0625rem}
.magnet__fine{font-size:.875rem;line-height:1.5;color:var(--muted);text-align:center}
.magnet__fine a{color:var(--forest)}

.magnet__done{padding:var(--s-2) 0 0}
.magnet__tick{width:48px;height:48px;color:var(--field);margin-bottom:var(--s-4)}
.magnet__done h2{font-size:clamp(1.5rem,1.3rem + .6vw,1.875rem);font-stretch:110%;font-weight:720;letter-spacing:-.015em;color:var(--ink);margin:0 var(--s-7) var(--s-3) 0;outline:0}
.magnet__done > p{font-size:1.0625rem;line-height:1.55;max-width:46ch;margin-bottom:var(--s-5)}
.magnet__done .btn{margin-bottom:var(--s-5)}
.magnet__after{padding-top:var(--s-4);border-top:1px solid var(--line);font-size:var(--fs-small) !important;color:var(--muted)}
.magnet__after a{color:var(--forest);font-weight:600}
.magnet__shut{display:block;margin-top:var(--s-4);min-height:44px;padding:0 var(--s-5);border:1.5px solid var(--forest);border-radius:var(--r-sm);background:transparent;color:var(--forest);font:inherit;font-weight:620;cursor:pointer}
.magnet__shut:hover{background:var(--ground-2)}

/* the nudge: bottom-right, so it never sits on the cookie bar (bottom-left), and it only
   appears once that bar has been answered anyway */
.magnet-nudge{position:fixed;right:var(--s-4);bottom:var(--s-4);z-index:var(--z-overlay);display:grid;grid-template-columns:112px 1fr;gap:var(--s-4);align-items:start;width:min(420px,calc(100vw - 2 * var(--s-4)));padding:var(--s-4) var(--s-4) var(--s-4);background:var(--white);border:1px solid var(--line);border-top:2px solid var(--forest);box-shadow:var(--shadow-float);opacity:0;transform:translateY(16px);transition:opacity .3s var(--ease),transform .3s var(--ease)}
.magnet-nudge.is-in{opacity:1;transform:none}
.magnet-nudge img{width:112px;aspect-ratio:4/3;object-fit:cover;border:1px solid var(--line);border-radius:var(--r-sm)}
.magnet-nudge__txt{padding-right:var(--s-6)}
.magnet-nudge .label{margin-bottom:var(--s-1)}
.magnet-nudge__h{font-size:1.0625rem;font-stretch:106%;font-weight:700;line-height:1.25;color:var(--ink);margin-bottom:var(--s-1)}
.magnet-nudge__p{font-size:.875rem;line-height:1.45;color:var(--muted);margin-bottom:var(--s-3)}
.magnet-nudge__go{min-height:44px;padding:0 var(--s-4);font-size:.9375rem}
.magnet-nudge__x{position:absolute;right:2px;top:2px;display:grid;place-items:center;width:44px;height:44px;background:none;border:0;color:var(--muted);cursor:pointer;border-radius:var(--r-sm)}
.magnet-nudge__x:hover{background:var(--ground-2);color:var(--ink)}
.magnet-nudge__x svg{width:18px;height:18px}

@media (max-width:640px){
  .magnet__in{padding:var(--s-5) var(--s-4) var(--s-5)}
  .magnet__grid,.magnet__who{grid-template-columns:1fr}
  .magnet__head img{width:72px}
  .magnet-nudge{left:var(--s-3);right:var(--s-3);bottom:var(--s-3);width:auto;grid-template-columns:80px 1fr;gap:var(--s-3)}
  .magnet-nudge img{width:80px}
  .magnet-nudge__p{display:none}
}
@media (prefers-reduced-motion:reduce){
  dialog.magnet[open]{animation:none}
  .magnet-nudge,.magnet__opt{transition:none;transform:none}
}

/* ════ 70-cookie.css ════ */
/* Cookie consent bar (live build only). Her wording; equal-weight choices (ICO:
   rejecting must be as easy as accepting), so gold stays the site's one action. */
.cookie-bar{position:fixed;left:var(--s-4);bottom:var(--s-4);z-index:var(--z-toast);width:min(600px,calc(100vw - 2 * var(--s-4)));background:var(--white);border:1px solid var(--line);border-top:2px solid var(--forest);border-radius:var(--r);box-shadow:var(--shadow-float);padding:var(--s-5);display:grid;gap:var(--s-4);opacity:0;transform:translateY(14px);transition:opacity .28s var(--ease),transform .28s var(--ease)}
.cookie-bar.is-in{opacity:1;transform:none}
.cookie-bar__status{margin:0;padding:var(--s-2) var(--s-3);border-radius:var(--r-sm);background:var(--ground-2);font-size:.875rem;color:var(--ink)}
.cookie-bar__btn[aria-pressed="true"]::before{content:"\2713";margin-right:.45em}
.cookie-bar__text{margin:0;font-size:.9375rem;line-height:1.55;color:var(--body)}
.cookie-bar__text b{display:block;margin-bottom:var(--s-1);font-size:1rem;font-stretch:106%;font-weight:680;color:var(--ink)}
.cookie-bar__text a{color:var(--forest);white-space:nowrap}
.cookie-bar__acts{display:flex;gap:var(--s-2);justify-content:flex-end}
.cookie-bar__btn{min-height:44px;min-width:112px;padding:0 var(--s-5);border-radius:var(--r-sm);border:1.5px solid var(--forest);background:transparent;color:var(--forest);font-size:.9375rem;font-stretch:106%;font-weight:620;line-height:1;cursor:pointer;transition:background-color .15s var(--ease),color .15s var(--ease);touch-action:manipulation}
.cookie-bar__btn:hover{background:var(--ground-2)}
.cookie-bar__btn--accept{background:var(--forest);color:var(--white)}
.cookie-bar__btn--accept:hover{background:var(--forest-2);color:var(--white)}
.legal .cookie-settings{background:none;border:0;padding:0;font:inherit;color:inherit;text-decoration:underline;cursor:pointer}
@media (max-width:640px){
  .cookie-bar{left:var(--s-3);bottom:var(--s-3);width:calc(100vw - 2 * var(--s-3));padding:var(--s-4)}
  .cookie-bar__acts{display:grid;grid-template-columns:1fr 1fr}
  .cookie-bar__btn{min-width:0}
}
@media (prefers-reduced-motion:reduce){.cookie-bar,.cookie-bar__btn{transition:none;transform:none}}

/* ════ 90-footer.css ════ */
/* ─────────────────────────────────────────────────────────────────────────
   Footer: forest ground. Brand + pages + contact, then the funding marks as
   white reverses straight on the forest, then the legal line.
   ───────────────────────────────────────────────────────────────────────── */
.site-foot{
  /* local tokens (footer only) */
  --foot-rule:rgb(228 236 229 / .16);   /* --on-forest at 16%: hairlines on forest */
  --plate-h:88px;                        /* every funding plate is this tall */
  background:var(--forest);color:var(--on-forest);
  padding:clamp(64px,7vw,96px) 0 var(--s-6);
  font-size:var(--fs-small);line-height:1.6;
}
.site-foot a{color:var(--white);text-decoration:none}
.site-foot a:hover{color:var(--white);text-decoration:underline;text-decoration-color:var(--sage);text-decoration-thickness:1px;text-underline-offset:4px}
.site-foot :focus-visible{outline-color:var(--sage)}

/* top: brand · pages · contact */
.foot-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,3fr) minmax(0,4fr);gap:var(--s-7) var(--s-6);align-items:start}
/* The lockup as a one-colour white reverse: the two greens drop to ~2:1 on forest, white reads at 11:1. */
.foot-brand .logo{height:64px;width:auto;margin:-3px 0 var(--s-5) -3px;filter:brightness(0) invert(1)}
.foot-brand p{max-width:34ch;font-size:var(--fs-body);line-height:1.55;color:var(--on-forest)}
.foot-col h4{margin:0 0 var(--s-4);color:var(--sage)}
.foot-col ul{list-style:none;margin:0;padding:0;display:grid;gap:var(--s-2)}
.foot-col .foot-pages{grid-template-columns:repeat(2,max-content);grid-template-rows:repeat(3,auto);grid-auto-flow:column;gap:var(--s-2) var(--s-7)}
.foot-col li{color:var(--on-forest-muted)}
.foot-col a{display:inline-flex;align-items:center;min-height:32px;font-size:1rem;font-stretch:106%;font-weight:620;letter-spacing:.005em}
.foot-col address{font-style:normal;color:var(--on-forest-muted);margin-top:var(--s-2)}
.foot-contact .foot-phone{font-size:1.375rem;font-stretch:110%;font-weight:680;letter-spacing:.01em}

/* funding + certification */
.funded{
  margin-top:clamp(48px,6vw,72px);padding-top:var(--s-6);border-top:1px solid var(--foot-rule);
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--s-5) var(--s-7);align-items:center;
}
.funded__marks{display:flex;align-items:center;gap:var(--s-6) var(--s-7)}
/* No tiles: each mark sits straight on the forest as a one-colour white reverse, dimmed until hovered.
   The two JPGs have baked-in white grounds, so they are greyscaled, inverted (white ground -> black) and
   screen-blended, which makes the black vanish into the forest. B Lab's SVG is transparent: plain white reverse. */
.funded__plate{display:flex;align-items:center;justify-content:center;flex:none;height:var(--plate-h)}
/* opacity sits on the img, not the plate: opacity on the plate would isolate the blend from the forest behind it */
.funded__plate img{width:auto;opacity:.8;transition:opacity .2s var(--ease);filter:grayscale(1) contrast(1.15) invert(1);mix-blend-mode:screen}
.funded__plate--ukspf img{height:calc(var(--plate-h) - 8px)}
.funded__plate--nnc img{height:44px}
.funded__plate--bcorp img{height:64px;filter:brightness(0) invert(1);mix-blend-mode:normal}
a.funded__plate:hover img,.funded__plate:hover img{opacity:1}
a.funded__plate:focus-visible{outline:2px solid var(--sage);outline-offset:6px}
.funded__text{display:grid;gap:var(--s-2);max-width:60ch}
.funded__text p{color:var(--on-forest-muted)}
.funded__note a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}

/* legal line */
.legal{
  margin-top:var(--s-6);padding-top:var(--s-5);border-top:1px solid var(--foot-rule);
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s-3) var(--s-6);
  font-size:.875rem;color:var(--on-forest-muted);
}
.legal__co{display:flex;flex-wrap:wrap;gap:var(--s-1) 0}
.legal__co > span + span::before{content:"·";margin:0 10px;color:var(--on-forest-muted)}
.legal__links{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2) var(--s-5)}
.legal__links a,.site-foot .legal .cookie-settings{color:var(--on-forest);font-weight:500;text-decoration:none;min-height:32px;display:inline-flex;align-items:center}
.legal__links a:hover,.site-foot .legal .cookie-settings:hover{color:var(--white);text-decoration:underline;text-decoration-color:var(--sage);text-underline-offset:4px}

@media (max-width:1100px){
  .funded{grid-template-columns:1fr}
}
@media (max-width:820px){
  .foot-grid{grid-template-columns:auto minmax(0,1fr);gap:var(--s-7) var(--s-8)}
  .foot-brand{grid-column:1 / -1}
}
@media (max-width:700px){
  /* UKSPF across the top, council + B Corp beneath: the three never squeeze into one row */
  .funded__marks{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s-5) var(--s-6)}
  .funded__plate--ukspf{grid-column:1 / -1;justify-content:flex-start}
  .funded__plate--nnc{justify-content:flex-start}
}
@media (max-width:560px){
  .site-foot{--plate-h:80px}
  body:has(.sticky-cta) .site-foot{padding-bottom:calc(var(--s-6) + 80px)}  /* clear the home page's sticky bar */
  .foot-grid{gap:var(--s-7) var(--s-7)}
  .foot-pages-wrap,.foot-grid > .foot-col:first-of-type{grid-column:1 / -1}  /* pages (two columns) and contact each get a full row on a phone */
  .foot-contact{grid-column:1 / -1}
  .foot-brand .logo{height:56px}
  .funded__plate--nnc img{height:38px}
  .funded__plate--bcorp img{height:56px}
  .legal{flex-direction:column;align-items:flex-start}
  .legal__co{flex-direction:column}
  .legal__co > span + span::before{content:none}
}

/* ════ 95-motion.css ════ */
/* Motion: enhance, never gate (DESIGN.md §7).
   Content is visible by default. The page script marks only the .rise blocks that
   start BELOW the first screen (.rv), and reveals each as it scrolls in (.in): a
   short, eased fade + 16px rise on a clock, not scrubbed to the scroll position,
   so nothing is ever left half-faded when the reader stops. Blocks that enter
   together step in 140ms apart (--rd, set by the script). Inside a revealed block
   the parts that are a real sequence follow on: the four steps, the report's maps
   (drawn left to right like a page printing), the claims, the FAQ rows, photos
   settling into their frames. Steps are 140ms apart, moves 1s or less: noticeable, never in the way.
   No JS, no IntersectionObserver, reduced motion, a headless render or print:
   no .rv is ever set, so everything is simply there. */
.rise{opacity:1;transform:none}

@media (prefers-reduced-motion:no-preference){
  .rise.rv{opacity:.001;transform:translateY(24px);
    transition:opacity .8s var(--ease) var(--rd,0ms),transform 1.05s var(--ease) var(--rd,0ms)}
  .rise.rv.in{opacity:1;transform:none}

  /* a heading's line follows its heading */
  .rise.rv > h2 ~ p,.rise.rv > .sec-head p{opacity:.001;transform:translateY(14px);
    transition:opacity .8s var(--ease) calc(var(--rd,0ms) + 200ms),transform 1s var(--ease) calc(var(--rd,0ms) + 200ms)}
  .rise.rv.in > h2 ~ p,.rise.rv.in > .sec-head p{opacity:1;transform:none}

  /* photographs settle into their frames (the scale property, so the cards' own hover zoom still works) */
  .rise.rv :is(.path__img,.tile__img,.how-media__img) img,.rise.rv.kits__img img,.rise.rv .tests__fig img{scale:1.05;
    transition:scale 1.6s var(--ease) var(--rd,0ms),transform .7s var(--ease)}
  .rise.rv.in :is(.path__img,.tile__img,.how-media__img) img,.rise.rv.in.kits__img img,.rise.rv.in .tests__fig img{scale:1}
  .rise.rv.kits__img,.rise.rv .tests__fig{overflow:hidden}

  /* the report: the maps print left to right, then the ADAS key steps in */
  .rise.rv .sheet__maps img{clip-path:inset(0 100% 0 0);transition:clip-path 1.1s cubic-bezier(.65,0,.35,1) .15s}
  .rise.rv.in .sheet__maps img{clip-path:inset(0)}
  .rise.rv .sheet__key li{opacity:.001;transition:opacity .4s var(--ease)}
  .rise.rv.in .sheet__key li{opacity:1}
  .rise.rv.in .sheet__key li:nth-child(1){transition-delay:.8s}
  .rise.rv.in .sheet__key li:nth-child(2){transition-delay:.88s}
  .rise.rv.in .sheet__key li:nth-child(3){transition-delay:.96s}
  .rise.rv.in .sheet__key li:nth-child(4){transition-delay:1.04s}
  .rise.rv.in .sheet__key li:nth-child(5){transition-delay:1.12s}
  .rise.rv.in .sheet__key li:nth-child(6){transition-delay:1.2s}
  .rise.rv.in .sheet__key li:nth-child(7){transition-delay:1.28s}

  /* sequences inside a block: the steps, the claims, the FAQ rows, the how-it-works photos */
  .rise.rv :is(.step,.claims > li,.faq > details,.how-media > figure){opacity:.001;transform:translateY(18px);
    transition:opacity .7s var(--ease),transform .95s var(--ease)}
  .rise.rv.in :is(.step,.claims > li,.faq > details,.how-media > figure){opacity:1;transform:none}
  .rise.rv.in :is(.step,.claims > li,.faq > details,.how-media > figure):nth-child(2){transition-delay:140ms}
  .rise.rv.in :is(.step,.claims > li,.faq > details,.how-media > figure):nth-child(3){transition-delay:280ms}
  .rise.rv.in :is(.step,.claims > li,.faq > details,.how-media > figure):nth-child(4){transition-delay:420ms}
  .rise.rv.in :is(.step,.claims > li,.faq > details,.how-media > figure):nth-child(5){transition-delay:540ms}
  .rise.rv.in :is(.step,.claims > li,.faq > details,.how-media > figure):nth-child(n+6){transition-delay:640ms}
}
@media print{.rise.rv,.rise.rv *{opacity:1 !important;transform:none !important;clip-path:none !important;scale:none !important}}
