/* ReScale Systems landing page
   Visual baseline: ../DESIGN.md (sage backgrounds, coffee ink, one terracotta accent).
   Orange marks only open leaks and the Book button. */

@font-face {
  font-family: "Bricolage Grotesque";
  src: url("fonts/bricolage.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

/* Hero headline: static cuts of Fraunces (opsz 144, SOFT 100, WONK 1), the soft, slightly
   wonky serif the owner chose. Upright SemiBold, plus a Medium Italic for "money." */
@font-face {
  font-family: "Fraunces Display";
  src: url("fonts/fraunces-display.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Fraunces Display";
  src: url("fonts/fraunces-display-italic.woff2") format("woff2");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("fonts/inter.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --orange: #e8805d;
  --scribble-red: #c23a2a;    /* the hand-drawn underlines only (hero turn, "We" in How it works) */
  --scribble-red-on-dark: #e5533d; /* the same red, lifted for the coffee band: 4.1:1 on --ink */
  --control-mute: #737a6a;    /* inactive carousel dots: 3:1 or better on the page background */
  --orange-deep: #9c3d1f;      /* terracotta text for links and labels: 4.8:1 or better on every page background */
  --ink: #2b2420;
  --ink-soft: #3a322c;
  --ink-mid: #463d36;
  --body: #625850;
  --body-mid: #949a8a;
  --mute: #cfd6c4;
  /* Palette: "Terracotta and sage, sage mist" (chosen 2026-10-14). Pale sage page backgrounds that
     alternate, a deeper sage hero band, warm charcoal ink, and a terracotta accent for the Book button. */
  --canvas: #ebeee5;
  --canvas-soft: #dbe1d2;      /* panels and cards on the pale sage */
  --canvas-alt: #e4e8dd;       /* alternate section bands: a gentle step from the pale sage */
  /* Paper: illustrated objects (phones, tickets, frames, the nav pill) sit a step lighter
     than any page background so they still read as things on the page. */
  --paper: #f6f8f2;
  --paper-tint: #ebeee5;       /* insets inside paper objects, e.g. an incoming text bubble */
  --on-dark: #f1f3ec;
  --on-dark-soft: #c6ccbc;

  --font-display: "Bricolage Grotesque", "Inter", system-ui, sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  --r-sm: 6px;
  --r-md: 6px;
  --r-lg: 24px;               /* large soft panels */
  --r-pill: 9999px;

  --gutter: 16px;
  --section-y: 64px;
  --nav-top: 10px;            /* gap above the floating nav */
  --nav-h: 48px;
  --header-h: calc(var(--nav-top) + var(--nav-h));
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --motion: 360ms;            /* one duration for glides, presses and the FAQ (stamp and pen run longer) */
}

@media (min-width: 640px) {
  :root { --gutter: 24px; --section-y: 88px; --nav-top: 14px; --nav-h: 52px; }
}

@media (min-width: 1100px) {
  :root { --gutter: 40px; --section-y: 112px; }
}

/* ---------- Base ---------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  scrollbar-color: var(--ink-mid) var(--canvas-soft);
}

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.125rem;
  line-height: 1.6;
  caret-color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--ink); color: var(--paper); }

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

/* Headlines: regular weight, tight leading, slightly negative tracking, sentence case. */
h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.04;
  text-wrap: balance;
}

/* Reading text: one muted warm gray, about 18px, 1.6 leading, a 45-character column. */
.lead,
.hero-sub,
.leak-line,
.step > p:last-child,
.faq details p,
.founder-note p:not(.signature),
.inline-stat > p:first-child,
.free-note,
.arrow-list li {
  max-width: 45ch;
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--body);
}

p { margin: 0; }

.lead,
.hero-sub,
.leak-line { text-wrap: pretty; }

ul, ol { margin: 0; padding: 0; }

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}

/* Plain links and summaries get a softly rounded ring; pills keep their own shape. */
a:not(.btn):focus-visible,
summary:focus-visible { border-radius: var(--r-sm); }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.nowrap { white-space: nowrap; }

/* Below-the-fold sections skip layout until they near the screen.
   Content stays in the accessibility tree, tab order and find-in-page. */
.how,
.free,
.faq,
.founder,
.final-cta {
  content-visibility: auto;
  contain-intrinsic-size: auto 900px;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.container {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip-link {
  position: absolute;
  left: 8px;
  top: -100px;
  z-index: 100;
  padding: 12px 16px;
  background: var(--ink);
  color: var(--on-dark);
  border-radius: var(--r-sm);
  font-weight: 600;
}

.skip-link:focus { top: 8px; }

.icon {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 20px;
  border: 0;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--motion) var(--ease-out);
}

/* Ink text on orange keeps 5.4:1 contrast at every size. */
.btn-primary {
  border: 1.5px solid var(--ink);
  box-shadow: 1.5px 1.5px 0 var(--ink); /* a solid offset backdrop, like a printed sticker */
  background: var(--orange);
  color: var(--ink);
}

.btn-primary:hover {
  transform: translateY(-2px);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

/* Pressed: the Book button gives a little under the finger, then springs back. */
.btn-primary:active,
.btn-primary:hover:active { transform: scale(0.97); }

.btn-sm { font-size: 0.875rem; padding: 10px 16px; }
.btn-lg { min-height: 52px; padding: 14px 28px; font-size: 1.0625rem; }

@media (min-width: 640px) {
  .btn-sm { font-size: 0.9375rem; padding: 10px 22px; }
  .btn-lg { min-height: 56px; font-size: 1.125rem; }
}

/* Secondary calls to action: accent text with a small arrow. */
.text-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--orange-deep);
  font-size: 1.125rem;
  font-weight: 600;
  text-decoration: none;
}

.text-link:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }

.icon-arrow { width: 20px; height: 20px; stroke-width: 2; transition: transform 220ms var(--ease-out); }

.text-link:hover .icon-arrow { transform: translateX(4px); }

@media (prefers-reduced-motion: reduce) {
  .icon-arrow { transition: none; }
}

@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover { transition: none; transform: none; }
}

/* ---------- Header: a floating cream pill plus the Book pill ----------
   The header row itself is transparent and lets clicks through; only the two pills
   catch the pointer. It overlaps the hero by its own height. */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--header-h);
  margin-bottom: calc(var(--header-h) * -1);
  pointer-events: none;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: 100%;
  padding-top: var(--nav-top);
}

.nav-pill,
.btn-nav { pointer-events: auto; }

.nav-pill {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  height: var(--nav-h);
  padding: 0 6px;
  border: 1.5px solid var(--ink);
  border-radius: var(--r-pill);
  box-shadow: 1.5px 1.5px 0 var(--ink); /* the same sticker backdrop as the Book button */
  background: var(--paper);
}

.btn-nav { height: var(--nav-h); flex: none; }

/* The orange sits on a layer so it can fade out (nav.js) while another Book button is on screen. */
.btn-primary.btn-nav { position: relative; isolation: isolate; background: var(--paper); }

