/* ============================================================================
   jj.loveland — shared design system
   Loaded by all three pages. Page-specific components live at the bottom,
   clearly sectioned. Everything above that is shared and shouldn't be edited
   for a single page's sake.
   ========================================================================= */

/* ============================================================
   1. TOKENS
   ============================================================ */
:root {
  /* Surfaces. Warm brown-black, never neutral grey. */
  --ink:    #14110F;
  --ash:    #1D1A17;   /* alternating bands */
  --char:   #2A2622;   /* hairlines */

  /* Ink on those surfaces */
  --bone:   #EDE8E1;
  --steel:  #8A847C;   /* 5.08:1 on --ink — do not darken, it fails AA below this */

  /* The inverted band. The application form is the only thing that sits on it,
     which makes the CTA the brightest object on every page. */
  --paper:      #EDE8E1;
  --paper-ink:  #14110F;
  --paper-mute: #6B655E;
  --paper-rule: #D6CFC5;

  /* --signal has exactly two jobs and no others:
     1. the primary action (Apply)
     2. the timeline charts
     Reaching for it anywhere else means using --bone or --steel instead. */
  --signal:      #2B4EF0;
  --signal-deep: #1C3AD4;

  --danger: #FF8A7A;   /* 4.9:1 on --ash — #FF6B5A failed AA for the error text */

  /* Two families. Archivo carries everything structural; Newsreader appears
     only when JJ speaks in first person. */
  --display: 'Archivo', system-ui, -apple-system, sans-serif;
  --voice:   'Newsreader', Georgia, serif;
  --meta:    'Archivo', system-ui, -apple-system, sans-serif;

  /* One spacing ladder. Every gap on the site is a step on it. */
  --s1: .5rem;
  --s2: 1rem;
  --s3: 1.5rem;
  --s4: 2.5rem;
  --s5: 4rem;

  --band: clamp(4rem, 9vw, 8rem);      /* vertical rhythm between sections */
  --gap:  clamp(2rem, 5vw, 4.5rem);    /* horizontal rhythm inside grids */
  --head: clamp(2.25rem, 5vw, 4rem);   /* section header → its content */

  --pad:   clamp(1.25rem, 5vw, 5rem);  /* page gutter */
  --max:   1180px;
  --nav-h: 64px;

  --rule: 1px solid var(--char);
  --ease: cubic-bezier(.22, 1, .36, 1);  /* one curve, everywhere */
}

/* ============================================================
   2. BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky nav instead of hiding under it */
  scroll-padding-top: calc(var(--nav-h) + 1rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--display);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Belt and braces against horizontal scroll on phones */
  overflow-x: hidden;
}

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

/* Text selection carries the brand instead of browser default blue */
::selection { background: var(--bone); color: var(--ink); }
.band--paper ::selection { background: var(--ink); color: var(--bone); }

/* Scrollbar tuned to the surface (browsers that support it; harmless elsewhere) */
html { scrollbar-color: var(--char) var(--ink); scrollbar-width: thin; }

a { color: inherit; }

button { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 3px;
  border-radius: 1px;
}
/* On the light band the cobalt ring would vanish — invert it */
.band--paper :focus-visible { outline-color: var(--paper-ink); }

/* Visible to screen readers, not to eyes */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Keyboard users get a way past the nav on every page */
.skip {
  position: absolute;
  left: var(--s2);
  top: -100px;
  z-index: 200;
  background: var(--signal);
  color: #fff;
  padding: .75rem 1.25rem;
  font-family: var(--meta);
  font-weight: 600;
  font-size: .8rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  transition: top .2s var(--ease);
}
.skip:focus { top: var(--s2); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ============================================================
   3. TYPOGRAPHY
   ============================================================ */
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 900;
  font-stretch: 112%;
  line-height: .95;
  letter-spacing: -.03em;
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: clamp(2.35rem, 6.4vw, 4.8rem); text-transform: uppercase; }
h2 { font-size: clamp(1.9rem, 5.2vw, 3.6rem);  text-transform: uppercase; }
h3 { font-size: clamp(1.2rem, 2.4vw, 1.6rem);  font-stretch: 100%; letter-spacing: -.015em; }
h4 { font-size: 1rem; font-stretch: 100%; letter-spacing: -.01em; }

/* Small uppercase labels. Archivo doing the job DM Mono used to. */
.eyebrow {
  font-family: var(--meta);
  font-weight: 600;
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--steel);
  margin: 0 0 var(--s3);
  display: flex;
  align-items: center;
  gap: .75rem;
}
.eyebrow::after { content: ""; flex: 1; height: 1px; background: var(--char); }

.lede {
  font-size: clamp(1.02rem, 1.9vw, 1.25rem);
  line-height: 1.6;
  color: var(--steel);
  max-width: 46ch;
  text-wrap: pretty;
}

/* JJ's own voice — first person only. If marketing copy ends up in here,
   that's the token telling you the writing has drifted. */
.voice {
  font-family: var(--voice);
  font-weight: 300;
  font-size: clamp(1.15rem, 2.35vw, 1.5rem);
  line-height: 1.72;
  max-width: 58ch;
  color: #DED8D0;
}
.voice p { margin: 0 0 2.1em; text-wrap: pretty; }  /* must exceed line-height */
.voice p:last-child { margin-bottom: 0; }
.voice em { font-style: italic; color: var(--bone); }
.voice strong { font-weight: 500; color: var(--bone); }

/* ============================================================
   4. LAYOUT PRIMITIVES
   ============================================================ */
.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.band { padding-block: var(--band); }
.band--tight { padding-block: calc(var(--band) * .55); }
.band--ash   { background: var(--ash); }
.band--paper { background: var(--paper); color: var(--paper-ink); }
/* Two same-coloured bands in a row would double their padding */
.band--ash + .band--ash { padding-top: 0; }

