/* ============================================================
   METRICS THAT CARE — "Warm Precision" design system
   Anchor's discipline · V5's palette + type scale · Zelt's hairlines
   Adapted from Getanchor style reference (refero.design)
   ONE substitution carries the whole thesis:
     terracotta #ee884f  →  clinical teal #005f56
     warm paper = the home · cool teal = the clinic · MTC = the bridge
   ============================================================ */

:root {
  /* ---- Surfaces (warm stack, deepest → floating) ---------- */
  --canvas:      #e9e0d1;  /* L0 page ground   (Anchor #e3d7cd) */
  --linen:       #f4ede1;  /* L1 section/card  (Anchor #f0e9e5) */
  --paper:       #fdf9f0;  /* L2 block/hover   — V5 --color-surface */
  --white:       #ffffff;  /* L3 floats above cream */

  /* ---- Ink ------------------------------------------------- */
  --ink:         #1d1c17;  /* V5 --color-on-surface (warm near-black) */
  --ink-2:       #3e4947;  /* V5 --color-on-surface-variant */
  --stone:       #696458;  /* secondary / helper copy — 4.5:1 on --canvas */
  --sand:        #d3c8b6;  /* hairline dividers */
  --sand-soft:   #e0d6c6;  /* faintest rule */

  /* ---- The one accent -------------------------------------- */
  --accent:      #005f56;  /* V5 --color-primary — THE only chromatic action */
  --accent-deep: #00443e;  /* hover */
  --accent-wash: #d9ece8;  /* faint teal tint, backgrounds only */
  --warm:        #724c28;  /* V5 --color-tertiary — secondary warm mark */
  --warm-wash:   #ffdcbf;  /* V5 --color-tertiary-fixed */

  /* ---- Status (semantic, never the accent) ----------------- */
  --live:        #1f6b45;
  --built:       #845c0c;
  --dev:         #696458;

  /* ---- Type ------------------------------------------------ */
  /* Atkinson Hyperlegible: Braille Institute, built for low vision.
     Plus Jakarta Sans: display only. Both already ship in V5. */
  --font-body:    "Atkinson Hyperlegible", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-display: "Plus Jakarta Sans", "Atkinson Hyperlegible", ui-sans-serif, system-ui, sans-serif;
  --font-mono:    ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;

  /* Anchor's scale, RAISED for a 50–75yo reading on a phone.
     Nothing on this site is ever smaller than 13px. */
  --t-caption:    0.75rem;   /* 12px — was 11 */
  --t-small:      0.875rem;  /* 14px */
  --t-body:       1.0625rem; /* 17px — was 15 */
  --t-sub:        1.1875rem; /* 19px — was 18 */
  --t-h-sm:       2.125rem;  /* 34px */
  --t-h:          2.75rem;   /* 44px */
  --t-h-lg:       3.375rem;  /* 54px */
  --t-display:    4.25rem;   /* 68px */

  /* ---- Shape ----------------------------------------------- */
  --r:        4px;      /* cards, inputs, nav — the precision note */
  --r-pill:   999px;    /* buttons + badges — Anchor's signature contrast */
  --shadow:   rgba(29,28,23,.01) 0 4px 1px 0, rgba(29,28,23,.04) 0 2px 1px 0, rgba(29,28,23,.06) 0 1px 1px 0;

  /* ---- Layout ---------------------------------------------- */
  --page:     1200px;
  --gap-sec:  clamp(4.5rem, 9vw, 7.5rem);
}

/* ============================================================ */

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.55;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---- Structure -------------------------------------------- */

.wrap {
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 4vw, 2.5rem);
}

section { padding-block: var(--gap-sec); }

.bg-canvas { background: var(--canvas); }
.bg-linen  { background: var(--linen); }
.bg-paper  { background: var(--paper); }
.bg-white  { background: var(--white); }
.bg-ink    { background: var(--ink); color: var(--paper); }
.bg-ink .eyebrow { color: var(--warm-wash); }
.bg-ink .desc, .bg-ink p { color: #d8d2c4; }

/* ---- Type roles -------------------------------------------- */

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--t-caption);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--stone);
  margin: 0 0 1.1rem;
}