.btn-nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--orange);
  transition: opacity 260ms var(--ease-out);
}

.btn-nav.is-quiet::before { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .btn-nav::before { transition: none; }
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 8px 0 4px;
  border-radius: var(--r-pill);
  text-decoration: none;
}

.brand-mark { width: 28px; height: 28px; flex: none; }

.brand-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.125rem;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.brand-suffix { display: none; }

.site-nav { display: none; }

/* Narrow phones: the mark carries the brand so the full Book label still fits. */
@media (max-width: 379px) {
  .brand { padding-right: 4px; }
  .brand-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
}

@media (min-width: 560px) {
  .brand-suffix { display: inline; }
}

@media (min-width: 900px) {
  .nav-pill { padding: 0 10px 0 8px; gap: 12px; }
  .site-nav { display: block; }
  .site-nav ul { display: flex; gap: 2px; list-style: none; }
  .site-nav a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 12px;
    border-radius: var(--r-pill);
    font-size: 0.9375rem;
    font-weight: 500;
    text-decoration: none;
  }
  .site-nav a:hover { text-decoration: underline; text-underline-offset: 0.3em; }

  /* The shared sliding oval (see "Sliding oval") rests on the current section and follows hover. */
  .site-nav { position: relative; }
  .site-nav ul { position: relative; z-index: 1; }
  .site-nav.has-glide a:hover { text-decoration: none; }
}

/* ---------- Hero ---------- */

.hero {
  padding-top: calc(var(--header-h) + 32px);
  padding-bottom: 56px;
  /* Warm tan band: text on it uses the darker body tone. */
  background: var(--mute);
  --body: var(--ink-mid);
}

.hero-copy { display: grid; gap: 20px; }

.hero-title {
  font-family: "Fraunces Display", var(--font-display);
  font-size: clamp(2.625rem, 1.45rem + 4.4vw, 5rem);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.02em;
  max-width: 16ch;
}

.hero-title em { font-style: italic; font-weight: 500; }

.hero-title-turn {
  display: block;
  width: fit-content;
  color: var(--ink);
}

/* The plug: a red marker scribble under the turn of the headline: two quick, uneven passes
   laid on top of each other, drawn once across the whole line (400:24) rather than repeated.
   Decorative only; red is used nowhere else. */
.hero-title-turn::after {
  content: "";
  display: block;
  width: 100%;
  aspect-ratio: 400 / 24;
  margin-top: 0.12em;
  background: var(--scribble-red);
  -webkit-mask: url("images/scribble.svg") center / 100% 100% no-repeat;
  mask: url("images/scribble.svg") center / 100% 100% no-repeat;
}

/* Pen stroke, once on load: the scribble draws in left to right, like the "We" lines. */
@media (prefers-reduced-motion: no-preference) {
  .hero-title-turn::after { animation: pen-draw 700ms var(--ease-out) 400ms both; }
}

@keyframes pen-draw {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0); }
}

.hero-side { display: grid; gap: 16px; justify-items: start; }

.hero-sub { max-width: 36ch; }

.hero-meta {
  display: grid;
  gap: 2px;
  font-size: 0.875rem;
  color: var(--body);
}

.hero-meta-facts { color: var(--ink-mid); font-weight: 500; }

@media (min-width: 640px) {
  .hero { padding-top: calc(var(--header-h) + 48px); }
  .hero-sub { font-size: 1.25rem; }
  .hero-meta { font-size: 0.9375rem; }
}

/* Wide screens: the headline runs the full width in two lines; the subhead sits
   under it on the left, the button and facts on the right. */
@media (min-width: 1000px) {
  .hero { padding-top: calc(var(--header-h) + 64px); padding-bottom: 72px; }
  .hero-copy { gap: 32px; }
  .hero-title { max-width: none; }
  .hero-title-turn { white-space: nowrap; }
  .hero-side {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "sub button" "sub meta";
    column-gap: 48px;
    row-gap: 12px;
    align-items: start;
  }
  .hero-sub { grid-area: sub; }
  .hero-side > .btn { grid-area: button; }
  .hero-meta { grid-area: meta; }
}

/* Scene: storefront illustration with the taped leak report.
   Default styles are the settled end state, so it holds without JS
   and under reduced motion. The sequence runs only under .is-animating. */
.scene {
  position: relative;
  margin: 28px 0 0;
  container-type: inline-size;
  overflow: clip;
}

@media (max-width: 639px) {
  .scene { margin-top: 16px; }
}

.scene-stage {
  position: relative;
  overflow: hidden;
  height: clamp(250px, 70vw, 360px);
  border-radius: var(--r-lg);
  background: var(--paper);
}

/* Narrow crop: keep the chalkboard, door and window centred. */
.scene-art {
  position: absolute;
  top: 0;
  left: 50%;
  height: 100%;
  width: auto;
  aspect-ratio: 1200 / 460;
  max-width: none;
  transform: translateX(-49.6%);
}

@media (min-width: 1100px) {
  .scene-stage { height: auto; aspect-ratio: 1200 / 460; }
  .scene-art { left: 0; width: 100%; height: 100%; transform: none; }
}

.s-canvas { fill: var(--paper); }
.s-mute { fill: var(--mute); }
.s-body { fill: var(--body); }
.s-ink { fill: var(--ink); }
.s-ink-soft { fill: var(--ink-soft); }
.s-ink-mid { fill: var(--ink-mid); }
.s-neighbor { fill: var(--mute); opacity: 0.45; }
.s-neighbor-win { fill: var(--paper); opacity: 0.8; }
.s-sidewalk { fill: var(--mute); }
.s-joint { fill: var(--body-mid); opacity: 0.45; }
.s-curb { fill: var(--body-mid); }
.s-lamps { fill: var(--body); }
.s-lamp { fill: var(--mute); }
.s-person { fill: var(--body-mid); }
.s-person-head { fill: var(--mute); }
.s-board { fill: var(--ink); stroke: var(--ink-mid); stroke-width: 5; }

.s-signtext {
  fill: var(--paper);
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 6px;
}

.s-chalk {
  fill: var(--paper);
  font-family: var(--font-body);
  font-size: 23px;
  font-weight: 600;
}

@media (min-width: 1100px) {
  .s-chalk { font-size: 19px; }
}

.tally {
  stroke: var(--paper);
  stroke-width: 4.5;
  stroke-linecap: round;
  transform-box: fill-box;
  transform-origin: 50% 0;
}

.tally-strike { transform-origin: 0 100%; }

/* The tally marks are now only the counter's timing track (hero.js); the number shows. */
.tallies { visibility: hidden; }
.s-count { font-size: 36px; font-weight: 700; transform-box: fill-box; transform-origin: 50% 60%; }

.head { fill: var(--ink); }
.leg { fill: var(--ink-soft); transform-box: fill-box; transform-origin: 50% 0; }
.t-a { fill: var(--body); }
.t-b { fill: var(--ink-mid); }
.t-c { fill: var(--body-mid); }
.t-coat { fill: var(--paper); stroke: var(--ink-mid); stroke-width: 2; }