.sec-head { max-width: 58ch; margin-bottom: var(--head); }
.sec-head h2 { margin-bottom: var(--s3); }

/* ============================================================
   5. BUTTONS
   Min height 48px everywhere — comfortably over the 44px touch target floor.
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .7rem;
  min-height: 48px;
  padding: .95rem 1.75rem;
  font-family: var(--meta);
  font-weight: 600;
  font-size: .8rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  border: 1px solid transparent;
  border-radius: 0;
  background: none;
  cursor: pointer;
  transition: background .18s ease, color .18s ease, border-color .18s ease, transform .18s var(--ease);
}
.btn--primary { background: var(--signal); color: #fff; }
.btn--primary:hover { background: var(--signal-deep); }
.btn--ghost { color: var(--bone); border-color: var(--char); }
.btn--ghost:hover { border-color: var(--bone); }
/* On the light band */
.band--paper .btn--ghost { color: var(--paper-ink); border-color: var(--paper-rule); }
.band--paper .btn--ghost:hover { border-color: var(--paper-ink); }

.btn__arrow { transition: transform .18s var(--ease); }
.btn:hover .btn__arrow { transform: translateX(4px); }

@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover, .btn--ghost:hover { transform: translateY(-2px); }
}
/* Full-width buttons on the narrowest phones so they never wrap awkwardly */
@media (max-width: 400px) {
  .btn { width: 100%; }
}

/* ============================================================
   6. NAV
   ============================================================ */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(20, 17, 15, .88);
  backdrop-filter: blur(14px);
  border-bottom: var(--rule);
  transition: transform .35s var(--ease);
}
.nav.is-hidden { transform: translateY(-100%); }
.nav.is-open { transform: none; }   /* never hide the nav while the menu is open */

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  height: var(--nav-h);
}

.nav__mark {
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 112%;
  font-size: 1.05rem;
  letter-spacing: -.02em;
  text-decoration: none;
  color: var(--bone);
  white-space: nowrap;
}
/* (the wordmark's separator span was retired with "jj.loveland") */

.nav__links { display: flex; align-items: center; gap: var(--s4); }
.nav__link {
  font-family: var(--meta);
  font-weight: 600;
  font-size: .78rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--steel);
  padding: .5rem 0;
  transition: color .18s ease;
}
.nav__link:hover { color: var(--bone); }
/* aria-current is the source of truth — the style follows the semantics */
.nav__link[aria-current="page"] { color: var(--bone); }
.nav__link[aria-current="page"]::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 4px;
  background: var(--signal);
}

.nav__cta { padding: .7rem 1.15rem; min-height: 40px; font-size: .72rem; }

/* Reading progress — injected by JS, transform-only, no transition needed
   (it's driven directly each frame). Bone, not signal: it informs, it
   doesn't act. Fixed to the viewport (not the nav) so it stays visible
   even while the nav itself is slid off-screen on scroll-down. */
.nav__progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  height: 4px;
  background: var(--bone);
  opacity: .55;
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}

.nav__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 48px; height: 48px;
  margin-right: -12px;
  border: 0;
  background: none;
  cursor: pointer;
}
.nav__bars { display: block; width: 22px; height: 12px; position: relative; }
.nav__bars::before, .nav__bars::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 2px;
  background: var(--bone);
  transition: transform .3s var(--ease), opacity .2s ease;
}
.nav__bars::before { top: 0; }
.nav__bars::after  { bottom: 0; }
.nav.is-open .nav__bars::before { transform: translateY(5px) rotate(45deg); }
.nav.is-open .nav__bars::after  { transform: translateY(-5px) rotate(-45deg); }

/* --- Mobile menu ------------------------------------------------------- */
@media (max-width: 860px) {
  .nav__toggle { display: flex; }

  .nav__links {
    position: fixed;
    top: var(--nav-h);
    left: 0;
    right: 0;
    /* Explicit height, not bottom:0 - the nav's backdrop-filter makes it
       the containing block for this fixed panel, so bottom:0 resolved
       against the 64px nav box (computed height: zero) instead of the
       viewport. The links were painting as bare overflow on phones. */
    height: calc(100vh - var(--nav-h));
    height: calc(100dvh - var(--nav-h));
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--s3);
    padding: var(--s5) var(--pad);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--ink);
    border-top: var(--rule);
    /* Not display:none - we animate it, and it must be inert when closed */
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .28s var(--ease), transform .28s var(--ease), visibility .28s;
  }
  .nav.is-open .nav__links { opacity: 1; transform: none; visibility: visible; }

  .nav__link {
    font-size: 1.6rem;
    font-weight: 900;
    font-stretch: 112%;
    letter-spacing: -.02em;
    color: var(--bone);
    padding: .35rem 0;
  }
  .nav__link[aria-current="page"]::after { width: 2.5rem; }

  .nav__links .btn { width: 100%; margin-top: var(--s2); font-size: .8rem; min-height: 52px; }
}

/* Stops the page scrolling behind the open menu */
body.is-locked { overflow: hidden; }

/* ============================================================
   7. FOOTER
   ============================================================ */
.foot { border-top: var(--rule); padding-block: var(--s5); }
.foot__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--s4);
}
.foot__meta {
  font-family: var(--meta);
  font-weight: 600;
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--steel);
  margin-top: var(--s1);
}
.foot__motif { width: 72px; color: var(--steel); opacity: .45; margin-top: var(--s3); }

.foot__nav { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s4); }
.foot__nav a {
  font-family: var(--meta);
  font-weight: 600;
  font-size: .74rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--steel);
  text-decoration: none;
  padding: .35rem 0;
  transition: color .18s ease;
}
.foot__nav a:hover { color: var(--bone); }

