/* ==========================================================================
   Strata Agronomy — design system
   --------------------------------------------------------------------------
   Rebuilt to the client-approved reference comp.

   What changed, and why it is worth writing down: the previous system was an
   editorial one — a serif display face, a page that descended tonally from
   pale mineral into near-black bedrock, full-bleed video behind most bands,
   and a lot of bespoke motion. It was coherent, but it was not what the
   client signed off on. The approved direction is warmer, brighter and far
   more conventional in the good sense: a pale sage page, deep green anchors
   at the top and bottom, and everything in between held in soft rounded
   cards.

   The three rules the whole sheet follows:

     1. TWO GROUNDS. Deep green (--forest-*) or pale sage (--sage-*). Every
        band is one or the other, and text colour follows from which one it
        is — never chosen per element.
     2. EVERYTHING IS A CARD. Radii are large and consistent (--r-*). Nothing
        sits on a hard 90-degree corner except the page edges themselves.
     3. ONE ACCENT. --leaf-soft is the only colour that is neither a green
        ground nor a neutral. It marks the thing to click and the word to
        read, and it is spent sparingly enough that it still means something.

   Palette source of truth: the logo (logos/Strata+logo.png) supplies --forest
   and --leaf exactly; the reference comp supplies the tonal structure those
   two are arranged into.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* ---- Brand: exact logo values. Neither is a surface colour. ---- */
  --forest:        #11532F;
  --leaf:          #6EB944;

  /* ---- Green grounds ----
     Muted and slightly olive rather than the logo's saturated forest. The
     comp's hero is a green you could photograph a field against; the logo
     green at full strength is a green you can only set type on. */
  --forest-deep:   #24401F;   /* the deepest anchor: footer base, scrims */
  --forest-mid:    #33512E;   /* hero and footer ground */
  --forest-soft:   #3E5F35;   /* lifted dark surfaces: stat panel, CTA band */
  --forest-line:   #4C6E42;   /* hairlines on a green ground */

  /* ---- Light grounds ---- */
  --sage:          #EFF1E6;   /* the page itself */
  --sage-deep:     #E4EAD7;   /* the foot of a card gradient, quiet bands */
  --card:          #F7F9F1;   /* the head of a card gradient */
  --line:          #D5DCC6;   /* hairlines on a light ground */

  /* ---- The one accent ---- */
  --leaf-soft:     #A7D06B;   /* buttons, marks, the emphasised word */
  --leaf-lift:     #BCDF89;   /* its hover state */
  /* The accent dropped to a value that clears AA as *text* on --sage.
     --leaf-soft itself sits near 1.6:1 there: it is a fill colour on light
     and a text colour only on green. */
  --leaf-ink:      #40682A;

  /* ---- Text ---- */
  --ink:           #16210F;   /* body on light — 15.9:1 on --sage */
  --muted:         #55624C;   /* secondary on light — 6.4:1 on --sage */
  --on-dark:       #F1F5EA;   /* body on green */
  --on-dark-mut:   #C2D2B2;   /* secondary on green — 6.9:1 on --forest-mid */

  /* ---- Spacing scale (4px base). No arbitrary padding anywhere. ---- */
  --s-1:  0.25rem;  /*  4 */
  --s-2:  0.5rem;   /*  8 */
  --s-3:  0.75rem;  /* 12 */
  --s-4:  1rem;     /* 16 */
  --s-5:  1.5rem;   /* 24 */
  --s-6:  2rem;     /* 32 */
  --s-7:  3rem;     /* 48 */
  --s-8:  4rem;     /* 64 */
  --s-9:  6rem;     /* 96 */
  --s-10: 8rem;     /* 128 */

  /* ---- Type ----
     One family, five weights. The reference comp is set in a single
     humanist-geometric sans doing all the work — display, UI and body — and
     the serif/sans/mono trio the old system used cannot be made to look like
     it. Plus Jakarta Sans is the closest free match to the comp: double-
     storey 'a', single-storey 'g', tall x-height, and a bold that stays open
     at display sizes instead of closing up. */
  --font: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", sans-serif;

  /* Fluid scale, clamped so it never collapses or runs away. Deliberately
     smaller at the top end than the old scale: the comp's hero headline is
     about 56px on a 1440 canvas, not 96px. */
  --t-hero:  clamp(2.25rem, 4.6vw, 3.5rem);
  --t-h1:    clamp(2rem, 3.8vw, 3rem);
  --t-h2:    clamp(1.625rem, 2.8vw, 2.25rem);
  --t-h3:    clamp(1.125rem, 1.6vw, 1.375rem);
  --t-lead:  clamp(1rem, 1.2vw, 1.125rem);
  --t-body:  1rem;
  --t-small: 0.9375rem;
  --t-label: 0.75rem;

  /* ---- Layout ---- */
  --wrap:      78rem;
  --wrap-text: 42rem;   /* ~68ch — reading measure */
  --gutter:    var(--s-5);

  /* ---- Radii ----
     The single most identifying property of the approved design. Cards are
     --r-card, panels and bands are --r-band, controls are --r-pill. */
  --r-sm:    0.5rem;
  --r-md:    0.875rem;
  --r-card:  1.25rem;
  --r-band:  2rem;
  --r-pill:  999px;

  /* ---- Elevation ----
     Two shadows, always together: a tight one that seats the card on the
     page and a wide soft one that lifts it. A single blur does one or the
     other and always looks like a default. */
  --lift:    0 1px 2px rgba(36, 64, 31, 0.06),
             0 18px 36px -22px rgba(36, 64, 31, 0.35);
  --lift-lg: 0 2px 4px rgba(36, 64, 31, 0.08),
             0 32px 60px -30px rgba(36, 64, 31, 0.45);

  /* ---- Motion ---- */
  --ease:     cubic-bezier(0.2, 0.6, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur:      220ms;
  --dur-slow: 620ms;
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* This design commits to a single light treatment. Declaring it explicitly
     makes native controls (the <select>, form UI) render correctly for
     visitors whose OS is set to dark. */
  color-scheme: light;
}