/* Settled state: walkers are inside, passer-by has gone. */
.walker,
.passer { opacity: 0; }

.walker { transform-box: fill-box; transform-origin: 50% 100%; }

/* Pause / play / replay */
.scene-control {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  min-width: 44px;
  padding: 0 12px;
  border: 0;
  background: none;
  color: var(--ink);
  font: 500 0.875rem/1 var(--font-body);
  cursor: pointer;
}

.scene-control[hidden] { display: none; }
.scene-control:hover .scene-control-text { text-decoration: underline; text-underline-offset: 0.25em; }

.scene-control-icon { width: 18px; height: 18px; fill: currentColor; }
.scene-control-icon > * { display: none; }
.scene-control[data-state="playing"] .ic-pause,
.scene-control[data-state="paused"] .ic-play,
.scene-control[data-state="done"] .ic-replay { display: inline; }

@media (max-width: 479px) {
  .scene-control { padding: 0; width: 44px; justify-content: center; }
  .scene-control-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

/* Leak report ticket: a one-line strip under the scene on small screens,
   a receipt taped in the shop window on wide ones. */
.ticket {
  position: relative;
  margin: 22px 0 0;
  padding: 12px 12px 10px;
  background: var(--paper);
  border: 1px solid var(--mute);
  border-radius: var(--r-sm);
  box-shadow: 0 1px 2px rgba(43, 36, 32, 0.08), 0 10px 24px -14px rgba(43, 36, 32, 0.3);
}

.ticket-head {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.ticket-title {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ticket-list {
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 8px;
}

.ticket-list li {
  position: relative;
  display: flex;
  flex: 1 1 0;
  align-items: center;
  gap: 6px;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.2;
}

.ticket-mark { position: relative; flex: none; width: 16px; height: 16px; }

.ticket-open,
.ticket-done {
  position: absolute;
  inset: 0;
  border-radius: var(--r-sm);
}

/* Open leak: orange. Plugged: coffee ink with a check. */
.ticket-open { border: 2px solid var(--orange); opacity: 0; }

.ticket-done { background: var(--ink); }

.ticket-done svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: var(--paper);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* On the strip the stamp lands over the top edge of its cell. */
.ticket-stamp {
  position: absolute;
  top: -26px;
  left: 14px;
  padding: 1px 6px;
  border: 2px solid var(--ink);
  border-radius: var(--r-sm);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transform: rotate(-5deg);
}

@media (min-width: 480px) {
  .ticket-list li { font-size: 0.875rem; }
}

@media (min-width: 1100px) {
  .ticket {
    position: absolute;
    left: 59.5%;
    top: 43.5%;
    width: 24.5%;
    margin: 0;
    padding: 1.1cqw 1.2cqw 1.2cqw;
    transform: rotate(-1.5deg);
  }

  /* Tape strips */
  .ticket::before,
  .ticket::after {
    content: "";
    position: absolute;
    top: -9px;
    width: 52px;
    height: 18px;
    background: var(--mute);
    opacity: 0.7;
    border-radius: 2px;
  }

  .ticket::before { left: 14px; transform: rotate(-5deg); }
  .ticket::after { right: 14px; transform: rotate(4deg); }

  .ticket-head {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip: auto;
    white-space: normal;
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding-bottom: 0.7cqw;
    border-bottom: 1px dashed var(--mute);
  }
  .ticket-title { font-size: clamp(0.8125rem, 1.15cqw, 0.9375rem); }
  /* No clipping here, so wider text spacing never hides anything; the stamp's slam grows
     from its right edge (below) so it stays over the ticket. */
  .ticket-list {
    display: grid;
    gap: 0.6cqw;
    margin-right: -6px;
    padding: 0.8cqw 6px 4px 0;
  }

  .ticket-list li {
    display: grid;
    grid-template-columns: 16px 1fr auto;
    gap: 8px;
    font-size: clamp(0.75rem, 1.08cqw, 0.875rem);
    font-weight: 500;
    line-height: 1.25;
    white-space: normal;
  }
  .ticket-mark { width: 16px; height: 16px; }
  .ticket-stamp {
    position: static;
    font-size: clamp(0.6875rem, 0.85cqw, 0.75rem);
    padding: 1px 5px;
    background: none;
    transform-origin: 100% 50%;
  }
}

/* ---------- The sequence ---------- */

.is-animating .ticket-stamp {
  animation: stamp-in 380ms cubic-bezier(0.2, 0.9, 0.3, 1) var(--d) both;
}

.is-animating .ticket-open {
  animation: mark-out 260ms var(--ease-out) var(--d) both;
}

.is-animating .ticket-done {
  animation: mark-in 320ms var(--ease-out) var(--d) both;
}

.is-animating .walker {
  animation: walk-in 2.4s linear var(--d) both;
}

.is-animating .walker-body {
  animation: bob 0.3s ease-in-out var(--d) 7 alternate both;
}

.is-animating .leg-a { animation: stride-a 0.3s ease-in-out var(--d) 7 alternate both; }
.is-animating .leg-b { animation: stride-b 0.3s ease-in-out var(--d) 7 alternate both; }

.is-animating .passer { animation: pass-by 4.6s linear both; }
.is-animating .passer-body { animation: bob 0.32s ease-in-out 0s 14 alternate both; }
.is-animating .passer-leg.leg-a { animation: stride-a 0.32s ease-in-out 0s 14 alternate both; }
.is-animating .passer-leg.leg-b { animation: stride-b 0.32s ease-in-out 0s 14 alternate both; }

.is-animating .room-group {
  animation: settle-in 450ms var(--ease-out) var(--d) both;
}

.is-animating .tally {
  animation: tick 240ms var(--ease-out) var(--d) both;
}

.scene.is-paused * { animation-play-state: paused !important; }

@keyframes stamp-in {
  0% { opacity: 0; transform: rotate(var(--stamp-r, -5deg)) scale(1.9); }
  55% { opacity: 1; transform: rotate(var(--stamp-r, -5deg)) scale(0.94); }
  100% { opacity: 1; transform: rotate(var(--stamp-r, -5deg)) scale(1); }
}

@keyframes mark-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes mark-in {
  from { opacity: 0; transform: scale(0.55); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes walk-in {
  0% { opacity: 1; transform: translate(0, 0); }
  86% { opacity: 1; transform: translate(559px, 0); }
  100% { opacity: 0; transform: translate(568px, -14px) scale(0.86); }
}

@keyframes pass-by {
  0% { opacity: 1; transform: translateX(0); }
  100% { opacity: 1; transform: translateX(-1600px); }
}

@keyframes bob {
  from { transform: translateY(0); }
  to { transform: translateY(-3px); }
}

@keyframes stride-a {
  from { transform: rotate(16deg); }
  to { transform: rotate(-16deg); }
}

@keyframes stride-b {
  from { transform: rotate(-16deg); }
  to { transform: rotate(16deg); }
}

@keyframes settle-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes tick {
  from { opacity: 0; transform: scale(0); }
  to { opacity: 1; transform: scale(1); }
}

/* Reduced motion: hold the settled end state, no movement. */
@media (prefers-reduced-motion: reduce) {
  .scene * { animation: none !important; }
  .scene-control { display: none; }
}

/* ---------- Sections ---------- */

.section { padding-block: var(--section-y); }

.section-head { display: grid; gap: 16px; max-width: 760px; }

.section-head h2 { font-size: clamp(2.25rem, 1.5rem + 3vw, 4rem); }

.source-credit { position: relative; font-size: 0.8125rem; color: var(--body); line-height: 1.4; }

.cta-row {
  display: grid;
  gap: 16px;
  justify-items: start;
  margin-top: 56px;
  padding: 32px 0 0;
  border-top: 1px solid var(--mute);
}

.cta-row p { font-family: var(--font-display); font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); font-weight: 400; letter-spacing: -0.02em; line-height: 1.1; max-width: 26ch; }

@media (min-width: 800px) {
  .cta-row { grid-template-columns: 1fr auto; align-items: center; padding: 40px 0 0; }

}

/* ---------- Leaks ---------- */

.leaks { background: var(--canvas); }

/* Large soft panels: no outline, no shadow. */
.panel {
  --panel-pad: 20px;
  padding: 28px var(--panel-pad) 24px;
  border-radius: var(--r-lg);
  background: var(--canvas-soft);
}

@media (min-width: 700px) {
  .panel { --panel-pad: 40px; padding-block: 40px 36px; }
}

@media (min-width: 1100px) {
  .panel { --panel-pad: 56px; padding-block: 56px 48px; }
}

.leak-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  font-size: clamp(1.75rem, 1.35rem + 1.6vw, 2.5rem);
}

.leak-num {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--orange-deep);
}

.sms {
  position: relative;
  max-width: 34ch;
  margin-top: 8px;
  padding: 10px 14px;
  border-radius: 16px;
  font-size: 0.9375rem;
  line-height: 1.4;
}

.sms-out {
  background: var(--ink);
  color: var(--on-dark);
  border-bottom-left-radius: 4px;
}

.sms-in {
  margin-left: auto;
  margin-right: 0;
  width: fit-content;
  background: var(--paper-tint);
  border: 1px solid var(--mute);
  border-bottom-right-radius: 4px;
  margin-bottom: 6px;
}

.stamp {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--r-sm);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.125rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  transform: rotate(-2deg);
}

.stamp-lost { background: var(--orange); color: var(--ink); }

.stamp-plugged { background: var(--ink); color: var(--paper); }

.stamp-note {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

.inline-stat {
  flex: 1 1 100%;
  display: grid;
  gap: 6px;
  max-width: 62ch;
  padding: 20px 0 0;
  border-top: 1px solid var(--mute);
}

.inline-stat > p:first-child { color: var(--ink); }

/* Phone mock (illustration only, not a working form). */
.phone {
  margin: 4px 0 0;
  width: 100%;
  max-width: 300px;
  padding: 10px;
  border-radius: 28px;
  background: var(--ink);
}

.phone-screen {
  display: grid;
  gap: 10px;
  padding: 18px 16px 16px;
  border-radius: 20px;
  background: var(--paper);
}

.phone-brand { font-family: var(--font-display); font-weight: 700; font-size: 0.9375rem; }

.mock-title { font-family: var(--font-display); font-weight: 600; font-size: 1.125rem; line-height: 1.15; }

.mock-field { display: grid; gap: 4px; }

.mock-label { font-size: 0.8125rem; font-weight: 600; }

.mock-input {
  display: block;
  height: 36px;
  border: 1px solid var(--ink);
  border-radius: var(--r-sm);
  background: var(--paper);
}

.mock-consent { display: grid; grid-template-columns: auto 1fr; gap: 8px; align-items: start; }

.mock-consent p { font-size: 0.75rem; line-height: 1.45; color: var(--ink-mid); }

.mock-check {
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border: 1.5px solid var(--ink);
  border-radius: 4px;
  background: var(--paper);
}

.mock-link { text-decoration: underline; text-underline-offset: 0.15em; }

.mock-button {
  padding: 10px;
  border-radius: var(--r-md);
  background: var(--ink);
  color: var(--paper);
  font-weight: 700;
  text-align: center;
  font-size: 0.9375rem;
}

/* ---------- Leaks: before / after stories ----------
   One panel. leaks.js turns the three stories into tabs; without JS they stack.
   Each story: one stage (the leak; the fix and the result) beside its notes,
   stat and a "See the full story" disclosure. */

/* Two buttons in one pill; the chosen side is filled coffee. */
.phase-toggle {
  display: inline-flex;
  justify-self: start;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--control-mute);
  border-radius: var(--r-pill);
  background: var(--paper);
}

.phase-toggle[hidden] { display: none; }

.phase-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 20px;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--ink-mid);
  font: 600 1rem/1.2 var(--font-body);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 180ms var(--ease-out), color 180ms var(--ease-out);
}