/* ============================================================
   8. MOTION
   Only transform and opacity are ever animated, so nothing on this site
   triggers layout while scrolling.
   ============================================================ */
.rise {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.rise.is-in { opacity: 1; transform: none; }

[data-stagger] { opacity: 0; transform: translateY(22px); }
.is-ready [data-stagger] {
  opacity: 1;
  transform: none;
  transition: opacity .9s var(--ease), transform .9s var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms);
}

/* Photographic grain — takes the digital sterility off the flat dark ground */
.grain {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: .035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Group stagger: one [data-stagger-io] container triggers on scroll-in and
   its [data-stagger-item] children cascade from that single moment. */
[data-stagger-item] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms);
}
[data-stagger-io].is-in [data-stagger-item] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .rise, [data-stagger], [data-stagger-item] { opacity: 1; transform: none; }
  /* Extra ancestor outranks the base rule further down the file */
  [data-stagger-io] .proof__cell[data-stagger-item] .stat__num { transform: none; }
  .nav.is-hidden { transform: none; }
  .grain { display: none; }
}

/* ============================================================
   PAGE — Testimonials / Transformations Grid
   Each slot has a comparison slider and a quote. Placeholders are
   clearly marked so real content can drop in without redesign.
   ============================================================ */
/* Cards are capped at 340px rather than stretching to fill. At the old
   minmax(320px, 1fr) a laptop gave each card ~486px, and at the 53:70
   portrait ratio that is a 641px-tall image inside roughly 570px of visible
   viewport - you could not see one transformation without going fullscreen.
   Capping the track keeps the tallest image at ~449px everywhere. */
.testimonials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 340px));
  justify-content: center;
  gap: var(--s4);
}
.testimonial {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: 0;
  transition: transform .22s var(--ease);
}
.testimonial__slider {
  aspect-ratio: 53 / 70;
  overflow: hidden;
  border: var(--rule);
  background: var(--ash);
  position: relative;
  transition: border-color .22s ease;
}
/* Small on purpose: several of these cards still hold placeholder content,
   and a glossier lift would make them read more finished than they are. */
@media (hover: hover) and (pointer: fine) {
  .testimonial:hover { transform: translateY(-4px); }
  .testimonial:hover .testimonial__slider { border-color: var(--steel); }
}
.testimonial__slider img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 12%;
}
.testimonial__quote {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  flex: 1;
}
.testimonial__text {
  font-family: var(--voice);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(0.95rem, 1.8vw, 1.15rem);
  line-height: 1.62;
  color: var(--steel);
}
.testimonial__name {
  font-family: var(--meta);
  font-weight: 600;
  font-size: .74rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bone);
}
.testimonial__placeholder {
  display: inline-block;
  background: var(--ash);
  border: 2px dashed var(--char);
  border-radius: 2px;
  padding: var(--s2) var(--s3);
  font-family: var(--meta);
  font-weight: 600;
  font-size: .65rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--steel);
  margin-top: auto;
}

/* ============================================================================
   9. PAGE COMPONENTS
   Migrated from the original single-file build. Shared across pages except
   where noted.
   ========================================================================= */

/* ------------------------------------------------------------
   HERO
   ------------------------------------------------------------ */
.hero {
  padding-block: calc(var(--band) * .38) calc(var(--band) * .8);
  position: relative;
  overflow: clip;                /* contains the aura's soft edge */
}

/* Static decorative layer behind the copy — bone-tinted so --signal keeps its
   two documented jobs. No animation: same runtime cost as .grain, i.e. none. */
.hero__aura {
  position: absolute;
  top: -12%;
  left: 50%;
  width: min(1100px, 92vw);
  height: 640px;
  transform: translate3d(-50%, 0, 0);
  background: radial-gradient(circle, rgba(237, 232, 225, .05) 0%, rgba(237, 232, 225, 0) 68%);
  z-index: 0;
  pointer-events: none;
}

.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.08fr .92fr;
  gap: var(--gap);
  align-items: stretch;          /* both columns end on the same line */
}
@media (max-width: 900px) { .hero__grid { grid-template-columns: 1fr; } }

/* The photo takes its height from the copy beside it, so the hero always
   resolves to one screen instead of the image dictating the fold. */
.hero__media { display: flex; flex-direction: column; }

/* Page-load door swing: the photo settles flat from a slight 3D angle,
   hinged at its outer edge. One-shot, transform-only, deliberately NOT
   pointer-tracking. Scoped to .hero__media so the compare slider on
   Transformations is untouched. */
.hero__media .compare {
  transform: perspective(1200px) rotateY(-14deg);
  transform-origin: 100% 50%;
  transition: transform 1.25s var(--ease) .45s;
}
.is-ready .hero__media .compare { transform: perspective(1200px) rotateY(0deg); }
@media (prefers-reduced-motion: reduce) {
  .hero__media .compare { transform: none; transition: none; }
}
@media (min-width: 901px) {
  .hero__media .compare { flex: 1 1 auto; aspect-ratio: auto; min-height: 420px; }
}

.hero h1 { margin-bottom: var(--s3); }
/* The headline's emphasis comes from a change of voice, not a change of colour —
   the serif ties it to JJ speaking rather than adding a third accent use. */
.hero h1 .said {
  display: block;
  font-family: var(--voice);
  font-weight: 400;
  font-style: italic;
  font-stretch: normal;
  text-transform: none;
  letter-spacing: -.02em;
}
.hero .lede { margin: 0 0 var(--s4); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }

/* ------------------------------------------------------------
   BEFORE / AFTER SLIDER
   ------------------------------------------------------------ */
