/* Bumpy website: one stylesheet for every page.
   Bumpy's brand (colours from App/Views/DesignSystem.swift, rounded type, lilac glass,
   the orange take-photo disc) laid out like an Apple product page.

   Layout rule: nothing is placed by guesswork. The opening stage is exactly one screen
   tall (small-viewport units, so mobile browser bars never cover it), its type is sized
   by whichever of width or height is tighter, and the phone takes whatever height is
   left. The phone's own details scale with the phone (container units). */

:root {
  --backdrop: rgb(179 161 242);   /* bumpyBackdrop */
  --lavender: rgb(219 214 250);   /* bumpyLavender */
  --lilac-soft: rgb(240 238 253);
  --paper: rgb(252 252 255);      /* bumpyPaper */
  --ink: rgb(38 33 64);           /* bumpyInk */
  --ink-deep: rgb(24 20 42);
  --accent: rgb(69 41 122);       /* bumpyAccent */
  --violet: rgb(143 122 204);     /* bumpyViolet */
  --orange: rgb(255 140 69);      /* bumpyOrange */
  --peach: rgb(255 214 184);      /* bumpyPeach */
  --muted: rgb(38 33 64 / 0.64);
  --muted-on-dark: rgb(252 252 255 / 0.68);
  --line: rgb(38 33 64 / 0.1);
  --tile-radius: 30px;
  /* Side margin: 20px on the smallest phones, growing with the screen to 56px (Apple's
     product pages keep a similar proportion). Never less than the notch's safe area. */
  --gutter: max(clamp(20px, 5vw, 56px), env(safe-area-inset-left), env(safe-area-inset-right));
  --max: 1120px;
  --nav-height: 52px;
  /* The bar's full height: its 52px plus the strip the status bar, notch or Dynamic Island
     covers when the page runs edge to edge (viewport-fit=cover: a Home Screen web app, an
     in-app browser, landscape). The inset is 0 in ordinary Safari, whose status bar is its
     own (checked on the iOS 27 simulator, 27 September 2026). */
  --nav-total: calc(var(--nav-height) + env(safe-area-inset-top, 0px));
  /* One screen below the bar. svh = the viewport with browser bars showing. */
  --screen: calc(100vh - var(--nav-total));
  --rounded: ui-rounded, "SF Pro Rounded", -apple-system, BlinkMacSystemFont, system-ui, "Segoe UI", Roboto, sans-serif;
  --system: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", Roboto, sans-serif;
  color-scheme: light;
}
@supports (height: 100svh) {
  :root { --screen: calc(100svh - var(--nav-total)); }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: var(--nav-total); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--system);
  font-size: 17px;
  line-height: 1.47;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
}
/* Past the ends of the page (under Safari's toolbar once you reach the bottom, and in the
   rubber-band overscroll) browsers show the page's background colour. On pages that end
   with the footer, that colour is the footer's lilac, so the footer runs on under Safari's
   controls; a paper layer on top keeps the page itself paper. This works because WebKit
   takes only the html and body background colours for it, never images
   (LocalFrameView::documentBackgroundColor). */
body:has(> .site-footer) { background: linear-gradient(var(--paper), var(--paper)), var(--lilac-soft); }

h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
img { display: block; max-width: 100%; height: auto; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
a:focus-visible { outline: 3px solid var(--orange); outline-offset: 3px; border-radius: 8px; }

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }

/* MARK: - Navigation: a frosted bar that reaches the top of the screen
   The page scrolls on under the bar, softened by its frosting (Nat, 27 September 2026).
   On iPhone (iOS 26 and later) Safari paints the strip under the status bar itself, solid,
   whenever a bar is pinned to the top of the page: for a frosted bar it uses the page's
   background colour (WebKit's LocalFrameView::fixedContainerEdges and
   WKWebView _updateFixedColorExtensionViews; checked on the iOS 27 simulator, 27 September
   2026). On pages with the footer that colour is the footer's lilac (see body). So the bar
   starts as that same solid lilac at its top edge, where it meets Safari's strip, and
   fades to 80% at its bottom edge: the join never shows, even over the dark cards, and
   the page still shows through the lower part of the bar, much as iOS fades content under
   its own bars. When the page itself runs edge to edge (a Home Screen web app,
   landscape), the bar's own padding covers the strip and its contents sit below it (the
   top safe-area inset). */