/* The header is sticky, so anchor targets must clear it or the heading lands
   underneath. */
:target,
section[id],
.article-body :is(h2, h3) {
  scroll-margin-top: 6.5rem;
}

body {
  margin: 0;
  background: var(--sage);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
h1, h2, h3, h4, p, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }

/* Removes the ~300ms tap delay and the default blue flash on touch devices. */
a, button, label, select, summary, [role="button"] {
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(17, 83, 47, 0.14);
}

/* One focus treatment for the whole site. Two rings — the accent plus a dark
   outer — so it is visible on both grounds without a per-band override. */
:focus-visible {
  outline: 2px solid var(--leaf-soft);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, .display {
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 {
  font-size: var(--t-h3);
  line-height: 1.3;
  letter-spacing: -0.012em;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.6;
  color: var(--muted);
  text-wrap: pretty;
}

/* The eyebrow. Was a mono face; the approved design has no monospace in it at
   all, so this is now the body face at its heaviest weight and widest
   tracking — which is what the comp's section labels are. */
.label {
  display: block;
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--leaf-ink);
}

/* The word inside a heading that carries the accent. One per heading. */
.accent { color: var(--leaf-soft); }
.band-surface .accent,
.band-lifted .accent { color: var(--leaf-ink); }

.prose p { margin-bottom: var(--s-5); max-width: var(--wrap-text); text-wrap: pretty; }
.prose p:last-child { margin-bottom: 0; }

/* Links inside running copy. Everything else on the site is a card or a
   button, so this only has to serve article bodies and the footer. */
.prose a,
.article-body a {
  color: var(--leaf-ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.prose a:hover,
.article-body a:hover { color: var(--forest); }

/* --------------------------------------------------------------------------
   4. Layout primitives
   -------------------------------------------------------------------------- */
.wrap {
  width: min(100% - (var(--gutter) * 2), var(--wrap));
  margin-inline: auto;
}

.section {
  position: relative;
  padding-block: clamp(var(--s-8), 8vw, var(--s-10));
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--s-6) var(--s-5);
}

.col-1-6  { grid-column: 1 / 7; }
.col-1-7  { grid-column: 1 / 8; }
.col-1-8  { grid-column: 1 / 9; }
.col-1-9  { grid-column: 1 / 10; }
.col-8-10 { grid-column: 8 / 11; }
.col-8-13 { grid-column: 8 / 13; }
.col-9-13 { grid-column: 9 / 13; }
.col-10-13{ grid-column: 10 / 13; }

@media (max-width: 60rem) {
  .grid > [class^="col-"] { grid-column: 1 / -1; }
}

/* The section head: eyebrow, heading, and the small sprout rule under it.
   Centred by default because that is what the approved comp does for every
   section on the home page; `.section-head--start` is the left-aligned
   variant the inner pages use. */
.section-head {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: var(--s-4);
  max-width: 46rem;
  margin-inline: auto;
  margin-bottom: var(--s-8);
}

.section-head p { color: var(--muted); text-wrap: pretty; }

/* The sprout divider. A 1px rule would be a generic separator; the mark is
   the site's own glyph, so the rule is *interrupted* by it — the same idea as
   the old horizon rule, restated in the new language. */
.section-head__mark {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--leaf-ink);
}
.section-head__mark::before,
.section-head__mark::after {
  content: "";
  width: var(--s-7);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line));
}
.section-head__mark::after { background: linear-gradient(90deg, var(--line), transparent); }

.section-head--start {
  justify-items: start;
  text-align: left;
  margin-inline: 0;
  max-width: 40rem;
}
.section-head--start .section-head__mark::before { display: none; }

/* A section head that has an action sitting opposite it (Resources, Field
   notes). Splits into a row once there is width for one. */
.section-head--split {
  max-width: none;
  justify-items: start;
  text-align: left;
}
@media (min-width: 48rem) {
  .section-head--split {
    grid-template-columns: 1fr auto;
    align-items: end;
  }
  .section-head--split > :last-child { grid-column: 2; grid-row: 1 / span 2; }
}

/* --------------------------------------------------------------------------
   5. Bands
   --------------------------------------------------------------------------
   Four grounds, and nothing else. `band-surface` is the page's own colour and
   is therefore usually implicit; it exists so a template can say which
   ground it means rather than relying on inheritance. */
.band-surface { background: var(--sage); }
.band-lifted  { background: var(--sage-deep); }
.band-forest  { background: var(--forest-mid); color: var(--on-dark); }
.band-bedrock { background: var(--forest-deep); color: var(--on-dark); }

/* The four dark grounds, named once.

   `.page-head` has to be in every one of these groups: it is the green band
   at the top of every inner page, and while it was missing the eyebrow
   resolved to --leaf-ink (2.0:1 on green — effectively invisible), the lead
   to --muted, and a ghost button to a dark outline with dark text. That is a
   failure that only shows on pages other than Home, which is exactly the
   class of bug a redesign ships. */
:is(.band-forest, .band-bedrock, .hero, .page-head) :is(h1, h2, h3, h4) {
  color: var(--on-dark);
}

:is(.band-forest, .band-bedrock, .hero, .page-head) .lead { color: var(--on-dark-mut); }
:is(.band-forest, .band-bedrock, .hero, .page-head) .label { color: var(--leaf-soft); }
:is(.band-forest, .band-bedrock, .hero, .page-head) .section-head p { color: var(--on-dark-mut); }

:is(.band-forest, .band-bedrock, .page-head) .section-head__mark { color: var(--leaf-soft); }
:is(.band-forest, .band-bedrock, .page-head) .section-head__mark::before {
  background: linear-gradient(90deg, transparent, var(--forest-line));
}
:is(.band-forest, .band-bedrock, .page-head) .section-head__mark::after {
  background: linear-gradient(90deg, var(--forest-line), transparent);
}

/* The signature seam. The pale page does not begin at a straight edge below
   the hero — it rises over it on a large radius, and the hero's artwork
   breaks across the join. One class, applied to whatever section follows a
   green band. */