.display, .h-lg, .h, .h-sm {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--ink);
  text-wrap: balance;
  margin: 0;
}
.display { font-size: clamp(2.6rem, 6.4vw, var(--t-display)); line-height: 1.0;  letter-spacing: -0.032em; }
.h-lg    { font-size: clamp(2.2rem, 5vw,   var(--t-h-lg));    line-height: 1.06; letter-spacing: -0.03em; }
.h       { font-size: clamp(1.95rem, 4.2vw, var(--t-h));      line-height: 1.12; letter-spacing: -0.028em; }
.h-sm    { font-size: clamp(1.6rem, 3.2vw, var(--t-h-sm));    line-height: 1.18; letter-spacing: -0.024em; }

.sub {
  font-size: var(--t-sub);
  line-height: 1.5;
  color: var(--ink-2);
  margin: 1.15rem 0 0;
  max-width: 34ch;
}
.desc { color: var(--stone); margin: 1rem 0 0; max-width: 58ch; }
.lead { font-size: var(--t-sub); color: var(--ink-2); max-width: 52ch; }

.measure { max-width: 62ch; }

/* ---- Buttons ----------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  font-family: var(--font-body);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: -0.005em;
  padding: .78rem 1.5rem;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color .16s ease, color .16s ease, border-color .16s ease;
  min-height: 48px; /* V5 touch target */
}
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-deep); }

.btn-ink { background: var(--ink); color: var(--paper); }
.btn-ink:hover { background: #000; }

.btn-quiet {
  background: transparent;
  color: var(--ink);
  border-color: var(--sand);
}
.btn-quiet:hover { background: var(--paper); border-color: var(--ink-2); }

.btn-row { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }

.textlink {
  color: var(--accent);
  font-weight: 700;
  font-size: var(--t-small);
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
}
.textlink:hover { color: var(--accent-deep); }

/* ---- Cards ------------------------------------------------- */

.card {
  background: var(--white);
  border-radius: var(--r);
  padding: 1.5rem;
  box-shadow: var(--shadow);
}
.card-flat {
  background: var(--linen);
  border-radius: var(--r);
  padding: 1.5rem;
}
.card-line {
  background: var(--paper);
  border: 1px solid var(--sand);
  border-radius: var(--r);
  padding: 1.5rem;
}

/* Explicit column counts — auto-fit misbehaves when a grid is nested
   inside a .split column (it silently collapses to 1). Deterministic wins. */
.grid { display: grid; gap: 1.5rem; }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 64rem) {
  .g-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .g-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 40rem) {
  .g-2, .g-3, .g-4 { grid-template-columns: minmax(0, 1fr); }
}

.card h3, .card-flat h3, .card-line h3 {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 .4rem;
}
.card p, .card-flat p, .card-line p {
  margin: 0;
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--stone);
}

/* ---- Status badges ----------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: var(--t-caption);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: .22rem .62rem;
  border-radius: var(--r-pill);
  background: var(--linen);
  color: var(--stone);
  white-space: nowrap;
}
.badge::before { content: ""; width: .4rem; height: .4rem; border-radius: 50%; background: currentColor; }
.badge-live  { color: var(--live);  background: #e4efe8; }
.badge-built { color: var(--built); background: #f5ecd8; }
.badge-dev   { color: var(--dev);   background: var(--linen); }

/* ---- Nav ---------------------------------------------------- */

.nav {
  background: var(--canvas);
  border-bottom: 1px solid var(--sand-soft);
  position: sticky;
  top: 0;
  z-index: 40;
}
.nav-in {
  max-width: var(--page);
  margin: 0 auto;
  padding: .85rem clamp(1.25rem, 4vw, 2.5rem);
  display: flex;
  align-items: center;
  gap: 1.5rem;
}
.brand {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.0625rem;
  letter-spacing: -0.03em;
  display: flex;
  align-items: center;
  gap: .55rem;
  white-space: nowrap;
}
.brand-logo {
  width: 1.75rem;
  height: auto;
  flex: none;
}
.foot .brand-logo { filter: brightness(1.28) saturate(.85); }
.nav-links {
  display: flex;
  gap: 1.4rem;
  margin-left: auto;
  align-items: center;
}
.nav-links a {
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--ink);
  padding: .35rem 0;
  min-height: 2.75rem;          /* 44px tap target */
  display: inline-flex;
  align-items: center;
}
.nav-links a:hover { color: var(--accent); }
.nav-links a[aria-current="page"] { color: var(--accent); font-weight: 700; }
.nav-cta { display: flex; gap: .6rem; align-items: center; }
.nav-cta .btn { min-height: 42px; padding: .5rem 1.15rem; }