.nav {
  position: sticky; top: 0; z-index: 10;
  height: var(--nav-total);
  padding-top: env(safe-area-inset-top, 0px);
  background: linear-gradient(rgb(240 238 253), rgb(240 238 253 / 0.8));   /* --lilac-soft, solid to 80% */
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line);
}
.nav .wrap { height: 100%; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.brand { display: flex; align-items: center; gap: 9px; color: var(--ink); font-family: var(--rounded); font-weight: 700; font-size: 19px; }
.brand:hover { text-decoration: none; }
.brand img { width: 28px; height: 28px; border-radius: 7px; }
.nav-links { display: flex; align-items: center; gap: 22px; font-size: 14px; }
.nav-links a { color: var(--ink); opacity: 0.8; }
.nav-links a:hover { opacity: 1; text-decoration: none; }

/* Launch status. Deliberately not a button: there is nothing to tap until the app is out. */
.status {
  display: inline-flex; align-items: center; gap: 8px;
  border-radius: 999px; white-space: nowrap;
  background: var(--lavender); color: var(--accent); font-weight: 600;
}
.status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--orange); }
.status.small { padding: 5px 12px; font-size: 13px; }
.status.large { padding: 10px 18px; font-size: 16px; }
.more { font-size: 19px; color: var(--accent); }
.more::after { content: " ›"; }

/* MARK: - Stage: the opening screen, then the scroll-driven film */