.band-rise {
  position: relative;
  z-index: 1;
  margin-top: calc(var(--s-6) * -1);
  border-radius: var(--r-band) var(--r-band) 0 0;
}

/* --------------------------------------------------------------------------
   6. Buttons
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--leaf-soft);
  --btn-fg: var(--forest-deep);
  --btn-bd: transparent;

  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0.8125rem var(--s-5);
  border: 1px solid var(--btn-bd);
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--t-small);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}

.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

/* The icon a button carries is always trailing and always the sprout, which
   is why it is sized here rather than per call site. */
.btn .icon { width: 1.0625rem; height: 1.0625rem; flex: none; }

.btn--primary { --btn-bg: var(--leaf-soft); --btn-fg: var(--forest-deep); }
.btn--primary:hover { --btn-bg: var(--leaf-lift); }

/* On a green ground a ghost button is a pale outline; on a light ground it is
   a dark one. Same class, resolved by the band it sits in. */
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--forest);
  --btn-bd: var(--line);
}
.btn--ghost:hover { --btn-bg: var(--card); --btn-bd: var(--leaf-ink); }

:is(.band-forest, .band-bedrock, .hero, .page-head, .site-footer) .btn--ghost {
  --btn-fg: var(--on-dark);
  --btn-bd: var(--forest-line);
}
:is(.band-forest, .band-bedrock, .hero, .page-head, .site-footer) .btn--ghost:hover {
  --btn-bg: rgba(255, 255, 255, 0.08);
  --btn-bd: var(--leaf-soft);
}

/* Solid dark. The About band's action, where a pale pill would disappear
   into the photograph beside it. */
.btn--forest { --btn-bg: var(--forest); --btn-fg: var(--on-dark); }
.btn--forest:hover { --btn-bg: var(--forest-soft); }

/* The inline "Learn More →" on a card. Not a .btn: it is a text link with a
   moving arrow, and giving it a pill would put two competing controls in
   every card. */
.link-more {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: var(--leaf-ink);
  font-size: var(--t-small);
  font-weight: 600;
  text-decoration: none;
}
.link-more .icon { width: 1rem; height: 1rem; transition: transform var(--dur) var(--ease); }
.link-more:hover .icon { transform: translateX(4px); }

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

/* --------------------------------------------------------------------------
   7. Skip link
   -------------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: var(--s-4);
  top: var(--s-4);
  z-index: 300;
  padding: var(--s-3) var(--s-5);
  border-radius: var(--r-pill);
  background: var(--forest);
  color: var(--on-dark);
  font-size: var(--t-small);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus-visible { transform: translateY(0); }

/* --------------------------------------------------------------------------
   8. Header
   --------------------------------------------------------------------------
   Sits transparently over the hero and takes a solid ground once the page has
   scrolled past it (site.js toggles .is-stuck). No backdrop-filter anywhere:
   a blurred layer over a moving page is the single most expensive thing a
   sticky header can do, and it buys nothing here because both states are
   opaque greens. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: transparent;
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.site-header.is-stuck {
  background: var(--forest-mid);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06),
              0 12px 30px -20px rgba(0, 0, 0, 0.6);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  min-height: 5rem;
}

.site-header__logo { flex: none; line-height: 0; }
.site-header__logo img { width: auto; height: 2.375rem; }

/* Nav centred between the logo and the action, which is what the approved
   comp does. `margin-inline: auto` on the nav rather than a three-column grid
   so a long logo simply pushes it rather than breaking the row. */
.nav {
  display: flex;
  align-items: center;
  gap: clamp(var(--s-4), 2.2vw, var(--s-6));
  margin-inline: auto;
}

.nav a {
  position: relative;
  padding-block: var(--s-2);
  color: var(--on-dark);
  font-size: var(--t-small);
  font-weight: 500;
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.nav a:hover { color: var(--leaf-soft); }

/* The current page is marked with a rule under it, not a colour change alone
   — colour alone fails for anyone who cannot distinguish these two greens. */
.nav a[aria-current="page"] { color: var(--leaf-soft); }
.nav a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 1px;
  background: var(--leaf-soft);
}

.nav__cta { flex: none; }

.nav-toggle {
  display: none;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3);
  border: 1px solid var(--forest-line);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--on-dark);
  font-size: var(--t-small);
  font-weight: 600;
  cursor: pointer;
}
.nav-toggle .icon { width: 1.125rem; height: 1.125rem; }

@media (max-width: 62rem) {
  .nav-toggle { display: inline-grid; place-items: center; }

  /* The row becomes logo · (spacer) · action · toggle. */
  .site-header__inner { gap: var(--s-3); }
  .site-header__logo { margin-right: auto; }

  .nav {
    position: absolute;
    top: 100%;
    left: var(--gutter);
    right: var(--gutter);
    flex-direction: column;
    align-items: stretch;
    gap: var(--s-1);
    margin: 0;
    padding: var(--s-4);
    border-radius: var(--r-card);
    background: var(--forest-mid);
    box-shadow: var(--lift-lg);
    /* Closed by default on small screens. `display: none` rather than a
       height transition: the panel's height depends on how many links a
       page has, and animating to an unknown height is what produces the
       jump this pattern is famous for. */
    display: none;
  }
  .site-header.is-open .nav { display: flex; }

  .nav a {
    padding: var(--s-3) var(--s-4);
    border-radius: var(--r-md);
  }
  .nav a[aria-current="page"] { background: rgba(255, 255, 255, 0.07); }
  .nav a[aria-current="page"]::after { display: none; }

  /* The open panel needs a ground behind it even at the top of the page. */
  .site-header.is-open { background: var(--forest-mid); }
}

/* Below ~26rem the action's label is what breaks the row, not the row itself. */
@media (max-width: 26rem) {
  .nav__cta { padding-inline: var(--s-4); font-size: 0.875rem; }
  .site-header__logo img { height: 2rem; }
}