.phase-link:hover { background: var(--canvas-soft); color: var(--ink); }

.phase-link[aria-pressed="true"] { background: var(--ink); color: var(--paper); }

.phase-link:focus-visible { outline-offset: 2px; border-radius: var(--r-pill); }

@media (prefers-reduced-motion: reduce) {
  .phase-link { transition: none; }
}

/* Phone pieces */
.phone-sm { max-width: 260px; }

.phone-bar {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--body);
  font-variant-numeric: tabular-nums;
}

.notif {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border-radius: var(--r-md);
  background: var(--paper-tint);
}

.notif-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pill);
  border: 2px solid var(--ink);
}

/* An unanswered call is an open leak. */
.notif-open .notif-icon { border-color: var(--orange); }

.notif-title { font-weight: 700; font-size: 0.9375rem; }

.notif-meta { font-size: 0.8125rem; color: var(--body); }

.phone-empty { font-size: 0.8125rem; color: var(--body); text-align: center; }

.sms-meta { font-size: 0.75rem; color: var(--body); }

.phone-screen .sms { margin-top: 0; }

/* Visit history (one-time customers, before) */
.visits {
  display: grid;
  gap: 10px;
  width: 100%;
  max-width: 300px;
  padding: 18px;
  border-radius: var(--r-md);
  border: 1px solid var(--mute);
  background: var(--paper);
}

.visits-head { font-family: var(--font-display); font-weight: 700; }

.visit { display: flex; align-items: center; gap: 10px; font-size: 0.9375rem; color: var(--body); }

.visit-done { color: var(--ink); font-weight: 600; }

.visit-dot { flex: none; width: 12px; height: 12px; border-radius: var(--r-pill); background: var(--ink); }

.visit-dot-empty { background: none; border: 2px dashed var(--body-mid); }

/* Open-leak status pill (orange marks an open leak only). */
.thread-status {
  justify-self: start;
  padding: 3px 10px;
  border-radius: var(--r-sm);
  font-size: 0.8125rem;
  font-weight: 700;
}

.thread-status-open { background: var(--orange); color: var(--ink); }