/* Below 62rem the nav used to be `display:none` with NOTHING in its place —
   no hamburger, no fallback — so on a phone the only way off a page was the
   logo. Instead of hiding the links behind an icon a 50-75yo reader has to
   discover, they wrap and stay visible. The header also stops being sticky
   here, so a two- or three-line nav costs the top of the page and nothing
   after it. */
@media (max-width: 62rem) {
  .nav { position: static; }
  .nav-in {
    flex-wrap: wrap;
    justify-content: center;
    gap: .25rem 1.25rem;
  }
  .nav-links {
    margin-left: 0;
    width: 100%;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0 1.15rem;
    border-top: 1px solid var(--sand-soft);
    padding-top: .35rem;
  }
  /* ~44px of tappable height per link, per the design system's touch target. */
  .nav-links a { padding: .6rem 0; }
}

/* ---- Trust bar ---------------------------------------------- */

.trustbar { padding-block: 2.75rem; border-block: 1px solid var(--sand-soft); }
.trust-logos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem 2.75rem;
  margin-top: 1.25rem;
}
.trust-logos span {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-small);
  letter-spacing: -0.01em;
  color: var(--ink);
  opacity: .62;
}
.center { text-align: center; }
.center .eyebrow { margin-bottom: 0; }

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

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.split-narrow { grid-template-columns: 1.12fr 1fr; }
@media (max-width: 56rem) {
  .split, .split-narrow { grid-template-columns: 1fr; }
}

/* ---- Report mock (the instrument) --------------------------- */

.stage {
  background: linear-gradient(170deg, #cfe4df 0%, #e6ddd0 48%, var(--linen) 100%);
  border-radius: var(--r);
  padding: clamp(1.25rem, 3vw, 2.25rem);
}
/* The real generated report, shown as paper. Never a mockup. */
.paper {
  margin: 0;
  background: var(--white);
  border-radius: var(--r);
  box-shadow: 0 1px 1px rgba(29,28,23,.07), 0 6px 18px -10px rgba(29,28,23,.28);
  overflow: hidden;
}
.paper img { width: 100%; display: block; }
.paper-wide { max-width: 56rem; margin-inline: auto; }
.stage-cap {
  margin: .9rem 0 0;
  font-family: var(--font-mono);
  font-size: .66rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--stone);
  text-align: center;
}

/* ---- Doors (situation router) -------------------------------- */

.doors { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 1.25rem; margin-top: 2.75rem; }
.door {
  background: var(--white);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  padding: 1.5rem 1.4rem 1.35rem;
  display: flex;
  flex-direction: column;
  gap: .55rem;
  min-height: 15rem;
  transition: transform .16s ease;
}
.door:hover { transform: translateY(-2px); }
.door .phase {
  font-family: var(--font-mono);
  font-size: .66rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent);
}
.door .said {
  font-family: var(--font-display);
  font-size: 1.28rem;
  line-height: 1.22;
  letter-spacing: -0.024em;
  font-weight: 700;
  text-wrap: balance;
}
.door .goes { font-size: var(--t-small); color: var(--stone); margin: 0; }
.door .to { margin-top: auto; padding-top: .9rem; }

/* ---- Ring / list rows ---------------------------------------- */

.rows { border-top: 1px solid var(--sand); margin-top: 2.5rem; }
.row {
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr auto;
  gap: .5rem 2rem;
  align-items: baseline;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--sand-soft);
}
.row .rname { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.02em; font-size: 1.0625rem; }
.row .rdesc { font-size: var(--t-small); color: var(--stone); }
@media (max-width: 46rem) {
  .row { grid-template-columns: 1fr; }
}

/* ---- Article: the page that actually gets read ----------------- */

.wrap-read { max-width: 46rem; }

.crumb {
  font-size: var(--t-caption);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--stone);
  margin: 0 0 1.4rem;
  display: flex;
  gap: .55rem;
  flex-wrap: wrap;
}
.crumb a { color: var(--accent); font-weight: 700; }
.crumb a:hover { text-decoration: underline; }
.crumb span { color: var(--sand); }

.post-meta {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--stone);
  margin: 1.1rem 0 0;
}

