/* ============================================================================
   Fitness Trackr - marketing site design system
   ----------------------------------------------------------------------------
   One stylesheet shared by index / whats-new / privacy-policy / support so the
   four pages cannot drift apart. The site is deliberately zero-build (see
   wrangler.jsonc: `website/` is served as plain static assets), so everything
   here is hand-written CSS with no preprocessor.

   Type: two self-hosted woff2 faces in assets/fonts, latin subset, ~63 KB
   total. Self-hosted rather than linked from fonts.googleapis.com so the page
   still makes zero third-party requests and still works fully offline - that is
   what the old "no external fonts" rule was protecting, and it survives intact.
     - Space Grotesk   display headings AND body (SIL OFL)
     - JetBrains Mono  eyebrows, indices, micro-labels (SIL OFL)

   One family carries both display and body: hierarchy comes from size, weight
   and tracking rather than from a second face. The mono is the only contrast,
   and it is reserved for micro-labels - never for reading copy.

   Motion: sections reveal on scroll. The hidden state is scoped under `.js`
   (set by an inline script in <head>) and wrapped in a reduced-motion guard, so
   with JavaScript off - or with motion reduced - every word is visible and the
   page is simply static. Never move the reveal styles out of that scope.
   ========================================================================== */

/* ------------------------------------------------------------------ Fonts -- */

@font-face{
  font-family:'Space Grotesk';
  src:url('./fonts/space-grotesk-latin.woff2') format('woff2');
  font-weight:300 700; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'JetBrains Mono';
  src:url('./fonts/jetbrains-mono-latin.woff2') format('woff2');
  font-weight:300 600; font-style:normal; font-display:swap;
}

/* Metric-matched fallback. Without it the swap from the system face to the
   webfont visibly reflows the hero, which at ~105px is a lurch rather than a
   nudge. The overrides pull the fallback's metrics close enough that the swap
   is near-invisible. Space Grotesk is slightly wide with a large x-height, so
   the fallback is scaled up rather than down. */
@font-face{
  font-family:'Space Fallback';
  src:local('Helvetica Neue'), local('Arial');
  size-adjust:103%; ascent-override:96%; descent-override:24%; line-gap-override:0%;
}

:root{
  /* Surfaces, darkest to lightest. Deeper and a touch cooler than before so the
     cream text and the cyan both gain separation. */
  --bg:#06070a;
  --bg-elev:#0a0c11;
  --card:#0d1015;
  --card-hi:#12161d;
  --line:#1a1f27;
  --line-hi:#28303a;

  /* Ink. Cream rather than blue-white - it takes the clinical edge off a very
     dark page without warming so far that it fights the cyan. */
  --text:#eae8e5;
  --muted:#98a1ad;
  --muted-dim:#6b7683;

  /* Accents - carried over from the app's palette. Used sparingly: the page is
     near-monochrome and the cyan earns its weight by being rare. */
  --accent:#00e0ff;
  --accent-soft:rgba(0,224,255,.10);
  --accent-line:rgba(0,224,255,.26);
  --positive:#22c55e;
  --positive-soft:rgba(34,197,94,.12);

  --radius:14px;
  --radius-lg:20px;
  --max:1240px;
  --prose:680px;

  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-soft:cubic-bezier(.22,1,.36,1);

  /* --font-display and --font are the same family on purpose. The display role
     is a weight and a tracking, not a second typeface. */
  --font:'Space Grotesk','Space Fallback',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --font-display:var(--font);
  --font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* Display weight. Space Grotesk gets heavy fast, so 600 carries the headings
     without them turning into slabs at 100px. */
  --w-display:600;

  /* Fluid display scale. Deliberately below the reference site's numbers: this
     page has ten sections where an agency portfolio has four, and 96px headings
     ten times over stop reading as restraint. The mono index and eyebrow above
     each heading carry the hierarchy that the extra size would have. */
  --fs-display:clamp(2.9rem,7.4vw,6.6rem);
  --fs-h2:clamp(2.1rem,4.3vw,3.6rem);
  --fs-h3:clamp(1.15rem,1.5vw,1.35rem);
  --fs-lead:clamp(1.05rem,1.35vw,1.2rem);

  --track-display:-.04em;
  --track-tight:-.02em;
  --track-wide:.18em;

  /* Spacious end of the scale - the redesign buys its calm with vertical room. */
  --section-y:clamp(72px,9vw,132px);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth; -webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font:16px/1.65 var(--font);
  font-synthesis-weight:none;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}

a{color:var(--accent); text-decoration:none}
img{max-width:100%}

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

.wrap{max-width:var(--max); margin:0 auto; padding:0 32px; position:relative}
.center{text-align:center}
/* The reading column on the sub-pages. Used for the page hero too, so the
   heading lines up with the prose underneath it instead of hanging left. */
.col{max-width:var(--prose); margin-left:auto; margin-right:auto}

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

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:9px;
  font-family:var(--font); font-weight:600; font-size:15px;
  padding:13px 24px; border-radius:999px;
  background:var(--text); color:var(--bg); border:1px solid transparent;
  cursor:pointer; white-space:nowrap;
  transition:transform .2s var(--ease-out), box-shadow .2s var(--ease-out), background-color .2s ease, border-color .2s ease;
}
.btn:hover{transform:translateY(-2px); box-shadow:0 10px 30px rgba(0,0,0,.5)}
.btn:active{transform:translateY(0)}