.compare {
  --pos: 50%;
  position: relative;
  margin: 0;
  aspect-ratio: 53 / 70;
  overflow: hidden;
  border: var(--rule);
  background: var(--ash);
  cursor: ew-resize;
  touch-action: pan-y;               /* let vertical scroll through, capture horizontal */
  user-select: none;
  -webkit-user-select: none;
}
.compare img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Anchored high: if the frame gets shorter than the photo, it trims from
     the bottom rather than cropping his head off. */
  object-position: 50% 12%;
  pointer-events: none;
}
/* clip-path is GPU-composited, so dragging never triggers layout */
.compare__clip {
  position: absolute;
  inset: 0;
  clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}
.compare__bar {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  width: 2px;
  margin-left: -1px;
  background: var(--bone);
  /* Keeps the divider legible where it crosses bright skin/wall areas */
  box-shadow: 0 0 10px rgba(0, 0, 0, .35);
  pointer-events: none;
}
/* Same visual language as the Before/After tag chips: blurred ink,
   hairline bone edge — the grip belongs to the site, not to a widget kit */
.compare__grip {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(20, 17, 15, .68);
  backdrop-filter: blur(8px);
  border: 1px solid var(--bone);
  color: var(--bone);
  display: grid;
  place-items: center;
  box-shadow: 0 4px 24px rgba(0, 0, 0, .45);
  transition: transform .25s var(--ease);
}
.compare__grip svg { width: 18px; height: 18px; }
.compare:hover .compare__grip { transform: translate(-50%, -50%) scale(1.08); }
.compare.is-held .compare__grip { transform: translate(-50%, -50%) scale(.94); }

.compare__tag {
  position: absolute;
  bottom: var(--s2);
  font-family: var(--meta);
  font-weight: 600;
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bone);
  background: rgba(20,17,15,.72);
  backdrop-filter: blur(8px);
  padding: .4rem .7rem;
  pointer-events: none;
  transition: opacity .3s var(--ease);
}
.compare__tag--l { left: var(--s2); }
.compare__tag--r { right: var(--s2); }
/* Fade each label out as the wipe swallows its side.
   Driven by --p (a unitless 0–100 written by JS) because arithmetic on a
   percentage isn't valid in calc(). */
.compare__tag--l { opacity: clamp(0, calc(var(--p, 50) / 16), 1); }
.compare__tag--r { opacity: clamp(0, calc((100 - var(--p, 50)) / 16), 1); }

/* Native range input: invisible, but gives us keyboard + screen-reader support free */
.compare__range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: none;
}
.compare__range:focus-visible { outline: none; }
.compare:has(.compare__range:focus-visible) { outline: 2px solid var(--signal); outline-offset: 3px; }

.compare__hint {
  margin: var(--s2) 0 0;
  font-family: var(--meta);
  font-weight: 600;
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--steel);
  text-align: center;
}

/* ------------------------------------------------------------
   PROOF STRIP — three numbers, its own band, nothing else
   ------------------------------------------------------------ */
.proof { border-block: var(--rule); }
.proof__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
.proof__cell {
  padding: clamp(2rem, 4.5vw, 3.25rem) 0;
  text-align: center;
  perspective: 640px;   /* stage for the number's scoreboard flip */
}

/* The one piece of 3D on the site: each number flips up like a gym
   scoreboard as its cell cascades in. One-shot, transform-only, hinged
   at the baseline. Rides the same --i delay as the cell itself. */
.proof__cell[data-stagger-item] .stat__num {
  transform: rotateX(-78deg);
  transform-origin: 50% 100%;
  transition: transform 1.1s var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms + 150ms);
}
[data-stagger-io].is-in .proof__cell .stat__num { transform: rotateX(0); }
.proof__cell + .proof__cell { border-left: var(--rule); }
@media (max-width: 640px) {
  .proof__grid { grid-template-columns: 1fr; }
  .proof__cell { padding-block: var(--s4); }
  .proof__cell + .proof__cell { border-left: 0; border-top: var(--rule); }
}
.stat__num {
  font-family: var(--display);
  font-weight: 900;
  font-stretch: 118%;
  font-size: clamp(2.4rem, 6vw, 3.9rem);
  line-height: .9;
  letter-spacing: -.04em;
}
.stat__label {
  font-family: var(--meta); font-weight: 600;
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--steel);
  margin-top: var(--s2);
}

/* ------------------------------------------------------------
   SIGNATURE — the weight timeline
   ------------------------------------------------------------ */
.chart { width: 100%; overflow: hidden; }
.chart svg { width: 100%; height: auto; display: block; }

/* Axis furniture stays recessive — it orients, it doesn't compete. */
.chart .axis { stroke: var(--char); stroke-width: 1; }

/* Colour now separates WHOSE line it is, not which direction it goes:
   JJ's whole fluctuation is solid signal (the regain is unmissable from
   shape alone), and the dashed steel fork is the coached path. */
.chart .seg { fill: none; stroke-width: 3; stroke-linecap: round; stroke: var(--signal); }

.chart .gridline { stroke: var(--char); stroke-width: 1; opacity: .6; }

/* Wide faint pass of the same path — reads as a glow with zero filter cost */
.chart .glow {
  fill: none;
  stroke: var(--signal);
  stroke-width: 8;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transition: opacity 1.2s ease 1.4s;
}
.chart.is-live .glow { opacity: .12; }

/* The fork — dashed so it reads as projection, not record */
.chart .coached {
  fill: none;
  stroke: var(--steel);
  stroke-width: 2;
  stroke-dasharray: 6 5;
  stroke-linecap: round;
}
.chart .cap--coach { fill: var(--steel); font-style: italic; text-transform: none; letter-spacing: .08em; font-size: 13px; }
.chart .coached, .chart .coach-node { opacity: 0; transition: opacity .8s ease 2.2s; }
.chart.is-live .coached, .chart.is-live .coach-node { opacity: 1; }

.chart .dot { fill: var(--ink); stroke-width: 2; stroke: var(--signal); transition: r .2s var(--ease); }
.chart .node:hover .dot { r: 8.5; }