.stage {
  position: relative;
  height: calc(var(--screen) * 2.8);   /* one screen of stage + 1.8 screens of scrubbing */
  background: radial-gradient(120% 60% at 50% 0%, var(--lavender) 0%, var(--lilac-soft) 50%, var(--paper) 100%);
}
.stage-inner {
  /* Stops short of the bottom of the screen. Safari on iPhone treats a pinned element
     that reaches the bottom edge (it looks 4px in) like a bottom bar and lays a flat band
     under its toolbar, which cut the film off above the toolbar. With the gap, the film's
     background runs on under Safari's controls. */
  --bottom-edge-gap: 12px;
  position: sticky; top: var(--nav-total);
  height: calc(var(--screen) - var(--bottom-edge-gap));
  max-width: var(--max); margin: 0 auto;
  /* The bottom keeps clear of the home indicator when the page runs edge to edge. */
  padding: clamp(14px, 3.5svh, 44px) var(--gutter) calc(clamp(12px, 2.5svh, 28px) + env(safe-area-inset-bottom, 0px));
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  justify-items: center;
  gap: clamp(10px, 2.4svh, 28px);
}
.stage-copy { text-align: center; }
.eyebrow { font-family: var(--rounded); font-weight: 700; font-size: clamp(15px, min(4vw, 2.4svh), 21px); color: var(--orange); margin: 0 0 clamp(4px, 1svh, 10px); letter-spacing: 0; }
.stage h1 {
  font-family: var(--rounded); font-weight: 800;
  font-size: clamp(34px, min(10.4vw, 6.6svh), 112px);
  line-height: 1.0; letter-spacing: -0.04em;
  margin: 0;
}
.stage h1 .soft { color: var(--violet); }
.stage .status.large { display: none; }
.stage-phone { min-height: 0; height: 100%; width: 100%; display: flex; justify-content: center; }
.stage-foot { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.hint { font-size: 14px; color: var(--muted); transition: opacity 400ms ease; }
.hint::after { content: " ↓"; }
.stage.started .hint { opacity: 0; }
.progress { width: min(220px, 56vw); height: 4px; border-radius: 4px; background: var(--line); overflow: hidden; }
/* main.js sets --film-progress from 0 to 1 as the film plays. */
.progress span { display: block; height: 100%; width: calc(var(--film-progress, 0) * 100%); background: var(--orange); border-radius: 4px; }

/* Wide and landscape screens: words on the left, phone on the right, both one screen tall.
   The hint runs down the phone's right-hand side, where eyes already are (Nat, 27 September
   2026): a track that fills downwards as the film plays, its words turned to read down it.
   The film keeps to the same frame as the bar above it and every section below
   (var(--max) and the gutter), so their edges line up (Nat, 27 September 2026). */
@media (min-width: 720px) and (min-aspect-ratio: 5/4) {
  .stage-inner {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-rows: minmax(0, 1fr);
    align-items: center; justify-items: start;
    column-gap: 0;
  }
  /* The copy sizes its tagline by its own width (cqi), so each line fits whatever room the
     phone leaves it. */
  .stage-copy { grid-row: 1; grid-column: 1; align-self: center; text-align: left; container-type: inline-size; width: 100%; padding-right: clamp(32px, 6vw, 96px); }
  /* The tagline splits only between each sentence's halves (non-breaking spaces in the
     markup). The widest half, "Bumpy makes", is about 6.2em, so 15cqi keeps it on one line
     with room to spare; 12svh keeps it in proportion on short screens. */
  .stage h1 { font-size: clamp(34px, min(15cqi, 12svh), 104px); }
  .stage .status.large { display: inline-flex; margin-top: clamp(14px, 3svh, 32px); }
  .stage-phone { grid-row: 1; grid-column: 2; }
  .stage-foot {
    grid-row: 1; grid-column: 3;
    align-self: center;
    /* Along the phone's straight side, clear of its rounded corners. */
    height: 76%;
    margin-left: clamp(16px, 2vw, 28px);
    flex-direction: row; align-items: flex-start; gap: 10px;
  }
  .stage-foot .progress { order: -1; width: 4px; height: 100%; }
  .stage-foot .progress span { width: 100%; height: calc(var(--film-progress, 0) * 100%); }
  /* Turned a quarter clockwise, words and arrow alike, so the arrow drawn as → points down. */
  .stage-foot .hint { writing-mode: vertical-rl; text-orientation: sideways; line-height: 1; }
  .stage-foot .hint::after { content: " →"; }
}

/* MARK: - The phone: a CSS iPhone showing the film, with Bumpy's glass caption and lilac chin.
   .phone is a size container, so every detail inside is in cqw (1cqw = 1% of the phone's width). */

.phone {
  container-type: size;
  height: 100%;
  max-width: 100%;
  aspect-ratio: 9 / 19.5;
  flex: none;
}
.bezel {
  width: 100%; height: 100%;
  border-radius: 17cqw;
  padding: 3.4cqw;
  background: linear-gradient(145deg, #3b3550, #15121f 40%, #2a2538);
  box-shadow:
    0 0 0 1.5px rgb(255 255 255 / 0.14) inset,
    0 50px 90px -30px rgb(69 41 122 / 0.45),
    0 30px 60px -40px rgb(24 20 42 / 0.6);
}
.screen { position: relative; width: 100%; height: 100%; border-radius: 13.8cqw; overflow: hidden; background: var(--ink-deep); }
.screen > img.frame { width: 100%; height: 100%; object-fit: cover; }
.island { position: absolute; top: 3.4cqw; left: 50%; transform: translateX(-50%); width: 31%; height: 9cqw; border-radius: 5cqw; background: #000; z-index: 2; }
.glass {
  background: rgb(252 252 255 / 0.5);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid rgb(255 255 255 / 0.55);
  box-shadow: 0 6px 20px rgb(24 20 42 / 0.12);
}
.caption {
  position: absolute; top: 16cqw; left: 50%; transform: translateX(-50%);
  padding: 2.1cqw 4.8cqw; border-radius: 999px;
  font-family: var(--rounded); font-weight: 700; font-size: 5.2cqw; color: var(--ink);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* Her end frame shows no week, as the app's films don't (main.js). */
.caption.ending { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
  .caption { transition: opacity 0.2s ease; }
}
.chin {
  position: absolute; left: 2.4cqw; right: 2.4cqw; bottom: 2.4cqw; height: 28cqw;
  border-radius: 11.5cqw 11.5cqw 12cqw 12cqw;
  background: rgb(219 214 250 / 0.62);
  -webkit-backdrop-filter: blur(18px) saturate(170%);
  backdrop-filter: blur(18px) saturate(170%);
  border: 1px solid rgb(255 255 255 / 0.6);
  display: flex; align-items: center; justify-content: space-around;
}
.chin .dot { width: 12cqw; height: 12cqw; border-radius: 50%; background: rgb(252 252 255 / 0.7); }
.chin .disc { width: 19.5cqw; height: 19.5cqw; border-radius: 50%; background: var(--orange); box-shadow: 0 0 0 1.5cqw rgb(252 252 255 / 0.85); }

/* MARK: - Features: one per screen
   Camera, alignment, Studio, reminders and privacy each fill a screen, so a visitor sees
   one feature and one card at a time (Nat, 27 September 2026: reminders and privacy too,
   and more room between cards). Each card is one screen less one gap: centred in the
   view, it shows half a gap above and below. Words above the card on narrow screens,
   beside it on wide ones (alternating sides). The card takes whatever height is left,
   capped so it never dominates a tall screen. */

.features { --feature-gap: clamp(40px, 6vw, 80px); padding-top: calc(var(--feature-gap) / 2); }
.features-list { display: grid; gap: var(--feature-gap); }
.feature {
  height: max(600px, calc(var(--screen) - var(--feature-gap)));
  border-radius: var(--tile-radius);
  padding: clamp(40px, 8svh, 96px) clamp(28px, 5vw, 80px);
  display: grid;
  /* One column exactly as wide as the panel's inside, so a card never widens it. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  gap: clamp(28px, 5svh, 56px);
  overflow: hidden;
}
.feature.ink { background: var(--ink); color: var(--paper); }
.feature.lav { background: var(--lavender); }
.feature-copy { max-width: 30rem; }
.feature h3 { font-family: var(--rounded); font-size: clamp(30px, min(4.4vw, 6svh), 52px); line-height: 1.06; letter-spacing: -0.035em; margin: 0 0 clamp(12px, 2svh, 20px); }
.feature p { margin: 0; font-size: clamp(17px, 1.6vw, 21px); line-height: 1.42; color: var(--muted); max-width: 34ch; }
.feature .kicker { font-size: 16px; font-weight: 600; color: var(--accent); margin: 0 0 12px; }
.feature.ink p { color: var(--muted-on-dark); }
.feature.ink .kicker { color: var(--peach); }
.feature .more { display: inline-block; font-size: 18px; margin-top: 18px; }
.feature.ink .more { color: var(--peach); }
/* A size container, so the card inside can be sized by the room it has both ways. */
.feature-demo { min-height: 0; height: 100%; display: flex; align-items: center; justify-content: center; container-type: size; }

@media (min-width: 760px) and (min-aspect-ratio: 1/1) {
  .feature { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); align-items: center; column-gap: clamp(40px, 6vw, 96px); }
  .feature.flip .feature-copy { order: 2; }
  /* Side by side, the card keeps the look it has always had here: as tall as the room
     allows (capped at 620px) and as wide as its column, which is taller than 4:5. */
  .feature-demo .demo { height: min(100%, 620px); }
}

/* 4. Reminders: the lock screen on photo day, with the app's real reminder (a still picture). */
/* Two classes, so it wins over .demo-card's ink, which comes later in this file. */
.demo-card.reminder-card { background: linear-gradient(160deg, var(--backdrop), var(--lavender) 55%, var(--peach)); }
.lock-clock { position: absolute; top: 12%; left: 0; right: 0; text-align: center; color: #fff; text-shadow: 0 1px 12px rgb(69 41 122 / 0.25); }
.lock-day { display: block; font-size: 5.5cqw; font-weight: 600; opacity: 0.9; }
.lock-time { display: block; font-family: var(--rounded); font-weight: 700; font-size: 22cqw; line-height: 1; letter-spacing: -0.02em; }
.reminder-card .notice { position: absolute; left: 5%; right: 5%; top: 46%; }
/* The notification (shared look). */
.notice { margin-top: auto; display: flex; gap: 12px; align-items: center; padding: 14px 16px; border-radius: 22px; background: rgb(252 252 255 / 0.78); }
.notice img { width: 38px; height: 38px; border-radius: 9px; }
.notice strong { display: block; font-size: 15px; }
.notice span { font-size: 15px; color: var(--muted); }
/* "now", as a lock-screen notification shows it (a <span>: <time> needs a machine-readable time). */
.notice .notice-time { margin-left: auto; align-self: flex-start; font-size: 13px; color: var(--muted); }

/* MARK: - Demos: the app's onboarding animations (demos.js), one per feature tile.
   Each card is 4:5 like the app's (StageCard), a size container so its details scale with it. */

/* The demo is the size container: cqw inside = 1% of the demo's width. In a one-column
   feature it is a 4:5 card as tall as the room left over allows, never wider than the column
   (125cqw of .feature-demo is the height at which a 4:5 card fills its width), capped at
   620px; side by side it keeps its taller look (see the features' wide layout). */
.demo { container-type: size; height: min(100cqh, 125cqw, 620px); aspect-ratio: 4 / 5; max-width: 100%; margin: 0 auto; }
.demo-card {
  position: relative; width: 100%; height: 100%;
  border-radius: 10cqw; overflow: hidden;
  box-shadow: 0 10px 36px rgb(38 33 64 / 0.18);
  background: var(--ink);
  isolation: isolate;
}
.demo-card > img, .demo-card .a-print, .demo-card .flash { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* A glass pill at the top centre naming what's happening (StagePill). */
.demo-pill {
  position: absolute; top: 5%; left: 50%; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  padding: 2.2cqw 4.4cqw; border-radius: 999px;
  font-family: var(--rounded); font-weight: 700; font-size: clamp(11px, 4.4cqw, 15px); color: var(--ink);
  background: rgb(252 252 255 / 0.62);
  -webkit-backdrop-filter: blur(14px) saturate(160%); backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid rgb(255 255 255 / 0.6);
  box-shadow: 0 4px 14px rgb(24 20 42 / 0.14);
  z-index: 5;
}
.demo-pill svg { width: 1.15em; height: 1.15em; flex: none; }
.demo-pill.mint { background: rgb(217 235 214 / 0.8); }   /* bumpyMint */
.demo-pill.mint svg { color: rgb(46 125 50); }
.demo-pill.sun { background: rgb(250 214 110 / 0.78); }   /* bumpySunshine */

/* 1. Camera */
.capture-card .live { transform-origin: 50% 50%; }
.capture-card .guide-cutout { opacity: 0; }
.capture-card .p-matched, .capture-card .p-hold { opacity: 0; }
.shutter { position: absolute; left: 0; top: 0; width: 18%; aspect-ratio: 1; z-index: 3; filter: drop-shadow(0 2px 6px rgb(0 0 0 / 0.25)); }
.shutter svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.shutter circle { fill: none; }
.shutter .track { stroke: rgb(255 255 255 / 0.9); }
.shutter .ring { stroke: rgb(217 235 214); stroke-linecap: round; stroke-dasharray: 0 999; }
.shutter .disc { position: absolute; inset: 12%; border-radius: 50%; background: var(--orange); }
.capture-card .thumb { position: absolute; left: 0; top: 0; width: 13%; height: auto; aspect-ratio: 1; object-fit: cover; border-radius: 22%; box-shadow: 0 0 0 2px #fff, 0 2px 5px rgb(0 0 0 / 0.25); z-index: 3; }
.capture-card .print { display: none; z-index: 4; }
.capture-card .flash { background: #fff; opacity: 0; z-index: 6; }

/* 2. Alignment: prints on a lilac surface, turned in depth. */
.align-card { background: linear-gradient(var(--lavender), rgb(179 161 242 / 0.55)); perspective: 900px; }
.align-card .a-print { transform-origin: 50% 21%; border-radius: 10cqw; overflow: hidden; --border: 0px; }
.align-card .a-print img { width: 100%; height: 100%; object-fit: cover; display: block; }
.align-card .a-print::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 var(--border) #fff; }
.a-guides { position: absolute; inset: 0; opacity: 0; z-index: 4; filter: drop-shadow(0 0 2px rgb(38 33 64 / 0.3)); }
.a-guides .h { position: absolute; left: 0; right: 0; top: 21%; height: 1.5px; background: #fff; }
.a-guides .v { position: absolute; top: 0; bottom: 0; left: 50%; width: 1.5px; background: #fff; }
.a-sheen { position: absolute; top: -30%; left: 25%; width: 50%; height: 160%; opacity: 0; z-index: 4; mix-blend-mode: plus-lighter;
  background: linear-gradient(135deg, rgb(255 255 255 / 0), rgb(255 255 255 / 0.45), rgb(255 255 255 / 0)); }
.align-card .p-lining, .align-card .p-lined { opacity: 0; }

/* 3. Studio: the card changes shape within a 4:5 box. */
.studio-box { position: relative; width: 100%; height: 100%; display: flex; justify-content: center; }
.studio-card { height: 100%; width: 80%; aspect-ratio: auto; flex: none; }
.studio-card .s-frame { transform-origin: 50% 50%; }
.s-captions { position: absolute; left: 0; right: 0; bottom: calc(12px + 42px + 14px); display: grid; place-items: center; z-index: 2; }
.s-caption { grid-area: 1 / 1; color: #fff; text-shadow: 0 2px 6px rgb(0 0 0 / 0.45); white-space: nowrap; opacity: 0; line-height: 1; }
.face-elegant { font-family: Didot, "Bodoni 72", "Bodoni MT", serif; font-weight: 700; }
.face-script { font-family: "Snell Roundhand", "Apple Chancery", cursive; font-weight: 700; }
.face-typewriter { font-family: "American Typewriter", "Courier New", monospace; font-weight: 700; }
.studio-card .demo-pill.sun { opacity: 0; }
.studio-card .p-shape { opacity: 1; }
.s-tools { position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%); display: flex; gap: 4px; padding: 4px; border-radius: 21px; z-index: 5;
  background: rgb(219 214 250 / 0.66); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); border: 1px solid rgb(255 255 255 / 0.6); }
.s-tool { --lit: 0; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  color: rgb(38 33 64 / calc(0.45 + 0.55 * var(--lit))); background: rgb(255 140 69 / var(--lit)); }
.s-tool svg { width: 16px; height: 16px; }
.s-save { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; z-index: 6; }
.s-save svg { position: absolute; width: 22%; aspect-ratio: 1; transform: rotate(-90deg); }
.s-save .ring { fill: none; stroke: var(--orange); stroke-width: 7; stroke-linecap: round; stroke-dasharray: 0 999; }
.s-save .p-saved { position: relative; top: auto; left: auto; transform: none; opacity: 0; }

/* 5. Privacy: the photo softened in lilac, the orange orb as its lock (OnboardingPrivacyStage; a still picture). */
.privacy-card .soft-photo { filter: blur(6px); transform: scale(1.06); }
.privacy-card::after { content: ""; position: absolute; inset: 0; background: var(--lavender); mix-blend-mode: multiply; z-index: 1; }
.orb {
  position: absolute; left: 50%; top: 50%; width: 36%; aspect-ratio: 1; translate: -50% -50%; z-index: 3;
  border-radius: 50%; display: grid; place-items: center; color: var(--ink);
  background: linear-gradient(135deg, rgb(250 214 110), var(--orange));
  box-shadow: 0 4px 8px rgb(0 0 0 / 0.16), 0 0 0 0 transparent;
}
.orb::before { content: ""; position: absolute; inset: -35%; border-radius: 50%; z-index: -1; opacity: 0.7;
  background: radial-gradient(closest-side, rgb(250 214 110), rgb(255 140 69 / 0.6), rgb(250 110 135 / 0)); }
.orb svg { width: 42%; height: 42%; }
@media (prefers-reduced-motion: no-preference) {
  .orb { animation: breathe 4.5s ease-in-out infinite; }
}
/* The orb's breath (OnboardingMotion.breathPeriod and breathDepth). */
@keyframes breathe { 0%, 100% { scale: 1; } 25% { scale: 1.035; } 75% { scale: 0.965; } }
.privacy-card .demo-pill { z-index: 4; }


/* MARK: - Closing */

/* One screen, its words in the middle (Nat, 27 September 2026). */
.closing { text-align: center; min-height: var(--screen); display: flex; align-items: center; justify-content: center; padding: clamp(40px, 8svh, 96px) 0; }
.closing .wrap { width: 100%; }
.closing img.icon { width: 88px; height: 88px; border-radius: 20px; margin: 0 auto 24px; box-shadow: 0 20px 40px -12px rgb(69 41 122 / 0.35); }
.closing h2 { font-family: var(--rounded); font-size: clamp(34px, 7vw, 80px); line-height: 1.03; letter-spacing: -0.04em; margin: 0 0 14px; }
.closing p { font-size: clamp(18px, 2.2vw, 24px); color: var(--muted); margin: 0 auto 26px; max-width: 30ch; line-height: 1.32; }

/* MARK: - Footer: small print, as on Apple's pages */

/* The small print stays above the home indicator when the page runs edge to edge. */
/* The footer's small text is a little darker than --muted: on lilac, --muted measures 4.48:1,
   just under the 4.5:1 that small text needs (Lighthouse, 27 September 2026); 72% ink is 5.7:1. */
.site-footer { --footer-text: rgb(38 33 64 / 0.72); background: var(--lilac-soft); margin-top: clamp(72px, 10vw, 110px); padding: 22px 0 calc(34px + env(safe-area-inset-bottom, 0px)); font-size: 12.5px; color: var(--footer-text); }
.site-footer .note { border-bottom: 1px solid var(--line); padding-bottom: 14px; margin: 0 0 14px; }
.site-footer .row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 20px; }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.site-footer a { color: var(--footer-text); }

/* MARK: - Text pages (privacy, support) */

.page-hero { background: radial-gradient(120% 90% at 50% 0%, var(--lavender), var(--paper) 75%); padding: clamp(48px, 9vw, 88px) 0 clamp(24px, 4vw, 40px); text-align: center; }
.page-hero h1 { font-family: var(--rounded); font-size: clamp(40px, 8vw, 88px); line-height: 1.02; letter-spacing: -0.04em; margin: 0; }
.page-hero p { font-size: clamp(18px, 2.2vw, 24px); color: var(--muted); margin: 16px auto 0; max-width: 32ch; line-height: 1.3; }
.page { max-width: 760px; margin: 0 auto; padding: 24px var(--gutter) 0; }
.page .meta { color: var(--muted); font-size: 14px; margin: 0 0 24px; text-align: center; }
.page h2 { font-family: var(--rounded); font-size: clamp(24px, 3vw, 28px); letter-spacing: -0.025em; margin: 48px 0 10px; }
.page p, .page li { font-size: 17px; }
.page ul { padding-left: 22px; }
.page li { margin: 6px 0; }
.page details { border-bottom: 1px solid var(--line); padding: 18px 0; }
.page summary { font-weight: 600; font-size: 19px; cursor: pointer; list-style: none; display: flex; justify-content: space-between; gap: 16px; }
.page summary::-webkit-details-marker { display: none; }
.page summary::after { content: "+"; font-weight: 400; font-size: 24px; line-height: 1; color: var(--accent); }
.page details[open] summary::after { content: "−"; }
.page details p { margin: 12px 0 0; color: var(--muted); }
.contact { background: var(--lavender); border-radius: var(--tile-radius); padding: 30px; margin-top: 48px; }
.contact h2 { margin-top: 0; }

/* MARK: - Entrance: tiles rise in once as they arrive (skipped with Reduce Motion or without JavaScript) */

.js .reveal { opacity: 0; transform: translateY(28px); transition: opacity 700ms ease, transform 700ms cubic-bezier(0.2, 0.7, 0.2, 1); }
.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
}

@media (max-width: 560px) {
  .nav-links { gap: 14px; }
}
