/* Sproutly — sproutly.page
   Tokens and decisions are documented in docs/design-plan.md.
   Green is fill only; --sprout-ink carries every green word, because --sprout
   measures 4.22:1 on --wash and misses AA. */

/* Nunito is the fallback for platforms without SF Rounded. Apple devices
   resolve ui-rounded first, so they never fetch these files. */
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/nunito-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  color-scheme: light dark;

  --ground: #F7F5F0;
  --surface: #FFFFFF;
  --wash: #E7F0E6;
  --ink: #2A211B;
  --ink-soft: #5C5049;
  --sprout: #3F7D53;
  --sprout-ink: #2E5E3E;
  --sprout-deep: #2E5E3E;
  --hairline: rgba(42, 33, 27, 0.12);
  --lift: 0 1px 2px rgba(42, 33, 27, 0.05), 0 12px 32px rgba(42, 33, 27, 0.06);

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 32px; --s7: 48px; --s8: 72px; --s9: 112px;

  --r-s: 10px; --r-m: 16px; --r-l: 26px; --r-pill: 999px;

  --measure: 33rem;
  --page: 60rem;

  --font: ui-rounded, "SF Pro Rounded", "Nunito", system-ui, -apple-system,
    "Segoe UI", sans-serif;

  --t-display: clamp(2.125rem, 1.35rem + 3.3vw, 3.25rem);
  --t-statement: clamp(1.375rem, 1.1rem + 1.2vw, 1.75rem);
  --t-lede: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
  --t-body: 1.0625rem;
  --t-small: 0.9375rem;
  --t-micro: 0.84375rem;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --d-quick: 160ms;
  --d-settle: 420ms;
  --d-bloom: 900ms;

  --dot: 60px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ground: #161815;
    --surface: #1E211D;
    --wash: #242B23;
    --ink: #E9EBE5;
    --ink-soft: #A8AFA4;
    --sprout: #8FC79C;
    --sprout-ink: #A9D8B4;
    --sprout-deep: #6FAE80;
    --hairline: rgba(233, 235, 229, 0.14);
    --lift: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.3);
  }
}

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

html { -webkit-text-size-adjust: 100%; }

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

h1, h2, h3 { font-weight: 600; margin: 0; }
p { margin: 0; }
img { max-width: 100%; height: auto; display: block; }

a { color: var(--sprout-ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--sprout-deep); }

/* One focus treatment, everywhere, never removed. */
:focus-visible {
  outline: 2px solid var(--sprout-deep);
  outline-offset: 2px;
  border-radius: var(--s1);
}

.skip {
  position: absolute; left: var(--s4); top: -4rem;
  background: var(--surface); color: var(--ink);
  padding: var(--s3) var(--s4); border-radius: var(--r-s);
  box-shadow: var(--lift); z-index: 10; text-decoration: none;
  transition: top var(--d-quick) var(--ease);
}
.skip:focus { top: var(--s4); }

/* ---------- layout ---------- */

.page {
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--s5);
}
.measure { max-width: var(--measure); }

/* ---------- masthead ---------- */

.site {
  padding-block: var(--s6) 0;
}
.site .page { display: flex; align-items: center; gap: var(--s3); }
.mark {
  width: 34px; height: 34px; border-radius: 9px;
  box-shadow: 0 1px 2px rgba(42, 33, 27, 0.08);
}
.wordmark {
  font-size: 1.125rem; font-weight: 600; letter-spacing: -0.01em;
  color: var(--ink); text-decoration: none;
}
.site nav {
  margin-left: auto; display: flex; gap: var(--s5); font-size: var(--t-small);
}
.site nav a { color: var(--ink-soft); text-decoration: none; }
.site nav a:hover { color: var(--sprout-ink); }

/* ---------- hero ---------- */
/* Left-aligned and editorial. A centred stack with the mark on top is what
   every launch page does; the brief asks type and space to carry this. */

.hero { padding-block: var(--s9) var(--s8); }
.hero h1 {
  font-size: var(--t-display);
  line-height: 1.06;
  letter-spacing: -0.022em;
  margin-bottom: var(--s5);
}
.hero .lede {
  font-size: var(--t-lede);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 30rem;
}

/* ---------- what it does ---------- */
/* Three beats, no cards, no icons in circles. A sequence, read downward. */