/* Table card with QR */
.tent {
  display: grid;
  justify-items: center;
  gap: 10px;
  width: 220px;
  padding: 18px 18px 20px;
  border-radius: var(--r-md);
  border: 1px solid var(--ink);
  background: var(--paper);
  text-align: center;
}

.tent-brand { font-family: var(--font-display); font-weight: 700; }

.qr { width: 132px; height: 132px; }
.qr-bg { fill: var(--paper); }
.qr-ink { fill: var(--ink); }

.tent-text { font-size: 0.875rem; font-weight: 600; line-height: 1.3; }

/* Dining room, side view */
.room { width: 100%; max-width: 380px; height: auto; }
.room-wall { fill: var(--paper); }
.room-wall-line { fill: var(--mute); }
.room-floor { fill: var(--mute); }
.room-lamp-cord { fill: var(--body); }
.room-lamp { fill: var(--ink-mid); }
.room-chair { fill: var(--mute); stroke: var(--body-mid); stroke-width: 1.5; }
.room-table { fill: var(--ink-mid); }
.room-glass { fill: var(--body-mid); }
.room-head { fill: var(--ink); }
.g-a { fill: var(--body); }
.g-b { fill: var(--body-mid); }
.g-c { fill: var(--ink-soft); }

/* Leak 2 message threads */
.thread {
  display: grid;
  gap: 8px;
  margin-top: 16px;
  padding: 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--mute);
  background: var(--paper);
}

.thread .sms { margin-top: 0; }

.thread-meta { font-size: 0.75rem; font-weight: 600; color: var(--body); }

/* QR card, compact (sits above the sign-up form) */
.tent-mini {
  display: grid;
  grid-template-columns: 72px 1fr;
  align-items: center;
  justify-items: start;
  gap: 12px;
  width: 100%;
  max-width: 300px;
  padding: 10px 12px;
  text-align: left;
}

.tent-mini .qr { width: 72px; height: 72px; }

.frame-signup { position: relative; gap: 12px; }

/* ---------- How it works ---------- */

.how {
  background: var(--ink);
  color: var(--on-dark);
  --body: var(--on-dark-soft);
}

.steps {
  list-style: none;
  display: grid;
  margin-top: 40px;
  border-top: 1px solid var(--body);
  counter-reset: how;
}

.step {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 14px;
  row-gap: 10px;
  padding: 24px 0 28px;
  border-bottom: 1px solid var(--ink-mid);
  counter-increment: how;
}

.step::before {
  content: counter(how);
  grid-row: 2;
  font-family: var(--font-display);
  font-size: 3.5rem;
  font-weight: 650;
  line-height: 0.9;
  font-variant-numeric: tabular-nums;
  color: var(--on-dark);
}

.step h3,
.step > p:last-child { grid-column: 1 / -1; }

.step h3 { font-size: 1.5rem; letter-spacing: -0.015em; }

.step > p:last-child { color: var(--body); max-width: 40ch; }

@media (min-width: 860px) {
  .steps { grid-template-columns: repeat(3, 1fr); }
  .step { align-content: start; padding: 32px 32px 8px 0; border-bottom: 0; }
  .step + .step { padding-left: 32px; border-left: 1px solid var(--ink-mid); }
  .step::before { font-size: 4.5rem; }
}

/* ---------- FAQ ---------- */

.faq { background: var(--canvas-alt); }

.faq-list { margin-top: 32px; max-width: 860px; border-top: 1px solid var(--ink); }

.faq details { border-bottom: 1px solid var(--mute); }

.faq summary {
  position: relative;
  display: block;
  min-height: 44px;
  padding: 20px 48px 20px 0;
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.3;
  cursor: pointer;
  list-style: none;
}

.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: "";
  position: absolute;
  right: 6px;
  top: 50%;
  width: 14px;
  height: 14px;
  margin-top: -9px;
  border-right: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  transform: rotate(45deg);
  transition: transform 200ms var(--ease-out);
}

.faq details[open] summary::after { transform: rotate(-135deg); margin-top: -2px; }

.faq summary:hover { color: var(--ink-mid); }

.faq details p { padding: 0 0 24px; }

@media (min-width: 640px) {
  .faq summary { font-size: 1.375rem; padding-block: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  .faq summary::after { transition: none; }
}

/* ---------- Founder ---------- */

.founder { background: var(--canvas); }

.founder-inner { display: grid; gap: 28px; }

.founder-inner h2 { font-size: clamp(2rem, 1.35rem + 2.8vw, 3.5rem); }

.founder-note { display: grid; gap: 20px; max-width: 860px; }

.founder-note div { display: grid; gap: 16px; }

.signature {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 400;
  color: var(--ink);
}

.signature::before { content: "— "; }

.founder-photo { display: block; width: 160px; }

.founder-photo img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border-radius: 50%; }

@media (min-width: 640px) {
  .founder-note { grid-template-columns: 216px 1fr; gap: 36px; align-items: start; }
  .founder-photo { width: 216px; }
}

/* ---------- Final CTA ---------- */

.final-cta {
  padding-block: calc(var(--section-y) * 1.1);
  background: var(--orange);
  color: var(--ink);
}

.final-inner { display: grid; gap: 20px; justify-items: start; }

.final-cta h2 { font-size: clamp(2.5rem, 1.5rem + 3vw, 3.75rem); letter-spacing: -0.025em; line-height: 1.02; max-width: 18ch; }

.final-inner > p { font-size: 1.25rem; color: var(--ink); }

.final-cta .btn { margin-top: 8px; }

/* On the accent field the Book button turns coffee so it stays the loudest thing on the band. */
.final-cta .btn-primary { background: var(--ink); color: var(--paper); box-shadow: 1.5px 1.5px 0 var(--paper); }

.final-cta :focus-visible { outline-color: var(--ink); }

.site-footer :focus-visible { outline-color: var(--paper); }

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

.site-footer {
  background: var(--ink);
  color: var(--on-dark);
  /* Overlap the band above by 1px so a fractional edge never shows a hairline. */
  margin-top: -1px;
  padding-block: 57px 48px;
  font-size: 0.9375rem;
}

.footer-inner { display: grid; gap: 8px; justify-items: start; }

.footer-name { font-family: var(--font-display); font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; }

.footer-links { list-style: none; display: grid; gap: 0; }

.footer-links a { display: inline-flex; align-items: center; min-height: 44px; }

@media (min-width: 760px) {
  .footer-links { grid-auto-flow: column; gap: 28px; }
}

/* ---------- Wide screens: heading beside content for the reading sections ---------- */
@media (min-width: 1000px) {
  .faq-inner,
  .founder-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr);
    gap: 64px;
    align-items: start;
  }
  .faq-list { margin-top: 0; max-width: none; }
  .founder-note { max-width: none; }
}

/* Wide screens: the closing band mirrors the hero (statement left, action right),
   and the FAQ heading stays beside the questions while they scroll. */
