/*
  JADE V2 — shared stylesheet for both pages (index + for-business).
  Stark white, system type, Deep Sea #0C2D40 as the only strong color note.
  Every value traces to docs/design-blueprint-260707.md (L7 fusion tokens),
  merged 260715 with the business-funnel storyboard grammar
  (jade-business-funnel-v1.html): hairline #e5e7eb card strokes, 20px frames,
  10px fields and buttons, quiet 13/19 captions, sign-in sheet signups.
  No frameworks, no build step. Motion: opacity + ≤16px translateY only,
  all behind prefers-reduced-motion.
*/
:root{
  /* ---- ink (Linear's 4-step gray hierarchy, on white) ---- */
  --ink:#1a1a1a;          /* primary text */
  --ink-2:#4a4a4a;        /* secondary text / ledes */
  --ink-3:#6f6f6f;        /* meta / muted */
  --ink-4:#8a8a8a;        /* quiet labels */
  --line:#d8d8d8;         /* structural hairlines (rules, inputs) */
  --line-2:#e5e7eb;       /* card frames + inner dividers (funnel grammar) */
  --fill:#f7f8f8;         /* lightest card fill */
  --fill-2:#f2f2f2;       /* deeper card fill */
  --alert:#FF8C00;        /* alert/error — snappy orange, never red (matches app) */

  /* ---- brand ---- */
  --deep-sea:#0C2D40;     /* the one strong color note (CTAs, FAQ band, accents) */
  --deep-sea-2:#123B54;   /* hover state only */
  --jade:#5BBEAD;         /* the leaf's mid tone. Plutonium accent: ONLY where a
                             CTA sits on deep sea and white would read as an input.
                             6.4:1 against deep-sea text. Never decorative. */
  --jade-2:#4FB2A0;       /* its hover */
  --on-deep-sea:#ffffff;
  --on-deep-sea-dim:rgba(255,255,255,.72);
  --deep-sea-line:rgba(255,255,255,.16);

  /* ---- type ---- */
  --font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --font-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
  --fs-display:clamp(38px,29px + 2.4vw,52px);     /* H1 — v1's approved range: 40 mobile → 52 tablet, capped there (the ceiling) */
  --fs-h2:clamp(22px,18.4px + .9vw,28px);
  --fs-h3:18px;
  --fs-lede:clamp(17px,15.4px + .4vw,20px);
  --fs-body:16px;
  --fs-meta:13px;
  --fs-label:12px;                                 /* mono eyebrows */
  --fs-stat:clamp(34px,26px + 1.9vw,48px);         /* metrics band numerals */

  /* ---- radii (funnel grammar: 20 frames · 16 cols · 10 controls) ---- */
  --r-card:20px;
  --r-ctl:10px;

  /* ---- spacing scale: 4 8 12 16 24 32 48 64 96 128 160 ---- */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px;
  --s7:48px; --s8:64px; --s9:96px; --s10:128px; --s11:160px;
  --section-gap:clamp(64px,40px + 6vw,128px);
  --section-gap-major:clamp(96px,56px + 8vw,160px); /* the leaf reveal's air budget */

  /* ---- motion ---- */
  --ease-out-expo:cubic-bezier(.16,1,.3,1);        /* the reveal ease */
  --ease-out-quart:cubic-bezier(.165,.84,.44,1);   /* micro-entrances */
  --ease-spring:cubic-bezier(.3,1.45,.45,1);       /* the twizzle — springy, lab-serious */
  --dur-micro:.15s;

  /* ---- containers ---- */
  --maxw:680px;           /* readable measure — single-column conversion spine */
  --maxw-wide:1080px;     /* desktop frame */
  /* fluid gutter (260727): the white space never gets shaved to the bone on a
     dragged-narrow desktop window. 24px floor on phones, ~39px at the 920
     breakpoint, 48px ceiling once the frame has real room. */
  --gutter:clamp(24px,4.5vw - 2px,48px);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  font-family:var(--font-sans);
  color:var(--ink);
  font-size:var(--fs-body);
  line-height:1.6;
  background:#fff;
}

/* ---- layout primitives ---- */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter)}
section{position:relative;padding:var(--section-gap) 0}
/* full-bleed hairline between chapters — the page's only horizontal ornament */
.rule{border:0;border-top:1px solid var(--line);width:100vw;margin:0 calc(50% - 50vw)}

/* ---- type scale ---- */
h1{
  font-size:var(--fs-display);line-height:1.08;letter-spacing:-0.022em;
  margin:0 0 var(--s4);font-weight:650;max-width:18ch;text-wrap:balance;
}
h2{
  font-size:var(--fs-h2);line-height:1.15;letter-spacing:-0.012em;
  margin:0 0 var(--s5);font-weight:650;max-width:22ch;text-wrap:balance;
}
/* (h2 .dim retired 260715; the last stragglers left the pages — rule removed 260810b) */
h3{font-size:var(--fs-h3);line-height:1.3;margin:0 0 6px;font-weight:600;text-wrap:balance}
p{margin:0 0 14px}
.sub,.lede{
  font-size:var(--fs-lede);line-height:1.45;color:var(--ink-2);
  margin:0 0 var(--s6);font-weight:400;max-width:38ch;text-wrap:pretty;
}
.sub-br{display:none}                          /* manual subhead break — desktop only */
.closing h2,.closing .sub{text-wrap:pretty}
.meta{font-size:var(--fs-meta);color:var(--ink-3)}
small{font-size:12px;color:var(--ink-3)}
em{font-style:italic}
/* mono eyebrow — the science-cue label (numbered where order is real) */
.eyebrow{
  font-family:var(--font-mono);font-size:var(--fs-label);line-height:1;
  letter-spacing:.12em;text-transform:uppercase;font-weight:500;
  font-variant-numeric:tabular-nums;color:var(--ink-3);margin:0 0 var(--s4);
  display:flex;align-items:center;gap:8px;
}
.eyebrow::before{content:"";width:7px;height:7px;background:var(--deep-sea);flex:none;
  position:relative;top:.5px}  /* r34: centered on the caps, not the line box */
.num{font-variant-numeric:tabular-nums}

/* ---- scroll reveal (clay grammar, restrained) ---- */
.reveal{opacity:0;transform:translateY(14px);
  transition:opacity .5s ease,transform .9s var(--ease-out-expo)}
.reveal.is-in{opacity:1;transform:none}
.reveal[data-d="1"]{transition-delay:.06s}
.reveal[data-d="2"]{transition-delay:.12s}
/* photo bands: the photograph lands first — the module holds a beat or two,
   then manifests on a slow, even fade (Nathan 260801). Applies to every
   photo band on both pages (TWIN RULE rides along via the shared class). */
/* 260809h (Nathan): the .9s hold let fast scrollers blaze past.
   260809i: the remaining .35s dead wait goes too — the fade BEGINS the
   moment the band appears and stretches to the same finish line
   (.35+.7=1.05s opacity, .35+1.1=1.45s transform), so the module
   materializes over the photograph instead of popping after it. */
.signup-band--photo .shell.reveal{transform:translateY(10px);
  transition:opacity 1.05s ease-out,transform 1.45s var(--ease-out-expo)}
.no-js .reveal{opacity:1;transform:none}

/* ---- CTA / form (fields mirror the intended Supabase beta_signups mapping) ---- */
.cta-block{margin-top:var(--s2)}
form{display:flex;flex-direction:column;gap:10px;max-width:420px}
/* (.field-label removed 260810b — superseded by the .f-label grammar below;
   the near-twin name was a trap for future edits) */
input,select{
  font:inherit;padding:13px 14px;border:1px solid var(--line);border-radius:var(--r-ctl);
  background:#fff;color:var(--ink);width:100%;
}
input:focus{outline:2px solid var(--deep-sea);outline-offset:-1px;border-color:var(--deep-sea)}
.field{position:relative;display:flex;width:100%}
.field-icon{
  position:absolute;left:14px;top:50%;transform:translateY(-50%);
  width:18px;height:18px;color:var(--ink-3);pointer-events:none;
}
.field input{padding-left:42px}
.field:focus-within .field-icon{color:var(--deep-sea)}
button{
  font:inherit;font-weight:600;padding:14px 18px;border:0;border-radius:var(--r-ctl);
  background:var(--deep-sea);color:#fff;cursor:pointer;width:100%;
  transition:background var(--dur-micro) ease;
}
button:hover{background:var(--deep-sea-2)}
button:focus-visible{outline:2px solid var(--deep-sea);outline-offset:2px}
.privacy-line{display:flex;align-items:center;gap:6px;margin:2px 0 0;font-size:12px;color:var(--ink-3)}
.privacy-line a{color:inherit;text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:1px;
  text-decoration-color:rgba(107,114,128,.45)}
.privacy-lock{width:13px;height:13px;flex:none;color:var(--ink-3)}

/* All signup forms share ONE set of proportions (hyperconsistency rule,
   260708): the chunky, spacious base sizing above. No compact variants. */

/* ---- visible field labels (NN/g, Baymard: labels visible, placeholder = example) ---- */
.f-group{display:block}
.f-label{display:block;font-size:12px;font-weight:600;letter-spacing:.02em;
  color:var(--ink-2);margin:0 0 5px}
.f-label .f-opt{font-style:normal;font-weight:400;opacity:.75}

/* ---- form validation (email only required; orange, never red) ---- */
.field-alert{border-color:var(--alert);box-shadow:0 0 0 1px var(--alert)}
.form-alert{margin:-4px 0 0;color:var(--alert);font-size:13px;font-weight:600}

/* ---- status pill ---- */
.pill{
  display:inline-flex;align-items:center;gap:7px;align-self:flex-start;
  width:max-content;max-width:100%;
  margin:0 0 var(--s4);padding:5px 13px;border-radius:999px;
  background:var(--deep-sea);color:#fff;
  font-size:12.5px;font-weight:600;letter-spacing:.01em;line-height:1.2;
}
.pill-dot{
  width:7px;height:7px;border-radius:50%;background:#AAE9CA; /* live-dot only, not a color role */
  box-shadow:0 0 0 0 rgba(170,233,202,.5);animation:pill-pulse 2.4s ease-out infinite;
}
@keyframes pill-pulse{
  0%{box-shadow:0 0 0 0 rgba(170,233,202,.5)}
  70%{box-shadow:0 0 0 7px rgba(170,233,202,0)}
  100%{box-shadow:0 0 0 0 rgba(170,233,202,0)}
}

/* ---- official 5-leaf rating (the app's LeafRating) ---- */
/* sits between the H1 and the subhead — sandwiched under "rating" */
.leaf-block{margin:var(--s1) 0 var(--s5)}
/* 260816b (option B of the trust-near-the-hero pass): the claim captions
   the leaves it's about. Hero toy only — the business methodology toy
   carries no note. */
/* 260904a (Nathan): one weight for the small secondary lines — 400, same as
   the form's .f-opt helper ("Decide where Jade opens first."). Was 500. */
.hero-copy .leaf-note{margin:9px 0 0;font-size:13.5px;font-weight:400;
  letter-spacing:.01em;color:var(--ink);opacity:.72}
/* r65: the B2B H1's closing leaf — rides the text line at cap height */
.h1-leaf{height:.72em;width:auto;vertical-align:-0.04em}
.leaf-score{display:flex;align-items:center;gap:10px}
.leaf-score .leaves{display:inline-flex;gap:2px;
  touch-action:none;-webkit-user-select:none;user-select:none}
.leaf-score .leaf{width:44px;height:44px;display:block;
  -webkit-user-drag:none}   /* the row is a scrubber */

/* ---- HERO — typography only (260812b: the receipt art retired at every
   width; see assets/Archive/receipt-fpo.jpg). Copy stacks over the app
   carousel; left-aligned at every width, so collapsing the window never
   re-flows the alignment. ---- */
.hero-grid{display:flex;flex-direction:column;gap:var(--s3)}
.hero{display:flex;flex-direction:column;align-items:flex-start}
.hero-section{padding-top:clamp(56px,9vh,120px);padding-bottom:clamp(24px,4vh,56px)}
/* 260812e (Nathan): the sub's three-line rag is CANON at EVERY width, not a
   desktop flourish. 260812c scoped the breaks to >=920, so below that the
   copy fell back to natural wrapping — which on a narrow phone rags as
   "Many businesses say / they're sustainable. / ..." (four lines). So the
   breaks are always on here, and the 38ch measure comes off so the box hugs
   the longest line instead of forcing an early wrap. text-wrap:wrap
   overrides the inherited `pretty`, which would otherwise rebalance around
   the manual breaks. Line one measures 314px at the phone size against 327px
   of room, so it holds down to ~370px wide; narrower than that it wraps,
   which is the same fallback as before, not a regression. */
.hero-copy .sub{max-width:none;text-wrap:wrap}
.hero-copy .sub-br{display:inline}
/* (260812f: the leaf-shadow wash audition is out — Nathan's call, the ATF
   stays type only. Rules and the derivative removed; the Unsplash original
   he supplied stays in assets/src if it is ever wanted.) */

/* =====================================================================
   SHARP BRANCH additions (260730, r31) — device frame, app carousel,
   leaf toy. (Panel media cards + mid-CTA + mesh hero button retired r31:
   screens moved to the carousel; all signup moments are photo-band twins.)
   ===================================================================== */
/* ---- phone frame: quiet dark bezel, app screenshot inside ---- */
.phone{margin:0;display:block;background:#0e1116;border-radius:43px;padding:9px;
  box-shadow:0 24px 48px -20px rgba(12,45,64,.35),0 4px 12px -6px rgba(12,45,64,.2)}
/* screen corner = the true iPhone display radius (~14% of logical width):
   34px at the carousel's 246px screen width */