.beats { padding-block: var(--s7) var(--s8); }
.beats ol { list-style: none; margin: 0; padding: 0; }
.beats li + li { margin-top: var(--s7); }
.beats h2 {
  font-size: var(--t-micro);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sprout-ink);
  margin-bottom: var(--s2);
}
.beats p { max-width: var(--measure); color: var(--ink-soft); }

/* ---------- why it is different ---------- */
/* The strongest thing about the product, so it gets the largest type on the
   page after the H1 and a full-bleed band of its own. Not a comparison table. */

.band {
  background: var(--wash);
  padding-block: var(--s9);
  margin-block: var(--s6);
}
.band ul { list-style: none; margin: 0; padding: 0; max-width: 36rem; }
.band li {
  font-size: var(--t-statement);
  line-height: 1.35;
  letter-spacing: -0.012em;
  color: var(--ink);
}
.band li + li { margin-top: var(--s5); }
.band .foot {
  margin-top: var(--s6);
  font-size: var(--t-small);
  color: var(--ink-soft);
  max-width: var(--measure);
}

/* ---------- the interest panel ---------- */
/* --lift is used here and nowhere else, so the one thing you can act on is
   the one thing that lifts off the page. */

.interest { padding-block: var(--s8); }
.panel {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-l);
  box-shadow: var(--lift);
  padding: var(--s7) var(--s6);
  max-width: 34rem;
}
@media (min-width: 30rem) { .panel { padding: var(--s7); } }

.panel h2 {
  font-size: var(--t-statement);
  line-height: 1.3;
  letter-spacing: -0.012em;
  margin-bottom: var(--s3);
}
.panel .sub { color: var(--ink-soft); font-size: var(--t-small); margin-bottom: var(--s6); }

/* The button and its morph. Height is fixed by .cta so no step of the
   confirmation can move anything around it. */
.cta { height: 56px; display: flex; }
.btn {
  position: relative;
  width: 100%;
  height: 56px;
  margin-inline: auto;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--sprout);
  color: var(--ground);
  font-family: inherit;
  font-size: var(--t-body);
  font-weight: 600;
  letter-spacing: -0.005em;
  cursor: pointer;
  display: grid;
  place-items: center;
  overflow: visible;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--d-quick) var(--ease), background var(--d-quick) var(--ease);
}
.btn:hover { background: var(--sprout-deep); }
.btn:active { transform: scale(0.98); }
.btn > * { grid-area: 1 / 1; }

.btn-label, .btn-done { display: flex; align-items: center; gap: var(--s2); white-space: nowrap; }
.btn-done { opacity: 0; }
.tick { width: 22px; height: 22px; flex: none; }
.tick path {
  fill: none; stroke: currentColor; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 24; stroke-dashoffset: 0;
}
.ring {
  position: absolute; inset: 0; border-radius: var(--r-pill);
  border: 2px solid var(--sprout); opacity: 0; pointer-events: none;
}

/* Settled confirmed state. Also the first-paint state for a returning
   visitor, via .is-joined on <html> set by boot.js before render. */
.btn.is-done .btn-label, .is-joined .btn .btn-label { opacity: 0; }
.btn.is-done .btn-done, .is-joined .btn .btn-done { opacity: 1; }
.btn.is-done, .is-joined .btn { cursor: default; background: var(--sprout); }

.status {
  font-size: var(--t-micro);
  color: var(--ink-soft);
  margin-top: var(--s3);
  min-height: 1.5em;
}

/* ---------- the questions ---------- */
/* 0fr -> 1fr so the section below is pushed down smoothly rather than
   teleporting. The inner element is inert while closed, so collapsed radios
   are never reachable by tab. */

.qs {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--d-settle) var(--ease);
}
.qs > .qs-in { overflow: hidden; min-height: 0; }
.qs.is-open, .is-joined .qs { grid-template-rows: 1fr; }

.qs-head { padding-top: var(--s7); }
.qs-head h3 { font-size: var(--t-body); margin-bottom: var(--s2); }
.qs-head p { font-size: var(--t-small); color: var(--ink-soft); }

.q { border: 0; margin: var(--s6) 0 0; padding: 0; min-width: 0; }
.q legend { font-size: var(--t-small); font-weight: 600; padding: 0; margin-bottom: var(--s3); }