/* "You are here" — a slow ring on the final point, running only while the
   chart is on screen (.is-pulsing is toggled by its IntersectionObserver).
   transform/opacity only; transform-box keeps the scale centred on the dot. */
.chart .dot-pulse {
  fill: none;
  stroke: var(--signal);
  stroke-width: 2;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: 50% 50%;
  pointer-events: none;
}
.chart.is-pulsing .dot-pulse { animation: chart-pulse 2.4s var(--ease) infinite; }
@keyframes chart-pulse {
  0%   { transform: scale(1);   opacity: .5; }
  70%  { transform: scale(2.1); opacity: 0; }
  100% { transform: scale(2.1); opacity: 0; }
}

.chart .lbs {
  fill: var(--bone);
  font-family: var(--display);
  font-weight: 900;
  font-stretch: 112%;
  font-size: 19px;
  letter-spacing: -.02em;
}
.chart .cap {
  fill: var(--steel);
  font-family: var(--meta); font-weight: 600;
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  transition: fill .2s var(--ease);
}
.chart .node:hover .cap { fill: var(--bone); }
.chart .hit { fill: transparent; cursor: default; }

/* Hover a point → its connected segments thicken and the pounds-changed
   labels fade in at each segment's midpoint. */
.chart .seg.is-hot { stroke-width: 4.5; }
.chart .delta {
  fill: var(--signal);
  font-family: var(--meta);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: .06em;
  opacity: 0;
  transition: opacity .2s var(--ease);
  pointer-events: none;
}
.chart .delta--up { fill: var(--steel); }
.chart .delta.is-hot { opacity: 1; }

/* Each segment draws in turn, so the eye follows the story in order:
   down, back up, down again. */
.chart .seg { stroke-dasharray: var(--len); stroke-dashoffset: var(--len); }
.chart.is-live .seg {
  stroke-dashoffset: 0;
  /* stroke-width/opacity listed so the hover highlight still transitions
     after the draw-in has claimed the transition property */
  transition: stroke-dashoffset var(--dur) linear var(--delay),
              stroke-width .2s var(--ease),
              opacity .2s var(--ease);
}
.chart .reveal-node { opacity: 0; transition: opacity .45s var(--ease) var(--delay); }
.chart.is-live .reveal-node { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .chart .seg { stroke-dashoffset: 0; }
  .chart .reveal-node { opacity: 1; }
  .chart .glow { opacity: .12; transition: none; }
  .chart .coached, .chart .coach-node { opacity: 1; transition: none; }
  /* Frozen ring instead of a loop */
  .chart .dot-pulse { animation: none; opacity: .35; transform: scale(1.5); }
}

.timeline__note {
  margin-top: var(--head);
  padding-top: var(--s3);
  border-top: var(--rule);
  max-width: 62ch;
}

/* ------------------------------------------------------------
   STORY
   ------------------------------------------------------------ */
.story__grid {
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: var(--gap);
  align-items: start;
}
@media (max-width: 860px) { .story__grid { grid-template-columns: 1fr; } }

.story__aside { position: sticky; top: 110px; }
@media (max-width: 860px) { .story__aside { position: static; } }
/* Sized to fit the ~260px sticky column — the longer "...enthusiast."
   heading overflowed at the global h2 size. */
.story__aside h2 { margin-bottom: 1.5rem; font-size: clamp(1.5rem, 3.8vw, 1.95rem); overflow-wrap: break-word; }

/* The journey mark: the chart's down-up-down shape, reduced to a glyph */
.aside__motif {
  width: 96px;
  color: var(--steel);
  opacity: .7;
  margin-top: var(--s4);
}

.byline { display: flex; align-items: center; gap: .85rem; margin-top: 2rem; }
.byline img { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; filter: grayscale(1) contrast(1.05); }
.byline__name { font-weight: 800; font-size: .95rem; letter-spacing: -.01em; }
.byline__role { font-family: var(--meta); font-weight: 600; font-size: .66rem; letter-spacing: .11em; text-transform: uppercase; color: var(--steel); margin-top: .2rem; }

.pullquote {
  font-family: var(--voice);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(1.6rem, 3.6vw, 2.5rem);
  line-height: 1.24;
  letter-spacing: -.015em;
  color: var(--bone);
  /* Deliberately larger than the paragraph rhythm around it, so it lands as a
     pause in the story rather than another paragraph that happens to be big. */
  margin: var(--s5) 0;
  max-width: 24ch;
  padding-left: clamp(1.25rem, 2.5vw, 2rem);
  border-left: 2px solid var(--steel);
  text-wrap: pretty;
}

/* ------------------------------------------------------------
   PLAN A
   ------------------------------------------------------------ */
#plan { position: relative; overflow: clip; }
.plan { max-width: 900px; position: relative; z-index: 1; }

/* "There is no Plan B." — the A, outlined like a blueprint, in the dead
   space the 900px list leaves on wide screens. Hidden where it would
   collide with content. */