@media (min-width: 1000px) {
  .final-inner {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    grid-template-areas: "title sub" "title action";
    column-gap: 48px;
    row-gap: 16px;
    align-items: end;
  }
  .final-inner > h2 { grid-area: title; }
  .final-inner > p { grid-area: sub; }
  .final-inner > .btn { grid-area: action; align-self: start; margin-top: 0; }

  .faq-inner .section-head { position: sticky; top: calc(var(--header-h) + 32px); }
}

/* Sign-up card: the QR card tilts onto the corner and the field labels sit inside the
   fields, so the card stays compact. The consent wording stays fully visible. */
.frame-signup .tent-mini {
  position: absolute;
  top: 4px;
  right: 4px;
  z-index: 1;
  display: block;
  width: auto;
  max-width: none;
  padding: 6px;
  transform: rotate(5deg);
}
.frame-signup .tent-mini > div { display: none; }

/* Keep the form's brand and title clear of the tilted QR card in the corner. */
.frame-signup .phone-brand,
.frame-signup .mock-title { padding-right: 60px; }
.frame-signup .tent-mini .qr { width: 52px; height: 52px; }

.frame-signup .mock-field { position: relative; gap: 0; }
.frame-signup .mock-label {
  position: absolute;
  top: 50%;
  left: 10px;
  transform: translateY(-50%);
  font-weight: 500;
  color: var(--body);
  pointer-events: none;
}
.frame-signup .mock-input { height: 36px; }

/* Long stamps put their note on its own line under the picture. */
.frame-stamp .stamp {
  flex-direction: column;
  align-items: center;
  gap: 2px;
  max-width: 100%;
  font-size: 1rem;
  line-height: 1.15;
  text-align: center;
}

/* ---------- Privacy page ---------- */
/* The floating header overlaps the page top, as on the hero. */
.legal.section { padding-top: calc(var(--header-h) + 48px); }

.legal-inner { display: grid; gap: 16px; max-width: 70ch; }

.legal h1 { font-size: clamp(2.25rem, 1.5rem + 3vw, 3.5rem); }

.legal h2 { margin-top: 16px; font-size: 1.375rem; }

.legal p { font-size: 1.125rem; }

.legal-inner ul { display: grid; gap: 6px; padding-left: 1.25em; font-size: 1.125rem; }

.legal-date { color: var(--body); font-size: 0.9375rem !important; }

.legal a { text-decoration: underline; text-underline-offset: 3px; }

.legal-back { display: inline-flex; align-items: center; min-height: 44px; }

/* ---------- How it works: spacing ---------- */
.how.section { padding-block: calc(var(--section-y) * 1.3); }

.how .steps { margin-top: 64px; }

.how .step { row-gap: 18px; padding-block: 36px 44px; }

@media (min-width: 860px) {
  .how .step { padding: 48px 40px 16px 0; }
  .how .step + .step { padding-left: 40px; }
}

.how .step::before { font-weight: 400; }

.how .step h3 {
  font-size: 1.625rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--on-dark);
}

.how :focus-visible { outline-color: var(--on-dark); }

/* ---------- Motion ----------
   Scroll reveals. Everything is visible without them:
   reveal.js hides only what sits below the fold, and only when motion is allowed. */
.rv-ready {
  opacity: 0;
  transform: translateY(28px);
}

.rv-ready.rv-in {
  opacity: 1;
  transform: none;
  transition: opacity 640ms var(--ease-out) var(--rv-d, 0ms), transform 760ms var(--ease-out) var(--rv-d, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  .rv-ready { opacity: 1; transform: none; }
  .step .we-line, .step .we-line::after { transform: none; }

}

/* Counting figures (reveal.js) hold their final width while they count. */
.count { display: inline-block; text-align: right; }

/* FAQ: where the browser can style the answer box, answers fade and settle in on open
   and fade out before closing. Elsewhere they open and close as before. */
@supports selector(::details-content) {
  @media (prefers-reduced-motion: no-preference) {
    .faq details::details-content {
      opacity: 0;
      transform: translateY(-6px);
      transition: opacity var(--motion) var(--ease-out), transform var(--motion) var(--ease-out), content-visibility var(--motion) allow-discrete;
    }
    .faq details[open]::details-content { opacity: 1; transform: none; }
  }
}

/* ---------- Free to start ----------
   Two open columns, no boxes: the call on the left, the plan on the right. */
.free { background: var(--canvas); }

.free-title {
  max-width: 18ch;
  font-size: clamp(2.25rem, 1.5rem + 3vw, 4rem);
}

.free-grid { display: grid; gap: 56px; margin-top: 48px; }

.free-col {
  display: grid;
  gap: 24px;
  align-content: start;
  padding-top: 24px;
  border-top: 1px solid var(--ink);
}

.free-col-title { font-size: 1.625rem; letter-spacing: -0.02em; }

.free-figure {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.75rem, 1.35rem + 1.6vw, 2.5rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: lining-nums;
  color: var(--ink);
}

.arrow-list { list-style: none; display: grid; gap: 10px; }

.arrow-list li { position: relative; padding-left: 32px; }

/* Drawn arrow bullet, tinted from the ink. */
.arrow-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.42em;
  width: 18px;
  height: 18px;
  background: var(--ink);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10h11M11 5.5 15.5 10 11 14.5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10h11M11 5.5 15.5 10 11 14.5'/%3E%3C/svg%3E") center / contain no-repeat;
}

.free .btn { justify-self: start; margin-top: 8px; }

@media (min-width: 860px) {
  .free-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 64px; margin-top: 64px; }
}

/* ---------- Leaks: one tabbed panel ---------- */

/* Wide screens: heading on the left, the intro beside it, so the section starts short. */
@media (min-width: 1000px) {
  .leaks-head {
    max-width: none;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 64px;
    align-items: end;
  }
}

.leaks-panel { margin-top: 28px; padding-block: 16px 20px; }

/* This section runs a little tighter than the others so the whole story fits in view. */
.leaks.section { padding-block: 48px; }

.leaks .cta-row { margin-top: 32px; padding-top: 24px; }

@media (min-width: 1000px) {
  .leaks.section { padding-block: 64px; }
  .leaks .cta-row { margin-top: 24px; padding-top: 20px; }
  .leaks-panel { margin-top: 24px; }
}

@media (min-width: 700px) {
  .leaks-panel { --panel-pad: 32px; padding-block: 24px 32px; }
}

.story + .story { margin-top: 40px; padding-top: 32px; border-top: 1px solid var(--mute); }

.story-head { display: grid; gap: 6px; margin-bottom: 20px; }

.story-head .leak-title { font-size: clamp(1.625rem, 1.3rem + 1.2vw, 2.125rem); }

.story-body { display: grid; gap: 20px; }

.story-main { display: grid; gap: 12px; align-content: start; }

.story-side { display: grid; gap: 16px; align-content: start; }

.story-side .inline-stat { padding-top: 16px; }

.story-side .inline-stat > p:first-child { font-size: 1.0625rem; max-width: 40ch; }

.leaks .source-credit { font-size: 1rem; }