.btn.accent{background:var(--accent); color:#04222a}
.btn.accent:hover{box-shadow:0 10px 34px rgba(0,224,255,.24)}
.btn.positive{background:var(--positive); color:#04220f}
.btn.positive:hover{box-shadow:0 10px 34px rgba(34,197,94,.24)}

.btn.ghost{background:transparent; color:var(--text); border-color:var(--line-hi)}
.btn.ghost:hover{border-color:var(--muted); background:rgba(255,255,255,.03)}

.appstore-badge{display:inline-flex; align-items:center; transition:transform .2s var(--ease-out)}
.appstore-badge:hover{transform:translateY(-2px)}
.appstore-badge img{height:52px; width:auto; display:block}

/* ------------------------------------------------------------------ Pills -- */

.pill{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--font-mono); font-size:11px; font-weight:400;
  letter-spacing:.06em; text-transform:uppercase; color:var(--muted);
  background:transparent; border:1px solid var(--line-hi);
  padding:7px 15px; border-radius:999px;
}
.pill b{color:var(--text); font-weight:500}
.pill.link{transition:border-color .25s ease, color .25s ease}
.pill.link:hover{border-color:var(--accent-line); color:var(--text)}
.pill .dot{width:5px; height:5px; border-radius:999px; background:var(--accent); flex:0 0 auto}

.tag-pro,.tag-new{
  display:inline-block; margin-left:8px; font-family:var(--font-mono);
  font-size:9px; font-weight:500; letter-spacing:.1em; text-transform:uppercase;
  border-radius:4px; padding:2px 6px; vertical-align:middle;
}
.tag-pro{color:var(--positive); border:1px solid rgba(34,197,94,.42); background:var(--positive-soft)}
.tag-new{color:var(--accent); border:1px solid var(--accent-line); background:var(--accent-soft)}

/* ------------------------------------------------------- Header / nav bar -- */

header.site{
  position:sticky; top:0; z-index:40;
  background:rgba(6,7,10,.66); backdrop-filter:blur(16px) saturate(150%);
  -webkit-backdrop-filter:blur(16px) saturate(150%);
  border-bottom:1px solid transparent;
  transition:border-color .3s ease, background-color .3s ease;
}
header.site.scrolled{border-bottom-color:var(--line); background:rgba(6,7,10,.88)}

.nav{display:flex; align-items:center; justify-content:space-between; height:70px}
.brand{display:flex; align-items:center; gap:12px; font-weight:600; font-size:16px; color:var(--text); letter-spacing:-.01em}
.brand img{width:30px; height:30px; border-radius:8px}
.nav-links{display:flex; align-items:center; gap:4px}
.nav-links a{
  color:var(--muted); font-family:var(--font-mono);
  font-size:11px; font-weight:400; letter-spacing:.07em; text-transform:uppercase;
  padding:9px 13px; border-radius:8px; transition:color .2s ease, background-color .2s ease;
}
.nav-links a:hover{color:var(--text); background:rgba(255,255,255,.04)}
.nav-links a.active{color:var(--text)}
.nav-cta{margin-left:10px}

/* Scroll progress hairline, pinned under the nav. Purely decorative. */
.scroll-progress{
  position:absolute; left:0; bottom:-1px; height:2px; width:100%;
  transform-origin:0 50%; transform:scaleX(0);
  background:linear-gradient(90deg,var(--accent),#7ad6ff);
  pointer-events:none;
}

/* ------------------------------------------------------------ Backgrounds -- */

/* Dot grid + a soft accent glow. Both are masked so they fade out rather than
   ending on a hard edge, and both sit behind content via z-index on .wrap. */
.grid-bg{position:relative; isolation:isolate; overflow:hidden}
.grid-bg::before{
  content:""; position:absolute; inset:0; z-index:-2;
  background-image:radial-gradient(circle at center, rgba(255,255,255,.09) 1px, transparent 1px);
  background-size:30px 30px;
  -webkit-mask-image:radial-gradient(ellipse 78% 60% at 50% 24%, #000 18%, transparent 76%);
  mask-image:radial-gradient(ellipse 78% 60% at 50% 24%, #000 18%, transparent 76%);
}
.grid-bg::after{
  content:""; position:absolute; z-index:-1;
  left:50%; top:-300px; width:1100px; height:680px; transform:translateX(-50%);
  background:radial-gradient(ellipse at center, rgba(0,224,255,.11), transparent 66%);
  pointer-events:none;
}

/* A single hairline that spans the viewport width, used between sections. */
.rule{height:1px; background:linear-gradient(90deg,transparent,var(--line) 18%,var(--line) 82%,transparent)}

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

section{padding:var(--section-y) 0}

/* The eyebrow is now a mono micro-label. Paired with .section-index it forms
   the editorial "01 / EVERYTHING YOU NEED" rail that carries hierarchy, which
   is what lets the headings stay smaller than the reference site's. */
.eyebrow{
  display:inline-block; color:var(--accent);
  font-family:var(--font-mono); font-weight:400; font-size:11px;
  letter-spacing:var(--track-wide); text-transform:uppercase;
}
.section-index{
  display:block; color:var(--muted-dim);
  font-family:var(--font-mono); font-size:11px; letter-spacing:.1em;
  margin:0 0 18px;
}
.center .section-index{text-align:center}

h1,h2,h3{font-family:var(--font-display); font-weight:var(--w-display)}
h2{
  font-family:var(--font-display); font-size:var(--fs-h2); line-height:1.06;
  margin:18px 0 20px; letter-spacing:var(--track-display); font-weight:var(--w-display);
}
h3{letter-spacing:var(--track-tight)}
.lead{
  color:var(--muted); font-family:var(--font); font-size:var(--fs-lead);
  line-height:1.6; max-width:600px; margin:0;
}
.center .lead{margin-left:auto; margin-right:auto}

/* Italic is the display face's accent voice - used on the second line of a
   headline the way the reference site uses its editorial italic. */
.em{font-style:italic}

.grad{
  background:linear-gradient(96deg,var(--accent),#7ad6ff 55%,#c7ecff);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}

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

.hero{
  padding:clamp(64px,8vw,116px) 0 clamp(56px,6vw,88px);
  display:grid; grid-template-columns:1.1fr .9fr; gap:56px; align-items:center;
}
/* line-height stays at 1 rather than going tighter: the display face has real
   descenders, and the line-mask reveal clips at the line box. */
.hero h1{
  font-size:var(--fs-display); line-height:1; letter-spacing:var(--track-display);
  margin:24px 0 26px; font-weight:var(--w-display);
}
.hero .sub{
  font-size:var(--fs-lead); line-height:1.6; color:var(--muted);
  margin:0 0 34px; max-width:480px;
}
.cta-row{display:flex; align-items:center; gap:16px; flex-wrap:wrap}
.cta-note{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.05em;
  text-transform:uppercase; color:var(--muted-dim); margin-top:20px; line-height:1.8;
}

/* Phone mockup. Shown flat and face-on everywhere - see the note below on why
   the devices carry no 3D lean. */
.phone{
  position:relative; width:300px; max-width:78vw; margin:0 auto;
  border:9px solid #151a21; border-radius:44px; background:#000;
  overflow:hidden;
  /* Four layers, in the order they read: the drop that seats the device on the
     page, a hairline rim so the black case separates from a black background,
     then two cyan layers standing in for the screen's own light spilling onto
     the surface behind it - a tight one that hugs the case and a wide, very
     faint bloom. It has to stay light rather than turn into a cyan ring, so if
     it ever needs more presence, widen the bloom before raising its alpha.
     The device is the only lit object on the page; this is what stops it
     reading as pasted on. */
  box-shadow:
    0 40px 100px rgba(0,0,0,.66),
    0 0 0 1px rgba(255,255,255,.045),
    0 22px 80px -14px rgba(0,224,255,.22),
    0 0 150px rgba(0,224,255,.07);
}
.phone img{display:block; width:100%}

/* Devices face straight forward. The screenshots are the product evidence, so
   they are shown flat and unskewed - a 3D lean makes the UI inside them harder
   to read and subtly misrepresents proportions. The scroll-driven settle below
   is a rise only, with no rotation to match. */
.hero-device .phone{transform:none}

/* ---------------------------------------------------------- Trust strip ---- */

/* Reworked from pills into a hairline-separated mono row - closer to the
   reference site's language and much quieter than four bordered capsules. */
.trust{
  display:flex; flex-wrap:wrap; justify-content:center; align-items:center;
  gap:0; padding:clamp(30px,4vw,48px) 0 0; margin-top:clamp(24px,3vw,36px);
  border-top:1px solid var(--line);
}
.trust .item{
  display:inline-flex; align-items:center; gap:10px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:300;
  letter-spacing:.08em; text-transform:uppercase; color:var(--muted);
  padding:10px clamp(14px,2.4vw,30px);
  border:0; background:none; border-radius:0;
}
.trust .item + .item{border-left:1px solid var(--line)}
.trust .item svg{width:14px; height:14px; flex:0 0 auto; color:var(--accent)}

/* --------------------------------------------------------------- Stat row -- */

.stats{
  display:grid; grid-template-columns:repeat(4,1fr); gap:0;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  margin-top:clamp(44px,5vw,68px); background:none; border-radius:0; overflow:visible;
}
.stat{background:none; padding:30px 22px; text-align:center}
.stat + .stat{border-left:1px solid var(--line)}
.stat .n{
  font-family:var(--font-display); font-size:clamp(2rem,3.4vw,2.9rem); font-weight:var(--w-display);
  letter-spacing:var(--track-display); display:block; line-height:1.05;
}
.stat .l{
  font-family:var(--font-mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--muted); margin-top:12px; display:block;
}

/* --------------------------------------------------------------- Marquee --- */

/* A single-line scrolling strip. Duplicated content is marked aria-hidden in
   the markup so a screen reader reads the phrase once, not twice. */
.marquee{
  overflow:hidden; border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  padding:clamp(18px,2.4vw,26px) 0; margin:0;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.marquee-track{
  display:flex; width:max-content; gap:0;
  animation:marquee 46s linear infinite;
}
.marquee:hover .marquee-track{animation-play-state:paused}
.marquee span{
  display:inline-flex; align-items:center; gap:26px;
  font-family:var(--font-display); font-size:clamp(1.5rem,2.6vw,2.2rem); font-weight:var(--w-display);
  letter-spacing:var(--track-display); color:var(--muted-dim); white-space:nowrap;
  padding-right:26px;
}
.marquee span::after{
  content:""; width:5px; height:5px; border-radius:999px;
  background:var(--accent); flex:0 0 auto; opacity:.55;
}
@keyframes marquee{
  from{transform:translateX(0)}
  to{transform:translateX(-50%)}
}

/* ---------------------------------------------------------- Feature cards -- */

/* Flat, rule-separated cells rather than floating boxes. The old raised-card
   treatment fought the editorial type; a grid of hairlines sits under it. */
.cards{display:grid; grid-template-columns:repeat(3,1fr); gap:0; margin-top:clamp(44px,5vw,64px); text-align:left; border-top:1px solid var(--line)}
.cards.two{grid-template-columns:repeat(2,1fr)}

.card{
  position:relative; background:none; border:0;
  border-bottom:1px solid var(--line); border-right:1px solid var(--line);
  border-radius:0; padding:clamp(26px,2.6vw,34px) clamp(22px,2.2vw,30px);
  overflow:hidden;
  transition:background-color .3s ease;
}
.card:nth-child(3n){border-right:0}
.cards.two .card:nth-child(3n){border-right:1px solid var(--line)}
.cards.two .card:nth-child(2n){border-right:0}
.card:hover{background:var(--card); transform:none; border-color:var(--line)}
.card::before{display:none}
.card .ic{
  width:38px; height:38px; border-radius:10px; display:grid; place-items:center;
  background:var(--accent-soft); border:1px solid var(--accent-line);
  margin-bottom:20px;
}
.card h3{
  margin:0 0 10px; font-family:var(--font-display); font-size:var(--fs-h3);
  font-weight:var(--w-display); letter-spacing:var(--track-tight); line-height:1.2;
}
.card p{margin:0; color:var(--muted); font-size:14.5px; line-height:1.68}

/* The three "new in this release" cards get an accent wash. */
.card.spot{background:linear-gradient(165deg,rgba(0,224,255,.06),transparent 62%)}
.card.spot:hover{background:linear-gradient(165deg,rgba(0,224,255,.10),var(--card) 62%)}

/* ------------------------------------------------------- Screenshot rail --- */

.rail-outer{position:relative}
.rail{
  display:flex; gap:24px; overflow-x:auto; padding:clamp(40px,5vw,58px) 32px 24px;
  scroll-snap-type:x mandatory; scrollbar-width:none;
}
.rail::-webkit-scrollbar{display:none}
/* Nine devices in a row sit close enough that the standard bloom would pool
   into one cyan smear behind the whole rail, so each keeps only the tight
   layer. The glow is meant to pick a device out, and in the rail nothing is
   being picked out. */
.rail .phone{
  flex:0 0 auto; width:236px; scroll-snap-align:center; margin:0;
  box-shadow:
    0 30px 70px rgba(0,0,0,.62),
    0 0 0 1px rgba(255,255,255,.045),
    0 16px 54px -16px rgba(0,224,255,.18);
}
/* Fade the rail into the page edges instead of clipping the phones flat. */
.rail-outer::before,.rail-outer::after{
  content:""; position:absolute; top:0; bottom:0; width:110px; z-index:2; pointer-events:none;
}
.rail-outer::before{left:0; background:linear-gradient(90deg,var(--bg),transparent)}
.rail-outer::after{right:0; background:linear-gradient(270deg,var(--bg),transparent)}
.rail-hint{
  text-align:center; color:var(--muted-dim); font-family:var(--font-mono);
  font-size:10px; letter-spacing:.1em; text-transform:uppercase; margin:6px 0 0;
}

/* ----------------------------------------------------------------- Bands --- */

.band{background:var(--bg-elev); border-top:1px solid var(--line); border-bottom:1px solid var(--line)}

/* A full-width feature panel: copy on one side, device on the other. */
.split{display:grid; grid-template-columns:1fr 1fr; gap:clamp(44px,5vw,72px); align-items:center}
.split-media .phone{transform:none}

/* ------------------------------------------------------ Live wipe demo (.wd)
   The one device on the page that is not a screenshot. Section 03 tells the
   visitor to drag the divider, so the divider is real: a rebuild of the app's
   Compare screen in markup, driven by assets/wipe-demo.js.

   Every size below is in `cqw` - percent of the phone's own screen width, with
   the container declared on `.wd` itself. That is what keeps the rebuilt chrome
   in proportion with the real screenshots beside it at any phone width, from
   the 300px desktop device down to the 78vw mobile one, with no breakpoints to
   maintain. Numbers are read off assets/shot-wipe-v1.2.png, which stays in the
   repo as the reference for this screen. Do not convert them to px.           */
.wd{
  container-type:inline-size;
  position:relative; width:100%; aspect-ratio:924/2000;
  background:#000; color:var(--text);
  font-family:var(--font); display:flex; flex-direction:column;
  overflow:hidden; user-select:none; -webkit-user-select:none;
}
.wd svg{width:1em; height:1em; flex:0 0 auto}

.wd-status{height:18.4cqw; flex:0 0 auto}

.wd-seg{
  flex:0 0 auto; display:flex; gap:.4cqw; margin:0 2.4cqw; padding:.55cqw;
  height:11.4cqw; background:#14171c; border-radius:2.9cqw;
}
.wd-seg-item{
  flex:1; display:flex; align-items:center; justify-content:center; gap:1.2cqw;
  border-radius:2.5cqw; font-size:3.7cqw; font-weight:700; letter-spacing:-.01em;
  color:#79818d;
}
.wd-seg-item svg{font-size:4.1cqw; stroke-width:1.6}
.wd-seg-item.on{background:var(--accent); color:#04141c}

.wd-card{
  flex:1 1 auto; min-height:0; margin:2.9cqw 2.4cqw 0;
  background:#0a0d12; border-radius:2.6cqw 2.6cqw 0 0; overflow:hidden;
}

.wd-mode{height:14cqw; display:flex; align-items:center; justify-content:center}
.wd-mode-track{display:flex; gap:.5cqw; padding:.7cqw; background:#15181e; border-radius:99px}
.wd-mode-item{
  display:flex; align-items:center; gap:1cqw; padding:1cqw 3.4cqw; border-radius:99px;
  font-size:3.2cqw; font-weight:700; letter-spacing:-.01em; color:#79818d;
}
.wd-mode-item svg{font-size:3.5cqw}
.wd-mode-item.on{background:rgba(0,224,255,.13); color:var(--accent)}

/* ---- The stage. `--wx` is the divider position and the single source of truth:
   the JS writes it, and the clip, the line and the handle all read it, so they
   can never drift apart by a frame.                                           */
.wd-stage{
  position:relative; aspect-ratio:3/4; overflow:hidden;
  border-radius:1.7cqw 1.7cqw 0 0; background:#111;
  touch-action:pan-y; cursor:ew-resize;
}
.wd-photo{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center top;
  -webkit-user-drag:none; user-select:none; pointer-events:none;
}
/* Base is AFTER; the wipe reveals BEFORE from the left - the same order as the
   app's WipeCompare, so the labels mean the same thing in both places. */
.wd-photo-before{clip-path:inset(0 calc(100% - var(--wx)) 0 0)}

.wd-tag,.wd-date{position:absolute; background:rgba(0,0,0,.55); color:#fff; border-radius:1.2cqw}
.wd-tag{
  top:3cqw; padding:.9cqw 2cqw; font-size:2.6cqw; font-weight:800;
  letter-spacing:.16em; text-transform:uppercase;
}
.wd-tag-l{left:3cqw}
.wd-tag-r{right:3cqw}
.wd-date{
  bottom:2.6cqw; padding:1.1cqw 2cqw; font-size:3cqw; font-weight:700;
  color:#dcdcdc; background:rgba(0,0,0,.5);
}
.wd-date-l{left:2.6cqw}
.wd-date-r{right:2.6cqw}

/* The app draws this line only when the visitor has the overlay option on. Here
   it is always on and a touch thinner: on a page nobody has been handed, the
   line is what says the two halves are one photo you can move. */
.wd-line{
  position:absolute; top:0; bottom:0; left:var(--wx); width:.45cqw; margin-left:-.225cqw;
  background:rgba(255,255,255,.85); pointer-events:none;
}
.wd-handle{
  position:absolute; top:50%; left:var(--wx);
  width:12.4cqw; height:12.4cqw; margin:-6.2cqw 0 0 -6.2cqw; padding:0;
  display:flex; align-items:center; justify-content:center;
  background:rgba(0,0,0,.55); border:.7cqw solid #fff; border-radius:50%;
  color:#fff; cursor:ew-resize; touch-action:none;
  transition:transform .18s var(--ease-out), box-shadow .18s var(--ease-out);
}
.wd-handle svg{font-size:6.6cqw}
.wd-handle:hover{transform:scale(1.08)}
.wd-handle:focus-visible{outline:none; box-shadow:0 0 0 .8cqw rgba(0,224,255,.55)}
.wd-stage.is-dragging .wd-handle{transform:scale(1.08)}
.wd-stage.is-dragging{cursor:grabbing}

.wd-align{
  display:flex; align-items:center; justify-content:space-between;
  height:8.7cqw; padding:0 3cqw; border-bottom:1px solid #171b21;
  font-size:3.4cqw; font-weight:700; letter-spacing:-.01em;
}
.wd-align-l{display:flex; align-items:center; gap:1.6cqw}
.wd-align-l svg{font-size:4cqw; color:var(--accent)}
.wd-chev{font-size:4cqw; color:#79818d}

.wd-stats{display:flex; padding:2.4cqw 0 0}
.wd-stats span{
  flex:1; display:flex; flex-direction:column; align-items:center; gap:.6cqw;
  font-size:2.7cqw; font-weight:600; color:#6b7683;
}
.wd-stats span + span{border-left:1px solid #171b21}
.wd-stats b{font-size:5cqw; font-weight:800; color:var(--text); letter-spacing:-.02em}
.wd-stats b.pos{color:var(--positive)}

/* The space left under the labels is the home-indicator area, so it is part of
   the proportion rather than slack to be tightened up. */
.wd-tabbar{
  flex:0 0 auto; display:flex; height:20.8cqw; padding-top:3.2cqw;
  background:#0a0c10; border-top:1px solid #171b21;
}
.wd-tabbar span{
  flex:1; display:flex; flex-direction:column; align-items:center; gap:1.1cqw;
  font-size:2.7cqw; font-weight:500; color:#6b7683;
}
.wd-tabbar span svg{font-size:6.2cqw}
.wd-tabbar span.on{color:var(--accent)}

/* Without container queries every `cqw` above is an invalid length and the
   rebuilt chrome would blow out of the case. Rather than ship a broken screen,
   drop the chrome and keep what the section is actually about: the two photos
   and a divider you can still drag. */
@supports not (container-type:inline-size){
  .wd{aspect-ratio:auto}
  .wd-status,.wd-seg,.wd-mode,.wd-align,.wd-stats,.wd-tabbar{display:none}
  .wd-card{margin:0; border-radius:0}
  .wd-stage{border-radius:0}
  .wd-tag{font-size:10px; padding:3px 8px; border-radius:6px; top:10px}
  .wd-tag-l{left:10px} .wd-tag-r{right:10px}
  .wd-date{font-size:11px; padding:4px 8px; border-radius:6px; bottom:8px}
  .wd-date-l{left:8px} .wd-date-r{right:8px}
  .wd-line{width:2px; margin-left:-1px}
  .wd-handle{width:38px; height:38px; margin:-19px 0 0 -19px; border-width:2px}
  .wd-handle svg{font-size:20px}
  .wd-handle:focus-visible{box-shadow:0 0 0 3px rgba(0,224,255,.55)}
}

/* --------------------------------------------------- Works with Apple Health
   Apple requires the badge to sit in a subordinate position (smaller than the
   main message), stand at least 30px tall, and keep clear space of at least a
   quarter of its height on every side. Do not shrink or crowd it.            */
.wwah{margin-top:34px; display:flex; justify-content:center}
.wwah img{height:44px; width:auto; display:block; margin:11px}
.wwah-note{max-width:620px; margin:22px auto 0; color:var(--muted); font-size:14px; line-height:1.7}

/* ------------------------------------------------------------------- Film -- */

/* Full-bleed brand film. The clip is 16:9 with its subject centre-right and a
   large unlit field on the left, so the copy is placed into space the footage
   already leaves empty instead of being knocked back with a scrim over the
   figure. A gradient still runs left-to-right, but only far enough to guarantee
   the text's contrast if the clip is ever replaced with a busier one. */
.film-band{
  position:relative; padding:0; overflow:hidden; isolation:isolate;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  background:#000;
  min-height:clamp(420px,54vw,720px);
  display:grid; align-items:center;
}
.film{
  position:absolute; inset:0; z-index:-2;
  width:100%; height:100%; object-fit:cover; object-position:62% center;
  display:block;
}
/* Left-side falloff for the copy, plus a top/bottom feather so the band meets
   the page instead of butting against it. */
.film-band::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(90deg, rgba(6,7,10,.94) 0%, rgba(6,7,10,.82) 32%, rgba(6,7,10,.28) 58%, rgba(6,7,10,0) 78%),
    linear-gradient(180deg, rgba(6,7,10,.55), transparent 22%, transparent 78%, rgba(6,7,10,.55));
}
.film-copy{position:relative; width:100%; padding:clamp(56px,7vw,96px) 0}
.film-copy .lead{max-width:34ch}

/* Copy left, device right, with the figure occupying the gap between them. The
   right column is pinned to the container edge so the phone clears the subject
   rather than sitting on top of him. */
.film-grid{
  display:grid; grid-template-columns:minmax(0,1.2fr) auto;
  gap:clamp(28px,4vw,64px); align-items:center;
}
/* Pulled in from the container edge so the device sits near the figure rather
   than hard against the right margin. This margin is the one number to change
   if it wants to be closer to or further from him. */
.film-device{justify-self:end; margin-right:clamp(0px,8vw,150px); text-align:center}
.film-device .phone{
  width:clamp(180px,17vw,244px); margin:0; transform:none;
  /* Dark UI over dark footage needs its own separation, so the rim and the cyan
     spill are carried further than the standard .phone shadow. */
  box-shadow:
    0 40px 90px rgba(0,0,0,.7),
    0 0 0 1px rgba(255,255,255,.055),
    0 22px 80px -12px rgba(0,224,255,.26),
    0 0 160px rgba(0,224,255,.10);
}
@media (max-width:900px){
  /* Portrait viewports crop a 16:9 subject badly, so the film moves behind the
     copy as a full-bleed backdrop and the falloff becomes vertical. The phone
     stacks under the copy at a reduced size rather than competing for width. */
  .film-band{min-height:0}
  .film{object-position:58% center}
  .film-band::before{
    background:
      linear-gradient(180deg, rgba(6,7,10,.92) 0%, rgba(6,7,10,.72) 42%, rgba(6,7,10,.6) 70%, rgba(6,7,10,.92) 100%);
  }
  .film-copy{padding:clamp(44px,9vw,72px) 0}
  .film-grid{grid-template-columns:1fr; gap:38px; justify-items:start}
  .film-device{justify-self:center; margin-right:0}
  .film-device .phone{width:200px}
}

/* ------------------------------------------------------------ Page heroes -- */

.page-hero{border-bottom:1px solid var(--line); padding:clamp(56px,7vw,92px) 0 clamp(44px,5vw,64px)}
.page-hero h1{
  font-family:var(--font-display); font-size:clamp(2.4rem,5.2vw,4.2rem); line-height:1;
  letter-spacing:var(--track-display); margin:20px 0 18px; font-weight:var(--w-display);
}
.page-hero .sub{font-size:var(--fs-lead); line-height:1.6; color:var(--muted); margin:0; max-width:var(--prose)}
.page-hero .eff{
  color:var(--muted-dim); font-family:var(--font-mono); font-size:10.5px;
  letter-spacing:.08em; text-transform:uppercase; margin:22px 0 0;
}

/* ------------------------------------------------------- What's New entries */

.release{max-width:var(--prose); margin-left:auto; margin-right:auto}
.rel-head{display:flex; align-items:baseline; gap:14px; flex-wrap:wrap; margin:0 0 14px}
.rel-version{font-family:var(--font-display); font-size:2rem; font-weight:var(--w-display); letter-spacing:var(--track-display)}
.rel-date{
  color:var(--muted-dim); font-family:var(--font-mono); font-size:10.5px;
  letter-spacing:.08em; text-transform:uppercase;
}
.rel-lead{color:var(--muted); font-size:16.5px; line-height:1.7; margin:0 0 36px}
.rel-lead strong{color:var(--text); font-weight:600}
/* Older releases sit visually behind the current one. */
.release.past .rel-version{font-size:1.5rem; color:var(--muted)}

.entry{
  position:relative; background:none; border:0; border-top:1px solid var(--line);
  border-radius:0; padding:28px 0 26px; margin:0;
}
.entry .ic{
  width:38px; height:38px; border-radius:10px; display:grid; place-items:center;
  background:var(--accent-soft); border:1px solid var(--accent-line); margin-bottom:18px;
}

/* ------------------------------------------------------------------ Icons -- */

/* One geometry for every icon on the site: 24x24 viewBox, currentColor stroke,
   round caps. These replaced the emoji the pages used to use - emoji render
   differently on every platform, cannot take the palette, and read as
   placeholder art at this size. */
.ic svg{width:19px; height:19px; display:block; color:var(--accent)}
.pill-ic{width:13px; height:13px; flex:0 0 auto; color:var(--accent)}
.btn-ic{width:16px; height:16px; flex:0 0 auto}
.entry h2{
  margin:0 0 11px; font-family:var(--font-display); font-size:1.45rem;
  letter-spacing:var(--track-tight); font-weight:var(--w-display); line-height:1.2;
}
.entry p{margin:0 0 13px; color:var(--muted); font-size:15.5px; line-height:1.72}
.entry p:last-child{margin-bottom:0}
.entry strong{color:var(--text); font-weight:600}

.shots{display:grid; grid-template-columns:repeat(3,1fr); gap:24px; margin:clamp(44px,5vw,60px) auto 8px; max-width:var(--prose)}
.shots .phone{width:auto; max-width:none; border-width:1px; border-color:var(--line); border-radius:20px; box-shadow:none}
.shot-cap{color:var(--muted); font-size:13px; margin:13px 2px 0; line-height:1.6}
.shot-cap b{
  color:var(--text); font-family:var(--font-mono); font-size:10px; font-weight:400;
  letter-spacing:.09em; text-transform:uppercase; display:block; margin-bottom:5px;
}

/* --------------------------------------------------------------- Callout --- */

.callout{
  max-width:var(--prose); margin:44px auto 0;
  background:var(--bg-elev); border:1px solid var(--line); border-left:2px solid var(--accent);
  border-radius:0 var(--radius) var(--radius) 0; padding:26px 28px;
}
.callout h2,.callout h3{margin:0 0 11px; font-family:var(--font-display); font-size:1.25rem; letter-spacing:var(--track-tight); font-weight:var(--w-display)}
.callout p{margin:0; color:var(--muted); font-size:15.5px; line-height:1.72}
.callout p + p{margin-top:12px}
.callout ul{margin:0; padding-left:20px; color:var(--muted)}
.callout li{margin:9px 0}
.callout strong{color:var(--text); font-weight:600}

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

.prose{max-width:var(--prose); margin:0 auto}
.prose h2{font-family:var(--font-display); font-size:1.7rem; margin:44px 0 14px; letter-spacing:var(--track-tight); font-weight:var(--w-display); line-height:1.15}
.prose h2:first-child{margin-top:0}
.prose p,.prose li{color:var(--muted); font-size:15.5px; line-height:1.78}
.prose strong{color:var(--text); font-weight:600}
.prose ul{padding-left:20px}
.prose li{margin:9px 0}
.prose a{border-bottom:1px solid var(--accent-line)}

/* --------------------------------------------------------------- Contact --- */

.contact{
  max-width:var(--prose); margin:32px auto 0;
  background:none; border:0; border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  border-radius:0; padding:26px 0;
  display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap;
}
.contact .ct{flex:1 1 320px}
.contact h3{margin:0 0 5px; font-family:var(--font-display); font-size:1.25rem; font-weight:var(--w-display); letter-spacing:var(--track-tight)}
.contact p{margin:0; color:var(--muted); font-size:14.5px; line-height:1.65}

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

.faq{max-width:var(--prose); margin:0 auto}
.cat{
  color:var(--accent); font-family:var(--font-mono); font-size:10.5px;
  letter-spacing:var(--track-wide); text-transform:uppercase; margin:44px 0 14px;
}
.cat:first-child{margin-top:0}

details{
  background:none; border:0; border-bottom:1px solid var(--line); border-radius:0;
  margin:0; overflow:hidden; transition:background-color .2s ease;
}
details:hover{border-color:var(--line-hi)}
details[open]{background:none; border-color:var(--line)}
summary{
  cursor:pointer; list-style:none; padding:20px 4px; font-weight:500; font-size:16px;
  color:var(--text); display:flex; align-items:center; justify-content:space-between; gap:16px;
  transition:color .2s ease;
}
summary::-webkit-details-marker{display:none}
summary:hover{color:var(--accent)}
summary .mk{flex:0 0 auto; width:20px; height:20px; position:relative; color:var(--accent); transition:transform .25s var(--ease-out)}
summary .mk::before,summary .mk::after{
  content:""; position:absolute; background:currentColor; border-radius:2px;
  left:50%; top:50%; transform:translate(-50%,-50%);
}
summary .mk::before{width:11px; height:1.5px}
summary .mk::after{width:1.5px; height:11px; transition:opacity .25s ease}
details[open] summary .mk{transform:rotate(180deg)}
details[open] summary .mk::after{opacity:0}
.ans{padding:0 4px 22px; color:var(--muted); font-size:15.5px; line-height:1.78}
.ans strong{color:var(--text); font-weight:600}

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

footer{padding:clamp(48px,6vw,72px) 0 48px; border-top:1px solid var(--line); color:var(--muted); font-size:14px; margin-top:clamp(56px,7vw,88px)}
.foot{display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:18px}
.foot .brand{font-size:15px}
.foot .brand img{width:28px; height:28px}
.foot-links a{
  color:var(--muted); margin-right:22px; font-family:var(--font-mono);
  font-size:10.5px; letter-spacing:.07em; text-transform:uppercase;
  transition:color .2s ease;
}
.foot-links a:hover{color:var(--text)}
.foot-copy{width:100%; color:var(--muted-dim); font-family:var(--font-mono); font-size:10px; letter-spacing:.06em}
.foot-legal{width:100%; color:var(--muted-dim); font-size:12px; line-height:1.65; opacity:.8}

/* ============================================================== Motion ==== */

/* Scroll reveal. The hidden state exists ONLY when JS has run (`.js`) and the
   visitor has not asked for reduced motion, so the page degrades to plain,
   fully visible HTML in every other case. `--i` is set by reveal.js to stagger
   the children of a [data-reveal-group]. */
@media (prefers-reduced-motion: no-preference){
  .js [data-reveal]{
    opacity:0;
    transform:translateY(26px);
    will-change:opacity, transform;
  }
  .js [data-reveal="fade"]{transform:none}
  .js [data-reveal="left"]{transform:translateX(-30px)}
  .js [data-reveal="right"]{transform:translateX(30px)}
  .js [data-reveal="zoom"]{transform:scale(.96)}
  .js [data-reveal].is-in{
    opacity:1;
    transform:none;
    transition:
      opacity .8s var(--ease-out) calc(var(--i, 0) * 70ms),
      transform .9s var(--ease-out) calc(var(--i, 0) * 70ms);
  }

  /* Line-mask reveal for display headings. reveal.js wraps each line of a
     [data-reveal="lines"] heading in .ln > .ln-i; the outer span clips and the
     inner one rises into it, which is the editorial "type rises off the
     baseline" effect. If the wrapping never runs, the heading is a plain
     [data-reveal] and still fades in - the transform below only ever applies to
     markup reveal.js created itself. */
  .js [data-reveal="lines"]{opacity:1; transform:none}
  /* The mask clips at the line box, which cuts the descenders off a serif at
     these sizes ("y" in day, "p" in photo). Pad the box out far enough to clear
     them and pull the same amount back off the bottom margin, so the mask grows
     without the heading's spacing moving. */
  .js [data-reveal="lines"] .ln{
    display:block; overflow:hidden;
    padding-bottom:.16em; margin-bottom:-.16em;
  }
  .js [data-reveal="lines"] .ln-i{
    display:block; transform:translateY(102%);
    transition:transform .95s var(--ease-out) calc(var(--l, 0) * 85ms);
  }
  .js [data-reveal="lines"].is-in .ln-i{transform:translateY(0)}
  /* Before reveal.js has wrapped anything, keep the heading hidden so it does
     not flash unmasked on a slow first paint. */
  .js [data-reveal="lines"]:not(.ln-ready){opacity:0}
  .js [data-reveal="lines"].ln-ready{opacity:1; transition:none}

  /* Scroll-linked effects. Progressive enhancement on top of the reveal:
     browsers without scroll-driven animations simply keep the static transform,
     which is already a finished-looking state. Keep these to transforms that
     look complete at any point in their range - a half-finished frame is what
     a visitor sees if they stop scrolling. */
  @supports (animation-timeline: view()){
    .js .hero-device .phone{
      animation:device-settle linear both;
      animation-timeline:view();
      animation-range:entry 10% cover 42%;
    }
    .js .band .split-media .phone{
      animation:device-settle linear both;
      animation-timeline:view();
      animation-range:entry 0% cover 46%;
    }
  }
}

@keyframes device-settle{
  from{transform:translateY(26px)}
  to{transform:translateY(0)}
}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .btn:hover,.card:hover,.appstore-badge:hover{transform:none}
  .marquee-track{animation:none; transform:none}
  .marquee{-webkit-mask-image:none; mask-image:none}
}

/* ========================================================== Responsive ==== */

@media (max-width:900px){
  h2{font-size:clamp(1.9rem,6vw,2.6rem)}
  .hero{grid-template-columns:1fr; padding:56px 0 24px; text-align:center; gap:44px}
  .hero .sub{margin-left:auto; margin-right:auto}
  .cta-row{justify-content:center}
  .cards,.cards.two{grid-template-columns:1fr}
  .card,.cards.two .card{border-right:0}
  .card:last-child{border-bottom:0}
  .split{grid-template-columns:1fr; gap:38px}
  .stats{grid-template-columns:repeat(2,1fr)}
  .stat:nth-child(3){border-left:0}
  .stat:nth-child(3),.stat:nth-child(4){border-top:1px solid var(--line)}
  .nav-links .hide-sm{display:none}
  .trust{border-top:1px solid var(--line)}
  .trust .item{padding:9px 14px}
  .trust .item + .item{border-left:0}
}

@media (max-width:640px){
  .wrap{padding:0 20px}
  .brand{white-space:nowrap; font-size:15px}
  .brand img{width:28px; height:28px}
  .nav-links{gap:0}
  .nav-links a{font-size:10px; padding:8px 7px}
  .nav-cta{display:none}
  .hero h1{letter-spacing:-.03em}
  .shots{grid-template-columns:1fr; gap:36px; max-width:340px; margin-left:auto; margin-right:auto}
  .rail{padding-left:20px; padding-right:20px}
  .rail-outer::before,.rail-outer::after{width:40px}
  .contact{flex-direction:column; align-items:flex-start}
  .entry{padding:24px 0 22px}
  .foot-links a{margin-right:18px}
  .marquee span{gap:18px; padding-right:18px}
}