/* answer-first block: 44% of AI citations come from the top third */
.answer {
  margin-top: 2rem;
  padding: 1.35rem 1.5rem;
  background: var(--white);
  border-left: 3px solid var(--accent);
  border-radius: var(--r);
  box-shadow: var(--shadow);
}
.answer p:last-child {
  margin: 0;
  font-size: var(--t-sub);
  line-height: 1.5;
  color: var(--ink);
}

/* ---- Prose ----------------------------------------------------- */

.prose { font-size: 1.125rem; line-height: 1.72; color: var(--ink-2); }
.prose > *:first-child { margin-top: 0; }
.prose p { margin: 0 0 1.35rem; max-width: none; }
.prose h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.6rem;
  line-height: 1.22;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin: 2.9rem 0 1rem;
  text-wrap: balance;
}
.prose h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 2.1rem 0 .75rem;
}
.prose ul, .prose ol { margin: 0 0 1.35rem; padding-left: 1.35rem; }
.prose li { margin-bottom: .6rem; }
.prose li::marker { color: var(--accent); font-weight: 700; }
.prose strong { color: var(--ink); font-weight: 700; }
.prose a {
  color: var(--accent);
  font-weight: 700;
  border-bottom: 1px solid var(--accent-wash);
}
.prose a:hover { border-bottom-color: var(--accent); }
.prose .rule { border: 0; border-top: 1px solid var(--sand); margin: 2.5rem 0; }

/* ---- FAQ (top-cited structure) --------------------------------- */

.faqs { display: grid; gap: 0; border-top: 1px solid var(--sand); margin-top: 2.25rem; }
.faq { padding: 1.4rem 0; border-bottom: 1px solid var(--sand-soft); }
.faq h3 {
  font-family: var(--font-display);
  font-size: 1.08rem;
  font-weight: 700;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 0 0 .5rem;
  text-wrap: balance;
}
.faq p { margin: 0; color: var(--ink-2); font-size: var(--t-body); line-height: 1.6; max-width: 70ch; }

/* ---- Blog: stat row, post meta, scheduled cards ---------------- */

.stats-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2.75rem;
  margin-top: 2.25rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--sand);
}
.stat {
  display: flex;
  flex-direction: column;
  font-size: var(--t-caption);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--stone);
}
.stat strong {
  font-family: var(--font-display);
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--accent);
  text-transform: none;
  font-variant-numeric: tabular-nums;
}

.card-meta {
  margin-top: .9rem !important;
  font-size: var(--t-caption) !important;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent) !important;
}
/* Scheduled (not yet published). Recedes by being LIGHTER and un-shadowed —
   never by getting darker or muddier than the live cards around it. */
.card-sched {
  background: var(--paper);
  border: 1px dashed var(--sand);
  box-shadow: none;
}
.card-sched .card-meta { color: var(--stone) !important; }