/* The stage: one large paper surface. Pictures sit straight on it (no frames inside). */
.stage {
  display: grid;
  gap: 24px;
  padding: 16px 12px;
  border-radius: 16px;
  background: var(--paper);
}

.stage-view { display: grid; gap: 16px; justify-items: center; align-content: center; }

.view-label { justify-self: start; font-size: 0.9375rem; font-weight: 600; color: var(--body); }

.beat { display: grid; gap: 12px; justify-items: center; align-content: start; width: 100%; }

.beat-arrow { display: grid; place-items: center; color: var(--body); }

.beat-arrow .icon { width: 24px; height: 24px; stroke-width: 2; transform: rotate(90deg); }

.stage .phone,
.stage .phone-sm { max-width: 300px; padding: 6px; border-radius: 22px; }

.stage .phone-screen { gap: 8px; padding: 12px; border-radius: 16px; }

.stage .thread { width: 100%; max-width: 340px; margin: 0; }

.stage .room { max-width: 280px; }

.stage .beat > .sms { max-width: 300px; margin: 0; }

/* Frame text never drops below 14px. */
.stage :is(.phone-bar, .notif-meta, .phone-empty, .sms-meta, .mock-label, .mock-consent p,
  .thread-meta, .thread-status, .stamp-note, .tent-text) { font-size: 0.875rem; }

.stage .mock-consent p { line-height: 1.4; }

/* Wide screens: stage on the left, notes, stat and the full story on the right.
   "With ReScale" shows the fix and the result side by side. */
@media (min-width: 900px) {
  .story-body { grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr); column-gap: 40px; align-items: start; }
  .stage { padding: 24px; }
  .stage-view.view-after { grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; column-gap: 12px; }
  .view-after .view-label { grid-column: 1 / -1; }
  .beat-arrow .icon { transform: none; }
}

/* ---------- Tabbed mode (set by leaks.js) ---------- */

.story-tabs {
  display: grid;
  gap: 2px;
  margin: 0 0 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--mute);
}

.story-tab {
  position: relative;
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  column-gap: 12px;
  align-content: start;
  min-height: 44px;
  padding: 8px 6px;
  border: 0;
  border-radius: 12px;
  background: none;
  color: var(--body);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* Phones: a radio-style marker shows the chosen story. */
.story-tab::before {
  content: "";
  grid-row: 1 / span 2;
  align-self: start;
  width: 16px;
  height: 16px;
  margin-top: 4px;
  border: 2px solid var(--ink-mid);
  border-radius: var(--r-pill);
}

.story-tab[aria-selected="true"]::before { border-width: 5px; border-color: var(--ink); }

.story-tab-name {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--ink-mid);
}

.story-tab-hook { grid-column: 2; font-size: 1rem; line-height: 1.45; color: var(--body); }

.story-tab[aria-selected="true"] .story-tab-name { color: var(--ink); }

.story-tab:hover .story-tab-name { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }

.story-tab:focus-visible { outline-offset: 0; }

/* Wide screens: three tabs across; the chosen one carries a coffee bar underneath. */
@media (min-width: 700px) {
  .story-tabs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding-bottom: 0; }
  .story-tab { grid-template-columns: minmax(0, 1fr); padding: 8px 12px 14px; border-radius: 12px 12px 0 0; }
  .story-tab::before { display: none; }
  .story-tab-hook { grid-column: 1; }
  .story-tab::after {
    content: "";
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: -1px;
    height: 3px;
    border-radius: 3px 3px 0 0;
    background: var(--ink);
    opacity: 0;
    transform: scaleX(0.6);
    transition: opacity 220ms var(--ease-out), transform 260ms var(--ease-out);
  }
  .story-tab[aria-selected="true"]::after { opacity: 1; transform: none; }
}

/* The tab already names the story and its hook. */
.is-tabbed .story-head {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.is-tabbed .story + .story { margin-top: 0; padding-top: 0; border-top: 0; }

.is-tabbed .view-label { display: none; }

/* Before and With ReScale share one spot on the stage and crossfade. */
.is-tabbed .stage { grid-template-areas: "view"; }

.is-tabbed .stage-view {
  grid-area: view;
  transition: opacity 320ms var(--ease-out), transform 420ms var(--ease-out), visibility 0s linear 0s;
}

.is-tabbed .story[data-phase="before"] .view-after,
.is-tabbed .story[data-phase="after"] .view-before {
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 200ms ease-in, transform 200ms ease-in, visibility 0s linear 200ms;
}

/* A newly chosen story fades in. */
@media (prefers-reduced-motion: no-preference) {
  .is-tabbed .story:not([hidden]) { animation: story-in 360ms var(--ease-out); }
}

@keyframes story-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* Narrow screens with motion: the fix crossfades to the result once. */
@media (max-width: 899px) and (prefers-reduced-motion: no-preference) {
  .is-tabbed .view-after:has([data-beat="result"]) { grid-template-areas: "beat"; }
  .is-tabbed .view-after:has([data-beat="result"]) > .beat { grid-area: beat; transition: opacity 360ms var(--ease-out), transform 420ms var(--ease-out), visibility 0s linear 0s; }
  .is-tabbed .view-after:has([data-beat="result"]) > .beat-arrow { display: none; }
  .is-tabbed .view-after[data-step="fix"] [data-beat="result"],
  .is-tabbed .view-after[data-step="result"] [data-beat="fix"] {
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity 200ms ease-in, transform 200ms ease-in, visibility 0s linear 200ms;
  }
}

@media (prefers-reduced-motion: reduce) {
  .is-tabbed .stage-view,
  .is-tabbed .story-tab::after { transition: none; }
}

/* ---------- Sliding oval (nav.js) ----------
   One indicator for the nav links, the leak tabs and the Before / With ReScale toggle.
   Transforms only: the container translates, the middle <i> stretches with scale, and the
   end cap translates to the far side, so the round ends never distort. --axis: y stacks
   the same three pieces top to bottom. Without JS none of this exists. */
.glide {
  --r: 22px;
  --glide-fill: var(--mute);
  --glide-line: 0px;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  transform: translate(var(--gx, 0), var(--gy, 0));
  transition: transform var(--motion) var(--ease-out), opacity var(--motion) var(--ease-out);
}
.glide.is-on { opacity: 1; }
.glide > i {
  position: absolute;
  top: 0;
  left: 0;
  border: var(--glide-line) solid var(--glide-edge, transparent);
  background: var(--glide-fill);
  transform-origin: 0 0;
  transition: transform var(--motion) var(--ease-out);
}
.glide[data-axis="x"] > i { height: var(--gh); width: var(--r); }
.glide[data-axis="x"] > i:nth-child(1) { border-right: 0; border-radius: var(--r) 0 0 var(--r); }
.glide[data-axis="x"] > i:nth-child(2) { left: calc(var(--r) - 1px); width: 100px; border-inline: 0; transform: scaleX(var(--gs)); }
.glide[data-axis="x"] > i:nth-child(3) { border-left: 0; border-radius: 0 var(--r) var(--r) 0; transform: translateX(var(--ge)); }
.glide[data-axis="y"] > i { width: var(--gw); height: var(--r); }
.glide[data-axis="y"] > i:nth-child(1) { border-bottom: 0; border-radius: var(--r) var(--r) 0 0; }
.glide[data-axis="y"] > i:nth-child(2) { top: calc(var(--r) - 1px); height: 100px; border-block: 0; transform: scaleY(var(--gs)); }
.glide[data-axis="y"] > i:nth-child(3) { border-top: 0; border-radius: 0 0 var(--r) var(--r); transform: translateY(var(--ge)); }
.glide.is-placing,
.glide.is-placing > i { transition: none; }

@media (prefers-reduced-motion: reduce) {
  .glide, .glide > i { transition: none; }
}

/* Leak tabs: the chosen tab sits on a paper oval with a 3:1 outline (it replaces the
   coffee bar), stacked on phones and across on wide screens. */
.leaks-panel.has-glide { position: relative; }
.leaks-panel > .glide { --axis: y; --glide-fill: var(--paper); --glide-line: 1.5px; --glide-edge: var(--control-mute); }
.has-glide .story-tab { z-index: 1; }
@media (min-width: 700px) {
  .leaks-panel > .glide { --axis: x; }
  .has-glide .story-tab::after { display: none; }
}

/* Before / With ReScale: the coffee fill glides to the chosen side. */
.phase-toggle.has-glide { position: relative; }
.phase-toggle > .glide { --glide-fill: var(--ink); }
.has-glide > .phase-link { position: relative; z-index: 1; }
.has-glide > .phase-link[aria-pressed="true"],
.has-glide > .phase-link[aria-pressed="true"]:hover { background: none; color: var(--paper); }

/* ---------- Owner pass, 2026-10-14 ---------- */

/* "Illustration": a small, quiet label in the corner of every drawn scene and mock. */
.illus-label {
  position: absolute;
  top: 10px;
  left: 14px;
  z-index: 1;
  color: var(--body);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.2;
  pointer-events: none;
}

.scene .illus-label { top: 14px; left: 16px; }

.stage { position: relative; padding-top: 36px; }

@media (min-width: 900px) {
  .stage { padding-top: 40px; }
  .stage .illus-label { top: 14px; left: 20px; }
}

/* Privacy pointer under the main Book buttons. */
.privacy-note { font-size: 0.875rem; color: var(--body); }

.privacy-note a { color: var(--ink); text-decoration: underline; text-underline-offset: 0.2em; }

.free .privacy-note { margin-top: -12px; }

/* How it works: the "We" in steps 2 and 3 carries the red scribble from the hero. */
.we-mark { position: relative; display: inline-block; }

.we-line {
  position: absolute;
  left: -4%;
  right: -8%;
  bottom: -0.22em;
  height: 0.44em;
  overflow: hidden;
  pointer-events: none;
}

.we-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--scribble-red-on-dark);
  /* A short two-pass scribble drawn for one word; the long hero one turns to a hairline this small. */
  -webkit-mask: url("images/scribble-short.svg") center / 100% 100% no-repeat;
  mask: url("images/scribble-short.svg") center / 100% 100% no-repeat;
}