.plan__ghost {
  position: absolute;
  top: 50%;
  right: -1%;
  transform: translateY(-50%);
  font-family: var(--display);
  font-weight: 900;
  font-stretch: 112%;
  font-size: clamp(280px, 32vw, 520px);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px var(--char);
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
@supports not (-webkit-text-stroke: 1px black) {
  .plan__ghost { color: rgba(42, 38, 34, .55); }
}
@media (max-width: 1100px) { .plan__ghost { display: none; } }

/* Each "Done" chip flips down as its item cascades in — the list is being
   checked off in front of you, not merely appearing. */
.plan__item { perspective: 420px; }
[data-stagger-io] .plan__check {
  transform: rotateX(-90deg);
  transform-origin: 50% 100%;
  transition: transform .55s var(--ease);
  transition-delay: calc(var(--i, 0) * 110ms + 260ms);
}
[data-stagger-io].is-in .plan__check { transform: none; }
@media (prefers-reduced-motion: reduce) {
  [data-stagger-io] .plan__check { transform: none; transition: none; }
}
.plan__head { margin-bottom: var(--head); }
.plan__head h2 { margin-bottom: var(--s3); }

.plan__list { list-style: none; margin: 0; padding: 0; border-top: var(--rule); }
.plan__item {
  display: flex;
  align-items: baseline;
  gap: clamp(1rem, 2.5vw, 2rem);
  padding: clamp(1rem, 2.2vw, 1.5rem) 0;
  border-bottom: var(--rule);
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 108%;
  font-size: clamp(1.35rem, 3.4vw, 2.35rem);
  line-height: 1.1;
  letter-spacing: -.025em;
  text-transform: uppercase;
  text-wrap: balance;
}
.plan__check {
  flex: none;
  font-family: var(--meta); font-weight: 600;
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .1em;
  color: var(--steel);
  text-transform: uppercase;
  transform: translateY(-.15em);
}
.plan__closer { margin-top: var(--head); max-width: 52ch; }

/* ------------------------------------------------------------
   WORKING TOGETHER
   ------------------------------------------------------------ */
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--char); border: var(--rule); }
@media (max-width: 860px) { .cards { grid-template-columns: 1fr; } }
.card__icon {
  width: 26px;
  height: 26px;
  fill: none;
  stroke: var(--steel);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  margin-bottom: var(--s2);
  transition: stroke .22s ease;
}
.card {
  background: var(--ink);
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
  /* Invisible at rest so the grid-gap hairline illusion is undisturbed;
     border-box sizing means adding it shifts nothing. */
  border: 1px solid transparent;
  transition: transform .22s var(--ease), border-color .22s ease;
}
@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-4px); border-color: var(--steel); }
  .card:hover .card__icon { stroke: var(--bone); }
}
.card__k {
  font-family: var(--meta); font-weight: 600;
  font-size: .68rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: 1.25rem;
}
.card h3 { margin-bottom: .85rem; }
.card p { margin: 0; color: var(--steel); font-size: .97rem; line-height: 1.6; }

/* ------------------------------------------------------------
   APPLICATION FORM
   ------------------------------------------------------------ */
.apply__grid {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: var(--gap);
  align-items: start;
}
@media (max-width: 900px) { .apply__grid { grid-template-columns: 1fr; } }
.apply__intro h2 { margin-bottom: 1.35rem; }

.apply__facts { list-style: none; margin: 2.25rem 0 0; padding: 0; }
.apply__facts li {
  display: flex;
  gap: .85rem;
  padding: .8rem 0;
  border-top: var(--rule);
  font-family: var(--meta); font-weight: 600;
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--steel);
  line-height: 1.5;
}
.apply__facts li::before { content: "→"; color: var(--steel); flex: none; }