/* --------------------------------------------------------------------------
   9. Hero
   --------------------------------------------------------------------------
   Two columns: the argument on the left, the stage on the right. The stage is
   the leaf-shaped panel with the plant standing in it — the one piece of the
   approved comp that is doing all the identifying work, so it is built out of
   real elements rather than a flat exported image. */
.hero {
  position: relative;
  padding-top: var(--s-6);
  padding-bottom: var(--s-10);
  background: var(--forest-mid);
  color: var(--on-dark);
  /* The header sits over this, so the hero starts under it rather than after
     it — the sticky header is `position: sticky` inside normal flow, and this
     negative margin is what pulls the green up behind it. */
  margin-top: -5rem;
  padding-top: calc(5rem + var(--s-6));
  overflow: hidden;
}

/* A soft radial lift behind the copy, so the flat green reads as a lit
   surface rather than a swatch. Cheap: one gradient, no blend mode, no
   filter, and it never repaints because nothing above it moves. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(70% 90% at 12% 18%, rgba(167, 208, 107, 0.16), transparent 62%),
    radial-gradient(60% 70% at 88% 78%, rgba(6, 42, 24, 0.5), transparent 70%);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--s-8) var(--s-7);
  align-items: center;
}

@media (min-width: 62rem) {
  .hero__inner { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); }
}

.hero__title {
  font-size: var(--t-hero);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  max-width: 16ch;
}

.hero__lead {
  margin-top: var(--s-5);
  max-width: 34ch;
}

.hero .actions { margin-top: var(--s-7); }

/* The three assurances under the action. Icon in a ring, then two short
   lines — the comp stacks them, and stacking is what keeps three of these in
   a row at tablet width without any of them wrapping mid-phrase. */
.assurances {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5) var(--s-7);
  margin-top: var(--s-8);
}

.assurance {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}

.assurance__ring {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--forest-line);
  border-radius: 50%;
  color: var(--leaf-soft);
}
.assurance__ring .icon { width: 1.25rem; height: 1.25rem; }

.assurance__text {
  font-size: var(--t-small);
  font-weight: 600;
  line-height: 1.35;
  color: var(--on-dark);
}
.assurance__text span { display: block; color: var(--on-dark-mut); font-weight: 500; }

/* ---- The stage ---- */
.hero__stage {
  position: relative;
  /* The leaf: one oversized corner against three ordinary ones. A blob
     built from four different radii reads as a mistake; one dominant corner
     reads as a shape. */
  border-radius: 13rem var(--r-band) var(--r-band) var(--r-band);
  background:
    linear-gradient(160deg, rgba(167, 208, 107, 0.28), rgba(167, 208, 107, 0.06) 58%),
    rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(167, 208, 107, 0.22);
  min-height: 24rem;
  /* Space for the words at the top and the plant standing at the foot. */
  padding: var(--s-8) var(--s-6) 0;
  display: grid;
  align-content: start;
  justify-items: end;
}

/* The three words. Set at heading scale and right-aligned inside the stage,
   with the middle one dropped to the muted tone so the group reads as a
   descent rather than as three equal shouts — the comp does the same. */