/* Pen stroke, once: when its step first scrolls in (reveal.js), the window slides right
   while the scribble inside slides back, so the line appears left to right in place. */
.step.rv-ready .we-line { transform: translateX(-101%); }
.step.rv-ready .we-line::after { transform: translateX(101%); }
.step.rv-in .we-line,
.step.rv-in .we-line::after {
  transform: none;
  transition: transform 700ms var(--ease-out) calc(var(--rv-d, 0ms) + 450ms);
}

/* Phones and tablets: How it works steps read a little smaller. */
@media (max-width: 859px) {
  .how .step { align-items: start; }
  .how .step h3 { font-size: 1.375rem; }
  .how .step > p:last-child { font-size: 1rem; line-height: 1.55; }
}

/* Wide screens: every leak story keeps the tallest story's height, so switching tabs never
   moves the page. Unchosen stories stay hidden from view, focus and screen readers. */
@media (min-width: 900px) {
  .leaks-panel.is-tabbed { display: grid; }
  .leaks-panel.is-tabbed > .story { grid-row: 2; grid-column: 1; }
  .leaks-panel.is-tabbed > .story[hidden] { display: block; visibility: hidden; }
}

/* 404 page */
.not-found { min-height: 62vh; }
.not-found-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; margin-top: 12px; }
.legal .btn { text-decoration: none; }

/* Source links: at least a 24px tall target (WCAG 2.5.8) without changing the line's look. */
.source-credit a { display: inline-block; padding-block: 3px; color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.source-credit a:hover { color: var(--ink); text-decoration-thickness: 2px; }

/* ---------- Concise preview (2026-10-15) ---------- */
.hero-meta-who { color: var(--ink-mid); }

.leaks-margin { margin-top: 14px; max-width: 52ch; font-size: 1.0625rem; line-height: 1.55; color: var(--ink); }
.leaks-margin .source-credit { display: inline; font-size: 0.875rem; }

/* A story with no notes beside it uses the full width. */
@media (min-width: 900px) {
  .story-body:not(:has(.story-side)) { grid-template-columns: minmax(0, 1fr); }
}

/* How it works: three short steps, no drawings. */
.how.section { padding-block: var(--section-y); }
.how .steps { margin-top: 40px; }
.how .step,
.how .step + .step { padding-block: 28px; }

@media (max-width: 859px) {
  .how .step {
    grid-template-columns: 3rem minmax(0, 1fr);
    column-gap: 14px;
    row-gap: 6px;
    padding-block: 22px;
  }
  .how .step::before { grid-column: 1; grid-row: 1 / span 2; font-size: 2.5rem; line-height: 1; }
  .how .step h3,
  .how .step > p:last-child { grid-column: 2; }
}

@media (min-width: 860px) {
  .how .step { padding: 36px 40px 8px 0; }
  .how .step + .step { padding-left: 40px; }
  .how .step::before { font-size: 3.5rem; }
}

/* Cost: the call and the plan, nothing else. */
.free-grid { margin-top: 40px; }

/* Desktop steps: number on top, then the heading and text. */
@media (min-width: 860px) {
  .how .step { grid-template-columns: minmax(0, 1fr); }
  .how .step::before { grid-row: 1; grid-column: 1; margin-bottom: 4px; }
  .how .step h3,
  .how .step > p:last-child { grid-column: 1; }
}

/* Desktop leaks: the stage fills the panel's reserved height and centres its picture,
   so a shorter story never leaves an empty band under it. */
@media (min-width: 900px) {
  .leaks-panel.is-tabbed > .story,
  .leaks-panel.is-tabbed > .story[hidden] { display: grid; }
  .leaks-panel.is-tabbed .story-body { align-items: stretch; }
  .leaks-panel.is-tabbed .story-main { grid-template-rows: auto minmax(0, 1fr); }
  .leaks-panel.is-tabbed .stage { align-content: center; }
}