.row-link { text-decoration: none; }
.row-link:hover .rname { color: var(--accent); }
.rmeta {
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.rows-dark { border-top-color: #3a382f; }
.rows-dark .row { border-bottom-color: #33312a; }
.rows-dark .rname { color: var(--paper); }
.rows-dark .rdesc { color: #a8a294; }
.rows-dark .rmeta { color: #8f8878; }
.rows-dark .row-link:hover .rname { color: var(--warm-wash); }

/* ---- Footer --------------------------------------------------- */

.foot { background: var(--ink); color: #d8d2c4; padding-block: 4rem 2.5rem; }
.foot a { color: #d8d2c4; font-size: var(--t-small); }
.foot a:hover { color: #fff; }
.foot-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(4, minmax(0, 1fr));
  gap: 2.5rem;
}
@media (max-width: 64rem) { .foot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 34rem) { .foot-grid { grid-template-columns: minmax(0, 1fr); } }
.foot h4 {
  font-family: var(--font-body);
  font-size: var(--t-caption);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: #8f8878;
  margin: 0 0 .9rem;
}
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.foot .brand { color: var(--paper); }

/* ---- Store badges ------------------------------------------- */

.stores { display: flex; flex-wrap: wrap; gap: .85rem; align-items: center; margin-top: 2rem; }
.stores a { display: inline-flex; }
.stores img { height: 48px; width: auto; }
.stores a:hover { opacity: .85; }

/* ---- Real app screenshots ----------------------------------- */

.shots {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem;
  margin-top: 2.75rem;
}
.shot { display: flex; flex-direction: column; gap: .75rem; margin: 0; }
.shot img {
  width: 100%;
  border-radius: var(--r);
  border: 1px solid var(--sand);
  background: var(--white);
}
.shot figcaption {
  font-size: var(--t-small);
  color: var(--stone);
  line-height: 1.45;
}
.shot strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin-bottom: .15rem;
}
.shot-phone {
  background: var(--linen);
  border-radius: var(--r);
  padding: 1rem;
}

/* ---- Scroll-pinned phone ------------------------------------------
   The phone holds still while the copy beside it advances; the screen
   inside it swaps per beat. Degrades in three directions: no JS -> the
   first screen simply stays; no IntersectionObserver -> same; narrow
   viewport -> the phone unpins and sits above the copy. */

.pinned .split, .pinned .split-narrow { align-items: start; }

.phone-stage {
  position: sticky;
  top: 5.5rem;            /* clears the sticky nav */
  align-self: start;
}
.phone {
  position: relative;
  width: min(19rem, 100%);
  margin-inline: auto;
  aspect-ratio: 1320 / 2868;
  background: var(--ink);
  border-radius: 2.6rem;
  padding: .45rem;
  box-shadow: 0 1px 2px rgba(29,28,23,.10), 0 26px 50px -26px rgba(29,28,23,.5);
}
.phone-screens {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 2.2rem;
  overflow: hidden;
  background: var(--paper);
}
.phone-screen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  opacity: 0;
  transition: opacity .4s ease;
}
/* Without JS the first screen is the one you see. */
.phone-screen:first-child { opacity: 1; }
.js-phone .phone-screen { opacity: 0; }
.js-phone .phone-screen.is-on { opacity: 1; }

.beat { padding-block: clamp(3.5rem, 14vh, 8rem); }
.beat:first-child { padding-top: 0; }
/* Trailing room so the phone stays pinned through the LAST beat instead of
   sliding out of frame while it's still being read. Sticky releases when the
   container's bottom reaches it, so the container has to outlast the copy. */
.beat:last-child  { padding-bottom: clamp(8rem, 26vh, 16rem); }
.beat-label {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--stone);
  margin: 0 0 .6rem;
}

/* Mobile keeps the pin. The first version made .phone-stage static here, which
   stacked the phone AFTER all five beats — you read every word, then met one
   phone at the bottom, and the sequence did nothing. Instead the phone sticks
   to the top of the viewport and the copy scrolls underneath it, which is the
   same idea the desktop layout has, rotated.
   The header is already non-sticky at this width, so top:0 is safe. */
@media (max-width: 56rem) {
  .pinned .split, .pinned .split-narrow {
    display: flex;
    flex-direction: column;
    /* MUST override the desktop `align-items: start` above. In a column that
       shrinks every item to its content width, so the sticky band ends up only
       as wide as the phone and the copy scrolls past it at the edges. */
    align-items: stretch;
  }
  .phone-stage {
    order: -1;                 /* phone above the copy, not after it */
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--canvas); /* copy scrolls under, not through */
    /* Full-bleed: break out of .wrap's inline padding so the band reaches both
       screen edges. Otherwise copy still shows in the gutters. */
    margin-inline: calc(-1 * clamp(1.25rem, 4vw, 2.5rem));
    padding-inline: clamp(1.25rem, 4vw, 2.5rem);
    padding-block: .6rem .55rem;
    margin-bottom: .75rem;
    border-bottom: 1px solid var(--sand-soft);
  }
  /* Sized by HEIGHT so it can never eat the screen on a short device.
     50vh leaves just under half the screen for the copy underneath. */
  .phone {
    width: auto;
    height: min(50vh, 26rem);
    padding: .38rem;
    border-radius: 2.1rem;
  }
  .phone-screens { border-radius: 1.75rem; }
  /* Pin the copy column to its own stacking level so a stray word can never
     paint over the band. A fragment of a heading was still showing beside the
     phone; this removes any ambiguity about paint order. */
  .pinned .split > :not(.phone-stage) { position: relative; z-index: 0; }
  .phone-stage .stage-cap { margin-top: .45rem; }
  .beat { padding-block: 2rem; }
  .beat:last-child { padding-bottom: 3rem; }
}
@media (max-width: 56rem) { .shots { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 34rem) { .shots { grid-template-columns: minmax(0, 1fr); } }
.foot-note {
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid #33312a;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 2rem;
  justify-content: space-between;
  font-size: var(--t-caption);
  color: #8f8878;
}

/* ---- Utility --------------------------------------------------- */

.stack { display: grid; gap: 1rem; }
.mt-0 { margin-top: 0; }
.hairline { border: 0; border-top: 1px solid var(--sand); margin: 0; }
.pill-note {
  display: inline-flex; align-items: center; gap: .45rem;
  background: var(--accent-wash); color: var(--accent-deep);
  font-size: var(--t-caption); font-weight: 700;
  padding: .3rem .75rem; border-radius: var(--r-pill);
}

/* ---- Form controls ---------------------------------------------
   The site had NO input styling at all until the contact form shipped:
   fields rendered as bare UA defaults on a cream ground, which for a
   low-vision reader is a box you cannot find. Border is 2px and ink-dark
   rather than a hairline for the same reason. --------------------- */

.field { display: block; margin: 0 0 1.35rem; }
.field > span {
  display: block;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: .4rem;
}
.field .req { color: var(--accent-deep); font-weight: 700; }
.field .hint {
  display: block;
  font-weight: 400;
  font-size: var(--t-small);
  color: var(--stone);
  margin-top: .15rem;
}

input[type="text"], input[type="email"], textarea, select {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--font-body);
  font-size: 1.0625rem;          /* never below 16px — iOS zooms on focus under it */
  line-height: 1.5;
  color: var(--ink);
  background: var(--white);
  border: 2px solid var(--ink-2);
  border-radius: var(--r-card, 4px);
  padding: .7rem .8rem;
  min-height: 3rem;              /* 48px touch target */
}
textarea { min-height: 9rem; resize: vertical; }
select { appearance: auto; }

input[type="text"]:hover, input[type="email"]:hover, textarea:hover, select:hover {
  border-color: var(--ink);
}
input[type="text"]:focus-visible, input[type="email"]:focus-visible,
textarea:focus-visible, select:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
}
input[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: #8a1c11;         /* paired with text, never colour alone */
}

.form-status {
  font-weight: 700;
  color: var(--ink);
  min-height: 1.5rem;
}
.form-status[data-state="error"] { color: #8a1c11; }
.form-status[data-state="ok"] { color: var(--accent-deep); }

button[disabled] { opacity: .55; cursor: not-allowed; }

/* ---- Skip link --------------------------------------------------
   Visible only on keyboard focus; first tab stop on every page. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--white);
  font-weight: 700;
  padding: .8rem 1.1rem;
  z-index: 100;
}
.skip:focus {
  left: .5rem;
  top: .5rem;
  position: fixed;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ============================================================
   NEWSLETTER POPUP — homepage-only scroll-triggered dialog
   Markup lives in index.html between </header> and the footer
   comment (see SPEC.md "THE ONE CONSTRAINT"); behaviour in
   assets/newsletter-modal.js. This file only styles it.

   .nl-modal        fixed full-viewport backdrop, centres the panel
   .nl-modal-panel  the dialog box (carries role="dialog" in markup)
   .nl-modal-title / .nl-modal-body / .nl-modal-actions / .nl-modal-close
   .nl-modal.is-open   open-state hook, added alongside hidden=false
   html.nl-modal-open  background-scroll lock, toggled by the JS —
                       nothing else in this file targets <html>, so this
                       class is otherwise a no-op without the rule below.

   Panel sits on --white ("L3 floats above cream" per the token comment)
   rather than --paper — it's the one element on this site that floats
   over a backdrop, and --paper is already this site's default page-card
   colour, which would make .btn-quiet's default hover (background:
   var(--paper)) invisible against an identically-coloured panel.
   --white sidesteps that without touching the shared button class.

   Contrast (computed, WCAG relative-luminance formula, not eyeballed):
     ink   (#1d1c17) on white (#ffffff)  = 17.06:1  — title
     ink-2 (#3e4947) on white (#ffffff)  =  9.34:1  — body copy
     stone (#696458) on white (#ffffff)  =  5.89:1  — close icon, default
     ink   (#1d1c17) on linen (#f4ede1)  = 14.66:1  — close icon, hover
     white (#ffffff) on accent (#005f56) =  7.58:1  — .btn-primary (existing)
     accent (#005f56) vs white           =  7.58:1  — focus ring / UI, needs only 3:1
   All pairs clear the 4.5:1 text minimum (and the 3:1 UI-component
   minimum) with room to spare — no fabricated failures to report here.
   ============================================================ */

html.nl-modal-open { overflow: hidden; }

.nl-modal {
  position: fixed;
  inset: 0;
  z-index: 200;              /* above the sticky nav (40) and skip link (100) */
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(29, 28, 23, .6); /* --ink, translucent — same literal RGB
                                        --shadow already hardcodes on this file,
                                        not a new colour */
}
.nl-modal.is-open { display: flex; animation: nl-modal-fade .2s ease; }
/* `hidden` is easily beaten by a display rule elsewhere; make sure it always
   wins over .is-open regardless of which one a bug leaves on the element. */
.nl-modal[hidden] { display: none !important; }

/* ⚠️ TRIPWIRE — read before lengthening the popup copy.
   .nl-modal-close is position:absolute inside this scrolling box, so it is NOT
   pinned: the moment the panel's content exceeds max-height, the close "×"
   scrolls out of the panel entirely. Measured Aug 17 with the current copy at a
   335px panel (the 375px-viewport width): content = 480px against a 512px
   mobile cap — only 32px of headroom.
     portrait  (SE 667 / iPhone 12 844): does NOT scroll  ✅
     landscape (375 / 390 tall):         DOES scroll — the × is unreachable ⚠️
   Esc, backdrop click, and "No thanks" all still dismiss, and "No thanks" sits
   at the bottom of the panel where a scrolled reader already is, which is why
   this ships. But ANY further copy growth pushes portrait over the cap too.
   If that happens, fix it properly: make this panel display:flex/column and the
   close button position:sticky;top:0;align-self:flex-end — do not just trim
   padding. */
.nl-modal-panel {
  position: relative;
  width: min(26rem, 100%);
  max-height: min(88vh, 40rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--white);
  border-radius: var(--r);
  box-shadow: var(--shadow), 0 24px 60px -24px rgba(29, 28, 23, .4);
  padding: 3.5rem 2.25rem 2.25rem;
}
.nl-modal.is-open .nl-modal-panel { animation: nl-panel-in .22s ease; }

@keyframes nl-modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes nl-panel-in {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.nl-modal-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.375rem;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 .75rem;
}
.nl-modal-body {
  font-size: var(--t-body);
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0 0 1.75rem;
  max-width: 34ch;
}

.nl-modal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
}
.nl-modal-actions .btn { flex: 1 1 auto; }
/* .btn-quiet's default hover (background: var(--paper)) is a near-invisible
   shift against this panel's --white — --paper is basically the panel's own
   near-neighbour, not a contrasting hover state. --linen is already this
   file's "one step darker than white" token (see .card-flat / nav hover),
   reused here rather than inventing a new colour. */
.nl-modal-panel .btn-quiet:hover { background: var(--linen); border-color: var(--ink-2); }

.nl-modal-close {
  position: absolute;
  top: .5rem;
  right: .5rem;
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 50%;
  color: var(--stone);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color .16s ease, color .16s ease;
}
.nl-modal-close:hover { background: var(--linen); color: var(--ink); }
.nl-modal-close:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* ---- Mobile: bottom sheet, not a full-bleed box ----------------
   375px is this site's priority breakpoint and the one that's never been
   eyeballed. A caregiver mid-scroll on a phone gets a comfortably-inset
   sheet anchored to the bottom — easier to thumb-dismiss, and it doesn't
   plant a hard-edged box in the middle of the screen. Reuses the file's
   existing 34rem breakpoint token (see .foot-grid) rather than a new one. */
@media (max-width: 34rem) {
  .nl-modal { align-items: flex-end; padding: 0; }
  .nl-modal-panel {
    width: 100%;
    max-height: min(85vh, 32rem);
    border-radius: var(--r) var(--r) 0 0;
    padding: 3.5rem 1.5rem calc(1.5rem + env(safe-area-inset-bottom, 0px));
  }
  .nl-modal-actions { flex-direction: column; }
}

/* Reduced motion: the blanket `* { transition/animation: none !important }`
   rule above already neutralises both keyframes on this element (it's
   global and !important, so source order doesn't matter). This block is
   the explicit, self-documenting version for the modal specifically, and
   guarantees the panel is never left mid-animation at opacity 0 — the base
   rules above never set a resting opacity/transform other than visible, so
   dropping the animation just shows the final state instantly. */
@media (prefers-reduced-motion: reduce) {
  .nl-modal.is-open,
  .nl-modal.is-open .nl-modal-panel { animation: none; }
}