.hero__words {
  display: grid;
  justify-items: end;
  gap: var(--s-1);
  font-size: clamp(1.5rem, 2.6vw, 2.125rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.hero__words span:nth-child(1) { color: #FFFFFF; }
.hero__words span:nth-child(2) { color: var(--on-dark-mut); }
.hero__words span:nth-child(3) { color: #FFFFFF; }

/* The plant breaks out of the stage at the foot, crossing onto the pale
   band below it. That overlap is the detail that stops the hero reading as
   two stacked rectangles, so it is worth the absolute positioning.
   `pointer-events: none` because it overhangs the section below and would
   otherwise eat clicks on whatever lands under it. */
.hero__plant {
  position: absolute;
  left: 50%;
  bottom: calc(var(--s-9) * -1);
  width: min(28rem, 108%);
  transform: translateX(-50%);
  pointer-events: none;
  /* Grounds the plant on the stage instead of letting it float. */
  filter: drop-shadow(0 24px 28px rgba(6, 42, 24, 0.45));
}

@media (max-width: 61.99rem) {
  .hero { padding-bottom: var(--s-9); }
  .hero__stage {
    min-height: 20rem;
    border-radius: 9rem var(--r-band) var(--r-band) var(--r-band);
  }
  .hero__plant { bottom: calc(var(--s-8) * -1); width: min(22rem, 92%); }
  .hero__title { max-width: none; }
}

/* --------------------------------------------------------------------------
   10. Service cards
   --------------------------------------------------------------------------
   The comp's six-card grid. Each card is: a ringed icon beside the name, the
   summary, the link, and then the illustration filling the foot of the card
   edge to edge. The illustration is last and grows into whatever height is
   left, which is what keeps six cards of unequal copy length aligned along
   both their top and bottom edges. */
.cards {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

.card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: linear-gradient(180deg, var(--card), var(--sage-deep));
  box-shadow: var(--lift);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

/* Hover lifts the whole card, and the card is a single link target — see
   .card__link below. Keyboard focus gets the same lift so the two inputs
   behave identically. */
.card:hover,
.card:focus-within {
  transform: translateY(-4px);
  box-shadow: var(--lift-lg);
}

.card__body {
  display: grid;
  gap: var(--s-3);
  padding: var(--s-5);
}

.card__head {
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

.card__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.875rem;
  height: 2.875rem;
  border-radius: 50%;
  background: #FFFFFF;
  color: var(--leaf-ink);
  box-shadow: 0 1px 2px rgba(36, 64, 31, 0.1);
}
.card__icon .icon { width: 1.375rem; height: 1.375rem; }

.card__title { margin: 0; }

.card__summary {
  color: var(--muted);
  font-size: var(--t-small);
  text-wrap: pretty;
}

/* The stretched link: the whole card is clickable, but only the "Learn More"
   text is in the tab order and only it is announced. Anything else inside
   would have to be a nested interactive element, which this pattern cannot
   have — so the card carries exactly one destination. */
.card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.card { position: relative; }

.card__art {
  width: 100%;
  height: clamp(7rem, 14vw, 9.5rem);
  margin-top: auto;
  object-fit: cover;
  /* The scenes are drawn 2:1, which is close to the ratio this box settles at
     across the grid's whole range, so `cover` has almost nothing to crop.
     Centred: what little it does take comes evenly off the sky and the
     deepest soil horizon, neither of which carries a subject. */
  object-position: 50% 50%;
}

/* --------------------------------------------------------------------------
   11. About band — photo, argument, figures
   -------------------------------------------------------------------------- */
.about {
  display: grid;
  gap: var(--s-6);
  align-items: stretch;
}

@media (min-width: 62rem) {
  .about { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
}

.about__intro {
  display: grid;
  gap: var(--s-5);
  align-content: center;
}

@media (min-width: 40rem) {
  .about__intro { grid-template-columns: 11rem minmax(0, 1fr); align-items: center; }
}

.about__plate {
  overflow: hidden;
  border-radius: var(--r-card);
  border: 1px solid var(--line);
  background: var(--sage-deep);
  aspect-ratio: 3 / 4;
}
.about__plate img { width: 100%; height: 100%; object-fit: cover; }

.about__copy { display: grid; gap: var(--s-4); justify-items: start; }

/* ---- The figures panel ---- */
.figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  padding: 1px;
  overflow: hidden;
  border-radius: var(--r-band);
  /* The 1px gaps show this through, which draws the dividing cross between
     the four cells without four separate borders that would double up. */
  background: var(--forest-line);
}

.figure {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: clamp(var(--s-5), 3.4vw, var(--s-7)) var(--s-5);
  background: var(--forest-soft);
  color: var(--on-dark);
}

.figure__ring {
  display: grid;
  place-items: center;
  flex: none;
  width: 3rem;
  height: 3rem;
  border: 1px solid var(--forest-line);
  border-radius: 50%;
  color: var(--leaf-soft);
}
.figure__ring .icon { width: 1.5rem; height: 1.5rem; }

.figure__value {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  /* Lining, tabular figures so a value counting up from zero does not shift
     the label beside it on every frame. */
  font-variant-numeric: tabular-nums;
}

.figure__label {
  display: block;
  margin-top: var(--s-1);
  font-size: var(--t-small);
  font-weight: 500;
  line-height: 1.3;
  color: var(--on-dark-mut);
}

@media (max-width: 26rem) {
  .figures { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   12. Process rail
   --------------------------------------------------------------------------
   Six steps in a row, each a ringed glyph over its ordinal and label, joined
   by a dashed rule. The rule is drawn as a pseudo-element on each step except
   the last, positioned at the ring's own centre line, so it stays aligned
   however tall the labels below it turn out to be. */
.process {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--s-4);
  counter-reset: step;
}

.process__step {
  position: relative;
  display: grid;
  justify-items: center;
  text-align: center;
  gap: var(--s-3);
}

.process__step::after {
  content: "";
  position: absolute;
  top: 2.5rem;             /* half the ring */
  left: calc(50% + 3rem);  /* the ring's right edge */
  right: calc(-50% + 3rem);
  height: 2px;
  background-image: linear-gradient(90deg, var(--line) 55%, transparent 55%);
  background-size: 10px 2px;
}
.process__step:last-child::after { display: none; }

.process__ring {
  display: grid;
  place-items: center;
  width: 5rem;
  height: 5rem;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--card);
  color: var(--leaf-ink);
  box-shadow: var(--lift);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.process__ring .icon { width: 2rem; height: 2rem; }

.process__step:hover .process__ring {
  border-color: var(--leaf-soft);
  color: var(--forest);
  transform: translateY(-3px);
}

.process__ordinal {
  font-size: 1.125rem;
  font-weight: 800;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.process__label {
  font-size: var(--t-small);
  font-weight: 600;
  line-height: 1.3;
  color: var(--muted);
  text-wrap: balance;
}

/* Six across needs about 60rem to stay legible; below that it folds to three,
   then two. The connector is dropped as soon as the row wraps — a dashed rule
   pointing off the end of a line is worse than no rule. */
@media (max-width: 64rem) {
  .process { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-6) var(--s-4); }
  .process__step::after { display: none; }
}
@media (max-width: 34rem) {
  .process { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .process__ring { width: 4.25rem; height: 4.25rem; }
  .process__ring .icon { width: 1.75rem; height: 1.75rem; }
}

/* --------------------------------------------------------------------------
   13. CTA band
   --------------------------------------------------------------------------
   A dark rounded panel inside the pale page rather than a full-bleed band —
   the comp's closing block is a card, and making it full-bleed here would
   put three consecutive edge-to-edge greens at the foot of the page (this,
   then the footer). */
.cta-panel {
  position: relative;
  overflow: hidden;
  display: grid;
  gap: var(--s-5);
  align-items: center;
  padding: clamp(var(--s-6), 4vw, var(--s-8));
  border-radius: var(--r-band);
  background: var(--forest-soft);
  color: var(--on-dark);
}

.cta-panel::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 120% at 8% 30%, rgba(167, 208, 107, 0.14), transparent 62%);
  pointer-events: none;
}

.cta-panel > * { position: relative; z-index: 1; }

.cta-panel__title { font-size: clamp(1.5rem, 2.6vw, 2rem); }
.cta-panel__copy { margin-top: var(--s-3); color: var(--on-dark-mut); max-width: 40ch; }

/* The image is pinned to the panel's right edge and cropped by it, which is
   what lets a rectangular illustration sit inside a 2rem radius without a
   visible seam. Hidden below the width where it would squeeze the copy. */
.cta-panel__art {
  position: absolute;
  right: 0;
  bottom: 0;
  top: 0;
  width: 34%;
  object-fit: cover;
  object-position: 50% 40%;
  z-index: 0;
  /* Fades into the panel on its left edge instead of stopping at a hard
     vertical line. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 42%);
  mask-image: linear-gradient(90deg, transparent, #000 42%);
}

@media (min-width: 52rem) {
  .cta-panel {
    grid-template-columns: minmax(0, 1fr) auto;
    padding-right: 38%;
  }
  .cta-panel .actions { margin-top: 0; }
}
@media (max-width: 51.99rem) {
  .cta-panel__art { display: none; }
}

/* --------------------------------------------------------------------------
   14. Footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--forest-mid);
  color: var(--on-dark);
  padding-top: clamp(var(--s-8), 7vw, var(--s-9));
}

.site-footer__grid {
  display: grid;
  gap: var(--s-7) var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

/* The brand column carries the mark, the sentence and the socials, and is
   worth roughly two of the link columns. */
.site-footer__brand { grid-column: span 2; }
@media (max-width: 44rem) { .site-footer__brand { grid-column: span 1; } }

.site-footer__logo img { width: auto; height: 2.5rem; }

.site-footer__blurb {
  margin-top: var(--s-5);
  max-width: 30ch;
  font-size: var(--t-small);
  color: var(--on-dark-mut);
  text-wrap: pretty;
}

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

.socials a {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--forest-line);
  border-radius: 50%;
  color: var(--on-dark-mut);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.socials a:hover {
  color: var(--forest-deep);
  background: var(--leaf-soft);
  border-color: var(--leaf-soft);
}
.socials .icon { width: 1.0625rem; height: 1.0625rem; }

.footer-heading {
  margin-bottom: var(--s-4);
  font-size: var(--t-small);
  font-weight: 700;
  color: var(--on-dark);
}

.footer-links { display: grid; gap: var(--s-3); }
.footer-links a {
  color: var(--on-dark-mut);
  font-size: var(--t-small);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.footer-links a:hover { color: var(--leaf-soft); }

.footer-address { font-style: normal; color: var(--on-dark-mut); font-size: var(--t-small); }

/* ---- Newsletter ----
   Field and button share one pill, which is the comp's treatment. The border
   lives on the wrapper rather than on the input so the two halves cannot
   drift apart by a pixel at different zoom levels. */
.footer-signup { display: grid; gap: var(--s-3); }

.signup-field {
  display: flex;
  align-items: center;
  padding: var(--s-1);
  padding-left: var(--s-4);
  border: 1px solid var(--forest-line);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.06);
  transition: border-color var(--dur) var(--ease);
}
.signup-field:focus-within { border-color: var(--leaf-soft); }

.signup-field input {
  flex: 1 1 6rem;
  min-width: 0;
  padding: var(--s-2) 0;
  border: 0;
  background: transparent;
  color: var(--on-dark);
  font-size: var(--t-small);
}
.signup-field input::placeholder { color: var(--on-dark-mut); }
/* The wrapper already shows focus, and a second ring inside it reads as two
   focused things. */
.signup-field input:focus-visible { outline: none; }

.signup-field .btn { flex: none; padding-inline: var(--s-4); }

.site-footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4);
  margin-top: clamp(var(--s-7), 5vw, var(--s-8));
  padding-block: var(--s-5);
  border-top: 1px solid var(--forest-line);
  font-size: var(--t-small);
  color: var(--on-dark-mut);
}

.site-footer__base nav { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.site-footer__base a { color: var(--on-dark-mut); text-decoration: none; }
.site-footer__base a:hover { color: var(--leaf-soft); }

/* --------------------------------------------------------------------------
   15. Forms
   -------------------------------------------------------------------------- */
.field { display: grid; gap: var(--s-2); margin-bottom: var(--s-5); }

.field > label {
  font-size: var(--t-small);
  font-weight: 600;
}

.optional { font-weight: 400; color: var(--muted); }

.input {
  width: 100%;
  padding: 0.8125rem var(--s-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: #FFFFFF;
  color: var(--ink);
  font-size: var(--t-small);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.input:focus-visible {
  outline: none;
  border-color: var(--leaf-ink);
  box-shadow: 0 0 0 3px rgba(167, 208, 107, 0.35);
}

select.input {
  /* The native arrow is drawn in the OS's own grey and clashes with the pill
     language everywhere else; this replaces it with the site's chevron. */
  appearance: none;
  padding-right: var(--s-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%2355624C' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 6 5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-4) center;
}

.hint {
  display: block;
  font-size: var(--t-small);
  color: var(--muted);
}

/* Honeypot. Moved out of view rather than `display: none` — some bots skip
   fields that are display-none specifically because it is the obvious tell. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* A form on a green ground (the waitlist, the footer) inverts. */
.band-forest .field > label,
.band-bedrock .field > label { color: var(--on-dark); }
.band-forest .hint,
.band-bedrock .hint,
.site-footer .hint { color: var(--on-dark-mut); }
.band-forest .optional,
.band-bedrock .optional { color: var(--on-dark-mut); }

/* ---- Form response ---- */
.form-msg {
  display: flex;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  margin-top: var(--s-5);
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--r-md);
  background: var(--card);
  font-size: var(--t-small);
  color: var(--ink);
}
.form-msg--ok { border-left-color: var(--leaf-ink); }
.form-msg--error { border-left-color: #B3452B; }

.band-forest .form-msg,
.band-bedrock .form-msg,
.site-footer .form-msg {
  border-color: var(--forest-line);
  background: rgba(255, 255, 255, 0.07);
  color: var(--on-dark);
}
.band-forest .form-msg--ok,
.band-bedrock .form-msg--ok,
.site-footer .form-msg--ok { border-left-color: var(--leaf-soft); }

/* The waitlist form gets a card of its own so it reads as a discrete object
   on the green band rather than as loose fields floating on it. */
.waitlist-form {
  padding: clamp(var(--s-5), 3vw, var(--s-7));
  border-radius: var(--r-band);
  background: var(--sage);
  color: var(--ink);
  box-shadow: var(--lift-lg);
}
/* …and therefore opts back out of the green-band form inversion above. */
.band-forest .waitlist-form .field > label { color: var(--ink); }
.band-forest .waitlist-form .hint,
.band-forest .waitlist-form .optional { color: var(--muted); }
.band-forest .waitlist-form .form-msg {
  border-color: var(--line);
  background: var(--card);
  color: var(--ink);
}
.band-forest .waitlist-form .form-msg--ok { border-left-color: var(--leaf-ink); }

.waitlist-form .btn { width: 100%; justify-content: center; }

.waitlist__note {
  margin-top: var(--s-5);
  font-size: var(--t-small);
  color: var(--on-dark-mut);
}

/* --------------------------------------------------------------------------
   16. Page heads (inner pages)
   -------------------------------------------------------------------------- */
.page-head {
  background: var(--forest-mid);
  color: var(--on-dark);
  margin-top: -5rem;
  padding-top: calc(5rem + var(--s-8));
  padding-bottom: clamp(var(--s-8), 7vw, var(--s-9));
}

.page-head::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 100% at 15% 20%, rgba(167, 208, 107, 0.14), transparent 60%);
  pointer-events: none;
}
.page-head > * { position: relative; z-index: 1; }

.page-head .label { margin-bottom: var(--s-4); }

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin-bottom: var(--s-5);
  font-size: var(--t-small);
  color: var(--on-dark-mut);
}
.breadcrumb a { color: var(--on-dark-mut); text-decoration: none; }
.breadcrumb a:hover { color: var(--leaf-soft); }
.breadcrumb li + li::before { content: "/"; margin-right: var(--s-2); opacity: 0.6; }
.breadcrumb ol { display: contents; }
.breadcrumb li { display: flex; align-items: center; }

/* --------------------------------------------------------------------------
   17. Stages — the long-form numbered sequence (Workshops curriculum)
   --------------------------------------------------------------------------
   Distinct from the process rail: this one has a paragraph per step, so it is
   a stack of cards rather than a row of glyphs. */
.stages { display: grid; gap: var(--s-4); }

.stage {
  display: grid;
  gap: var(--s-3) var(--s-5);
  padding: var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
}

@media (min-width: 40rem) {
  .stage { grid-template-columns: 4rem minmax(0, 1fr); align-items: start; }
}

.stage__ordinal {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--leaf-ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.stage__title { margin-bottom: var(--s-2); }
.stage__body p { color: var(--muted); text-wrap: pretty; }

.band-forest .stage,
.band-bedrock .stage {
  border-color: var(--forest-line);
  background: var(--forest-soft);
}
.band-forest .stage__ordinal,
.band-bedrock .stage__ordinal { color: var(--leaf-soft); }
.band-forest .stage__body p,
.band-bedrock .stage__body p { color: var(--on-dark-mut); }

/* --------------------------------------------------------------------------
   18. Post list (Resource Hub)
   -------------------------------------------------------------------------- */
.post-list {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

.post-item { display: flex; }

.post-item__link {
  display: grid;
  align-content: start;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: linear-gradient(180deg, var(--card), var(--sage-deep));
  box-shadow: var(--lift);
  color: inherit;
  text-decoration: none;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.post-item__link:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-lg);
}

.post-item__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
}

.post-item__title { margin: 0; }
.post-item__excerpt { color: var(--muted); font-size: var(--t-small); text-wrap: pretty; }

.tag {
  display: inline-block;
  padding: 0.1875rem var(--s-3);
  border-radius: var(--r-pill);
  background: var(--leaf-soft);
  color: var(--forest-deep);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   19. Empty state
   -------------------------------------------------------------------------- */
.empty {
  display: grid;
  justify-items: center;
  gap: var(--s-3);
  max-width: 40rem;
  margin-inline: auto;
  padding: clamp(var(--s-7), 6vw, var(--s-9)) var(--s-5);
  border: 1px dashed var(--line);
  border-radius: var(--r-band);
  background: var(--card);
  text-align: center;
}
.empty__title { font-size: var(--t-h3); font-weight: 700; }
.empty p { color: var(--muted); text-wrap: pretty; }

/* --------------------------------------------------------------------------
   20. People (About)
   -------------------------------------------------------------------------- */
.person {
  display: grid;
  gap: var(--s-5) var(--s-7);
  padding: clamp(var(--s-5), 3vw, var(--s-7));
  margin-bottom: var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--r-band);
  background: var(--card);
}
.person:last-child { margin-bottom: 0; }

@media (min-width: 48rem) {
  .person { grid-template-columns: 15rem minmax(0, 1fr); align-items: start; }
}

.person__plate {
  overflow: hidden;
  border-radius: var(--r-card);
  background: var(--sage-deep);
  aspect-ratio: 4 / 5;
}
.person__plate img { width: 100%; height: 100%; object-fit: cover; }

/* No stock photography stand-in. A typographic plate is honest about the
   absence and still holds the layout — banded, because the banding is the
   brand's own idea and a flat grey box is not. */
.person__plate--initial {
  display: grid;
  place-items: center;
  background:
    linear-gradient(180deg, var(--sage-deep) 0 38%, var(--forest-soft) 38% 68%, var(--forest-deep) 68%);
}
.person__initial {
  font-size: clamp(4rem, 9vw, 6rem);
  font-weight: 800;
  letter-spacing: -0.05em;
  color: var(--leaf-soft);
  line-height: 1;
}

.person__body { display: grid; gap: var(--s-4); align-content: start; }
.person__name { margin: 0; }
.person__body .label { color: var(--leaf-ink); }

.creds {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}
.creds__item {
  padding: var(--s-1) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--sage);
  font-size: var(--t-small);
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   21. Methodology (About)
   -------------------------------------------------------------------------- */
.method {
  display: grid;
  gap: var(--s-5) var(--s-7);
  padding-block: clamp(var(--s-6), 4vw, var(--s-7));
  border-top: 1px solid var(--forest-line);
}
.method:first-of-type { border-top: 0; padding-top: 0; }

@media (min-width: 52rem) {
  .method { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); }
}

.method__head { align-self: start; }
.method__name { margin-bottom: var(--s-3); }
.method__thesis { color: var(--leaf-soft); font-weight: 600; text-wrap: pretty; }
.method__prose { color: var(--on-dark-mut); text-wrap: pretty; }

.method__points { display: grid; gap: var(--s-3); margin-top: var(--s-5); }
.method__point {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s-3);
  font-size: var(--t-small);
  color: var(--on-dark);
}
.method__point::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  margin-top: 0.55em;
  border-radius: 50%;
  background: var(--leaf-soft);
}

/* --------------------------------------------------------------------------
   22. Facts (Workshops)
   -------------------------------------------------------------------------- */
.facts {
  display: grid;
  gap: var(--s-4);
  margin: 0;
  align-content: start;
}

.fact {
  padding: var(--s-5);
  border: 1px solid var(--forest-line);
  border-radius: var(--r-card);
  background: rgba(255, 255, 255, 0.06);
}
.fact dt { margin-bottom: var(--s-1); }
.fact__value {
  margin: 0;
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--on-dark);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   23. Register — the engagement disclosure list
   --------------------------------------------------------------------------
   Kept from the previous system because it is the only place the site states
   what an engagement actually delivers, and the approved comp has no
   equivalent. Restated in the new language: a stack of cards, each opening on
   click, rather than hairline rows. */
.register { display: grid; gap: var(--s-4); }

.register__disclosure {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  overflow: hidden;
}
.register__disclosure[open] { box-shadow: var(--lift); }

.register__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-2) var(--s-5);
  padding: var(--s-5);
  cursor: pointer;
  list-style: none;
}
.register__head::-webkit-details-marker { display: none; }