.chips { position: relative; display: flex; flex-wrap: wrap; gap: var(--s2); }
.chips input {
  position: absolute;
  width: 1px; height: 1px;
  margin: 0; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
}
.chips label {
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: var(--s2) var(--s4);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  background: var(--ground);
  color: var(--ink);
  font-size: var(--t-small);
  cursor: pointer;
  transition: background var(--d-quick) var(--ease), color var(--d-quick) var(--ease),
    border-color var(--d-quick) var(--ease);
}
.chips label:hover { border-color: var(--sprout); }

/* Selected changes fill only. No weight change, no added glyph, nothing that
   could re-measure the chip and rewrap the group. The inset shadow thickens
   the edge without occupying layout. */
.chips input:checked + label {
  background: var(--sprout);
  border-color: var(--sprout);
  color: var(--ground);
  box-shadow: inset 0 0 0 1px var(--sprout);
}
.chips input:focus-visible + label {
  outline: 2px solid var(--sprout-deep);
  outline-offset: 2px;
}

@media (forced-colors: active) {
  .chips input:checked + label { outline: 3px solid Highlight; outline-offset: -3px; }
  .btn { border: 1px solid ButtonText; }
}

/* ---------- what happens next ---------- */

.next { padding-block: var(--s7) var(--s8); }
.next h2 {
  font-size: var(--t-micro); letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--sprout-ink); margin-bottom: var(--s3);
}
.next p { max-width: var(--measure); color: var(--ink-soft); }
.next p + p { margin-top: var(--s4); }

/* ---------- footer ---------- */

.site-foot {
  border-top: 1px solid var(--hairline);
  padding-block: var(--s6) var(--s8);
  font-size: var(--t-small);
  color: var(--ink-soft);
}
.site-foot nav { display: flex; flex-wrap: wrap; gap: var(--s5); margin-bottom: var(--s4); }
.site-foot nav a { color: var(--ink-soft); text-decoration: none; }
.site-foot nav a:hover { color: var(--sprout-ink); }
.site-foot .fine { max-width: var(--measure); font-size: var(--t-micro); line-height: 1.6; }
.site-foot .fine + .fine { margin-top: var(--s3); }

/* ---------- long-form document pages ---------- */

.doc { padding-block: var(--s8) var(--s8); max-width: 40rem; }
.doc h1 {
  font-size: clamp(1.875rem, 1.4rem + 2vw, 2.5rem);
  line-height: 1.12; letter-spacing: -0.02em;
  margin-bottom: var(--s2);
}
.doc .updated { color: var(--ink-soft); font-size: var(--t-small); margin-bottom: var(--s6); }
.doc h2 { font-size: 1.1875rem; margin: var(--s7) 0 var(--s3); letter-spacing: -0.01em; }
.doc p { margin-bottom: var(--s4); color: var(--ink); }
.doc ul { margin: 0 0 var(--s4); padding-left: var(--s5); }
.doc li { margin-bottom: var(--s2); }
.doc .callout {
  background: var(--wash);
  border-radius: var(--r-m);
  padding: var(--s5);
  margin-bottom: var(--s6);
}
.doc .callout p:last-child { margin-bottom: 0; }
.doc .soon {
  border: 1px dashed var(--hairline);
  border-radius: var(--r-m);
  padding: var(--s5);
  color: var(--ink-soft);
}
.doc .soon p:last-child { margin-bottom: 0; }

/* ---------- motion ---------- */
/* Everything expressive lives in here. The reduced-motion path is not a faster
   version of this, it is the absence of it. */

@media (prefers-reduced-motion: no-preference) {
  .btn.is-morphing { animation: morph var(--d-bloom) var(--ease) forwards; }
  .btn.is-morphing .btn-label { animation: label-out 220ms var(--ease) 60ms forwards; }
  .btn.is-morphing .btn-done { animation: label-in 340ms var(--ease) 560ms forwards; }
  .btn.is-morphing .tick path { animation: draw 260ms var(--ease) 340ms backwards; }
  .btn.is-morphing .ring { animation: ring 640ms var(--ease) 340ms forwards; }

  @keyframes morph {
    0%, 8%   { width: 100%; }
    36%, 62% { width: var(--dot); }
    100%     { width: 100%; }
  }
  @keyframes label-out { to { opacity: 0; transform: translateY(-6px); } }
  @keyframes label-in  { from { opacity: 0; } to { opacity: 1; } }
  @keyframes draw      { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
  @keyframes ring {
    0%   { opacity: 0.55; transform: scale(1); }
    100% { opacity: 0;    transform: scale(1.6); }
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 120ms !important;
  }
  .qs { transition: none !important; }
  .btn:active { transform: none; }
}
