/* ══════════════════════════════════════════════════════════════════
   site.css — the shared kit, lifted out of v11

   v11 is the landing page and keeps its own inline stylesheet, so it
   is never at risk from an edit here. Everything in this file is the
   part of v11 that the rest of the site needs to look like the same
   site: the palette, the nav, the buttons, the section rhythm, the
   one green mark, and the fill-in-as-you-arrive reveal.

   Two rules carry over and matter more than they look:

   1. Nothing may be invisible without JavaScript. Every opacity:0
      default is keyed on .js, which an inline head script adds. A
      reader with scripting off — or a model reading the page — gets
      the whole thing.
   2. Green is the mark of a person having watched something happen.
      It is allowed on kickers, the primary button, the hand-drawn
      underline and the small dots, and nowhere else, so it never has
      to compete with itself.
   ══════════════════════════════════════════════════════════════════ */
/* ── the two palettes ────────────────────────────────────────────
   Dark is the default and lives here on :root, so a reader with no
   JavaScript — or a model reading the markup — gets the site exactly
   as it has always looked, with no extra rules and no flash. Light is
   an OVERRIDE, applied only when an inline head script finds a stored
   choice and sets data-theme="light" before the first paint.

   The light values are not eyeballed: each one was matched to the
   contrast its dark counterpart carries, so the two themes read with
   the same weight rather than one being a washed-out copy of the
   other. The ratios in the comments are against that theme's --ink.

   Every colour used anywhere in the kit is a token here. A literal
   hex or rgba() below would survive the theme switch and show up as
   one stubborn dark smudge on the light page, so there are none. */