@media (min-width: 52rem) {
  .register__head { grid-template-columns: 16rem minmax(0, 1fr) 12rem auto; }
}

.register__name { margin: 0; }
.register__summary { color: var(--muted); font-size: var(--t-small); }
.register__basis { color: var(--leaf-ink); font-size: var(--t-small); font-weight: 600; }

/* The marker: a plus that becomes a minus. Two rules, one of which is
   rotated away when the disclosure opens. */
.register__marker {
  position: relative;
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid var(--line);
  border-radius: 50%;
  justify-self: end;
}
.register__marker::before,
.register__marker::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.625rem;
  height: 2px;
  border-radius: 1px;
  background: var(--leaf-ink);
  transform: translate(-50%, -50%);
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.register__marker::after { transform: translate(-50%, -50%) rotate(90deg); }
[open] .register__marker::after { transform: translate(-50%, -50%) rotate(0deg); opacity: 0; }

.register__panel {
  padding: 0 var(--s-5) var(--s-5);
  border-top: 1px solid var(--line);
  padding-top: var(--s-5);
}
.register__panel-label {
  margin-bottom: var(--s-3);
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--leaf-ink);
}
.register__points { display: grid; gap: var(--s-3); }
.register__point {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s-3);
  font-size: var(--t-small);
  color: var(--muted);
}
.register__point::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  margin-top: 0.55em;
  border-radius: 50%;
  background: var(--leaf-soft);
}