.phone img{display:block;width:100%;height:auto;border-radius:34px;background:#fff}
/* ---- the app carousel lives in the HERO now (r32): snap swipe, eyebrow
   riding above it. Full-bleed track on mobile; column-bound on desktop. ---- */
.hero-media{display:flex;flex-direction:column;gap:var(--s4);margin-top:var(--s6);min-width:0}
/* 260820c: the bleed escapes to the VIEWPORT, not the wrap — at 756-919px
   the wrap caps at 680 and floats centered, so a gutter-only escape left
   the track clipping ~100px inside the window on both sides (Nathan's
   "premature mask", Safari, tall monitor). 50% - 50vw reaches the true
   edge at every width; the padding puts the first phone back on the
   wrap's content edge (the two terms cancel to the plain gutter whenever
   the wrap fills the window, so phones are untouched). */
.appcar{display:flex;gap:22px;overflow-x:auto;scroll-snap-type:x mandatory;
  margin:0 calc(50% - 50vw);
  /* 50vw - 50% measured from the track's viewport-pinned edge IS the wrap
     content edge (50% resolves against the wrap's content width, so the
     wrap's own gutter is already inside the difference — adding it again
     shoved the first phone a gutter past the eyebrow). On a wrap that
     fills the window the expression collapses to the plain gutter. */
  padding:18px calc(50vw - 50%) 16px;
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.appcar::-webkit-scrollbar{display:none}
.car-item{position:relative;margin:0;flex:none;scroll-snap-align:center;width:min(264px,72vw);
  display:flex;flex-direction:column;gap:10px}
@media(max-width:919px){
  /* 260812b: the receipt's absolute-positioning stack retired with the art.
     The clip STAYS — the carousel's reveal glide (translateX(68px) below)
     would otherwise push a sideways scrollbar during the animation. */
  .hero-section{overflow-x:clip}
}
/* 260809f (Nathan, replaces the one-round boop): on phones the track
   GLIDES INTO PLACE from the right as it reveals — rides the .reveal
   moment, so it fires exactly when the user encounters it. Desktop
   needs no hint; the unmasked bleed already says "I slide". */
@media(max-width:919px){
  /* 260809i (Nathan): +20px start — the glide reads clearer */
  .hero-media.reveal .appcar{transform:translateX(68px);
    transition:transform .9s var(--ease-out-expo)}
  .hero-media.reveal.is-in .appcar{transform:none}
  .no-js .hero-media .appcar{transform:none}
}
/* (260816b: the 260808b/260812c "Scrollable" sticker is banked — nobody
   read it; the carousel auto-center + §11 walk shows instead of telling.
   The track's 18px top padding stays: it was the sticker's protrusion
   headroom and now simply keeps the reveal-glide clip comfortable.) */
.car-item .phone{width:100%}
.car-item figcaption{text-align:center}
/* the auto-walking business page: fixed screen viewport, tall composite
   inside, translateY keyframes with finger-like pauses (stops are per-image
   CSS vars, percentages of the composite's own height) */
.phone-view{display:block;border-radius:34px;overflow:hidden;
  /* 260819e: bezel-colored, NOT white — this box's own background was the
     white that flashed at the top edge on Safari: two rounded boxes (bezel
     + screen) rounding to different fractional pixels for a frame during
     load transitions let a sliver of it peek. The content covers the box
     completely (260819d overscan), so the ground never shows by design;
     when a raster wobble exposes a sliver anyway, it now reads as bezel.
     (Dark mode's #34393d bezel vs this #0e1116: still dark-on-dark.) */
  background:#0e1116;
  aspect-ratio:393/852;
  /* 260819d: pin the rounded clip to its own layer — Safari re-rasterized
     it during load transitions and the edge wobbled a pixel */
  transform:translateZ(0)}

/* ---- the INTERACTIVE walker (r36): a real scroll container in the phone.
   Layout runs at the app's native 393pt width; media.js zooms it to the
   frame. Auto-walk is JS (§11) and yields to any human touch. ---- */
/* 260816b (Nathan): native rubber-band OFF (overscroll-behavior none — the
   pull dropped the mock nearly half a screen of white). media.js §11 gives
   touch a short leash instead: ~30px of resisted pull, spring home. */
.iwalk{width:393px;height:852px;overflow-y:auto;overscroll-behavior:none;
  scrollbar-width:none;background:#fff;font-family:var(--font-sans);
  -webkit-font-smoothing:antialiased;outline:none;
  /* 260819c: keep the scroll layer composited for good — promote/demote
     at each tour glide re-rasterized the top clip edge (hairline flash) */
  will-change:scroll-position}
/* rubber-band reveal, the app's exact architecture (r54 — the r53
   container gradient bled through the transparent dossier mid-scroll):
   a mesh block hidden ABOVE the scroll origin, revealed only by the
   pull-down bounce. Three layers ported from app/business/[id].tsx —
   mint bloom, aqua wash, Deep Sea diagonal (#082338 here mirrors the
   app's shipped gradient verbatim; the deprecated-color rule defers to
   the app being the source of truth for its own capture). */
/* 260813b (Nathan): the Deep Sea overscroll mesh is RETIRED from the mock
   entirely — on his iOS the bounce paints the scroller's background, so
   the mesh kept surfacing at card seams no matter how it was sized.
   260814a: the photo strip that replaced it is retired too (same seam
   problem) — the pull-down reveals plain white, full stop. */
.iw-overscroll{background:#fff}  /* 260819e: .phone-view left this pair — bezel-colored now, see its rule */
.iw-overscroll{height:400px;margin-top:-400px}
/* 260813a: the pull-down bounce on iOS reveals the SCROLLER's background,
   not content above the origin — so .iwalk's white ground was what showed
   (Nathan saw plain white where the app shows the mesh). The mesh now
   lives on .iwalk itself, but sized to the app's exact 400px overscroll
   block (app/business/[id].tsx: overscrollBackground height 400, stops
   verbatim) over an opaque white base — so a bottom bounce, seam, or gap
   further down can only ever expose white, never the mesh. The
   .iw-overscroll block above stays for engines that translate content. */
/* 260814a (Nathan): the background strip is retired entirely — the 260813b
   photo strip still surfaced at unexpected seams while scrolling, same
   failure mode as the mesh before it. The bounce now reveals plain white,
   which iOS reads as ordinary app chrome. */
.iwalk{background:#fff}
.iwalk::-webkit-scrollbar{display:none}
.iw-img{display:block;width:100%;height:auto}
/* 260808g (Nathan saw a hairline mid-mock at certain desktop widths):
   the iwalk renders through a fractional transform scale, and the seams
   between the two captures and the live dossier can open a sub-pixel
   gap. Each junction now overlaps 1px on an explicit white ground. */
.iwalk .iw-dossier{background:#fff;margin-top:-1px}
.iw-img[data-stop="reviews"]{margin-top:-1px}
/* scoped dossier grammar (from the Sustainability v2 artifact) */
/* the dossier's <section> elements must NOT inherit the page's section
   rhythm (var(--section-gap) padding blew the accordions apart, 260801) */
.iwalk section{padding:0}
.iwalk .iw-dossier{padding:1px 24px 0;color:#111827}
.iwalk .section-title{font-size:24px;font-weight:700;color:#000;letter-spacing:-.3px;margin:0 0 12px}
.iwalk .accs{margin-top:0}
.iwalk .acc{border-top:1px solid #e5e7eb}
.iwalk .acc:first-of-type{border-top:0}
.iwalk .acc:last-child{border-bottom:1px solid #e5e7eb}
.iwalk .acc__head{width:100%;background:none;border:0;font-family:inherit;cursor:pointer;
  display:flex;align-items:center;gap:8px;padding:15px 0;text-align:left}
.iwalk .acc__title{font-size:16px;font-weight:600;color:#111827;letter-spacing:-.2px}
.iwalk .acc__count{font-size:13px;color:#6b7280;flex:1}
.iwalk .acc__chev{width:16px;height:16px;color:var(--deep-sea);flex:none;
  transition:transform .28s cubic-bezier(.4,0,.2,1)}
.iwalk .acc[data-open="true"] .acc__chev{transform:rotate(180deg)}
.iwalk .acc__panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .32s cubic-bezier(.4,0,.2,1)}
.iwalk .acc[data-open="true"] .acc__panel{grid-template-rows:1fr}
.iwalk .acc__inner{overflow:hidden}
.iwalk .acc__body{padding:0 0 16px}
.iwalk .cert{display:flex;align-items:flex-start;gap:11px;padding:10px 0}
.iwalk .cert__dot{width:18px;height:18px;flex:none;display:grid;place-items:center;margin-top:1px}
.iwalk .cert__dot::before{content:"";width:5px;height:5px;border-radius:50%;background:#22C55E}
.iwalk .cert.lapsed .cert__dot::before{background:#d1d5db}
.iwalk .cert__main{flex:1;min-width:0}
.iwalk .cert__name{font-size:15px;font-weight:600;color:#111827;letter-spacing:-.1px}
.iwalk .cert.lapsed .cert__name{color:#9ca3af}
.iwalk .cert__meta{font-size:13px;color:#6b7280;margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.iwalk .cert.lapsed .cert__meta{color:#9ca3af}
.iwalk .pill{display:inline-flex;align-items:center;gap:5px;text-decoration:none;font-size:12px;
  font-weight:500;color:#6b7280;background:#f3f4f6;border-radius:10px;padding:3px 8px;flex:none;
  margin:0;letter-spacing:0;line-height:1.4}
.iwalk .pill svg{width:10px;height:10px;opacity:.7}
.iwalk .pill--lapsed{background:#FEF3C7;border:1px solid #FDE68A;color:#B45309}
.iwalk .filter{display:flex;gap:8px;padding:2px 0 12px}
.iwalk .filter button{font-family:inherit;font-size:13px;font-weight:600;padding:6px 14px;width:auto;
  border-radius:999px;border:1px solid #d1d5db;background:#fff;color:#6b7280;cursor:pointer;transition:none}
.iwalk .filter button:hover{background:#fff}
.iwalk .filter button[aria-pressed="true"]{background:var(--deep-sea);border-color:var(--deep-sea);color:#fff}
.iwalk .item{display:flex;gap:11px;padding:11px 0}
.iwalk .item+.item{border-top:1px solid #e5e7eb}
.iwalk .item__glyph{width:18px;height:18px;flex:none;display:grid;place-items:center;margin-top:19px}
.iwalk .item.good .item__glyph svg{width:15px;height:15px;color:var(--deep-sea)}
.iwalk .item.watch .item__glyph svg{width:20px;height:20px}
.iwalk .item__main{flex:1;min-width:0}
.iwalk .item__date{font-size:12px;font-weight:600;color:#9ca3af;letter-spacing:.5px;text-transform:uppercase}
.iwalk .item__head{font-size:15px;font-weight:600;color:#111827;line-height:20px;letter-spacing:-.1px;margin:3px 0 7px}
.iwalk .src{display:inline-flex;align-items:center;gap:5px;text-decoration:none;font-size:12px;font-weight:500;
  color:#6b7280;background:#f3f4f6;border-radius:10px;padding:3px 9px}
.iwalk .src svg{width:11px;height:11px;opacity:.7}
.iwalk .src-row{display:flex;align-items:center;gap:8px}
.iwalk .selfpub{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:#9ca3af}
.iwalk .show-more{width:100%;background:none;border:0;border-top:1px solid #e5e7eb;font-family:inherit;
  display:flex;align-items:center;justify-content:center;gap:5px;padding:12px 0 4px;cursor:pointer;
  font-size:13px;font-weight:600;color:var(--deep-sea);transition:none}
.iwalk .show-more:hover{background:none}
.iwalk .show-more svg{width:14px;height:14px}
/* (260816b: .iwalk .refreshed removed with its 260815f-deleted markup.) */
@media(prefers-reduced-motion:reduce){.phone-view img{animation:none}}
/* the review frame's blinking caret — measured text-end coordinates */
.screenw{position:relative;display:block;container-type:inline-size}
/* blank-results state (260801): white covers hide the result rows until
   the typed query lands, then fade out top-to-bottom like a list render */
.sr-cover{position:absolute;left:0;width:100%;background:#fff;
  pointer-events:none;transition:opacity .3s ease}
.screenw.is-live .sr-cover{opacity:0}
.no-js .sr-cover{opacity:0}
/* the search frame's live-typed query (media.js §10): overlay at the
   measured field-text coordinates (left 17.55% · top 16.90% · 16pt/393) */
.search-type{position:absolute;left:17.55%;top:16.90%;height:2.11%;
  display:flex;align-items:center;
  font-family:var(--font-sans);font-size:4.07cqw;color:#000;
  letter-spacing:-.01em;white-space:nowrap}
.st-caret{width:1.5px;height:5.1cqw;background:#007AFF;border-radius:1px;
  margin-left:1px;animation:caret-blink 1.1s steps(1) infinite}
.type-caret{position:absolute;left:79.58%;top:83.33%;width:1.5px;height:2.58%;
  background:#007AFF;border-radius:1px;
  animation:caret-blink 1.1s steps(1) infinite}
@keyframes caret-blink{0%,55%{opacity:1}56%,100%{opacity:0}}
@media(prefers-reduced-motion:reduce){.type-caret{animation:none}}
/* the Kermit flip in the closing headline */
/* (260810a: .kermit strike retired with the "easy being green" closer —
   Nathan: "green" is a burnt term; the site now says sustainable/
   sustainability and lets the evidence carry the tone.) */
/* ---- hero leaf toy (media.js §9): the app's tappable review leaves ---- */
.leaf-btn{background:none;border:0;padding:0;width:auto;cursor:pointer;
  display:block;border-radius:8px}
.leaf-btn:hover{background:none}
.leaf-btn:focus-visible{outline:2px solid var(--deep-sea);outline-offset:3px}
.leaf-btn .leaf{display:block}
@keyframes leaf-pop{
  0%{transform:scale(1)}
  40%{transform:scale(1.28) rotate(-4deg)}
  70%{transform:scale(.94)}
  100%{transform:scale(1)}
}
.leaf-btn.popping .leaf{animation:leaf-pop .42s cubic-bezier(.3,1.45,.45,1)}
@media(prefers-reduced-motion:reduce){.leaf-btn.popping .leaf{animation:none}}

/* =====================================================================
   SIGNUP SHELL — restyled 260715 to the app's sign-in sheet (funnel
   Stage 03): white card, hairline frame, grab handle, Deep Sea button.
   Close enough to the app to be mistaken for it. One shell closes the
   page; the pinned dock carries signup until then.
   ===================================================================== */
.signup-band{padding:var(--s7) 0 var(--section-gap)}
.shell{
  position:relative;z-index:1;
  background:#fff;color:var(--ink);
  border:1px solid var(--line-2);
  border-radius:var(--r-card) var(--r-card) 14px 14px;
  box-shadow:0 10px 24px -18px rgba(12,45,64,.25);
  padding:20px 18px 22px;
  max-width:480px;margin:0 auto;text-align:left;
}
/* (the sheet's grab dragline retired 260727 — Nathan: no longer necessary) */
.shell h2{
  color:var(--ink);font-size:clamp(19px,17px + .6vw,22px);letter-spacing:-.012em;
  margin:0 0 5px;max-width:none;font-weight:700;
}
.shell-sub{color:var(--ink-3);font-size:13px;line-height:1.5;margin:0 0 var(--s4);text-wrap:pretty}
.shell form{max-width:none;text-align:left}
.shell .f-label{color:var(--ink-2)}
/* =====================================================================
   TWIN RULE (Nathan 260728): the FAB-spawned sheet and the conclusion
   signup module bear the SAME traits and content — any edit to one must
   land in both, concurrently. .shell--glass is the closing module wearing
   the sheet's exact skin: frost, hairline ring, deep shadow, mesh CTA.
   Behind it, .signup-band--photo floats it on the LA City photograph —
   see below. Liquid-glass audition (260728): the frost is more open than
   the sheet's (.7 white vs .82, deeper blur) so the city actually refracts
   through it; the two dials to tune are the .7 alpha and the 32px blur.
   ===================================================================== */
.shell--glass{
  border:0;border-radius:var(--r-card);
  background:
    linear-gradient(180deg,rgba(255,255,255,.55),rgba(255,255,255,0) 42%),
    rgba(255,255,255,.7);
  -webkit-backdrop-filter:saturate(180%) blur(32px);
  backdrop-filter:saturate(180%) blur(32px);
  box-shadow:0 24px 60px -20px rgba(2,14,22,.45);
}
/* TWIN RULE — heroic signup headline (Nathan 260729): "Sign up / now" at a
   display scale inside the 480px card, in the site's heroic type grammar
   (650 / -0.022em / tight leading, same as .tw-word). The support line
   scales up with it. Shared by the conclusion module AND the FAB sheet,
   both pages; the B2B pair carries its own copy in the same clothes. */
.shell--glass .signup-hero,.dock-panel .signup-hero{
  /* r33: sized to hold the longer 1-2-3 headlines ("It's not easy being
     green" = 25ch) on two lines in the 480px card and on phones alike */
  font-size:clamp(24px,19px + 1.6vw,34px);line-height:1.08;letter-spacing:-0.022em;
  font-weight:650;margin:0 0 12px;max-width:none;text-wrap:balance;
}
.shell--glass .signup-hero+.shell-sub,.dock-panel .signup-hero+.shell-sub{
  font-size:clamp(15px,14px + .3vw,16px);line-height:1.5;margin:0 0 var(--s5);
}
/* r32 (Nathan): headline + support line center; the form stays left-aligned */
.shell--glass .signup-hero,.dock-panel .signup-hero,
.shell--glass .shell-sub,.dock-panel .shell-sub{text-align:center}
/* 260830i (Nathan): while its signup's thank-you modal is open, the band's
   card cedes the stage: ONE modal-like surface at any instant. visibility
   (never display): the reveal transition doesn't list it so the card
   vanishes the same frame the scrim tints, the band keeps its height (the
   photo sizes to the band and would hop), and media.js §4 lifts the class
   on modal close so second signups still have their card. */
.shell.is-ceded{visibility:hidden;
  /* 260830j (Nathan's live test): Safari keeps a hidden element's
     backdrop-filter alive on its compositor layer, so the ceded card's
     blur went on frosting the band photo behind the modal. Zeroing the
     filter here tears the layer down; invisible everywhere else anyway. */
  -webkit-backdrop-filter:none;backdrop-filter:none}
/* the sheet's 1px hairline ring, masked exactly like the dock's */
.shell--glass::before{content:"";position:absolute;inset:0;border-radius:inherit;
  padding:1px;background:rgba(12,45,64,.14);
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  mask-composite:exclude;pointer-events:none}
/* the conclusion backdrop (fourth pass, 260728 — dim retired for the LA
   City photo): a full-bleed photograph fills the closing section, cropped
   cover with vertical headroom so media.js §8 can drift it slowly against
   the scroll (transform parallax — iOS-safe, unlike background-attachment).
   A quiet Deep Sea tint keeps the frost and the cross-link legible. The
   module floats on the photo — the liquid-glass audition finally has
   something to refract. Section padding centers the module in the region
   (Nathan: it rode too high). */
/* r47 (Nathan 260801): symmetric padding — the module centers on the
   band's horizon, and all three bands stand the same height. (The old
   +56px top pad and the shorter first band both retired.) */
.signup-band--photo{overflow:hidden;
  padding-top:var(--section-gap);padding-bottom:var(--section-gap)}
.signup-photo{position:absolute;top:0;bottom:0;left:50%;width:100vw;
  margin-left:-50vw;overflow:hidden;pointer-events:none}
/* full-frame contained figure (r55): for photos whose whole scene is the
   point — no cover-crop, radius-carded, same corner credit.
   (DORMANT 260810b: no current usage; kept as the utility for future pages.) */
.figure-wide{position:relative;margin:var(--s7) 0 0;border-radius:var(--r-card);
  overflow:hidden}
.figure-wide img{display:block;width:100%;height:auto}
.figure-wide[data-credit]::after{content:attr(data-credit);
  position:absolute;right:10px;bottom:8px;
  font-size:10px;letter-spacing:.02em;color:rgba(255,255,255,.5);
  pointer-events:none}
/* tiny human-evidence credit, bottom-right (Unsplash license requires no
   attribution; this is a courtesy — deliberately small and unlinked)
   260902a (Nathan): 16px further in from the right edge, here and on
   .photo-credits — Safari's overlay scrollbar was sitting on the name. */
.signup-photo[data-credit]::before{content:attr(data-credit);
  position:absolute;right:26px;bottom:8px;z-index:1;
  font-size:10px;letter-spacing:.02em;color:rgba(255,255,255,.5);
  pointer-events:none}
/* overscan opened up 260729 (122%/-11% → 136%/-18%): more vertical real
   estate for media.js §8 to pan across; TRAVEL there rides the same dial */
.signup-photo img{position:absolute;left:0;top:-18%;width:100%;height:136%;
  object-fit:cover;will-change:transform}
/* 260812d (Nathan): band 1 PINS LEFT. With cover, the default 50% centering
   trims both edges as the band narrows, and the woman in red sits hard on
   the left edge — she was the first thing to go. Anchoring at 0 means the
   left edge is never cropped, so she is always in the shot; everything the
   band gives up now comes off the right, which is the emptier side since
   the 260812c recrop. */
#signup-top .signup-photo img{object-position:0 50%}
/* the florist (260801): pull the zoom back — it's about her shop, not her.
   Less overscan = a wider slice of the photo on phones; the frame biases
   left so the greenery does the framing. The section needs data-travel="4"
   wherever this lands: 102% overscan leaves ~1% of headroom, and the default
   64px parallax drift would pull straight past it.
   260812e: re-scoped from #signup-mid to a CLASS, because the middle bands
   retired and this photo moved to the business page's closing band. The
   treatment now travels with the photo instead of with a position. */
.signup-photo--florist img{top:-1%;height:102%;object-position:0 50%}
/* r69 (Nathan, B2B band 2 phones): the florist rides CENTER behind the
   glass — foliage frames the module's edges instead of the elbow crop */
@media(max-width:919px){
  .signup-photo--her-center img{object-position:50% 50%}
}
/* r70 (Nathan, from Safari's smallest macOS window): centered at 500+
   the widening slice admits the doorframe architecture left of frame.
   These steps PIN the crop's left edge at the same image point true
   mobile shows (x≈610 of 2000 — the readable plant sliver), so the
   look matches his approved iPhone frame and she drifts off-center as
   the window grows. Steps approximate the pin as the slice widens;
   past ~720 the full-frame slice is wider than the image right of the
   sliver, so 100% (right edge flush) is the best available. */
@media(min-width:500px) and (max-width:919px){
  .signup-photo--her-center img{object-position:68% 50%}
}
@media(min-width:620px) and (max-width:919px){
  .signup-photo--her-center img{object-position:82% 50%}
}
@media(min-width:720px) and (max-width:919px){
  .signup-photo--her-center img{object-position:100% 50%}
}
/* =====================================================================
   B2B BAND 1 · SINGLE PHOTO (260808a, supersedes the r66 assemblages
   and the never-shipped 260807a mobile plates) — one Unsplash frame
   (Social.Cut boutique interior, 3:2) at every width. No registration
   rule anymore: nothing in the photo is composed against the module,
   so object-fit:cover simply crops each viewport out of the same
   frame. Band geometry is unchanged: 900px tall through tablet,
   62.5vw capped at 900 on desktop, frame CAPS at 1440 wide — past
   that rounded corners and page ground, so pixels never stretch
   (Nathan's quality guard, 260806).
   ===================================================================== */
/* 260808b (Nathan): the extra-tall 900px mobile/tablet band RETIRED — it
   existed to seat the assemblage montage (the shopper's face needed the
   headroom). With one cover-cropped photo the band now stands the same
   height as every other photo band below 920 (shell + section-gap padding,
   from .signup-band--photo). Desktop keeps the framed-art treatment. */
.signup-band--art .wrap{width:100%}
@media(min-width:920px){
  #signup.signup-band--art{padding:0;height:min(62.5vw,900px);
    display:flex;flex-direction:column;justify-content:center}
}
/* r71: centered by LAYOUT, not transform — translateX(-50%) at odd
   viewport widths lands on a half pixel and composites a hairline of
   page ground down the left edge (Nathan saw it in narrow Safari).
   left/right:0 + auto margins snap to the pixel grid; 100% (not 100vw)
   keeps desktop scrollbars from skewing the math. */
.signup-photo--art{width:min(100%,1440px);left:0;right:0;
  margin:0 auto;transform:none}
.signup-photo--art img{position:static;top:auto;width:100%;height:100%;
  object-fit:cover;will-change:auto;
  /* 260808a: center crop — a landscape interior with no faces to protect;
     the tall mobile band takes a vertical slice from mid-frame (rack on
     the left, hanging goods center) which reads as shop at any width */
  object-position:50% 50%}
/* past the art's native 1440: framed edge, never stretched pixels */
@media(min-width:1441px){
  .signup-photo--art{border-radius:var(--r-card);overflow:hidden}
  .signup-band--art .photo-credits{
    right:calc((100vw - 1440px)/2 + 28px)}
}
/* 260813c (Nathan): the People bands get the same ceiling — full bleed
   until band-queue's native 2000px, then a centered rounded frame instead
   of stretched pixels (mirrors the business band's >1441 treatment; the
   corner credit rides inside the photo so it needs no offset math). */
@media(min-width:2001px){
  .signup-photo:not(.signup-photo--art){width:2000px;left:0;right:0;
    margin:0 auto;border-radius:var(--r-card)}
}
/* 260808a: the raw photo carries no baked grading (unlike the r66
   assemblages), so the standard bottom ramp below applies again —
   the earlier background:none override is retired with the art. */
/* 260808a: single attribution, plain text — same tiny grammar as the
   data-credit corner text, no longer a link (the footer "Photography"
   link carries the collection). Lives OUTSIDE the pointer-events:none
   photo layer, as the band's direct child. */
.photo-credits{position:absolute;right:26px;bottom:8px;z-index:2;
  font-size:10px;letter-spacing:.02em;color:rgba(255,255,255,.6);
  text-shadow:0 1px 4px rgba(8,25,38,.5)}
/* 260729 second pass: the sky carries NO tint at all — flat zero to the
   photo's midline, then the ramp gathers where it protects the white
   cross-link and the module's legibility. (The prior gradient held .05-.10
   over the sky; Nathan: preserve the original bright sky.) */
.signup-photo::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,
    rgba(8,25,38,0) 0%,
    rgba(8,25,38,0) 50%,
    rgba(8,25,38,.12) 68%,
    rgba(8,25,38,.38) 100%)}
/* the cross-link under the module reads white on the photo */
/* r56: the cross-link lives in its own Deep Sea strip between the closing
   band and the footer (both sites) — protected, prominent, and no longer
   riding the photo or clobbering the credit. */
/* r65 AUDITION (Nathan 260806): the cross-band tries BLACK instead of
   Deep Sea — both pages share this rule. Revert = var(--deep-sea). */
/* 260915a (Nathan): the strip wasn't getting seen. Taller band (26 → 44px
   of padding), and the cross-link drops its underline for a WHITE PILL
   BUTTON on the black ground ("For Business →" / "For People →"). Dark mode
   inverts the whole thing: white band, black pill, white label. The lead-in
   ("Own a business?") gets a step up in size too. */
.cross-band{background:#000;padding:44px 0}
.cross-band .closing-cross{margin:0;gap:16px;font-size:15px;color:rgba(255,255,255,.85)}
.cross-band .nav{display:inline-flex;align-items:center;min-height:44px;padding:0 22px;
  border-radius:999px;border-bottom:0;background:#fff;color:#000;font-size:15px;
  transition:transform var(--dur-micro) ease,opacity var(--dur-micro) ease}
.cross-band .nav:hover{opacity:.88;transform:translateY(-1px)}
/* 260902c (Nathan): in dark mode the black strip vanished into the black
   page — it goes WHITE with black type there, both pages ("Own a business?"
   under the People page, "Shopping for sustainability?" under Business).
   Light mode keeps r65's black. 260915a: the pill inverts with it. */
html.dark .cross-band{background:#fff}
html.dark .cross-band .closing-cross{color:rgba(0,0,0,.85)}
html.dark .cross-band .nav{background:#000;color:#fff}
/* the twin CTAs: leaf centered with the label (260728 — the leaf moved
   down from the sheet's header into the button) */
.shell--glass form button,.dock-panel form button{
  display:flex;align-items:center;justify-content:center;gap:9px}
.btn-leaf{width:19px;height:19px;flex:none}
/* 260820e (Nathan, from the cellular smoke test): the first submit carries
   the lazy Turnstile load + challenge + API round trip — seconds on
   cellular. "One moment…" alone read as a hang; the ring says "working".
   currentColor inherits every button's ink; reduced motion keeps text only. */
form button.is-busy::after{content:"";display:inline-block;flex:none;
  width:13px;height:13px;border-radius:50%;
  border:2px solid currentColor;border-right-color:transparent;
  animation:btn-spin .7s linear infinite}
form button.is-busy .btn-leaf{display:none}
@keyframes btn-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){form button.is-busy::after{display:none}}
/* CTA label reveal — the button arrives set; the label fades in once the
   shell has revealed (replaced the scale boop, 260709: calmer, less thirsty) */
@media(prefers-reduced-motion:no-preference){
  html:not(.no-js) .shell button .btn-label{opacity:0;transition:opacity .7s ease .45s}
  html:not(.no-js) .shell.is-in button .btn-label{opacity:1}
  /* photo-band shells hold .35s + fade .7s — the label still lands last */
  html:not(.no-js) .signup-band--photo .shell button .btn-label{transition-delay:.9s}
}
.shell .privacy-line{color:var(--ink-3);justify-content:center}
.shell .privacy-lock{color:var(--ink-3)}

/* =====================================================================
   01 · WHAT JADE DOES — heroic type stack (260729, replaces the mind
   map). Study B's stacked grammar at EVERY viewport (Nathan's call: the
   flank is dead, the mobile stack is the look): the word at the true
   ZERO-finale scale, mono index under it, tagline, body — everything
   visible outright, nothing behind a click. Fit beats ZERO's 80px floor
   on phones (Business is the width test) via the 21cqw cap; .tw-stack
   is the container.
   ===================================================================== */
/* DORMANT 260810b: the tw-* stack left the pages (mission-copy + sticky
   tabs carry §01 now); .signup-hero still cites .tw-word's heroic settings. */
.tw-section{padding:var(--section-gap-major) 0 var(--section-gap)}
/* the tab stack docks flush onto the photo band below it — no white gap
   between the folded tabs and the signup module (Nathan 260802) */
.hjw{padding-bottom:0}
.tw-stack{container-type:inline-size}
.tw-row{padding:48px 0}
.tw-row:first-child{padding-top:12px}
.tw-row+.tw-row{border-top:1px solid var(--line-2)}
.tw-word{font-size:min(clamp(80px,52px + 8.4vw,156px),21cqw);font-weight:650;
  letter-spacing:-0.022em;line-height:.98;margin:0;color:var(--ink)}
.tw-tag{font-size:var(--fs-lede);font-weight:600;letter-spacing:-0.01em;
  color:var(--ink);margin:14px 0 0}
.tw-sub{font-size:var(--fs-body);line-height:1.6;color:var(--ink-2);
  max-width:52ch;margin:10px 0 0;text-wrap:pretty}
/* ---- the mission-grade prose moment (opens §02 since 260729 — it left
   §01's tail for the top of How Jade works; .hjw-mission spaces it there:
   air below the statement, then the smaller H2 leads the tab stack) ---- */
.mission-copy{
  font-size:clamp(23px,18px + 1.5vw,34px);line-height:1.35;letter-spacing:-0.015em;
  font-weight:550;color:var(--ink);max-width:30ch;text-wrap:pretty;margin:0;
}
/* 260812c (Nathan): a little more air before the pull, so the punchline
   lands as its own beat instead of running on from the setup */
.hjw-mission{margin:6px 0 28px;font-weight:450}
/* 260808d (Nathan): the long-goal line as a PULL — indent + vertical rule,
   pull-quote grammar on our own words (no quote marks; correct usage,
   magazines pull their own lines). 260808g (Nathan): weight contrast
   FLIPPED — the body thins to 450 and the pull carries the 550; the rule
   slims to 2px in the hairline gray the site already draws with.
   (the 450 lives on .hjw-mission's declaration above, 260810b merge)
   260812d (Nathan): the pull goes DEEP SEA — the long-goal line is the one
   moment on the page that earns colour, and the ink-to-accent step is the
   whole kick. The hairline rule stays grey on purpose: colouring both would
   double the emphasis and cost the line its quiet. */
.mission-pull{font-weight:550;color:var(--deep-sea);
  border-left:2px solid var(--line-2);
  padding-left:clamp(16px,1.2vw + 12px,24px);margin:0 0 clamp(44px,32px + 3vw,72px) 2px}
/* Deep Sea is unreadable on the dark ground (it is not remapped in the dark
   token block), so the accent swaps toward Jade — but 260812m (Nathan): not
   the stark mint. The pull is to white what Deep Sea is to black: Deep Sea
   is black pulled toward its hue; this is white pulled toward jade #5BBEAD.
   260812n (Nathan): dialed from 25% (#BFE6DF) down to ~13% — it should be
   hard to tell the mint is even there, a barely-there grayish whisper. */
html.dark .mission-pull{color:#EAF7F4;border-left-color:var(--line-2)}

/* ---- metrics finale styles (shell version lives with .stats below) ----
   DORMANT 260810b: the ZERO finale left the pages (no .zero-num in any HTML);
   media.js §6 stays wired and no-ops. Kept for the evidence band's return. */
/* the heroic numeral — deliberately the largest thing on the page. Same
   clamp as .tw-word's inner scale, and .stat-num already carries the §01
   hero grammar (650 / -0.022em), so the title-case "Zero" finale (260729)
   matches the What-is-Jade words exactly. tw-word's 21cqw fit cap is
   skipped: "Zero" clears the 80px floor on every phone.
   (.stat-num.zero-num: must outrank .stat-num, which sits later in the file) */
.stat-num.zero-num{font-size:clamp(80px,52px + 8.4vw,156px);font-variant-numeric:tabular-nums}
/* the sneaky 0→o morph (260729, title case): the counter's numeral
   crossfades into a lowercase letter o while the cell's width eases
   between the two glyphs' measured sizes (media.js sets width + scale) */
.zg{display:inline-grid;vertical-align:bottom}
.zg span{grid-area:1/1;white-space:pre;text-align:center}
.zg .zg-o{opacity:0}
.stat-flip{margin:0;text-wrap:pretty;opacity:0;transform:translateY(10px);
  transition:opacity .5s ease,transform .8s var(--ease-out-expo)}
.stat-flip.is-in{opacity:1;transform:none}
.no-js .stat-flip{opacity:1;transform:none}

/* =====================================================================
   LEAF FAB — the app's review FAB, ported one-to-one (260727, replaces the
   centered dock capsule). Collapsed: dark liquid-glass pill bottom-RIGHT
   (app spec: r33, pad 16/24, 22px leaf, 17px/600 white label, gradient
   hairline border, deep-ocean glass). Tap expands it into the sign-in
   sheet; a sideways swipe PARKS it at the screen edge as a chevron sliver
   (never gone — tap brings it back). Fades while the closing shell is in
   view. Placement gets dialed per-viewport once it's in the wild.
   ===================================================================== */
.dock{
  position:fixed;right:16px;left:auto;bottom:calc(36px + env(safe-area-inset-bottom));
  z-index:60;color:#fff;
  background:
    linear-gradient(160deg,rgba(125,211,192,.2),rgba(85,193,188,.15) 34%,rgba(0,0,0,0) 60%),
    linear-gradient(135deg,rgba(8,35,56,.72),rgba(12,45,64,.9) 55%,rgba(12,45,64,.85));
  -webkit-backdrop-filter:blur(20px) saturate(140%);
  backdrop-filter:blur(20px) saturate(140%);
  border:0;border-radius:33px;
  box-shadow:0 8px 16px rgba(12,45,64,.4);
  touch-action:pan-y;
  transition:transform .3s var(--ease-out-quart),opacity .3s ease;
}
/* the app's 1px aqua→teal gradient border, masked to a ring */
.dock::before{content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:linear-gradient(135deg,rgba(125,211,192,.3),rgba(85,193,188,.2));
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  mask-composite:exclude;pointer-events:none}
.dock-inner{position:relative}
.dock-bar{display:flex;align-items:center}
.dock-toggle{flex:1;display:flex;align-items:center;gap:10px;width:auto;
  background:none;color:inherit;border:0;border-radius:inherit;
  padding:16px 24px;font-size:17px;font-weight:600;letter-spacing:.3px;
  text-align:left;white-space:nowrap;
  transition:transform .15s var(--ease-out-quart)}
.dock-toggle:hover{background:none}
.dock-toggle:active{transform:scale(.95)}       /* the app's press spring */
.dock-leaf{width:22px;height:22px;flex:none}
/* chevron only exists in the open sheet (collapse affordance); the
   collapsed pill is leaf + label, exactly like the app FAB */
.dock-chev{display:none;margin-left:auto;width:16px;height:16px;
  color:var(--ink-3)}
.dock-chev svg{width:100%;height:100%;display:block}
/* ---- open: the pill becomes the sign-in sheet, centered center-center at
   every viewport (260727). Liquid-glass frost approximates the app sheet:
   translucent white over a blur, top highlight, hairline ring. The scrim
   below gives the frost something to read against on a white page. ---- */
.dock.is-open{left:50%;right:auto;top:50%;bottom:auto;
  transform:translate(-50%,-50%);
  width:min(480px,calc(100vw - 24px));max-height:calc(100vh - 24px);
  overflow-y:auto;color:var(--ink);
  background:
    linear-gradient(180deg,rgba(255,255,255,.6),rgba(255,255,255,0) 42%),
    rgba(255,255,255,.82);
  -webkit-backdrop-filter:saturate(170%) blur(26px);
  backdrop-filter:saturate(170%) blur(26px);
  border-radius:var(--r-card);
  box-shadow:0 24px 60px -20px rgba(2,14,22,.45)}
.dock.is-open::before{background:rgba(12,45,64,.14)}
/* the scrim behind the centered sheet (media.js creates it): dims the page
   so the frost reads, and its tap is the generous close target */
.dock-scrim{position:fixed;inset:0;z-index:55;background:rgba(8,25,38,.3);
  opacity:0;pointer-events:none;transition:opacity .3s ease}
.dock-scrim.is-on{opacity:1;pointer-events:auto}
.dock.is-open .dock-inner{padding:0 18px}
/* 260728: the open sheet matches the conclusion module's proportions
   (Nathan — the header band was reserving its own row, extra air up top).
   The open header loses its title and leaf (the leaf rides the CTA button
   now); the chevron drops down to float on the h2's line, top-right, and
   the sheet's padding mirrors the shell's 20/18/22. The whole chrome
   outside the form still collapses (media.js). Collapsed pill untouched. */
.dock.is-open .dock-bar{position:absolute;top:12px;right:12px;z-index:1}
.dock.is-open .dock-toggle{padding:6px;font-size:0;letter-spacing:0;cursor:pointer}
.dock.is-open .dock-label,.dock.is-open .dock-leaf{display:none}
.dock.is-open .dock-chev{display:inline-flex;width:20px;height:20px;margin-left:0}
.dock-panel{padding:20px 0 22px}
.dock-panel:focus{outline:none}
/* (grab dragline retired 260727; its generous collapse behavior lives on —
   any tap on the sheet's chrome outside the form collapses it, media.js) */
/* the twin CTAs carry the FAB's glass-mesh gradient (260727, extended to
   the conclusion module 260728): same aqua-over-deep-ocean wash, different
   silhouette — the pill visually "lands" on this button */
.dock-panel form button,.shell--glass form button{
  background:
    linear-gradient(160deg,rgba(125,211,192,.28),rgba(85,193,188,.18) 34%,rgba(0,0,0,0) 60%),
    linear-gradient(135deg,#0F3A55,#0C2D40 55%,#0E3550);
  box-shadow:0 6px 18px -6px rgba(12,45,64,.5)}
.dock-panel form button:hover,.shell--glass form button:hover{
  background:
    linear-gradient(160deg,rgba(125,211,192,.34),rgba(85,193,188,.24) 34%,rgba(0,0,0,0) 60%),
    linear-gradient(135deg,#144263,#123B54 55%,#124061)}
/* 260812l AUDITION (Nathan, uncommitted until ruled): the submit CTA flips
   to the FAB's LIGHT liquid glass — same mesh wash + near-white ground as
   html.dark .dock:not(.is-open), label and leaf ink in Deep Sea. Applies to
   every form instance (shells + dock sheet, both pages) per the twin rule.
   In dark mode the shells are dark glass (r58), so this light button reads
   there the same way the light FAB reads on the dark ground — it stays.
   REVERT = delete this whole block; the Deep Sea rules above resume. */
/* 260813a (Nathan): the light button is DARK MODE ONLY — unscoped, it had
   overridden the Deep Sea button in light mode too. Light mode falls back
   to the original button{background:var(--deep-sea)} rules above. */
html.dark .dock-panel form button,html.dark .shell--glass form button{
  color:#0C2D40;
  background:
    linear-gradient(160deg,rgba(125,211,192,.28),rgba(85,193,188,.16) 34%,rgba(255,255,255,0) 60%),
    linear-gradient(135deg,rgba(255,255,255,.9),rgba(236,242,244,.82) 55%,rgba(255,255,255,.86));
  box-shadow:0 6px 18px -6px rgba(12,45,64,.35)}
html.dark .dock-panel form button:hover,html.dark .shell--glass form button:hover{
  background:
    linear-gradient(160deg,rgba(125,211,192,.36),rgba(85,193,188,.22) 34%,rgba(255,255,255,0) 60%),
    linear-gradient(135deg,#ffffff,#e7eef1 55%,#fdfefe)}
/* the whole-leaf glyph is aqua-on-light already, but give the label's ink an
   explicit ride on descendants (the span inherits color; nothing else needed) */
/* END 260812l AUDITION */
.dock-panel h2{color:var(--ink);font-size:clamp(19px,17px + .6vw,22px);
  letter-spacing:-.012em;margin:0 0 5px;max-width:none;font-weight:700}
.dock-panel .shell-sub{margin-bottom:var(--s4)}
.dock-panel form{max-width:none}
.dock-panel .privacy-line{justify-content:center}
/* mid-swipe: the pill tracks the finger with no easing fighting it */
.dock.dock-swiping{transition:none}
/* mid-FLIP (260727): the base transform transition would run UNDER the WAAPI
   morph and fight it at the end — silenced for the animation's duration */
.dock.dock-flip{transition:none}
/* ---- edge-park (Nathan's design): the pill slides right until a rounded
   sliver peeks, chevron pointing back into the page; tap = it returns ---- */
.dock.dock-parked{transform:translateX(calc(100% - 30px));
  border-radius:16px 33px 33px 16px}
.dock.dock-parked .dock-leaf,.dock.dock-parked .dock-label{opacity:0;
  transition:opacity .2s ease}
.dock-park-chev{display:none;position:absolute;left:7px;top:50%;
  width:16px;height:16px;margin-top:-8px;color:#fff;opacity:.9;
  transform:rotate(90deg);pointer-events:none}
.dock-park-chev svg{width:100%;height:100%;display:block}
.dock.dock-parked .dock-park-chev{display:block}
/* while the closing shell is in view the FAB steps aside, returns after */
.dock.dock-away{opacity:0;pointer-events:none}
/* entrance: a slow, quiet fade-up (260727 — was a .35s pop) */
@media(prefers-reduced-motion:no-preference){
  .dock:not([hidden]){animation:dock-in 1.1s var(--ease-out-expo)}
}
@keyframes dock-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* desktop with a real pointer: higher and further in from the corner */
@media(min-width:920px) and (hover:hover) and (pointer:fine){
  .dock{right:40px;bottom:72px}
}

/* =====================================================================
   HOW JADE WORKS — Linear numbering × Ethyca sticky stack (pure CSS).
   Each .stack-card sets --i; wrapper sets --n. Tabs accumulate under the
   topbar; panels scroll beneath. Degrades to a clean labeled stack.
   ===================================================================== */
.stack{--row:64px;--topbar-h:57px}
.stack .tabwrap{
  position:sticky;z-index:1;pointer-events:none;
  top:calc(var(--topbar-h) + var(--i)*var(--row));
  height:calc((var(--n) - var(--i))*var(--row));
}
.stack .tab{
  position:relative;
  height:var(--row);display:flex;align-items:center;gap:var(--s4);
  pointer-events:auto;
  padding:0 var(--s4);
}
/* hairline back (Nathan 260801, refined from the r33 retirement): a thin
   inset line under each title — open state: title / line / body copy with
   even air; stacked end state: the line sits just above the next tab. */
.stack .tab::after{content:"";position:absolute;left:var(--s4);right:var(--s4);
  bottom:0;height:1px;background:var(--line-2)}
/* the tab shells run edge-to-edge at EVERY width (Nathan 260806 — the
   ramp's tint goes full bleed; content stays in the column). Same trick
   as .rule: a 100vw underlay pulled to the viewport edges, wearing the
   row's own tint via background:inherit. (Mobile-only until r65.) */
.stack .tab{isolation:isolate}
.stack .tab::before,.stack .panel::before{content:"";position:absolute;
  top:0;bottom:0;left:50%;width:100vw;margin-left:-50vw;
  background:inherit;z-index:-1}
.tab-num{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  font-size:13px;font-weight:500;color:var(--deep-sea);flex:none;
}
/* r37 (Nathan 260731): first word bold, rest lighter — "Free" pops */
.tab-title{font-size:17px;font-weight:440;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tab-title b{font-weight:700}
/* the "soon" chip: the Launching-soon pill's grammar, sized for a tab row,
   sitting right after the title like a final word */
.tab-chip{
  font-size:10px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  background:var(--deep-sea);color:#fff;border-radius:999px;padding:4px 9px;
  flex:none;margin-left:-6px;line-height:1;
}
/* panel copy rides HIGH in the band (260715): inside the negative space
   below the resting tab's baseline, not vertically centered */
.stack .panel{
  position:sticky;z-index:0;
  top:calc(var(--topbar-h) + var(--i)*var(--row) + var(--row));
  margin-top:calc((var(--n) - 1 - var(--i))*-1*var(--row));
  min-height:clamp(200px,32vh,300px);
  padding:26px var(--s4) var(--s6);
  display:flex;flex-direction:column;justify-content:flex-start;
}
/* tab bar + its panel share a background; the ramp darkens down the stack */
.t0 .tab,.p0{background:#fff}
.t1 .tab,.p1{background:#fafbfb}
.t2 .tab,.p2{background:#f5f7f7}
.t3 .tab,.p3{background:#eef2f3}
.panel p{color:var(--ink-2);max-width:38ch;text-wrap:pretty;
  font-size:clamp(19px,17px + .6vw,24px);line-height:1.45;margin:0}
/* the twizzle: panel copy lands with a small springy settle */
.panel-in{transform:translateY(16px) rotate(.5deg);transform-origin:0 100%;
  transition:opacity .45s ease,transform .8s var(--ease-spring)}
/* the section AFTER a .stack must scroll over it and end the stack */
.stack-end{position:relative;z-index:5;background:#fff}

/* ---- metrics band (attributed grandeur) — funnel shells, 260727:
   rectangular hairline cards (the ≥720 square ruling reversed by Nathan) —
   height is content-driven and the grid equalizes each row, so the four
   stat cells sit at the uniform height cell 01 needs. Structure is
   identical across all five: big stat → little title → subtitle/source. ---- */
.stats{display:grid;grid-template-columns:1fr;gap:14px;margin-top:var(--s7)}
/* r66 (Nathan 260806 refinement of the r65 ledger): hairlines and the
   hover micro-interaction RETIRE — the row is just icon-beside-title
   over body copy. Icons sit LEFT of each title at text scale; copy
   wraps pretty (the no-widows standing rule). 2×2 phones, 4-up ≥920. */
.stats--quad{grid-template-columns:1fr 1fr !important;gap:18px 24px}
.stats--quad .stat{background:transparent;border:0;border-radius:0;
  padding:6px 2px 10px}
html.dark .stats--quad .stat{background:transparent}
.q-head{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.q-icon{width:19px;height:19px;flex:none;color:var(--deep-sea)}
html.dark .q-icon{color:var(--jade)}
/* r67: all four titles hold TWO lines at every width (Nathan: "Add to the
   record" was the lone one-liner in the quadrant). Measured cause: only
   in ~125-155px columns did the three longer titles wrap while the short
   one didn't. A shared measure cap wraps all four the same way at every
   breakpoint, so the body copy below always starts on the same line. */
.stats--quad .stat h3{margin:0;font-size:16px;letter-spacing:-.01em;
  max-width:11.5ch;text-wrap:balance}   /* 11.5ch ≈ 123px: under "Add to the record" (129px), over the longest single word ("certifications") */
.stats--quad .stat-what{text-wrap:pretty;margin-top:2px}
@media(min-width:920px){
  .stats--quad{grid-template-columns:repeat(4,1fr) !important;gap:18px 28px}
}
.stat{border:1px solid var(--line-2);border-radius:var(--r-card);
  background:#fff;padding:22px 22px 18px;
  display:flex;flex-direction:column}
.stat-final{grid-column:1/-1}
.stat-num{
  font-size:var(--fs-stat);line-height:1;letter-spacing:-0.022em;font-weight:650;
  font-variant-numeric:tabular-nums;color:var(--ink);
}
/* secondary type bumped 260729 late (Nathan: up on mobile, a touch less on
   desktop — the ≥920 block dials both back down half a step) */
.stat-what{margin:6px 0 4px;font-size:15px;color:var(--ink-2);max-width:none}
.stat-src{
  margin:auto 0 0;padding-top:10px;
  font-family:var(--font-mono);font-size:12px;letter-spacing:.04em;
  color:var(--ink-4);
}
.stat-src a{color:inherit;text-decoration:none}
.stat-src a:hover{color:var(--ink-2)}
.stat-src .src-url{display:block;margin-top:2px;border-bottom:0}
/* the finale's subtitle line follows the source-line typography exactly —
   including the auto-top margin + padding, so the mono line sits at the
   same depth as the other cells' source lines (260729 consistency pass) */
.stat-final .stat-flip{font-family:var(--font-mono);font-size:12px;
  letter-spacing:.04em;color:var(--ink-4);max-width:none;
  margin:auto 0 0;padding-top:10px}

/* ---- roadmap — DORMANT 260810b (no page carries it; the B2B "Where we're
   headed" placeholder is its natural landing spot) — the lab timeline (260715): one hairline track, station
   dots. Vertical rail on mobile, left→right on desktop. Now = filled +
   breathing; the rest hollow. ---- */
.rmap{position:relative;display:flex;flex-direction:column;gap:var(--s6);padding-left:28px}
.rmap::before{content:"";position:absolute;left:4px;top:8px;bottom:8px;width:1px;background:var(--line)}
.rm-item{position:relative}
.rm-item::before{content:"";position:absolute;left:-28px;top:2px;
  width:9px;height:9px;border-radius:50%;background:#fff;border:1.5px solid var(--deep-sea)}
.rm-now::before{background:var(--deep-sea);
  box-shadow:0 0 0 0 rgba(170,233,202,.5);animation:pill-pulse 2.4s ease-out infinite}
.rm-item .eyebrow{margin-bottom:8px}
.rm-item .eyebrow::before{display:none}
.rm-item .meta{font-size:14px;color:var(--ink-2);max-width:34ch;text-wrap:pretty}

/* ---- FAQ — the Deep Sea band ---- */
.faq-section{background:var(--deep-sea);color:var(--on-deep-sea);
  padding:var(--section-gap) 0}
.faq-section h2{color:#fff}
.faq-section .lede{color:var(--on-deep-sea-dim)}
.faq-section .eyebrow{color:var(--on-deep-sea-dim)}
.faq-section .eyebrow::before{background:#fff}
.faq{border-top:1px solid var(--deep-sea-line)}
.faq details{border-bottom:1px solid var(--deep-sea-line)}
.faq summary{
  list-style:none;cursor:pointer;display:flex;align-items:baseline;gap:var(--s4);
  padding:18px 2px;font-size:16px;font-weight:600;color:#fff;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary .q-num{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  font-size:12px;color:var(--on-deep-sea-dim);flex:none;
}
/* chevron rotates on the wrapping span, never the <svg> (v1 Safari gotcha) */
.faq summary .q-chev{margin-left:auto;flex:none;width:16px;height:16px;display:inline-flex;
  color:var(--on-deep-sea-dim);transition:transform .2s ease;align-self:center}
.faq summary .q-chev svg{width:100%;height:100%;display:block}
.faq details[open] summary .q-chev{transform:rotate(180deg)}
.faq summary:focus-visible{outline:2px solid #fff;outline-offset:2px}
.faq .a{padding:0 2px 20px;max-width:56ch}
.faq .a p{color:var(--on-deep-sea-dim);margin:0 0 10px;font-size:15px;line-height:1.6;text-wrap:pretty}
.faq .a p:last-child{margin-bottom:0}

/* ---- methodology — white-paper two-column ---- */
.method-grid{display:grid;grid-template-columns:1fr;gap:var(--s6)}
.method-head .lede{margin-bottom:0}
/* 260808j (Nathan, supersedes the 260808i accordion pill): the rows PEEK —
   clamped to roughly the first row, a gradient fades them into the page
   ground, and a quiet "Show more" pill sits under the fade. (260809d,
   Nathan: teaser line retired for good — both drafts lasted a round —
   and the first row loses its hairline + top padding, so the lede
   flows straight into the peek.) */
.method-rows-wrap .method-row:first-child{border-top:0;padding-top:2px}
.method-rows-wrap{position:relative;max-height:210px;overflow:hidden;
  transition:max-height .5s var(--ease-out-expo,ease)}
.method-rows-wrap::after{content:"";position:absolute;left:0;right:0;bottom:0;
  height:110px;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,0),var(--method-fade,#fff));
  transition:opacity .3s ease}
.method-body.is-open .method-rows-wrap{max-height:2400px}
.method-body.is-open .method-rows-wrap::after{opacity:0}
/* 260809c (Nathan): label + chevron sit dead center in the pill */
.method-more{display:inline-flex;align-items:center;justify-content:center;gap:9px;margin-top:14px;
  font-size:14px;font-weight:600;color:var(--deep-sea);cursor:pointer;
  background:none;border:1px solid var(--line-2);border-radius:999px;
  padding:11px 18px;font-family:inherit}
.method-more span{flex:none;white-space:nowrap}
.method-more .q-chev svg{width:16px;height:16px;display:block;
  transition:transform .25s ease}
/* 260809e (Nathan): highlighted state = deep-sea FILL — type and chevron
   flip white with it, or the label drowns */
.method-more:hover,.method-more:active{background:var(--deep-sea);
  border-color:var(--deep-sea);color:#fff}
.method-more .mm-hide{display:none}
.method-body.is-open .mm-show{display:none}
.method-body.is-open .mm-hide{display:inline}
.method-body.is-open .method-more .q-chev svg{transform:rotate(180deg)}
.method-rows{display:flex;flex-direction:column}
.method-row{border-top:1px solid var(--line);padding:var(--s4) 2px var(--s5);
  display:flex;gap:var(--s4);align-items:baseline}
.method-row .m-num{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  font-size:12px;color:var(--deep-sea);flex:none;padding-top:2px;
}
.method-row .m-body{margin:0;font-size:15px;color:var(--ink-2);line-height:1.6;
  max-width:52ch;text-wrap:pretty}
.method-row .m-body strong{color:var(--ink);font-weight:600}

/* ---- pricing preview (AUDITION 260715) — funnel Stage-04 columns ----
   DORMANT 260810b: off-page since the B2B rework; kept — the pricing
   experiment (docs/pricing-experiment-260809.md) is plan of record. */
.price-cols{display:grid;grid-template-columns:1fr;gap:14px;margin:var(--s6) 0 4px}
.price-col{border:1px solid var(--line-2);border-radius:16px;padding:20px;background:#fff}
.price-col--paid{border-color:var(--deep-sea)}
.price-k{font-family:var(--font-mono);font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.1em;color:var(--ink-4);margin:0}
.price-col--paid .price-k{color:var(--deep-sea)}
.price-t{font-size:18px;font-weight:650;color:var(--ink);letter-spacing:-.01em;margin:4px 0 2px}
.price-p{font-size:13px;color:var(--ink-3);margin:0 0 12px}
.feat{display:flex;gap:9px;padding:8px 0;font-size:14px;line-height:1.45;color:var(--ink-2)}
.feat+.feat{border-top:1px solid var(--line-2)}
.feat-check{width:15px;height:15px;flex:none;margin-top:3px;color:var(--deep-sea)}
.plaque{background:var(--fill);border-radius:12px;padding:14px 16px;
  font-size:13px;line-height:1.55;color:var(--ink-3);margin:14px 0 0}
.plaque strong{color:var(--ink-2);font-weight:600}

/* ---- founder's note — illuminated-manuscript PFP + LinkedIn sign-off.
   The block centers on the screen (260715); the eyebrow stays on the page
   grid like every other section. Signature outranks the LinkedIn link,
   which shrinks to a near-Easter-egg. ---- */
/* 260814c (Nathan): 52ch→54ch — the block read pushed-left with an airy
   right edge. At 54 the lead paragraph's breaks are unchanged (56 turned
   its rag into a staircase) while the lower paragraphs fill the measure. */
.founder{max-width:54ch;margin-left:auto;margin-right:auto}
/* body scale, not lede (260727 — Nathan: the message read too large).
   260808g (Nathan): desktop earns 2px back. */
.founder p{font-size:inherit;line-height:1.55;color:var(--ink-2);text-wrap:pretty}
@media(min-width:920px){.founder p{font-size:18px}}
/* circle text-wrap retired (Nathan 260801 — too much fanfare).
   260809i (Nathan): float retired too — the PFP and paragraph one share
   a flex row, portrait CENTERED on the paragraph's height however many
   lines it runs. */
.founder-lead{margin-bottom:14px}
.founder-lead::after{content:"";display:block;clear:both}
.founder-lead p{margin:0}
/* 260814c (Nathan): mobile splits from desktop. The flex row shortened ALL
   nine phone lines against the PFP — too much grandiosity on the portrait.
   Mobile floats it instead, with vertical margins sizing the float box to
   FIVE lines, defined in lh units so it holds through copy or metric
   changes (260814f, Nathan: the px-budgeted box straddled a line-height
   rounding boundary — his iOS wrapped 5 lines against a 4-line box, so
   the PFP sat high). Float box = 5lh - 4px (the -2px per margin keeps
   the boundary line from coin-flipping on renderer rounding); PFP
   centered in it by symmetric margins. .founder-lead carries the same
   type metrics as .founder p ONLY so the img's lh unit resolves to the
   paragraph's line-height — keep them in sync (see the serif EXPERIMENT
   block). Desktop keeps the 260809i centered flex row. */
.founder-pfp{float:left;margin:34.4px 20px 34.4px 0;
  margin-top:calc((5lh - 76px)/2 - 2px);
  margin-bottom:calc((5lh - 76px)/2 - 2px)}
@media(min-width:920px){
  .founder-lead{display:flex;align-items:center;gap:20px}
  .founder-pfp{float:none;margin:0}
}
/* 260813 (Nathan): 96→76 — quieter portrait, confidence-through-restraint
   (big-logo energy in reverse); still clearly a face at arm's length */
.founder-pfp{flex:none;width:76px;height:76px;border-radius:50%;
  background:var(--fill-2);border:1px solid var(--line-2);
  object-fit:cover}
/* quiet footnotes: the fire-sentence sources read as marginalia, not homework.
   260729: no longer superscript-high — optically centered on the line
   (vertical-align:middle plus a 2px lift; the pure programmatic center sat
   low to the eye), one shade lighter than --ink-4 (Nathan's calls). */
.founder sup.cite{font-size:10.5px;line-height:0;margin-left:2px;
  vertical-align:middle;position:relative;top:-2px}
.founder sup.cite a{color:#9e9e9e;text-decoration:none;font-weight:600;
  font-family:var(--font-mono);padding:1px}   /* 260810b: --mono never existed; the fallback was carrying it */
.founder sup.cite a:hover{color:var(--ink);text-decoration:underline}
.founder .sign{font-size:16px;color:var(--ink-2);margin-top:var(--s5);clear:left}
.founder .sign strong{color:var(--ink);font-weight:650}
/* (260812b: the signature's LinkedIn badge retired — an outbound link at
   the conversion moment. Rules removed with it; company LinkedIn stays in
   the footer. The optical-centering note lives in git before 260812b.) */

/* ---- commitments: secret toggle (kept mechanism — rotate .chev, not the svg)
   DORMANT 260810b: removed from the pages 260805 (no badges earned yet);
   returns specific at launch if they're real. media.js §3 stays wired. ---- */
.commitments{display:flex;flex-wrap:wrap;gap:14px;align-items:stretch;margin-top:0}
.commit-logo{
  flex:1 1 160px;min-height:72px;
  display:flex;align-items:center;justify-content:center;text-align:center;
  background:#fff;border:1px solid var(--line);border-radius:10px;
  padding:16px;color:var(--ink-2);font-size:13px;font-weight:600;line-height:1.3;
}
.commit-section{position:relative;padding:0}
.commit-toggle{
  position:absolute;top:0;left:50%;transform:translate(-50%,-50%);z-index:1;
  display:inline-flex;align-items:center;justify-content:center;
  background:#fff;border:0;padding:6px 16px;cursor:pointer;color:var(--ink-3);width:auto;
}
.commit-toggle:hover{background:#fff;color:var(--ink)}
.commit-toggle .chev{display:inline-flex;width:16px;height:16px;transition:transform .2s ease}
.commit-toggle .chev svg{width:100%;height:100%;display:block}
.commit-toggle[aria-expanded="true"] .chev{transform:rotate(180deg)}
.commit-toggle:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:6px}
.commit-section .commit-body{padding:var(--s7) 0}
.commit-body[hidden]{display:none}
.commitments--sm{gap:10px}
.commitments--sm .commit-logo{flex-basis:130px;min-height:56px;font-size:12px;padding:12px}

/* ---- top bar (kept mechanism: liquid-glass sticky) ---- */
.topbar{
  position:sticky;top:0;z-index:50;
  border-bottom:1px solid var(--line);
  background:rgba(255,255,255,0.85);
  -webkit-backdrop-filter:saturate(180%) blur(18px);
  backdrop-filter:saturate(180%) blur(18px);
}
.topbar-inner{display:flex;align-items:center;justify-content:space-between;
  max-width:var(--maxw);margin:0 auto;padding:14px var(--gutter)}
/* article-page topbar nav cluster (260810b: promoted from the inline style
   the four sub-pages each carried — one rule, four pages) */
.topnav{display:flex;align-items:center;gap:18px}
a.nav{font-size:14px;font-weight:600;color:var(--ink);text-decoration:none;
  border-bottom:1.5px solid var(--ink);transition:opacity var(--dur-micro) ease;
  white-space:nowrap}
a.nav:hover{opacity:.55}
.nav.nav--current{color:var(--ink-3);border-bottom-color:transparent;cursor:default}

/* ---- closing CTA ---- */
.closing h2{font-size:clamp(26px,20px + 1.6vw,34px);line-height:1.12;letter-spacing:-0.022em}

/* the FAQ backdoor: quiet row under the list. r37 (Nathan 260731):
   left-justified, and "Add it" flips solid — white fill, black type */
.faq-more{display:flex;align-items:center;justify-content:flex-start;gap:12px;
  margin-top:var(--s6);font-size:14px;color:var(--on-deep-sea-dim)}
.faq-add{font-size:13px;font-weight:600;color:#111;text-decoration:none;
  background:#fff;border:1px solid #fff;border-radius:999px;padding:7px 16px;
  transition:background var(--dur-micro) ease,border-color var(--dur-micro) ease}
.faq-add:hover{background:rgba(255,255,255,.85);border-color:rgba(255,255,255,.85)}

/* ---- FAQ answer links — inherit the dim ink, stay legible on the
   Deep Sea band ---- */
.faq .a a{color:inherit;text-decoration:underline;text-underline-offset:2px}

/* ---- starter strip (r60, B2B): the reassurance card between the pitch and
   the free-claim quadrant. Quadrant grammar (hairline stroke, no fill); the
   button hands off to #signup-end. Bottom padding drops — the gap below is
   the next section's top air. ---- */
/* 260808i (Nathan): the hairline above is gone and the strip's own top
   air with it — the stack section's bottom gap is the whole separation */
/* 260814a (Nathan): airy top — the strip breathes below the Deep Sea band,
   an exhale for owners the Year One ask might intimidate (retires the
   260808i zero-top tightening). */
/* 260815c (Nathan, mobile): that exhale RETIRED with the band it answered.
   It only ever stood in for absent padding — #why-list ran padding-bottom:0
   under Year One — so once the pull restored #why-list's normal bottom gap,
   the strip's own top padding stacked on top of it and the air above the card
   came out double the air below. The strip now contributes nothing of its own
   at either end: above = #why-list's bottom padding, below = the next
   section's top padding, and the two match. */
.starter-strip{padding-top:0;padding-bottom:0}
/* 260814c (Nathan): desktop trims the strip's air 20% above and below
   (below = the next section's top padding) — still isolated, less airy.
   260815c: the 20% trim now has to be spent on #why-list's bottom padding,
   since that (not the strip) is what makes the air above. Both sides .8. */
@media(min-width:920px){
  #why-list{padding-bottom:calc(var(--section-gap)*.8)}
  .starter-strip+section{padding-top:calc(var(--section-gap)*.8)}
}
.starter-card{display:flex;align-items:center;justify-content:space-between;
  flex-wrap:wrap;gap:14px 24px;border:1px solid var(--line-2);
  border-radius:var(--r-card);padding:22px 24px}
.starter-copy h2{font-size:20px;letter-spacing:-0.014em;margin:0}
.starter-copy p{margin:5px 0 0;font-size:14px;line-height:1.5;color:var(--ink-3)}
.starter-btn{flex:none;font-size:14px;font-weight:600;color:#fff;
  text-decoration:none;background:var(--deep-sea);border-radius:999px;
  padding:11px 20px;transition:opacity var(--dur-micro) ease}
.starter-btn:hover{opacity:.85}
/* dark mode (Nathan 260806): the strip INVERTS to dark liquid glass —
   the closing shells' frost recipe on the hairline-card geometry, so it
   still reads as the same object luma-flipped. Button stays the r45
   light-flip: white pill on the dark ground, unmissable. */
html.dark .starter-card{border-color:rgba(255,255,255,.16);
  background:
    linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 42%),
    rgba(9,20,26,.55);
  -webkit-backdrop-filter:saturate(160%) blur(20px);
  backdrop-filter:saturate(160%) blur(20px)}
html.dark .starter-btn{background:#fff;color:#111}
/* the in-page hop the starter button makes */
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}

/* ---- long-form article pages (about, privacy-policy, terms) ----
   Prose holds the readable measure at every width (the ≥920 .wrap widening is
   outranked by the higher-specificity selector); footer .wrap stays wide.
   The big section-gap rhythm is swapped for plain prose spacing. */
.article section .wrap{max-width:var(--maxw)}
.article section{padding:40px 0 0}
.article section:first-of-type{padding-top:48px}
.article section:last-of-type{padding-bottom:var(--section-gap)}
.article h1{font-size:clamp(32px,26px + 2vw,44px);margin-bottom:14px}
.article p{color:var(--ink-2);line-height:1.65;text-wrap:pretty}
.article .lede{margin-bottom:0;
  /* 260905e (Nathan, from his iPhone): text-wrap:pretty OFF for the About
     lede. Safari's pretty optimizes the WHOLE paragraph (Chrome's only the
     last few lines, which is all the 260815d measurements ever saw): it
     evened lines 2-8 at a narrower width and left line 1 hanging out with
     an "It pairs" stub under it. Plain greedy wrapping reads as prose; the
     and&nbsp;business tie still guards the last line. */
  text-wrap:auto}
.article p a{color:inherit;text-decoration:underline;text-underline-offset:2px}
/* 260809i (Nathan): the About lede's waitlist links carry a subtle extra
   weight — a little something, not a shout. The questions line stands as
   its own thought with a breath above it. */
.article .lede a{font-weight:550}
.about-cta{margin-top:18px}
.article ul{margin:0 0 14px;padding-left:20px;color:var(--ink-2)}
.article li{margin:0 0 10px;line-height:1.6}
/* 260812a: the privacy page's standing commitment — framed in the site's
   hairline card grammar (funnel-frame stroke), not a highlight fill.
   Structure, not a shout. */
.pp-commitment{border:1px solid var(--line-2);border-radius:6px;
  padding:14px 16px;margin-bottom:1em}
.article li b{color:var(--ink)}

/* ---- footer — 260808b: rebuilt on Linear's measured grammar (Nathan's
   pick after a footer audit): labeled left-aligned columns, ink labels
   over MUTED links (the labels do the wayfinding), ~21px row pitch,
   24px label-to-list air, generous top padding. Mobile = 2-up column
   grid (Linear's own phone behavior), brand + © spanning the top row.
   Supersedes the r66 centered cluster. ---- */
footer{padding:56px 0 48px;color:var(--ink-3);font-size:13px;border-top:1px solid var(--line)}
/* 260808c (Nathan): THREE columns at every width — brand + tiny © | the
   Company/Fine-print stack | Connect.
   260808e (Nathan): the lockup CENTERS in its track (logo clearspace —
   equal air both sides, more on desktop where the track is wider); every
   gap in the footer equalizes to 28px; and the grid baseline-aligns, so
   the row-one labels sit on the word Jade's baseline. */
/* 260808g (Nathan, audition): mark-only brand — the word hides, the leaf
   shrinks a notch and TOP-aligns with the column labels (baseline
   alignment and its lockup nudges retire with the wordmark). */
.foot-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:28px;
  align-items:start}
/* col 2's two stacked groups, same 28px air as every other footer gap */
.foot-col{display:flex;flex-direction:column;gap:28px}
/* 260808f (Nathan): >=720 the middle stack dissolves into the grid
   (display:contents) — FOUR columns, Fine print last, brand still 1.5fr */
@media(min-width:720px){
  .foot-grid{grid-template-columns:1.5fr 1fr 1fr 1fr}
  .foot-col{display:contents}
}
.foot-cell{display:flex;flex-direction:column;gap:2px;align-items:flex-start;
  line-height:19.5px}
/* label in ink, links muted — 24px of air before the list (Linear's gap) */
.foot-label{color:var(--ink);font-weight:600;margin-bottom:14px}
/* brand cell: the leaf mark alone (© retired 260808f, wordmark hidden
   260808g), centered in its track so the mark keeps equal clearspace.
   Restore the word by deleting the display:none + the 28px override. */
.foot-brand{justify-self:center}
.foot-brand .brand{--logo-leaf:28px}
.foot-brand .brand-word{display:none}
/* the footer lockup (260729 final pass): the full brand pair at the pinned
   topbar's exact size (.brand supplies --logo-leaf/-word + gap), leaf in
   solid deep sea. The mask reads jade-leaf-SOLID.svg — same mark with
   stroked backer paths under the shared edges, killing the antialias
   hairline the two ascender sub-shapes left in the plain-svg mask. */
.foot-leaf{width:calc(var(--logo-leaf)*33/38.01);height:var(--logo-leaf);
  display:block;background:var(--deep-sea);
  -webkit-mask:url(assets/jade-leaf-solid.svg) no-repeat center/contain;
  mask:url(assets/jade-leaf-solid.svg) no-repeat center/contain}
footer .brand-word{color:var(--deep-sea)}
/* links stay quiet; hover brightens to ink, no underline (Linear grammar) */
.foot-cell a{color:inherit;text-decoration:none;transition:color .15s ease}
.foot-cell a:hover{color:var(--ink)}

/* ====================================================================
   PROGRAMMATIC JADE LOGO — single source of truth (mechanism kept from v1).
   Change --logo-leaf / --logo-word once; both topbars + both footers move.
   "Jade" optically centered on the leaf's horizon line (the 1px nudge).
   ==================================================================== */
/* the logo is a link home on every page (Nathan 260802) */
a.brand{text-decoration:none;color:inherit}
a.brand:hover{opacity:.85}
.brand{
  --logo-leaf:34px;
  --logo-word:28px;
  display:inline-flex;align-items:center;gap:8px;
}
.brand-leaf{height:var(--logo-leaf);width:auto;display:block}
.brand-word{
  font-family:inherit;
  font-size:var(--logo-word);font-weight:900;letter-spacing:-0.02em;
  color:var(--ink);line-height:1;text-transform:none;position:relative;top:1px;
}
.brand-suffix{font-weight:400;letter-spacing:-0.01em}
.closing-cross{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;
  margin-top:22px;font-size:13px;color:var(--ink-3)}

/* ---- narrow phones: tighter stack rows + compact brand lockup ---- */
@media(max-width:639px){
  .stack{--row:52px}
  .tab-title{font-size:15px}
  .tab-num{font-size:12px}
  /* footer lockup tracks the topbar's compact brand exactly (260729) */
  .topbar .brand,footer .brand{--logo-leaf:26px;--logo-word:21px;gap:6px}
  /* forms span the wrap so left and right gutters match */
  form{max-width:none}
  .cta-block form{max-width:none}
}

/* ---- TABLET (≥720) ---- */
@media(min-width:720px){
  .stats{grid-template-columns:1fr 1fr}
  .price-cols{grid-template-columns:1fr 1fr}
}

/* =====================================================================
   DESKTOP (≥920) — same grammar, wider frame. The hero goes two-column
   (receipt right of the ATF cluster); the metrics HOLD the 2×2 quadrant.
   ===================================================================== */
@media(min-width:920px){
  .wrap,.topbar-inner{max-width:var(--maxw-wide)}
  /* 260812e (Nathan): the cluster settles back down a step — 260812d cut the
     headroom too hard. Still under the pre-mega-type value, so the carousel
     keeps its peek at the fold. */
  .hero-section{padding-top:clamp(72px,9vh,120px)}
  /* the air beneath the ATF cluster, halved (260727): §01 peeks at the fold */
  .hero-section{padding-bottom:clamp(12px,2vh,28px)}
  .tw-section{padding-top:clamp(48px,28px + 4vw,80px)}
  /* desktop flank AUDITION (Nathan 260729 evening): body copy rides right of
     the word, bottom-aligned with the tagline, which stays under the word.
     Mobile keeps the pure stack. */
  .tw-row{display:grid;grid-template-columns:1fr 360px;column-gap:56px;
    align-items:end}
  .tw-row .tw-word{grid-column:1}
  .tw-row .tw-tag{grid-column:1;margin-top:12px}
  .tw-row .tw-sub{grid-column:2;grid-row:1/3;align-self:end;margin:0 0 .2em}
  body{font-size:17px}
  .stack{--row:64px}
  /* evidence, desktop (260727 Nathan's grid): three equal cells on row one;
     row two = the fourth cell + the ZERO finale at double width, so the
     payoff sits inside the grid instead of floating under it */
  .stats{gap:16px;grid-template-columns:repeat(3,1fr)}
  .stat-final{grid-column:2/-1}
  /* the secondary-type bump lands softer on the wide frame */
  .stat-what{font-size:14px}
  .stat-src,.stat-final .stat-flip{font-size:11.5px}
  .sub-br{display:inline}

  /* 260812c (Nathan, approved): MEGA-TYPE ATF, replacing the two-column era
     that ended with the receipt. The headline takes the WHOLE frame at
     display scale; beneath it one row shares that width — the leaf toy holds
     the left (it is the visual echo of "trust the rating", so it stays under
     the headline) and the subhead sits beside it, the two bottom-aligned on
     a single baseline. Air falls to the right of the sub, framed by the
     headline's full-width block above, so it reads as composition rather
     than a leftover column.
     ANTI-SNAP: the clamp starts at 52px — the exact tablet value — so
     dragging the window across 920 scales the headline continuously.
     Alignment stays left at every width, so nothing re-flows on collapse. */
  /* 260812d (Nathan): the side-by-side row is out — leaf toy and subhead stay
     STACKED under the headline exactly as they do on phones, so the only
     thing that changes across breakpoints is the headline's size. The width
     is spent on the headline alone; the air below-right is framed by it.
     SCOPE: .hero-copy, the consumer hero only. for-business.html also carries
     a bare .hero, which keeps the 760px measure below and must not inherit
     the mega type. The doubled class (.hero.hero-copy) outranks .hero
     outright, so reordering this file can't flip the two. */
  .hero{max-width:760px}
  .hero-grid{display:flex;flex-direction:column;gap:var(--s7)}
  .hero.hero-copy{max-width:none;width:100%}
  .hero-copy h1{max-width:none;
    font-size:clamp(52px,2.5px + 5.38vw,80px);
    line-height:1.03;letter-spacing:-0.032em;margin-bottom:var(--s5)}
  /* 260812c (Nathan): the sub grows a step to hold its own under the mega
     headline. The 38ch measure comes OFF so the manual .sub-br breaks decide
     the line ends — with them in place nothing reaches a natural wrap. */
  .hero-copy .sub{max-width:none;font-size:clamp(20px,14px + .65vw,24px)}
  .hero-media{margin-top:0;min-width:0}
  /* 260809f (Nathan): the desktop track UNMASKS — full-bleed both ways
     (same 50%-50vw escape as .rule).
     260812e (Nathan): the four phones now CENTER in that full-bleed track
     instead of starting at the wrap's left edge. `safe` is what makes this
     safe: the moment the row is wider than the window, centring would push
     the first phone off the left edge and out of scroll reach, so the
     keyword drops the alignment back to flex-start and the row pins left
     and runs off the right exactly as it does today. Browsers without
     `safe` ignore the whole value and land on that same flex-start. */
  /* 260820a: `safe center` is OUT — Safari parses it but centers anyway,
     so an overflowing row hung off BOTH window edges: the left phone
     amputated and unreachable (overflow left of a scroll container cannot
     be scrolled to), the right cut reading as a premature mask. The auto
     margins below are the engine-proof spelling of the same intent: free
     space → they split it and the row centers; overflow → they collapse
     to zero and the row pins left, scrolling off the right edge. */
  .hero-media .appcar{margin:0 calc(50% - 50vw);
    padding:18px 24px 16px}
  .hero-media .car-item:first-child{margin-left:auto}
  .hero-media .car-item:last-child{margin-right:auto}
  /* 260820a (Nathan): the rail must never END inside the window — on wide
     frames the four phones fit, center, and die as a static graphic. The
     phones now grow with the viewport so the last one always breaks the
     right edge DECISIVELY (overhang = 6vw + 18px, ~100px at 1440 — a 25vw
     curve left a 10px kiss that read as no overhang at all). The 430px cap
     is the height budget: a wider phone would outgrow a laptop fold. Cap
     math: bleed holds through ~1810px windows; wider than that the row
     fits and centers as a complete shelf — 1920 landscape physically can't
     bleed without a fold-breaking phone, so the shelf is the ruling there
     until a fifth screen joins the rail. */
  .car-item{width:clamp(264px,26.5vw - 18px,430px)}
  /* (260809g: the 260808g-09f ATF band-card era ends — #signup-top is a
     standard full-bleed photo band below the hero again, no overrides.) */

  /* roadmap: time reads left→right on the one hairline track */
  .rmap{flex-direction:row;gap:var(--s5);padding-left:0;padding-top:28px}
  .rmap::before{left:4px;right:4px;top:4px;bottom:auto;width:auto;height:1px}
  .rm-item{flex:1}
  .rm-item::before{left:0;top:-28px}

  /* methodology: white-paper two-column — heading left, sourced rows right */
  .method-grid{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:var(--s8)}

  /* metrics + stack headers share Linear's header grid: h2 left, lede right */
  .sec-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    gap:var(--s6);align-items:start;margin-bottom:var(--s7)}
  .sec-head h2{margin-bottom:0}
  .sec-head .lede{margin-bottom:0;justify-self:start}

  /* footer (r66): the desktop 4-col grid retires — three cells in four
     columns left an empty track that shoved the cluster left. The
     centered flex cluster above now rules every width. */

  /* closing CTA centered at a readable measure */
  .closing{max-width:700px;margin-left:auto;margin-right:auto;text-align:center}
  .closing form{margin-left:auto;margin-right:auto;align-items:center}
  .closing .sub{margin-left:auto;margin-right:auto}
}
@media(max-width:919px){
  .sec-head .lede{margin-bottom:0}
  .sec-head{margin-bottom:var(--s6)}
}

/* =====================================================================
   DARK MODE (r37, Nathan 260731) — auto only, no toggle. The head script
   stamps html.dark when the OS prefers dark OR the local clock reads
   7pm-7am. Deep Sea becomes the ground, type flips white, phone bezels
   LIGHTEN (a dark bezel would melt into the ground), and the app captures
   + live dossier stay light — they're the product, not the chrome.
   ===================================================================== */
/* r45 (Nathan 260801): the ground goes TRUE dark — Apple's dark-mode
   neutrals (#000 system background, #1C1C1E elevated) — while the
   deliberate Deep Sea chapters (tab ramp, FAQ band) keep their color. */
html.dark{background:#000}
html.dark body{background:#000;color:var(--ink)}
html.dark{
  --ink:#f4f7f8;
  --ink-2:rgba(244,247,248,.78);
  --ink-3:rgba(244,247,248,.6);
  --ink-4:rgba(244,247,248,.45);
  --line:rgba(255,255,255,.18);
  --line-2:rgba(255,255,255,.13);
  --fill:rgba(255,255,255,.05);
  --fill-2:rgba(255,255,255,.08);
}
/* topbar: same liquid glass, deep-sea tinted */
html.dark .topbar{background:rgba(18,18,20,.8);border-bottom-color:var(--line-2)}
/* the pill can't be deep-sea-on-deep-sea */
html.dark .pill{background:rgba(255,255,255,.12)}
html.dark .eyebrow::before{background:var(--jade)}
/* phone bezels lighten (Nathan's call) — the captures inside stay light */
html.dark .phone{background:#34393d;   /* 260812n (Nathan): charcoal — the
   bezel should register against the black ground without popping; the
   light silver (#9fabb4) read too loud in dark mode */
  box-shadow:0 24px 48px -20px rgba(0,0,0,.55),0 4px 12px -6px rgba(0,0,0,.35)}
/* cards + bands that hard-code white grounds */
html.dark .stat,html.dark .price-col,html.dark .commit-logo{background:#1C1C1E}
html.dark .stack-end{background:#000}
/* the tab ramp inverts: it BRIGHTENS down the stack instead of darkening */
/* r57 (Nathan): the dark ramp mirrors the light one by FORMULA, not by
   deep-sea shades. Light mode = white with a growing whisper of jade
   (#fff -> #eef2f3 is ~a 5% jade-tinted pull). Dark mode = black with
   the same growing whisper: jade #5BBEAD composited over #000 at
   0 / 5 / 9 / 13% alpha, precomputed to opaque hexes (sticky tabs must
   stay opaque as panels scroll beneath). */
html.dark .t0 .tab,html.dark .p0{background:#000}
html.dark .t1 .tab,html.dark .p1{background:#030605}
html.dark .t2 .tab,html.dark .p2{background:#050a09}
html.dark .t3 .tab,html.dark .p3{background:#070f0e}
/* FAQ band: one shade below the ground so the chapter still reads */
html.dark .faq-section{background:#092231}
/* r58 (Nathan): the signup shells go DARK liquid glass in dark mode —
   deep frost over the band photo, light ink, jade focus. The open dock
   sheet is their twin and matches. */
html.dark .shell,html.dark .dock.is-open{
  --ink:#f4f7f8;--ink-2:rgba(244,247,248,.8);--ink-3:rgba(244,247,248,.62);
  --ink-4:rgba(244,247,248,.45);--line:rgba(255,255,255,.24);
  --line-2:rgba(255,255,255,.15)}
html.dark .shell--glass{
  background:
    linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 42%),
    rgba(9,20,26,.64)}
html.dark .shell--glass::before{background:rgba(255,255,255,.18)}
html.dark .dock.is-open{
  background:
    linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 42%),
    rgba(9,20,26,.74)}
html.dark .dock.is-open::before{background:rgba(255,255,255,.18)}
html.dark .shell input,html.dark .dock.is-open input{
  background:rgba(255,255,255,.09);color:#f4f7f8;
  border-color:rgba(255,255,255,.22)}
html.dark .shell input::placeholder,html.dark .dock.is-open input::placeholder{
  color:rgba(244,247,248,.42)}
html.dark .shell input:focus,html.dark .dock.is-open input:focus{
  outline-color:var(--jade);border-color:var(--jade)}
/* the FAB flips to LIGHT liquid glass on the dark ground (Nathan 260801):
   same silhouette, press spring, mesh wash, hairline ring and blur —
   luma inverted, label in Deep Sea. Open sheet keeps its light skin. */
html.dark .dock:not(.is-open){
  color:#0C2D40;
  background:
    linear-gradient(160deg,rgba(125,211,192,.28),rgba(85,193,188,.16) 34%,rgba(255,255,255,0) 60%),
    linear-gradient(135deg,rgba(255,255,255,.9),rgba(236,242,244,.82) 55%,rgba(255,255,255,.86));
  box-shadow:0 8px 20px rgba(0,0,0,.55)}
html.dark .dock:not(.is-open)::before{
  background:linear-gradient(135deg,rgba(12,45,64,.22),rgba(85,193,188,.35))}
html.dark .dock:not(.is-open) .dock-park-chev{color:#0C2D40}
/* (260816b: the walker sticker's dark-mode flip left with the sticker.) */
/* methodology fold: same flip — deep-sea text drowns on dark, and the
   fade must dissolve into the true-dark ground, not white */
html.dark .method-more{color:#fff}
html.dark .method-more:hover,html.dark .method-more:active{
  background:#fff;border-color:#fff;color:var(--deep-sea)}
html.dark .method-rows-wrap::after{
  background:linear-gradient(180deg,rgba(0,0,0,0),#000)}
/* footer lockup: the deep-sea leaf + word flip white */
html.dark .foot-leaf{background:#fff}
html.dark footer .brand-word{color:#fff}
html.dark footer{border-top-color:var(--line-2)}
/* founder cites were a fixed light-gray hex */
html.dark .founder sup.cite a{color:rgba(244,247,248,.5)}
/* commit-toggle sits on the ground it patches over */
html.dark .commit-toggle,html.dark .commit-toggle:hover{background:#000}
/* article pages inherit the tokens; links/borders already var-driven */

/* ---- reduced motion: kill everything ---- */
@media(prefers-reduced-motion:reduce){
  .pill-dot{animation:none}
  .reveal{opacity:1;transform:none;transition:none}
  .hero-media .appcar{transform:none;transition:none}
  .signup-band--photo .shell.reveal{transition:none;transition-delay:0s}
  .panel-in{transform:none;transition:none}
  .rm-now::before{animation:none}
  .dock{transition:none}
  *{transition-duration:.01ms !important}
}

/* ---- terms assent note (260813, Nathan): one centered run with the
   privacy sentence — "Your privacy is respected. By joining, you agree
   to the terms." — wrapping as a unit when the row is tight. A pinch
   smaller (12→11px, Nathan: the long run read dominant), and the
   underline retreats to just "privacy"/"terms" so the line reads calm
   while the click affordance stays visible — whole sentences remain
   the tap targets. ---- */
.privacy-line{flex-wrap:wrap;justify-content:center;font-size:11px}
.privacy-line a{text-decoration:none}
/* 260905f (Nathan): the two-line legalese cluster sat a touch too close
   under the CTA — a few px more air, every form instance, both pages */
.shell .privacy-line,.dock-panel .privacy-line{margin-top:8px}
.privacy-line a .pl-u{text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:1px;
  text-decoration-color:rgba(107,114,128,.45)}

/* ==== EXPERIMENT 260813 (Nathan) — founder's message in a humanist
   bookish serif (ref: Weighty Thoughts screenshot — Lora-adjacent).
   Iowan Old Style is the closest resident face on his iOS/macOS review
   devices; Palatino/Georgia carry other platforms. REVERT = delete this
   block; nothing else was touched. Risk he named: typography soup vs
   the science-lab register everywhere else. ==== */
.founder p{font-family:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  font-size:17.5px;line-height:1.7;letter-spacing:.002em}
/* .founder-lead mirrors the p metrics so the PFP's lh-unit float margins
   (mobile wrap window) resolve to the paragraph's real line-height. */
.founder-lead{font-size:17.5px;line-height:1.7}
@media(min-width:920px){.founder p{font-size:19px}}
.founder .sign{font-family:var(--font-sans)}  /* signature stays lab-coat */
/* ==== /EXPERIMENT ==== */

/* ==== YEAR ONE band PULLED 260815a (Nathan): held for a future campaign.
   The whole block — .yearone gradient ground, h2, -body, -badge hairlines —
   plus the `#why-list{padding-bottom:0}` override that clustered the Deep Sea
   band under the tab stack, is intact at 7877d41 and comes back together.
   #why-list keeps its normal section padding-bottom while the band is out.
   260815c: restoring the band ALSO means undoing the starter-strip spacing
   fix in the starter-strip block above — that band's return puts a section
   between #why-list and the strip again, so the strip needs its own top air
   back (`padding-top:var(--section-gap)`, .8 on desktop) and #why-list's
   desktop `padding-bottom:calc(var(--section-gap)*.8)` has to go. ==== */

/* =====================================================================
   DAY-0 SIGNUP PLUMBING (260817) — honeypot, thank-you modal, cookie
   consent toast. Modal + toast adapted from comps/thank-you.html and
   comps/cookie-toast.html (260810 comps) onto the site's tokens; the
   liquid-glass recipe matches the dock/shell family.
   ===================================================================== */

/* honeypot: parked far off-canvas, never display:none (some bots skip
   fields the layout engine dropped entirely) */
.hp-field{position:absolute !important;left:-9999px;width:1px;height:1px;
  opacity:0;pointer-events:none}

/* ---- thank-you modal ---- */
.ty-scrim{position:fixed;inset:0;z-index:80;background:rgba(8,25,38,.3);
  opacity:0;pointer-events:none;transition:opacity .3s ease}
.ty-scrim.is-on{opacity:1;pointer-events:auto}
.ty-modal{position:fixed;left:50%;top:50%;z-index:85;
  width:min(480px,calc(100vw - 24px));
  transform:translate(-50%,-50%);
  /* 260830m (Nathan): the glass is now the signup card's EXACT recipe
     (.55 gradient over .7 white, blur 32, saturate 180) instead of the
     modal's old denser .82/26 frost, so the photo reacts through the
     thank-you exactly as it did through the card it replaced. Safe only
     because of the brightness term below; see 260830l. */
  background:linear-gradient(180deg,rgba(255,255,255,.55),rgba(255,255,255,0) 42%),rgba(255,255,255,.7);
  /* 260830l (Nathan): the scrim sits UNDER this glass, so the blur was
     drinking an already-darkened photo and the whole modal took a grey
     veil. brightness(1.43) is the exact inverse of the scrim's 0.7
     multiply, so inside the glass only, the backdrop reads undimmed and
     the modal keeps the signup card's pop; the page around it still dims.
     The ghost carries the same chain; dark mode inverts its own .5 scrim. */
  -webkit-backdrop-filter:saturate(180%) blur(32px) brightness(1.43);
  backdrop-filter:saturate(180%) blur(32px) brightness(1.43);
  border-radius:20px;
  box-shadow:0 24px 60px -20px rgba(2,14,22,.45);
  /* 260817 (Nathan): more air — the box breathes like the shell it follows */
  padding:44px 26px 30px;text-align:center}
.ty-modal::before{content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:rgba(12,45,64,.14);
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  mask-composite:exclude;pointer-events:none}
.ty-modal[hidden]{display:none}
/* 260830m (Nathan saw a white flash): while the ghost is mid-morph, the
   modal contributes ONLY its content; its own glass, shadow, and ring
   stay off so the two translucent whites never stack into a solid-white
   blip. media.js lifts this class the same frame the ghost is removed,
   and the recipes are identical, so the handoff is pixel-invisible. */
.ty-modal.ty-morphing{background:transparent;box-shadow:none;
  -webkit-backdrop-filter:none;backdrop-filter:none}
.ty-modal.ty-morphing::before{opacity:0}
.ty-modal.in{animation:ty-in .6s var(--ease-out-expo)}
/* 260830h (Nathan asked to see it): the sheet-to-modal FLIP morph. A
   content-free ghost box rides between the scrim (80) and the modal (85):
   it starts as the open dock sheet (its dark glass, via .ty-ghost-from
   fading out) and lands as the modal's light glass, while the modal's
   own content fades in over it. Geometry animates on the ghost only, so
   no glyph ever stretches; media.js §4 drives it on dock signups. */
.ty-ghost{position:fixed;z-index:82;pointer-events:none;overflow:hidden;
  border-radius:20px;
  /* 260830m: twin of .ty-modal's card-recipe glass, always identical */
  background:linear-gradient(180deg,rgba(255,255,255,.55),rgba(255,255,255,0) 42%),rgba(255,255,255,.7);
  /* 260830l: same scrim compensation as .ty-modal, so the morph never
     dips dim mid-flight */
  -webkit-backdrop-filter:saturate(180%) blur(32px) brightness(1.43);
  backdrop-filter:saturate(180%) blur(32px) brightness(1.43);
  box-shadow:0 24px 60px -20px rgba(2,14,22,.45)}
.ty-ghost .ty-ghost-from{position:absolute;inset:0;
  background:
    linear-gradient(160deg,rgba(125,211,192,.2),rgba(85,193,188,.15) 34%,rgba(0,0,0,0) 60%),
    linear-gradient(135deg,rgba(8,35,56,.72),rgba(12,45,64,.9) 55%,rgba(12,45,64,.85))}
html.dark .ty-ghost{
  /* 260830m: the dark card's .64 glass, not the old denser .74 */
  background:linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 42%),rgba(9,20,26,.64);
  /* 260830l: dark mode's scrim multiplies by .5, so its inverse is 2 */
  -webkit-backdrop-filter:saturate(180%) blur(32px) brightness(2);
  backdrop-filter:saturate(180%) blur(32px) brightness(2)}
@keyframes ty-in{from{opacity:0;transform:translate(-50%,calc(-50% + 12px))}
  to{opacity:1;transform:translate(-50%,-50%)}}
/* (260817: the 44px top leaf retired same day — it read as forced. The
   leaf rides the headline's last sentence at .72em now, .h1-leaf's own
   grammar, so the modal quotes the hero instead of inventing a mark.) */
.m-hd{font-size:clamp(24px,19px + 1.6vw,34px);line-height:1.08;letter-spacing:-.022em;
  font-weight:650;margin:0 0 14px;max-width:none;text-wrap:balance}
.m-sub{font-size:clamp(15px,14px + .3vw,16px);line-height:1.5;color:var(--ink-3);
  margin:0 auto 30px;max-width:34ch;text-wrap:pretty}
/* the Done button wears the twin CTAs' glass-mesh wash (light mode) and
   their light liquid glass (dark) — same traits as the button that just
   signed the reader up, one module earlier */
.m-btn{
  background:
    linear-gradient(160deg,rgba(125,211,192,.28),rgba(85,193,188,.18) 34%,rgba(0,0,0,0) 60%),
    linear-gradient(135deg,#0F3A55,#0C2D40 55%,#0E3550);
  box-shadow:0 6px 18px -6px rgba(12,45,64,.5)}
.m-btn:hover{
  background:
    linear-gradient(160deg,rgba(125,211,192,.34),rgba(85,193,188,.24) 34%,rgba(0,0,0,0) 60%),
    linear-gradient(135deg,#144263,#123B54 55%,#124061)}
html.dark .m-btn{
  color:#0C2D40;
  background:
    linear-gradient(160deg,rgba(125,211,192,.28),rgba(85,193,188,.16) 34%,rgba(255,255,255,0) 60%),
    linear-gradient(135deg,rgba(255,255,255,.9),rgba(236,242,244,.82) 55%,rgba(255,255,255,.86));
  box-shadow:0 6px 18px -6px rgba(12,45,64,.35)}
html.dark .m-btn:hover{
  background:
    linear-gradient(160deg,rgba(125,211,192,.36),rgba(85,193,188,.22) 34%,rgba(255,255,255,0) 60%),
    linear-gradient(135deg,#ffffff,#e7eef1 55%,#fdfefe)}
.m-meta{margin:18px 0 0;font-size:12px;color:var(--ink-3)}
/* 260830b: the address moved from the meta line into the sub (Nathan's
   triage copy); it keeps the same quiet emphasis it had in the meta */
.m-meta b,.m-sub .m-addr{color:var(--ink-2);font-weight:600}
html.dark .ty-scrim{background:rgba(8,25,38,.5)}
html.dark .ty-modal{
  /* 260830m: dark card parity, twin of html.dark .ty-ghost */
  background:linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 42%),rgba(9,20,26,.64);
  /* 260830l: dark scrim inverse, twin of html.dark .ty-ghost */
  -webkit-backdrop-filter:saturate(180%) blur(32px) brightness(2);
  backdrop-filter:saturate(180%) blur(32px) brightness(2)}
html.dark .ty-modal::before{background:rgba(255,255,255,.18)}

/* ---- cookie consent toast: bottom-LEFT (the FAB owns the right corner),
   full-width minus gutters on phones ---- */
.toast{position:fixed;z-index:75;left:16px;right:16px;
  bottom:calc(16px + env(safe-area-inset-bottom));
  background:linear-gradient(180deg,rgba(255,255,255,.6),rgba(255,255,255,0) 42%),rgba(255,255,255,.82);
  -webkit-backdrop-filter:saturate(170%) blur(26px);
  backdrop-filter:saturate(170%) blur(26px);
  border-radius:20px;
  box-shadow:0 24px 60px -20px rgba(2,14,22,.45);
  padding:16px 18px}
.toast::before{content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:rgba(12,45,64,.14);
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  mask-composite:exclude;pointer-events:none}
@media(min-width:720px){.toast{left:40px;right:auto;bottom:32px;max-width:400px}}
.toast[hidden]{display:none}
.toast.in{animation:toast-in .7s var(--ease-out-expo)}
@keyframes toast-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.t-hd{margin:0 0 4px;font-size:14px;font-weight:600}
.t-copy{margin:0 0 14px;font-size:13px;line-height:1.55;color:var(--ink-3);text-wrap:pretty}
.t-copy a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.t-row{display:flex;gap:8px;flex-wrap:wrap}
.t-btn{font-size:14px;width:auto;border-radius:999px;padding:10px 16px;flex:1 1 auto}
.t-essential{background:none;border:1px solid var(--line);color:var(--deep-sea)}
.t-essential:hover{background:none;border-color:var(--deep-sea)}
.t-saved{display:none;align-items:center;gap:8px;font-size:13px;font-weight:600;margin:0}
.t-saved svg{width:15px;height:15px;color:var(--jade)}
.toast.done .t-hd,.toast.done .t-copy,.toast.done .t-row{display:none}
.toast.done .t-saved{display:flex}
.toast.out{animation:toast-out .4s ease forwards .9s}
@keyframes toast-out{to{opacity:0;transform:translateY(8px)}}
html.dark .toast{
  background:linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 42%),rgba(9,20,26,.74)}
html.dark .toast::before{background:rgba(255,255,255,.18)}
html.dark .t-essential{color:#fff;border-color:var(--line)}
html.dark .t-essential:hover{border-color:#fff}
html.dark .t-allow{background:#fff;color:#111}
html.dark .t-allow:hover{background:rgba(255,255,255,.85)}

@media(prefers-reduced-motion:reduce){
  .ty-modal.in,.toast.in{animation:none}
  .toast.out{animation:none;opacity:0}
  .ty-scrim{transition:none}
}

/* ---- 404 (260822d): rate this broken link ----
   The H1 is the plain instruction ("Rate this 404."); the eyebrow above it
   reads "Page not found" (260828g, Nathan: copy settled after a day of the
   404 living in a longer eyebrow-less H1; that experiment is in git at
   260828e/f). The hero leaf toy sits beneath, empty, as the shortcut home.
   Vertical rhythm = the hero's, exactly (Nathan 260821): eyebrow s4 → H1 s4
   → leaf-block s1/s5 → sub s6 → CTA → tip s5; section top = hero-section's
   clamp. Lab register: the eyebrow tick goes neutral charcoal (ink-2 both
   modes; in dark that's the white-gray, outranking the jade flip).
   260828a: .list-page rides along on every rule the 404's frame needs; it is
   the email-click landings (confirmed.html, unsubscribed.html): same rhythm,
   no eyebrow, no leaf toy, same water below. */
.err-404 .eyebrow::before{background:var(--ink-2)}
html.dark .err-404 .eyebrow::before{background:var(--ink-2)}
/* (260828e: the 260828c/d hairline-off audition retired — Nathan slept on it
   and ruled the topbar hairline stays, everywhere, for now. Code in git.) */
.err-404 .err-body,.list-page .err-body{padding-top:clamp(56px,9vh,120px)}       /* = .hero-section (bottom set with the band below) */
.err-404 h1,.list-page h1{margin-bottom:var(--s4)}                          /* hero h1, not the article 14px */
.err-404 .leaf-block{margin:var(--s1) 0 var(--s6)}           /* hero top; bottom one step up (260822d, Nathan): the H1's descender room makes the gap above read ~25px, so 32 below puts the pill at the same visual distance */
.err-404 .lede,.list-page .lede{margin:0 0 var(--s6)}                          /* = .sub/.lede, undoing .article's 0 */
.err-cta{margin:0}
.err-404 .err-tip,.list-page .err-tip{margin:var(--s5) 0 0;color:var(--ink-3)}   /* outranks .article p's ink-2 */
.err-404 .err-tip a,.list-page .err-tip a{color:inherit}
/* 260830f (Nathan, reversing 260830d's brief Done button): every landing
   page closes with the PILL (.starter-btn) — confirmed, unsubscribed, 404
   alike. His ruling: the landing is the start of something new and the end
   of the journey, so it takes the invitation grammar; and the unsubscribe
   flow keeps BOTH its buttons pills so the shape never jarringly changes
   (the two grammars should stay subconscious). The 10px flow control
   remains the shape for form submits, the modal Done, and email CTAs. */
/* the confirmed address can be arbitrarily long — never let it overflow */
.list-page .lede b{overflow-wrap:anywhere}
/* 260830e: /unsubscribe's two-step ask rides the /unsubscribed asset —
   the Worker stamps body.unsub-ask onto the same file and these rules
   swap which state shows; the plain /unsubscribed page keeps the done
   state and never sees the ask */
.unsub-ask-state{display:none}
.unsub-ask .unsub-ask-state{display:block}
.unsub-ask .unsub-done-state{display:none}
.err-br{display:none}
@media(min-width:640px){.err-br{display:inline}}   /* the note's manual break, desktop only */

/* live reef band (explore.org cam), 260821z: the player runs full and
   uncropped, FULL-BLEED at every width (100vw escape like .rule), square
   corners, no padding below — it butts straight into the footer's top
   hairline so white never hands off to white. No caption of ours: their
   on-screen branding is the attribution (YouTube: no overlays/obscuring;
   explore.org: keep their notices). */
.err-404 .err-body,.list-page .err-body{padding-bottom:56px}                       /* = footer padding-top: the white above the water matches the white below it */
.err-404 section.err-live,.list-page section.err-live{padding:0;position:relative;left:50%;width:100vw;margin-left:-50vw}  /* ties .article section:last-of-type, later wins */
.err-live-frame{position:relative;aspect-ratio:16/9;background:#061e2e;overflow:hidden}
.err-live-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.err-live-frame noscript a{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;color:#fff;font-size:13px;text-align:center;padding:var(--s5)}

/* the gusted-leaf rig (404 Easter egg) — DORMANT since 260821x (Nathan:
   "too many leaves", keep on ice). Page script lives in git at 260821w.
   cam > path > rock > flip; each layer owns one axis of the physics. */

/* =====================================================================
   260902a (Nathan): the POST-SIGN-UP page state (media.js §4 settleBands,
   §5 jade:settled). After the thank-you closes, every photo band drops to
   half its height and loses its card: the photos stay as quiet visual
   rests between sections instead of asking three more times. The photo
   layer does NOT rescale — it keeps the band's old height (--band-h) and
   rides up by --settle-k while the band closes over it, so the picture
   holds still and the page "squints" onto its best slice. A band marked
   data-settle="gone" closes to nothing and leaves the flow instead
   (260902b the People page's skyline, 260902d the Business page's
   florist). Page view only: a refresh puts
   the forms back, by design.
   ===================================================================== */
.signup-band--photo{transition:height .7s var(--ease-out-expo)}
.signup-band--photo.is-settling{padding:0;overflow:hidden}
.signup-band--photo.is-settling .shell{opacity:0;visibility:hidden;
  transition:opacity .25s ease,visibility 0s linear .25s}
.signup-band--photo.is-settling .signup-photo{top:0;bottom:auto;
  height:var(--band-h);transition:top .7s var(--ease-out-expo)}
.signup-band--photo.is-settled .signup-photo{top:calc(-1 * var(--settle-k,0px))}
/* the corner credit follows the band's new bottom edge (the layer's own
   bottom is out of frame now) */
.signup-band--photo.is-settled .signup-photo[data-credit]::before{
  bottom:calc(50% + 8px - var(--settle-k,0px))}
/* bands off screen at the moment of settling (and reduced motion) snap */
.signup-band--photo.no-motion,.signup-band--photo.no-motion .signup-photo,
.signup-band--photo.no-motion .shell{transition:none}
/* the returning pill fades in already parked — dock-in's translateY
   keyframe would fight the parked translateX and snap at the end */
@media(prefers-reduced-motion:no-preference){
  .dock.dock-again:not([hidden]){animation:dock-fade .9s ease-out}
}
@keyframes dock-fade{from{opacity:0}to{opacity:1}}