.form { background: var(--ash); border: var(--rule); padding: clamp(1.5rem, 3.5vw, 2.75rem); }
.field { margin-bottom: 1.65rem; }
.field:last-of-type { margin-bottom: 2rem; }
.field label {
  display: block;
  font-family: var(--meta); font-weight: 600;
  font-size: .72rem;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--steel);
  margin-bottom: .6rem;
}
.field label .req { color: var(--steel); }
.field input, .field textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--char);
  color: var(--bone);
  font-family: var(--display);
  font-size: 1.02rem;
  line-height: 1.5;
  padding: .6rem 0;
  border-radius: 0;
  transition: border-color .18s ease;
}
.field textarea { resize: vertical; min-height: 3.4rem; }
.field input:hover, .field textarea:hover { border-bottom-color: var(--steel); }
.field input:focus, .field textarea:focus { outline: none; border-bottom-color: var(--signal); }
.field input::placeholder, .field textarea::placeholder { color: #4A4642; }

.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
@media (max-width: 560px) { .form__row { grid-template-columns: 1fr; gap: 0; } }

.field__err {
  display: none;
  font-family: var(--meta); font-weight: 600;
  font-size: .7rem;
  letter-spacing: .05em;
  color: var(--danger);
  margin-top: .5rem;
}
.field.is-error input, .field.is-error textarea { border-bottom-color: var(--danger); }
.field.is-error .field__err { display: block; }

.form__submit { width: 100%; justify-content: center; }
.form__submit[disabled] { opacity: .55; cursor: wait; }
.form__fine {
  font-family: var(--meta); font-weight: 600;
  font-size: .68rem;
  letter-spacing: .06em;
  color: var(--steel);
  margin: 1.1rem 0 0;
  text-align: center;
  line-height: 1.6;
}
.form__status { font-family: var(--meta); font-weight: 600; font-size: .78rem; margin-top: 1rem; text-align: center; color: var(--steel); line-height: 1.6; }
.form__status.is-bad { color: var(--danger); }
.form__status a { color: inherit; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.thanks { text-align: center; padding: clamp(2rem, 5vw, 3.5rem) 0; }
.thanks h3 { margin-bottom: 1rem; }
.thanks p { color: var(--steel); margin: 0 auto; max-width: 40ch; }

/* ------------------------------------------------------------
   MOBILE STICKY CTA
   ------------------------------------------------------------ */
@keyframes dock-enter {
  from { transform: translateY(110%); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.dock {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  padding: .75rem var(--pad) calc(.75rem + env(safe-area-inset-bottom));
  background: rgba(20,17,15,.94);
  backdrop-filter: blur(14px);
  border-top: var(--rule);
  transform: translateY(110%);
  opacity: 0;
  transition: transform .35s var(--ease), opacity .35s var(--ease);
}
.dock.is-up {
  animation: dock-enter .4s var(--ease) forwards;
}
.dock .btn { width: 100%; justify-content: center; }
@media (min-width: 861px) { .dock { display: none; } }

/* ============================================================================
   10. LATE OVERRIDES & PAGE-SPECIFIC COMPONENTS
   Appended after §9 on purpose: the paper-band rules below must out-cascade
   the dark form styles above them.
   ========================================================================= */

/* ------------------------------------------------------------
   THE FORM ON PAPER — the application is the brightest thing
   on every page. These restate only what changes on the light
   surface; structure comes from §9.
   ------------------------------------------------------------ */
.band--paper .eyebrow { color: var(--paper-mute); }
.band--paper .eyebrow::after { background: var(--paper-rule); }
.band--paper .lede { color: var(--paper-mute); }

.band--paper .form {
  background: #FBF9F6;                /* one step brighter than the band */
  border-color: var(--paper-rule);
}
.band--paper .field label { color: var(--paper-mute); }
.band--paper .field label .req { color: var(--paper-mute); }
.band--paper .field input,
.band--paper .field textarea {
  color: var(--paper-ink);
  border-bottom-color: var(--paper-rule);
}
.band--paper .field input:hover,
.band--paper .field textarea:hover { border-bottom-color: var(--paper-mute); }
.band--paper .field input:focus,
.band--paper .field textarea:focus { border-bottom-color: var(--signal); }
.band--paper .field input::placeholder,
.band--paper .field textarea::placeholder { color: #B5AEA4; }

/* Error red legible on the light surface */
.band--paper .field__err,
.band--paper .form__status.is-bad { color: #B9382A; }
.band--paper .field.is-error input,
.band--paper .field.is-error textarea { border-bottom-color: #B9382A; }

.band--paper .form__fine { color: var(--paper-mute); }
.band--paper .form__status { color: var(--paper-mute); }
.band--paper .apply__facts li { color: var(--paper-mute); border-top-color: var(--paper-rule); }
.band--paper .apply__facts li::before { color: var(--paper-mute); }
.band--paper .thanks p { color: var(--paper-mute); }

/* ------------------------------------------------------------
   PAGE HEAD — the opener on Pricing and Transformations.
   Also the dock's scroll sentinel on those pages.
   ------------------------------------------------------------ */
.page-head { padding-bottom: calc(var(--band) * .45); }
.page-head h1 { margin-bottom: var(--s3); }

/* ------------------------------------------------------------
   PRICING — tiers. Same coaching in every tier; the cards sell
   time, not feature lists.
   ------------------------------------------------------------ */
.tiers {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s3);
  align-items: stretch;
}
@media (max-width: 900px) { .tiers { grid-template-columns: 1fr; } }

/* Two payment options for one package, narrower than the old 3-up so the
   pair reads as a choice rather than a lineup of plans. */
/* margin-inline centres the narrower pair in the wrap - without it the two
   cards sat left with dead space beside them. */
.tiers--pair {
  grid-template-columns: repeat(2, 1fr);
  max-width: 780px;
  margin-inline: auto;
}
@media (max-width: 900px) { .tiers--pair { grid-template-columns: 1fr; } }

/* Prices read as a comparison, so they're centred in their cards */
.tiers--pair .tier { text-align: center; align-items: center; }
.tiers--pair .tier .tier__blurb { max-width: 30ch; }

/* Scale-end tick on the ruler: marks the 12-month span, not a plan */
.ruler__mark--scale { background: var(--char); }
.ruler__mark--scale .ruler__marklabel { color: var(--steel); }

.tier {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  border: var(--rule);
  background: var(--ink);
  padding: clamp(1.75rem, 3vw, 2.5rem);
}
.tier--featured { border-color: var(--bone); }
.tier__tag {
  position: absolute;
  top: 0; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--signal);
  color: #fff;
  font-family: var(--meta);
  font-weight: 600;
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: .45rem .8rem;
  white-space: nowrap;
}
.tier__len {
  font-family: var(--display);
  font-weight: 900;
  font-stretch: 118%;
  font-size: clamp(2.6rem, 5vw, 3.6rem);
  line-height: .9;
  letter-spacing: -.04em;
}
.tier__len small {
  display: block;
  font-family: var(--meta);
  font-weight: 600;
  font-size: .66rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--steel);
  margin-top: .5rem;
}
.tier__blurb { color: var(--steel); font-size: .95rem; line-height: 1.6; margin: 0; }
.tier__price {
  font-weight: 800;
  font-size: 1.1rem;
  letter-spacing: -.01em;
  margin-top: var(--s2);
}
.tier__price span {
  display: block;
  font-weight: 400;
  font-size: .8rem;
  color: var(--steel);
  margin-top: .3rem;
}
.tier .btn { margin-top: auto; width: 100%; }

/* Every-tier strip: what's always included, as one quiet row */
.includes { display: flex; flex-wrap: wrap; gap: .6rem; margin: 0; padding: 0; list-style: none; }
.includes li {
  border: var(--rule);
  padding: .55rem .95rem;
  font-family: var(--meta);
  font-weight: 600;
  font-size: .7rem;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--bone);
}

/* ------------------------------------------------------------
   THE COMMITMENT RULER — pricing's chart. Twelve months laid
   flat, the regain window hatched in the same muted treatment
   the regain wears on the Home timeline. Commitment marks show
   what each tier outlasts.
   ------------------------------------------------------------ */
.ruler { position: relative; margin-top: var(--head); padding-top: 2.4rem; }
.ruler__track {
  position: relative;
  height: 58px;
  border: var(--rule);
  background: repeating-linear-gradient(
    to right,
    var(--char) 0 1px,
    transparent 1px calc(100% / 12)
  );
}
.ruler__zone {
  position: absolute;
  top: 0; bottom: 0;
  left: calc(100% * 4 / 12);
  width: calc(100% * 2 / 12);
  background: repeating-linear-gradient(135deg, rgba(138, 132, 124, .3) 0 6px, transparent 6px 12px);
  border-inline: 1px solid var(--steel);
}
.ruler__zonelabel {
  position: absolute;
  top: 0;
  left: calc(100% * 5 / 12);
  transform: translateX(-50%);
  font-family: var(--meta);
  font-weight: 600;
  font-size: .62rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--steel);
  white-space: nowrap;
}
.ruler__mark {
  position: absolute;
  top: -6px; bottom: -6px;
  width: 2px;
  background: var(--bone);
}
.ruler__mark--featured { background: var(--signal); }
.ruler__marklabel {
  left: 50%;
  position: absolute;
  top: calc(100% + 10px);
  transform: translateX(-50%);
  font-family: var(--meta);
  font-weight: 600;
  font-size: .66rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--bone);
  white-space: nowrap;
}
.ruler__marklabel--end { transform: translateX(-100%); }
.ruler__note { margin-top: var(--s5); }

/* ------------------------------------------------------------
   FAQ — native <details>, no JS to break.
   ------------------------------------------------------------ */
.faq { max-width: 760px; border-top: var(--rule); }
.faq details { border-bottom: var(--rule); }
.faq summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s2);
  padding: var(--s3) 0;
  font-weight: 800;
  font-stretch: 108%;
  font-size: 1.02rem;
  letter-spacing: -.01em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover::after { color: var(--bone); }