/* --------------------------------------------------------------------------
   24. Pull quote
   -------------------------------------------------------------------------- */
.quote {
  display: grid;
  gap: var(--s-5);
  padding: clamp(var(--s-6), 4vw, var(--s-8));
  border-radius: var(--r-band);
  background: var(--forest-soft);
  color: var(--on-dark);
}

.quote__body {
  margin: 0;
  font-size: clamp(1.375rem, 2.4vw, 1.875rem);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.quote__source { display: grid; gap: var(--s-1); }
.quote__name { font-style: normal; font-weight: 700; }
.quote__role { font-size: var(--t-small); color: var(--on-dark-mut); }

/* --------------------------------------------------------------------------
   25. Article (Resource detail)
   -------------------------------------------------------------------------- */
.video {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--r-band);
  background: var(--forest-deep);
  margin-bottom: var(--s-7);
}
.video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.article-cover {
  overflow: hidden;
  border-radius: var(--r-band);
  margin-bottom: var(--s-7);
}
.article-cover img { width: 100%; }

.article-body {
  max-width: var(--wrap-text);
  margin-inline: auto;
  font-size: 1.0625rem;
}
.article-body > * + * { margin-top: var(--s-5); }
.article-body :is(h2, h3) { margin-top: var(--s-8); }
.article-body h2 { font-size: var(--t-h2); }
.article-body h3 { font-size: var(--t-h3); }
.article-body p { text-wrap: pretty; }
.article-body :is(ul, ol) { display: grid; gap: var(--s-3); padding-left: var(--s-5); }
.article-body ul { list-style: disc; }
.article-body ol { list-style: decimal; }
.article-body li::marker { color: var(--leaf-ink); }
.article-body img { border-radius: var(--r-card); }
.article-body blockquote {
  padding: var(--s-5);
  border-left: 3px solid var(--leaf-soft);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  background: var(--card);
  color: var(--muted);
}
.article-body :is(code, pre) {
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
  font-size: 0.9em;
}
.article-body pre {
  padding: var(--s-5);
  border-radius: var(--r-md);
  background: var(--forest-deep);
  color: var(--on-dark);
  overflow-x: auto;
}
/* Wide content scrolls inside its own box rather than putting the page on a
   horizontal scrollbar. */
.article-body .table-scroll,
.article-body table { display: block; overflow-x: auto; max-width: 100%; }

/* --------------------------------------------------------------------------
   26. Utilities
   -------------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.stack-sm { display: grid; gap: var(--s-3); }
.stack    { display: grid; gap: var(--s-5); }

/* --------------------------------------------------------------------------
   27. Scroll reveal
   --------------------------------------------------------------------------
   Only active when `.js` is present (site.js adds it pre-paint). Absent that,
   every [data-reveal] element is simply visible — the correct no-JS fallback,
   and the reason the class is added by an inline script in <head> rather than
   by the deferred bundle. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

/* A group staggers its own children by index, written as --i by site.js. */
.js [data-reveal-group] [data-reveal] {
  transition-delay: calc(var(--i, 0) * 70ms);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Everything still arrives, nothing moves to get there. */
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
  .btn:hover, .card:hover, .post-item__link:hover { transform: none; }
}