:root{
  color-scheme:dark;
  --ink:#1A1A18;        /* matte black — the base */
  --surf:#212220;       /* the one lifted surface */
  --deep:#16201B;       /* a green-shifted band, so dark-on-dark never goes flat */
  --line:#2C2C29;
  --head:#F6F6F3;       /* 16.1:1 */
  --body:#B4B6AE;       /* 8.5:1  */
  --soft:#8C9A93;       /* 5.9:1  */
  --green:#7FC9AD;      /* the mark, legible on matte black — 9.0:1 */
  --green-deep:#2D5F4E; /* the same green, for fills that must sit behind white */
  --digit:#5C5E56;      /* resting foliage — 2.7:1, deliberately quiet */
  /* the green again as raw channels, so the four translucent greens
     (selection, dot halo, the hairlines) can be written as one token
     instead of five literals that only ever matched the dark theme */
  --green-rgb:127,201,173;
  --btn-hi:#9BD8C1;     /* primary button, hover: a step brighter */
  --ctl-hi:#3E4A44;     /* bordered control, hover: a step lighter than --line */
  --u-img:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 140 7' preserveAspectRatio='none'%3E%3Cpath d='M1.5 4.6 C 24 1.6 47 6.2 70 3.4 C 93 0.6 116 5.2 138.5 2.6' fill='none' stroke='%237FC9AD' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}
/* ── light ──────────────────────────────────────────────────────
   Chosen against #FAFAF7, mirroring the dark theme's ratios:
   head 16.7 (was 16.1), body 8.3 (8.5), soft 6.0 (5.9), digit 2.6
   (2.7). The green has to travel furthest: #7FC9AD is built to sit
   on matte black and manages only 1.7:1 on an off-white page, so
   light gets a deep green at 6.1:1 that is still unmistakably the
   same mark. The button inverts with it — a dark green plate with
   off-white text — because .btn already paints --green under --ink. */
:root[data-theme="light"]{
  color-scheme:light;
  --ink:#FAFAF7;
  --surf:#FFFFFF;
  --deep:#EDF3EF;
  --line:#DCDDD6;
  --head:#1A1A18;       /* 16.7:1 */
  --body:#4A4C45;       /* 8.3:1  */
  --soft:#5A625D;       /* 6.0:1  */
  --green:#1F6B52;      /* the mark, legible on off-white — 6.1:1 */
  --green-deep:#7FC9AD; /* the pair flips: this is the one for dark fills */
  --digit:#9BA094;      /* 2.6:1 — the same quiet as the dark theme's */
  --green-rgb:31,107,82;
  --btn-hi:#17553F;     /* on light, "brighter" means deeper */
  --ctl-hi:#B8BEB4;
  --u-img:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 140 7' preserveAspectRatio='none'%3E%3Cpath d='M1.5 4.6 C 24 1.6 47 6.2 70 3.4 C 93 0.6 116 5.2 138.5 2.6' fill='none' stroke='%231F6B52' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--ink);color:var(--body);
  font:400 17px/1.66 Inter,system-ui,sans-serif;-webkit-font-smoothing:antialiased}
/* Only while a switch is actually happening: a permanent transition here
   would make every page arrive fading from the wrong colour. site.js adds
   .swapping for one beat around the click.

   Just the two page-background elements, never a descendant selector. A
   `.swapping *` would set the `transition` shorthand on everything and so
   replace the transitions .reveal, .u and the hero reel are already running,
   and a toggle clicked mid-fade would snap them. The text recolours
   instantly, which nobody notices; the page behind it fades. */
.swapping,.swapping body{transition:background-color .22s ease}
a{color:inherit}
img{max-width:100%;display:block}
h1,h2,h3{color:var(--head);margin:0;font-family:Chivo,sans-serif}
em{font-style:italic}
::selection{background:rgba(var(--green-rgb),.22);color:var(--head)}
.wrap{max-width:1500px;margin:0 auto;padding:0 32px}
.narrow{max-width:1040px;margin:0 auto}
.kicker{font:500 11px/1.4 Inter,sans-serif;letter-spacing:.13em;text-transform:uppercase;color:var(--soft)}
.kicker.g{color:var(--green)}

/* ── the mark: an underline drawn by hand, meaning a person saw this ── */
.u{
  display:inline;padding-bottom:6px;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
  background-image:var(--u-img);
  background-repeat:no-repeat;background-position:0 100%;background-size:0 7px;
  transition:background-size .6s cubic-bezier(.35,.05,.25,1);
}
.in .u,.in.u{background-size:100% 7px}
.in .u:nth-of-type(2){transition-delay:.4s}
.in .u:nth-of-type(3){transition-delay:.8s}

/* ── nav ── */
.nav{display:flex;align-items:center;justify-content:space-between;padding:18px 0;position:relative;z-index:5}
.wordmark{display:flex;align-items:center;gap:10px;font:700 19px/1 Chivo,sans-serif;letter-spacing:-.02em;color:var(--head);text-decoration:none}
/* the mark: a trunk that forks once. Small enough to read as a glyph. */
.logo{position:relative;width:15px;height:18px;flex:none}
.logo::before{content:"";position:absolute;left:6.6px;bottom:0;width:1.8px;height:11px;background:var(--head);border-radius:1px}
.logo::after{content:"";position:absolute;left:1.5px;top:1px;width:12px;height:9px;
  border:1.8px solid var(--green);border-bottom:0;border-radius:7px 7px 0 0}
.nav nav{display:flex;gap:26px}
.nav nav a{color:var(--body);text-decoration:none;font-size:15px;white-space:nowrap}
.nav nav a:hover{color:var(--green)}
.nav nav a[aria-current="page"]{color:var(--head)}
.btn{display:inline-block;background:var(--green);color:var(--ink);text-decoration:none;padding:13px 22px;
  font:500 15px/1 Inter,sans-serif;border-radius:4px;transition:background .18s ease}
.btn:hover{background:var(--btn-hi)}
.btn.sm{padding:10px 17px;font-size:14px}
.btn.ghost{background:transparent;color:var(--head);border:1px solid var(--line)}
.btn.ghost:hover{border-color:var(--green);color:var(--green)}

/* ── the phone menu ──────────────────────────────────────────────
   A <details>, so it opens with scripting off and needs no state in
   JS. It replaces the inline links below 880px rather than wrapping
   them onto a second row, which would push the landing page's tree
   under the fold. */
.menu{display:none;position:relative}
.menu summary{list-style:none;cursor:pointer;color:var(--body);font-size:15px;
  border:1px solid var(--line);border-radius:4px;padding:9px 14px}
.menu summary::-webkit-details-marker{display:none}
.menu summary:hover{color:var(--green);border-color:var(--green)}
.menu[open] summary{color:var(--head)}
.menu .sheet{position:absolute;right:0;top:calc(100% + 8px);min-width:210px;z-index:20;
  background:var(--surf);border:1px solid var(--line);border-radius:6px;padding:6px;
  display:grid;gap:2px}
.menu .sheet a{display:block;padding:11px 14px;border-radius:4px;color:var(--body);
  text-decoration:none;font-size:15px}
.menu .sheet a:hover{background:var(--ink);color:var(--green)}
.menu .sheet a[aria-current="page"]{color:var(--head)}
@media (max-width:880px){
  .nav nav{display:none}
  .nav .btn.sm{display:none}
  .menu{display:block}
}

/* ── the trailing controls ───────────────────────────────────────
   The toggle, the button and the phone menu travel together in one
   box so that .nav still has exactly three children and its
   space-between lays the header out as it always has. Dropping the
   toggle straight into .nav as a fourth child would have pulled the
   links off centre on every page of the site. */
.navend{display:flex;align-items:center;gap:12px}

/* ── the theme toggle ────────────────────────────────────────────
   A real <button>, and deliberately not two other things it could
   have been: analytics reads clicks off <a> elements, and it counts
   every `details:not(.menu)` as an FAQ question, so a link or a
   <details> here would quietly file changing the theme as a footer
   click or a question asked.

   It is hidden until the `js` class lands. That is the one place the
   no-JavaScript rule runs backwards — hidden WITHOUT .js rather than
   with it — and it is the same call .grove-ctl .again already makes:
   with scripting off the site is dark and a toggle could not do
   anything, so a dead control would be worse than no control. It
   hides a switch, never a word of content, so the page still reads
   whole. */
.tt{display:none}
.js .tt{display:inline-flex;align-items:center;justify-content:center}
.tt{width:38px;height:38px;flex:none;padding:0;cursor:pointer;
  background:transparent;border:1px solid var(--line);border-radius:4px;
  color:var(--soft);transition:color .16s ease,border-color .16s ease}
.tt:hover{color:var(--green);border-color:var(--ctl-hi)}
.tt:focus-visible{outline:2px solid var(--green);outline-offset:2px}
.tt svg{width:17px;height:17px;display:block;fill:none;stroke:currentColor;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
/* The icon shows the theme you would GET, not the one you are in,
   which is the way a light switch reads: sun while it is dark. */
.tt .moon{display:none}
:root[data-theme="light"] .tt .sun{display:none}
:root[data-theme="light"] .tt .moon{display:block}

/* ── page head: every page but the landing one opens the same way ── */
/* The measure belongs on the elements, not on the block: a `ch` is sized by
   the font it is set in, so a max-width here was quietly measuring the 17px
   body font and squeezing a 54px headline into a 300px column. */
.phead{padding:54px 0 12px}
.phead h1{font:700 clamp(32px,4.4vw,54px)/1.06 Chivo,sans-serif;letter-spacing:-.035em;margin:14px 0 0;max-width:15ch}
.phead .sub{font-size:18px;max-width:52ch;margin:20px 0 0}
@media (max-width:820px){.phead{padding:38px 0 8px}}

/* ── section rhythm ── */
.sec{padding:96px 0}
.sec.deep{background:var(--deep)}
.sec.tight{padding:66px 0}
.sec h2{font:600 clamp(28px,3.4vw,42px)/1.12 Chivo,sans-serif;letter-spacing:-.03em;margin:14px 0 0;max-width:20ch}
.sec .big{font-size:19px;max-width:56ch;margin:22px 0 0}
.three{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);margin-top:48px;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.three>div{background:var(--ink);padding:30px 28px 34px}
.sec.deep .three>div{background:var(--deep)}
.three h3{font:600 20px/1.25 Chivo,sans-serif;letter-spacing:-.02em}
.three p{margin:12px 0 0;font-size:15.5px}
.three .kicker{display:block;margin-bottom:14px}
@media (max-width:820px){.three{grid-template-columns:1fr}.sec{padding:66px 0}}

.quote{font:300 clamp(21px,2.5vw,30px)/1.52 Newsreader,Georgia,serif;color:var(--head);max-width:26ch;margin:0}
.two{display:grid;grid-template-columns:1fr 1fr;gap:62px;align-items:center}
.by{margin-top:22px;color:var(--soft);font-size:14.5px}
@media (max-width:900px){.two{grid-template-columns:1fr;gap:34px}}

.cta{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.cta .free{color:var(--soft);font-size:14px}
.close{padding:100px 0 104px;text-align:center;border-top:1px solid var(--line)}
.close h2{margin:0 auto 26px;max-width:18ch}
.close .cta{justify-content:center}
.foot{padding:26px 0 58px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;color:var(--soft);font-size:14px;border-top:1px solid var(--line)}
.foot nav{display:flex;gap:22px;flex-wrap:wrap}
.foot a{text-decoration:none}
.foot a:hover{color:var(--green)}

/* ── the small green dot, borrowed from the tree's moments ── */
.dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--green);
  box-shadow:0 0 0 3px rgba(var(--green-rgb),.15);flex:none}

/* ── the fill-in: short, soft, no overshoot ── */
.reveal{transition:opacity .44s ease,transform .44s cubic-bezier(.25,.7,.3,1)}
.js .reveal{opacity:0;transform:translateY(11px)}
.reveal.in{opacity:1;transform:none}
.reveal.d1{transition-delay:.08s}.reveal.d2{transition-delay:.16s}.reveal.d3{transition-delay:.24s}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal{opacity:1!important;transform:none!important;transition:none!important}
  /* the theme swap too: the switch still works, it just lands at once */
  .swapping,.swapping body{transition:none!important}
  .u{background-size:100% 7px!important;transition:none!important}
}