.faq summary::after {
  content: "+";
  flex: none;
  color: var(--steel);
  font-weight: 600;
  font-size: 1.2rem;
  line-height: 1;
  transition: transform .25s var(--ease), color .2s ease;
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq__a {
  padding: 0 0 var(--s3);
  color: var(--steel);
  max-width: 60ch;
  line-height: 1.6;
  margin: 0;
}


/* ------------------------------------------------------------
   BACK TO TOP — a small CSS-3D dumbbell (the site's one ambient 3D
   object, and it's a real control, not decor). Built from planes in
   preserve-3d space: two crossed strips read as the bar, and each end
   stacks two circles at different depths for the plates. Transform-only,
   ~52px, hidden where the mobile dock owns the bottom edge.
   ------------------------------------------------------------ */
.lift {
  position: fixed;
  right: clamp(1rem, 2vw, 1.5rem);
  bottom: clamp(1rem, 2vw, 1.5rem);
  z-index: 55;
  width: 52px;
  height: 52px;
  border: 1px solid var(--char);
  border-radius: 50%;
  background: rgba(29, 26, 23, .82);
  backdrop-filter: blur(10px);
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity .3s var(--ease), transform .3s var(--ease), border-color .2s ease;
}
.lift.is-shown { opacity: 1; transform: none; pointer-events: auto; }
.lift:hover { border-color: var(--steel); }
@media (max-width: 860px) { .lift { display: none; } }

.lift__scene {
  width: 34px;
  height: 34px;
  position: relative;
  transform-style: preserve-3d;
  animation: lift-spin 9s linear infinite;
}
@keyframes lift-spin {
  from { transform: rotateX(14deg) rotateY(0turn); }
  to   { transform: rotateX(14deg) rotateY(1turn); }
}

.lift__bar, .lift__plate { position: absolute; top: 50%; left: 50%; }
.lift__bar {
  width: 30px;
  height: 3px;
  margin: -1.5px 0 0 -15px;
  border-radius: 2px;
  background: var(--steel);
}
.lift__bar--cross { transform: rotateX(90deg); }
.lift__plate {
  width: 15px;
  height: 15px;
  margin: -7.5px 0 0 -7.5px;
  border-radius: 50%;
  border: 2px solid var(--bone);
  background: rgba(20, 17, 15, .92);
}
.lift__plate--l1 { transform: rotateY(90deg) translateZ(-9px); }
.lift__plate--r1 { transform: rotateY(90deg) translateZ(9px); }
.lift__plate--l2, .lift__plate--r2 {
  width: 11px;
  height: 11px;
  margin: -5.5px 0 0 -5.5px;
}
.lift__plate--l2 { transform: rotateY(90deg) translateZ(-12.5px); }
.lift__plate--r2 { transform: rotateY(90deg) translateZ(12.5px); }

@media (prefers-reduced-motion: reduce) {
  /* A fixed three-quarter pose instead of the spin */
  .lift__scene { animation: none; transform: rotateX(14deg) rotateY(-32deg); }
}

/* ------------------------------------------------------------
   PROSE - running body copy for the privacy page. Kept in
   Archivo, not --voice: that serif is reserved for JJ telling
   his story, and a policy is information, not narrative.
   ------------------------------------------------------------ */
.prose { max-width: 62ch; }
.prose h2 {
  /* Subheads here are signposts, not section titles, so they drop the
     uppercase display treatment the page h2s carry. */
  font-size: clamp(1.1rem, 2.1vw, 1.35rem);
  font-stretch: 100%;
  text-transform: none;
  letter-spacing: -.015em;
  line-height: 1.25;
  margin: var(--s5) 0 var(--s2);
}
.prose h2:first-child { margin-top: 0; }
.prose p {
  color: var(--steel);
  line-height: 1.7;
  margin: 0 0 1.15em;
  text-wrap: pretty;
}
.prose a {
  color: var(--bone);
  text-decoration: underline;
  text-decoration-color: var(--char);
  text-underline-offset: 3px;
  transition: text-decoration-color .18s ease;
}
.prose a:hover { text-decoration-color: var(--bone); }
.prose__updated {
  margin-top: var(--s5);
  padding-top: var(--s3);
  border-top: var(--rule);
  font-family: var(--meta);
  font-weight: 600;
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
}
