/* ==========================================================================
   alphamatch.app — the public page.

   Two stylesheets in one file, kept apart by prefix:

   1. The page itself. Everything without a `.appui` ancestor.
   2. `.appui …` — the app's own interface, redrawn for the web so the demo
      shows the real screens rather than a picture of them. The tokens,
      type and radii are lifted from `mockups/Main.dc.html`, which is the
      design's source of truth. If a screen changes there, change it here.

   The screen the app runs in has NO bezel, notch, buttons or rounded
   hardware. That is deliberate and not a style preference: Apple's
   marketing guidelines forbid illustrated or rendered Apple devices, and
   forbid animating, flipping or spinning them. A neutral rounded screen is
   compliant, and it puts the interface at full size instead of losing 15%
   of the width to a drawn chassis. Do not add a frame back.
   ========================================================================== */

/* --- tokens ---------------------------------------------------------------
   Oxblood on Slate, 2026-09-10. Mirrors app/lib/theme/tokens.dart, which is
   the authority — read that file before changing anything here. Sampled off
   the app icon rather than chosen against it: hue 350, with the icon's own
   specular carried into every filled surface.

   Light is the default and the system setting is not consulted. There is no
   `prefers-color-scheme` query anywhere in this file on purpose: the palette
   is the brand, and honouring the OS meant a first-time reader on a dark
   phone never saw the page the way it is meant to look. Dark is a choice the
   reader makes with the button in the nav, and it is remembered per browser.

   So there are two states, not three: bare `:root` is light, and
   `[data-theme="dark"]` is the override. */
:root {
  color-scheme: light;

  --bg: #F5F5F6; --surface: #FFFFFF; --surface2: #EBEBED; --navbg: #FFFFFF;
  --ink: #101012; --ink2: #45454E; --muted: #6E6E77; --faint: #83838B;
  --line: rgba(16,16,18,0.1); --line2: rgba(16,16,18,0.18);
  --track: rgba(16,16,18,0.12);
  --accent: #7B2434; --accent-ink: #FFFFFF; --accent-deep: #7B2434;
  --accent-soft: rgba(123,36,52,0.1); --accent-border: rgba(123,36,52,0.45);
  --rosetext: #5E1826;
  --gold: #7A6118; --gold-ink: #FFFFFF; --gold-soft: rgba(154,124,42,0.12);
  --gold-border: rgba(154,124,42,0.42); --goldtext: #7A6118;
  --good: #237552; --good-soft: rgba(35,117,82,0.1);
  --good-border: rgba(35,117,82,0.32); --goodtext: #1B5B40;
  --danger: #C23A3A;
  --blue: #4763B8; --blue-ink: #FFFFFF; --bluetext: #35509E;
  --blue-soft: rgba(71,99,184,0.1); --blue-border: rgba(71,99,184,0.35);
  --bubble-them: #EBEBED; --bubble-them-ink: #101012;
  --bubble-you: #7B2434; --bubble-you-ink: #FFFFFF;
  --map-grad: linear-gradient(120deg, #EBEBED 0%, #E6E6E9 55%, #E1E8E6 100%);
  /* Two layers, the way the icon is lit: a white specular over a deepening
     body, light from the top right. CSS can stack them; Flutter cannot, so
     app/lib/theme/tokens.dart bakes the same result into one stop list. */
  --accent-grad: linear-gradient(212deg, rgba(255,255,255,0.20) 0%, rgba(255,255,255,0) 34%),
                 linear-gradient(212deg, #96303F 0%, #7B2434 46%, #4E1620 100%);
  /* Gradient TEXT, not a fill. The fill above is deep so white sits on it;
     run masked type through that and it drops to 2.3:1 on this ground. */
  --text-grad: linear-gradient(135deg, #7B2434 0%, #5E1826 100%);
  --blue-grad: linear-gradient(135deg, #4763B8 0%, #2E8FA0 100%);
  --hero-grad: radial-gradient(120% 90% at 80% -10%, #F1E3E5 0%, #F5F5F6 55%);
  --match-grad: radial-gradient(140% 100% at 50% 0%, #F3E0E3 0%, #F5F5F6 60%);
  --unlock-grad: radial-gradient(130% 90% at 50% -10%, #F4E8D4 0%, #F5F5F6 55%);
  --pass-grad: radial-gradient(130% 80% at 50% -5%, #E0E7F8 0%, #F5F5F6 55%);
  --plan-sel: linear-gradient(140deg, #E7EDFB 0%, #F2F5FD 100%);
  --dim: rgba(16,16,18,0.4);
  --card-shadow: 0 1px 2px rgba(16,16,18,0.05), 0 10px 26px -14px rgba(16,16,18,0.14);
  --glow: rgba(123,36,52,0.22);
  --display: "Bricolage Grotesque", "Instrument Sans", system-ui, sans-serif;
  --sans: "Instrument Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --gutter: clamp(20px, 5vw, 56px);
  --measure: 62ch;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0F0F11; --surface: #191A1C; --surface2: #1F2023; --navbg: #131315;
  --ink: #F2F2F3; --ink2: #DCDCE0; --muted: #9C9CA4; --faint: #85858B;
  --line: rgba(255,255,255,0.08); --line2: rgba(255,255,255,0.14);
  --track: rgba(255,255,255,0.12);
  --accent: #D08A95; --accent-ink: #FFFFFF; --accent-deep: #7B2434;
  --accent-soft: rgba(208,138,149,0.14); --accent-border: rgba(208,138,149,0.5);
  --rosetext: #E8B6BC;
  --gold: #C9A96A; --gold-ink: #1E1608; --gold-soft: rgba(201,169,106,0.15);
  --gold-border: rgba(201,169,106,0.45); --goldtext: #EFE2C9;
  --good: #4FBF95; --good-soft: rgba(79,191,149,0.08);
  --good-border: rgba(79,191,149,0.3); --goodtext: #B4E5D0;
  --danger: #F07070;
  --blue: #8FA7E8; --blue-ink: #101425; --bluetext: #B9C6EE;
  --blue-soft: rgba(143,167,232,0.15); --blue-border: rgba(143,167,232,0.4);
  --bubble-them: #1F2023; --bubble-them-ink: #F2F2F3;
  --bubble-you: #6B1E2C; --bubble-you-ink: #F2F2F3;
  --map-grad: linear-gradient(120deg, #1F2023 0%, #262A2E 55%, #1E2A2E 100%);
  --accent-grad: linear-gradient(212deg, rgba(255,255,255,0.20) 0%, rgba(255,255,255,0) 34%),
                 linear-gradient(212deg, #96303F 0%, #7B2434 46%, #4E1620 100%);
  --text-grad: linear-gradient(135deg, #D08A95 0%, #E8B6BC 100%);
  --blue-grad: linear-gradient(135deg, #8FA7E8 0%, #7ED0D8 100%);
  --hero-grad: radial-gradient(120% 90% at 80% -10%, #2A1A1C 0%, #0F0F11 55%);
  --match-grad: radial-gradient(140% 100% at 50% 0%, #331E22 0%, #0F0F11 60%);
  --unlock-grad: radial-gradient(130% 90% at 50% -10%, #2C2418 0%, #0F0F11 55%);
  --pass-grad: radial-gradient(130% 80% at 50% -5%, #1C2338 0%, #0F0F11 55%);
  --plan-sel: linear-gradient(140deg, #232B45 0%, #191A26 100%);
  --dim: rgba(6,6,8,0.62);
  --card-shadow: 0 1px 2px rgba(0,0,0,0.3), 0 10px 26px -18px rgba(0,0,0,0.65);
  --glow: rgba(208,138,149,0.30);
}

/* --- page base ----------------------------------------------------------- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 16px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: var(--accent); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.wrap { width: min(1160px, 100% - (var(--gutter) * 2)); margin-inline: auto; }
.narrow { width: min(760px, 100% - (var(--gutter) * 2)); margin-inline: auto; }

section { padding: clamp(64px, 9vw, 128px) 0; position: relative; }
.band { background: var(--surface); border-block: 1px solid var(--line); }

h1, h2, h3 { font-family: var(--display); font-weight: 800; letter-spacing: -0.025em; margin: 0; }
h1 { font-size: clamp(38px, 6.4vw, 74px); line-height: 1.02; }
h2 { font-size: clamp(28px, 3.8vw, 45px); line-height: 1.06; }
h3 { font-size: clamp(19px, 1.7vw, 22px); line-height: 1.2; letter-spacing: -0.015em; }
p { margin: 0; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 18px;
}
.eyebrow::before {
  content: ""; width: 22px; height: 2px; border-radius: 2px; background: currentColor;
}
.lede { color: var(--muted); font-size: clamp(16px, 1.5vw, 19px); max-width: var(--measure); margin-top: 20px; }
.gtext { background-image: var(--text-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* Buttons. The store link is a link, never a fake badge — Apple's badge
   artwork may not be redrawn, animated, or shown more than once a page. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 52px; padding: 0 26px; border-radius: 14px;
  font: 600 15.5px var(--sans); text-decoration: none;
  background: var(--accent-grad); color: var(--accent-ink);
  box-shadow: 0 12px 34px -14px var(--glow);
  transition: transform .16s ease, box-shadow .16s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 18px 40px -14px var(--glow); }
.btn.quiet {
  background: none; color: var(--ink); border: 1px solid var(--line2);
  box-shadow: none; font-weight: 500;
}
.btn.quiet:hover { border-color: var(--accent-border); }
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-top: 32px; }
.cta-note { font-size: 13px; color: var(--faint); margin-top: 14px; }
/* Coming soon, in words. Not a drawn store badge: Apple's guidelines allow
   only their own artwork, and only once the app is really there. Until then
   both open the waitlist. */
.stores { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.close .stores { justify-content: center; }
.store {
  display: inline-flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--line2); color: var(--ink2);
  font: 500 13px var(--sans); text-decoration: none;
  transition: border-color .16s ease;
}
.store::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.store:hover { border-color: var(--accent-border); }

/* --- scroll progress + nav ------------------------------------------------ */
.progress {
  position: fixed; top: 0; left: 0; height: 2px; width: 0;
  background: var(--accent-grad); z-index: 60; transition: width .1s linear;
}
nav.top {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid transparent; transition: border-color .3s;
}
nav.top.stuck { border-bottom-color: var(--line); }
nav.top .in {
  display: flex; align-items: center; gap: 26px; height: 66px;
  width: min(1160px, 100% - (var(--gutter) * 2)); margin-inline: auto;
}
.wordmark {
  display: flex; align-items: center; gap: 9px; text-decoration: none;
  color: var(--ink); font-family: var(--display); font-weight: 800;
  font-size: 17.5px; letter-spacing: -0.01em; margin-right: auto;
}
.wordmark svg { width: 24px; height: 24px; flex: none; }
/* The app icon, not a drawn heart. It ships as a rounded square already, so
   the radius here only softens the corners the raster leaves at small sizes. */
.wordmark img { width: 26px; height: 26px; flex: none; border-radius: 7px; }
nav.top .links { display: flex; gap: 24px; }
nav.top .links a { color: var(--muted); text-decoration: none; font-size: 14.5px; transition: color .2s; }
nav.top .links a:hover { color: var(--ink); }
nav.top .btn { height: 40px; padding: 0 18px; font-size: 14px; }
.themebtn {
  all: unset; cursor: pointer; width: 36px; height: 36px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); color: var(--muted); flex: none;
}
.themebtn:hover { color: var(--ink); border-color: var(--line2); }
@media (max-width: 860px) { nav.top .links { display: none; } }
/* One line, always (QA m12). At 375px the button wrapped to three lines and
   spilled out of its pill, and the wordmark broke in two. */
nav.top .btn, .wordmark { white-space: nowrap; }
@media (max-width: 420px) {
  nav.top .early-word { display: none; }
  /* Four items in 335px: the 26px desktop gaps alone took 78. */
  nav.top .in { gap: 8px; }
  nav.top .btn { padding: 0 12px; }
  .wordmark { font-size: 16px; }
}
/* The smallest phones (320px): the icon alone carries the brand. */
@media (max-width: 350px) {
  nav.top .wm-text { display: none; }
}

/* --- reveal on scroll -----------------------------------------------------
   The final state is the CSS default; `.rise` only *starts* an element
   somewhere else. With JavaScript off, or reduced motion asked for, the page
   is simply already in place rather than permanently invisible. */
.rise { opacity: 0; transform: translateY(22px); transition: opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1); }
.rise.seen { opacity: 1; transform: none; }
.rise.d1 { transition-delay: .06s; } .rise.d2 { transition-delay: .13s; }
.rise.d3 { transition-delay: .2s; }  .rise.d4 { transition-delay: .27s; }

/* --- hero ----------------------------------------------------------------- */
.hero {
  padding: clamp(40px, 6vw, 86px) 0 clamp(56px, 7vw, 104px);
  background-color: var(--bg); background-image: var(--hero-grad);
  background-size: 165% 165%; animation: aur 20s ease-in-out infinite alternate;
  overflow: hidden;
}
@keyframes aur { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }
.hero .in {
  display: grid; grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
  gap: clamp(32px, 5vw, 72px); align-items: center;
}
@media (max-width: 940px) {
  .hero .in { grid-template-columns: 1fr; }
  .hero .stage { justify-self: center; }
}
h1 .line { display: block; }
.hero .lede { font-size: clamp(16.5px, 1.6vw, 19.5px); }
.hero .proof {
  display: flex; flex-wrap: wrap; gap: 10px; margin-top: 30px;
}
.hero .proof span {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 600; color: var(--ink2);
  padding: 7px 13px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line);
}
.hero .proof svg { width: 13px; height: 13px; flex: none; }

/* --- the neutral screen ---------------------------------------------------
   390 x 844 laid out at its own size and scaled with a transform, so the
   interface inside is written once at real dimensions and never reflows to
   fit a column. `--fit` is set by JS from the space actually available. */
.stage { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.screenwrap {
  position: relative;
  width: calc(390px * var(--fit, 1)); height: calc(844px * var(--fit, 1));
}
.screenwrap .inner {
  position: absolute; top: 0; left: 0; width: 390px; height: 844px;
  transform: scale(var(--fit, 1)); transform-origin: top left;
}
.screen {
  width: 390px; height: 844px; border-radius: 30px; overflow: hidden;
  background: var(--bg); position: relative;
  border: 1px solid var(--line2);
  box-shadow: 0 40px 90px -40px rgba(0,0,0,.7), 0 0 0 1px rgba(255,255,255,.02);
}
.pointer {
  position: absolute; width: 27px; height: 27px; border-radius: 50%; z-index: 40;
  background: radial-gradient(circle at 32% 30%, rgba(255,255,255,.95), rgba(255,255,255,.42) 45%, rgba(255,255,255,.1) 70%);
  border: 1.5px solid rgba(255,255,255,.8);
  box-shadow: 0 4px 14px rgba(0,0,0,.45);
  transform: translate(-50%, -50%); pointer-events: none; opacity: 0;
  transition: left .62s cubic-bezier(.4,0,.2,1), top .62s cubic-bezier(.4,0,.2,1),
              transform .18s ease, opacity .3s;
}
.pointer.on { opacity: 1; }
.pointer.tap { transform: translate(-50%, -50%) scale(.62); }
.controls { display: flex; align-items: center; gap: 8px; }
.controls button {
  all: unset; cursor: pointer; font: 600 11px var(--sans); letter-spacing: .1em;
  text-transform: uppercase; color: var(--faint);
  padding: 7px 13px; border-radius: 999px; border: 1px solid var(--line);
}
.controls button:hover { color: var(--ink); border-color: var(--line2); }
.caption {
  font-size: 13px; color: var(--muted); text-align: center; min-height: 20px;
  max-width: 34ch; margin: 0 auto;
}
.caption b { color: var(--ink); font-weight: 600; }

/* --- feature sections ----------------------------------------------------- */
.split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 76px); align-items: center;
}
.split.flip .stage { order: -1; }
@media (max-width: 940px) {
  .split, .split.flip { grid-template-columns: 1fr; }
  .split .stage, .split.flip .stage { order: 0; justify-self: center; }
}
.points { display: flex; flex-direction: column; gap: 20px; margin-top: 30px; }
.point { display: flex; gap: 14px; }
.point .ic {
  flex: none; width: 38px; height: 38px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); border: 1px solid var(--accent-border);
}
.point .ic svg { width: 18px; height: 18px; stroke: var(--accent); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.point .ic.g { background: var(--good-soft); border-color: var(--good-border); }
.point .ic.g svg { stroke: var(--good); }
.point .ic.b { background: var(--blue-soft); border-color: var(--blue-border); }
.point .ic.b svg { stroke: var(--blue); }
.point .ic.y { background: var(--gold-soft); border-color: var(--gold-border); }
.point .ic.y svg { stroke: var(--gold); }
.point p { color: var(--muted); font-size: 14.5px; margin-top: 5px; }

/* --- card grids ----------------------------------------------------------- */
.grid { display: grid; gap: 18px; margin-top: 48px; }
.grid.g3 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid.g4 { grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); }
.card {
  background: var(--bg); border: 1px solid var(--line); border-radius: 20px;
  padding: 26px 24px; box-shadow: var(--card-shadow);
}
.band .card { background: var(--bg); }
.card .ic {
  width: 40px; height: 40px; border-radius: 12px; margin-bottom: 16px;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); border: 1px solid var(--accent-border);
}
.card .ic svg { width: 19px; height: 19px; stroke: var(--accent); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.card .ic.g { background: var(--good-soft); border-color: var(--good-border); }
.card .ic.g svg { stroke: var(--good); }
.card .ic.b { background: var(--blue-soft); border-color: var(--blue-border); }
.card .ic.b svg { stroke: var(--blue); }
.card .ic.y { background: var(--gold-soft); border-color: var(--gold-border); }
.card .ic.y svg { stroke: var(--gold); }
.card p { color: var(--muted); font-size: 14.5px; margin-top: 10px; }

/* --- the free-and-clear note --------------------------------------------- */
.freenote {
  margin-top: 30px; padding: 20px 24px; border-radius: 18px;
  background: var(--good-soft); border: 1px solid var(--good-border);
  font-size: 14.5px; color: var(--goodtext);
}
.freenote b { color: var(--good); }

/* --- faq ------------------------------------------------------------------ */
.faq { margin-top: 44px; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none; padding: 22px 40px 22px 0; position: relative;
  font-family: var(--display); font-weight: 700; font-size: 17.5px; letter-spacing: -0.015em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: 30px;
  width: 9px; height: 9px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(45deg); transition: transform .22s;
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq .a { padding: 0 0 24px; color: var(--muted); font-size: 15px; max-width: var(--measure); }

/* --- closing + footer ----------------------------------------------------- */
.close {
  text-align: center; background-color: var(--bg); background-image: var(--match-grad);
  background-size: 165% 165%; animation: aur 20s ease-in-out infinite alternate;
}
.close .cta-row { justify-content: center; }
footer { border-top: 1px solid var(--line); padding: 54px 0 44px; font-size: 14px; }
footer .in { display: flex; flex-wrap: wrap; gap: 30px; justify-content: space-between; }
footer .cols { display: flex; flex-wrap: wrap; gap: 56px; }
footer h4 { font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--faint); margin: 0 0 14px; font-weight: 700; }
footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
footer a { color: var(--muted); text-decoration: none; }
footer a:hover { color: var(--ink); }
footer .fine { color: var(--faint); font-size: 12.5px; margin-top: 34px; max-width: 70ch; }

/* ==========================================================================
   .appui — the app's interface.
   Written at 390px. Everything is absolute or flex inside .screen.
   ========================================================================== */
.appui { width: 390px; height: 844px; position: relative; overflow: hidden;
  background: var(--bg); color: var(--ink); font: 15px/1.5 var(--sans);
  display: flex; flex-direction: column; }
.appui .view { position: absolute; inset: 0; display: none; flex-direction: column; overflow: hidden; }
.appui .view.on { display: flex; }
.appui h1 { font-family: var(--display); font-weight: 800; letter-spacing: -0.02em; color: var(--ink); }
.appui .disp { font-family: var(--display); font-weight: 800; letter-spacing: -0.02em; }
.appui .mut { color: var(--muted); }
.appui .fnt { color: var(--faint); }
.appui .grad { background: var(--accent-grad); color: var(--accent-ink); }

/* header + nav: 63px each, exactly as the prototype fixed them */
.appui .head {
  height: 63px; flex: none; display: flex; align-items: center;
  justify-content: space-between; padding: 8px 16px 4px;
}
.appui .head .brand { display: flex; align-items: center; gap: 8px; }
.appui .head .brand span { font-family: var(--display); font-weight: 700; font-size: 17px; letter-spacing: -0.01em; }
.appui .circ {
  width: 44px; height: 44px; border-radius: 999px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--line);
}
.appui .circ.accent { background: var(--accent-soft); border-color: var(--accent-border); }
.appui .nav {
  height: 63px; flex: none; display: flex; align-items: center;
  border-top: 1px solid var(--line); background: var(--navbg);
  padding-bottom: 2px;
}
.appui .nav i {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  font-style: normal; font-size: 9.5px; font-weight: 600; color: var(--faint);
}
.appui .nav i.on { color: var(--accent); }
.appui .nav svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.appui .body { flex: 1; min-height: 0; overflow: hidden; padding: 0 20px; }
.appui .pad { padding: 10px 24px 0; }
.appui .sub { font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.appui .step { font-size: 12px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }
.appui .cta {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  height: 52px; border-radius: 14px; background: var(--accent-grad);
  color: var(--accent-ink); font-weight: 700; font-size: 15px;
}
.appui .cta.ghost { background: none; border: 1px solid var(--line2); color: var(--ink); font-weight: 600; }
.appui .cta.g { background: var(--good); color: var(--bg); }
.appui .row {
  display: flex; align-items: center; gap: 12px; padding: 12px 16px;
  border-radius: 14px; background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--card-shadow);
}
.appui .row svg { flex: none; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.appui .row .tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.appui .row .tx b { font-size: 13.5px; font-weight: 600; }
.appui .row .tx s { font-size: 12px; color: var(--faint); text-decoration: none; }
.appui .chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px;
  border-radius: 999px; font-size: 11px; font-weight: 600;
  background: rgba(20,16,24,.72); border: 1px solid rgba(255,255,255,.14); color: #DFF5E9;
}
.appui .chip svg { width: 12px; height: 12px; fill: none; stroke-width: 2.3; stroke-linecap: round; stroke-linejoin: round; }
.appui .chip.gold { color: #EFE2C9; }
.appui .chip.live { background: rgba(184,9,127,.28); border-color: rgba(255,138,164,.55); color: #FFD3DD; font-weight: 700; }

/* the deck card */
.appui .deck { flex: 1; position: relative; min-height: 0; }
.appui .card2 {
  position: absolute; inset: 0; overflow: hidden;
  background: radial-gradient(130% 110% at 20% 0%, #7A3B52 0%, #3A2136 48%, #1C1220 100%);
  transition: transform .5s cubic-bezier(.4,0,.2,1), opacity .5s;
}
.appui .card2 img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 30%; }
.appui .ken { position: absolute; inset: 0; animation: ken 16s ease-in-out infinite alternate; }
@keyframes ken { from { transform: scale(1); } to { transform: scale(1.09); } }
.appui .lb { opacity: 0; animation: lb 6s ease-in-out infinite; }
.appui .lc { opacity: 0; animation: lc 6s ease-in-out infinite; }
@keyframes lb { 0%,20% { opacity: 0; } 33%,53% { opacity: 1; } 66%,100% { opacity: 0; } }
@keyframes lc { 0%,53% { opacity: 0; } 66%,86% { opacity: 1; } 97%,100% { opacity: 0; } }
.appui .stamp {
  position: absolute; top: 26px; padding: 5px 14px; border-radius: 10px;
  font-family: var(--display); font-weight: 800; font-size: 26px; letter-spacing: .04em;
  opacity: 0; transition: opacity .2s; z-index: 4;
}
.appui .stamp.like { left: 18px; transform: rotate(-14deg); border: 3px solid #4FBF95; color: #4FBF95; }
.appui .stamp.pass { right: 18px; transform: rotate(14deg); border: 3px solid #F07070; color: #F07070; }
.appui .badges { position: absolute; top: 12px; left: 14px; display: flex; gap: 8px; flex-wrap: wrap; max-width: 362px; }
.appui .meta {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 90px 14px 12px;
  background: linear-gradient(180deg, rgba(20,16,24,0) 0%, rgba(20,16,24,.92) 62%);
  display: flex; flex-direction: column; gap: 10px;
}
.appui .meta .nm { display: flex; align-items: baseline; gap: 10px; }
.appui .meta .nm b { font-family: var(--display); font-weight: 800; font-size: 28px; letter-spacing: -0.02em; color: #F2F2F3; }
.appui .meta .nm s { font-size: 13px; color: #C9BDD0; text-decoration: none; }
.appui .facts { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.appui .facts span { display: flex; align-items: center; gap: 5px; font-size: 12.5px; color: #C9BDD0; }
.appui .facts svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.appui .prompt {
  border-radius: 16px; background: rgba(20,16,24,.55); border: 1px solid rgba(255,255,255,.16);
  backdrop-filter: blur(8px); padding: 11px 14px; display: flex; align-items: center; gap: 12px;
}
.appui .prompt .q { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #B4A8BC; }
.appui .prompt p { font-size: 13.5px; line-height: 1.45; color: #F2F2F3; margin-top: 4px; }
.appui .acts { display: flex; align-items: center; justify-content: center; gap: 22px; padding-top: 2px; }
.appui .acts .b {
  display: flex; align-items: center; justify-content: center; border-radius: 999px;
  background: rgba(20,16,24,.55); border: 1px solid rgba(255,255,255,.22);
  transition: transform .18s ease;
}
.appui .acts .b.pass { width: 56px; height: 56px; }
.appui .acts .b.rose { width: 48px; height: 48px; border-color: rgba(201,169,106,.55); position: relative; }
.appui .acts .b.rose em {
  position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px; background: #C9A96A; color: #1E1608; font: 800 9.5px/16px var(--sans);
  font-style: normal; text-align: center;
}
.appui .acts .b.like {
  width: 66px; height: 66px; background: var(--accent-grad); border: none;
  box-shadow: 0 10px 28px -8px rgba(184,9,127,.55); animation: beat 1.9s ease-in-out infinite;
}
@keyframes beat { 0%,30%,60%,100% { transform: scale(1); } 12% { transform: scale(1.13); } 42% { transform: scale(1.07); } }
.appui .acts .b.hit { transform: scale(.88); }

/* the aurora screens: match, we-met, passport, unlock */
.appui .aur { background-color: var(--bg); background-size: 165% 165%; animation: aur 16s ease-in-out infinite alternate; }
.appui .aur.match { background-image: var(--match-grad); }
.appui .aur.warm { background-image: var(--unlock-grad); }
.appui .aur.cool { background-image: var(--pass-grad); }
.appui .centre { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; padding: 0 28px; }
.appui .pair { position: relative; width: 230px; height: 150px; }
.appui .pair .ph { position: absolute; width: 118px; height: 134px; border-radius: 20px; overflow: hidden; border: 2px solid var(--accent); box-shadow: 0 14px 30px -12px rgba(0,0,0,.5); }
.appui .pair .ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 20%; }
.appui .pair .l { left: 0; top: 8px; transform: rotate(-7deg); }
.appui .pair .r { right: 0; top: 0; transform: rotate(6deg); }
.appui .pair .heart {
  position: absolute; left: 50%; top: 56%; transform: translate(-50%,-50%);
  width: 54px; height: 54px; border-radius: 999px; background: var(--accent);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 24px -6px rgba(184,9,127,.7);
}
.appui .conf { position: absolute; top: -12px; border-radius: 2px; z-index: 3; pointer-events: none; animation: conf 1.7s ease-in both; }
@keyframes conf { 0% { transform: translateY(-20px) rotate(0); opacity: 1; } 100% { transform: translateY(430px) rotate(520deg); opacity: 0; } }
.appui .panel {
  width: 100%; border-radius: 18px; background: var(--surface);
  border: 1px solid var(--line); box-shadow: var(--card-shadow); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 10px;
}
.appui .panel.hot { border-color: var(--accent-border); }
.appui .panel .lab { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--rosetext); }
.appui .panel p { font-size: 14px; line-height: 1.55; }
.appui .panel .fine { font-size: 11.5px; color: var(--faint); line-height: 1.5; }
.appui .stack { width: 100%; display: flex; flex-direction: column; gap: 11px; }

/* verify */
.appui .ring { position: relative; width: 220px; height: 220px; display: flex; align-items: center; justify-content: center; }
.appui .ring svg.r { position: absolute; inset: 0; }
.appui .ring .disc { width: 168px; height: 168px; border-radius: 50%; background: var(--surface2); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.appui .ring .disc img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%; opacity: .82; }
.appui .ring .hint {
  position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
  padding: 6px 14px; border-radius: 999px; background: var(--surface);
  border: 1px solid var(--line2); font-size: 12px; font-weight: 600; color: var(--ink2); white-space: nowrap;
}
.spin { animation: spin 1.1s linear infinite; transform-origin: center; }
@keyframes spin { to { transform: rotate(360deg); } }
.pop { animation: pop .5s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes pop { 0% { transform: scale(0); } 70% { transform: scale(1.15); } 100% { transform: scale(1); } }

/* chapters */
.appui .pager { display: flex; gap: 4px; padding: 10px 14px 0; }
.appui .pager i { flex: 1; height: 3px; border-radius: 2px; background: rgba(255,255,255,.3); }
.appui .pager i.on { background: #fff; }
.appui .chapter {
  border-radius: 18px; background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--card-shadow); padding: 15px 17px; display: flex; flex-direction: column; gap: 7px;
}
.appui .chapter .n { font-size: 10.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--rosetext); }
.appui .chapter b { font-family: var(--display); font-weight: 800; font-size: 17px; letter-spacing: -0.015em; }
.appui .chapter p { font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.appui .chapter.open { border-color: var(--accent-border); background: var(--accent-soft); }

/* date planner */
.appui .opt {
  border-radius: 16px; border: 1.5px solid var(--line); background: var(--surface);
  padding: 13px 15px; display: flex; align-items: center; gap: 12px;
  transition: border-color .22s, background .22s, transform .18s;
}
.appui .opt.sel { border-color: var(--blue-border); background: var(--plan-sel); }
.appui .opt .when { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--bluetext); }
.appui .opt b { font-size: 14.5px; font-weight: 600; display: block; margin-top: 3px; }
.appui .opt s { font-size: 12px; color: var(--faint); text-decoration: none; }
.appui .opt .tick { margin-left: auto; width: 22px; height: 22px; border-radius: 999px; border: 1.5px solid var(--line2); flex: none; display: flex; align-items: center; justify-content: center; }
.appui .opt.sel .tick { background: var(--blue); border-color: var(--blue); }

/* hidden album */
.appui .dots4 { display: flex; gap: 11px; justify-content: center; }
.appui .dots4 i { width: 13px; height: 13px; border-radius: 50%; background: var(--surface2); border: 1px solid var(--line2); transition: background .2s, transform .2s; }
.appui .dots4 i.f { background: var(--gold); border-color: var(--gold); transform: scale(1.12); }
.appui .keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.appui .keys b {
  height: 50px; border-radius: 14px; background: var(--surface); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center; font-size: 17px; font-weight: 600;
  transition: background .14s;
}
.appui .keys b.hit { background: var(--surface2); }
.appui .gal { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.appui .gal i { aspect-ratio: 3/4; border-radius: 12px; overflow: hidden; display: block; }
.appui .gal img { width: 100%; height: 100%; object-fit: cover; }

/* funnel */
.appui .stat { display: flex; flex-direction: column; gap: 5px; }
.appui .stat .bar { height: 9px; border-radius: 999px; background: var(--surface2); overflow: hidden; }
.appui .stat .bar i { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--accent-grad); transition: width 1s cubic-bezier(.3,.9,.3,1); }
.appui .stat .bar i.g { background: var(--good); }
.appui .stat .lbl { display: flex; justify-content: space-between; font-size: 12.5px; }
.appui .stat .lbl b { font-weight: 600; }
.appui .stat .lbl s { color: var(--faint); text-decoration: none; }

/* toast */
.appui .toast {
  position: absolute; bottom: 96px; left: 50%; transform: translate(-50%, 14px);
  background: var(--surface2); color: var(--ink); border: 1px solid var(--line2);
  border-radius: 999px; padding: 9px 17px; font-size: 12.5px; opacity: 0;
  transition: opacity .25s, transform .25s; z-index: 60; white-space: nowrap;
  box-shadow: 0 8px 24px rgba(0,0,0,.3);
}
.appui .toast.on { opacity: 1; transform: translate(-50%, 0); }

/* enter animation, applied by the driver when a view is mounted */
.appui .in-up { animation: inup .42s cubic-bezier(.2,.9,.3,1) both; }
@keyframes inup { from { opacity: 0; transform: translateY(12px); } }

/* --- reduced motion -------------------------------------------------------
   Everything that loops stops. The demo still shows its final state, which
   is why each scene's last frame is a complete screen rather than a
   half-finished one. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero, .close, .appui .aur { animation: none; }
  .appui .ken, .appui .lb, .appui .lc, .appui .acts .b.like,
  .appui .conf, .spin, .pop, .appui .in-up { animation: none; }
  .appui .lb, .appui .lc { opacity: 0; }
  .appui .conf { display: none; }
  .rise { opacity: 1; transform: none; transition: none; }
  .pointer { display: none; }
  .btn { transition: none; }
}

/* --- the honest funnel ----------------------------------------------------
   Page furniture rather than an app screen: it is a claim about our own
   numbers, so it belongs in the page's voice, not inside a phone. */
.fstat { display: flex; flex-direction: column; gap: 7px; }
.flbl { display: flex; justify-content: space-between; gap: 16px; font-size: 14.5px; align-items: baseline; }
.flbl b { font-weight: 600; }
.flbl s { color: var(--faint); text-decoration: none; font-size: 13px; text-align: right; }
.fbar { height: 11px; border-radius: 999px; background: var(--surface2); overflow: hidden; }
.fbar i {
  display: block; height: 100%; width: 0; border-radius: 999px;
  background: var(--accent-grad);
  transition: width 1.1s cubic-bezier(.25,.9,.3,1);
}
.fbar i.g { background: var(--good); }
@media (prefers-reduced-motion: reduce) { .fbar i { transition: none; } }

/* --- policy documents -----------------------------------------------------
   /privacy and /terms. Apple 3.1.2 requires a reachable Terms of Use link on
   any screen selling an auto-renewing subscription, and both are store
   listing URLs, so they have to resolve in one hop and keep working. */
.doc { padding: 56px 0 96px; }
.doc h1 { font-size: clamp(32px, 5vw, 48px); margin-bottom: 10px; }
.doc .stamp2 { color: var(--faint); font-size: 13.5px; margin-bottom: 40px; }
.doc h2 { font-size: clamp(21px, 2.4vw, 26px); margin: 44px 0 14px; }
.doc p, .doc li { color: var(--ink2); font-size: 15.5px; max-width: var(--measure); }
.doc p { margin-bottom: 16px; }
.doc ul { padding-left: 20px; margin: 0 0 16px; }
.doc li { margin-bottom: 9px; }
.doc strong { color: var(--ink); }
.doc .back { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); text-decoration: none; font-size: 14px; margin-bottom: 34px; }
.doc .back:hover { color: var(--ink); }

/* ==========================================================================
   Second wave of app screens: events, safety, the dashboard and the paywall,
   the likes grid, the loop capture. Same rules as above — these are the
   product's own screens, redrawn, not decoration.
   ========================================================================== */

/* events */
.appui .ev {
  display: flex; gap: 11px; align-items: center; padding: 9px;
  border-radius: 15px; background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--card-shadow);
}
.appui .ev .pic { width: 74px; height: 74px; border-radius: 12px; overflow: hidden; flex: none; background: var(--surface2); }
.appui .ev .pic img { width: 100%; height: 100%; object-fit: cover; }
.appui .ev .tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.appui .ev .tx .w { font-size: 10.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--rosetext); }
.appui .ev .tx b { font-size: 14.5px; font-weight: 600; }
.appui .ev .tx s { font-size: 12px; color: var(--faint); text-decoration: none; }
.appui .ratio {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px;
  border-radius: 999px; background: var(--good-soft); border: 1px solid var(--good-border);
  font-size: 10.5px; font-weight: 700; color: var(--goodtext); align-self: flex-start;
}
.appui .hero-pic { position: relative; height: 240px; flex: none; overflow: hidden; }
.appui .hero-pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.appui .hero-pic .fade {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 60px 18px 14px;
  background: linear-gradient(180deg, rgba(20,16,24,0) 0%, rgba(20,16,24,.92) 62%);
}

/* speed dating / video */
.appui .vids { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.appui .vids .v { position: relative; aspect-ratio: 3/4; border-radius: 16px; overflow: hidden; background: #1F2023; }
.appui .vids .v img { width: 100%; height: 100%; object-fit: cover; }
.appui .vids .v span {
  position: absolute; left: 8px; bottom: 8px; font-size: 11px; font-weight: 600; color: #F2F2F3;
  background: rgba(20,16,24,.7); padding: 4px 9px; border-radius: 999px;
}
.appui .clock {
  font-family: var(--display); font-weight: 800; font-size: 30px; letter-spacing: -0.02em;
  color: var(--accent); text-align: center;
}

/* the likes grid: covered until you look */
.appui .tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; }
.appui .tiles .t { position: relative; aspect-ratio: 3/4; border-radius: 14px; overflow: hidden; background: var(--surface2); }
.appui .tiles .t img { width: 100%; height: 100%; object-fit: cover; filter: blur(13px) saturate(1.15); transform: scale(1.12); transition: filter .5s, transform .5s; }
.appui .tiles .t.open img { filter: none; transform: none; }
.appui .tiles .t .veil {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  flex-direction: column; gap: 5px; font-size: 11.5px; font-weight: 600; color: #F2F2F3;
  background: rgba(20,16,24,.34); transition: opacity .4s;
}
.appui .tiles .t.open .veil { opacity: 0; }
.appui .tiles .t .rose {
  position: absolute; top: 8px; left: 8px; width: 24px; height: 24px; border-radius: 999px;
  background: var(--gold); display: flex; align-items: center; justify-content: center;
}

/* the reasons list on a report */
.appui .pick {
  display: flex; align-items: center; gap: 11px; padding: 12px 14px; border-radius: 13px;
  border: 1.5px solid var(--line); font-size: 14px; transition: border-color .2s, background .2s;
}
.appui .pick.sel { border-color: var(--accent-border); background: var(--accent-soft); }
.appui .pick .dot { width: 18px; height: 18px; border-radius: 999px; border: 1.5px solid var(--line2); flex: none; }
.appui .pick.sel .dot { background: var(--accent); border-color: var(--accent); }

/* ==========================================================================
   The shelf — every other screen in the app, at a glance.
   Static, scrollable by hand, and deliberately not animated: it is an index,
   not a fifth demo competing for attention.
   ========================================================================== */
.shelf { margin-top: 44px; position: relative; }
.shelf .track {
  display: flex; gap: 20px; overflow-x: auto; padding: 4px var(--gutter) 26px;
  scroll-snap-type: x mandatory; scrollbar-width: thin;
}
.shelf .track::-webkit-scrollbar { height: 7px; }
.shelf .track::-webkit-scrollbar-thumb { background: var(--line2); border-radius: 999px; }
.shelf .cell { flex: none; scroll-snap-align: center; display: flex; flex-direction: column; gap: 12px; }
.shelf .mini {
  width: 234px; height: 506px; border-radius: 20px; overflow: hidden; position: relative;
  border: 1px solid var(--line2); background: var(--bg);
  box-shadow: 0 26px 60px -34px rgba(0,0,0,.75);
}
.shelf .mini .appui { position: absolute; top: 0; left: 0; transform: scale(0.6); transform-origin: top left; }
.shelf .cap { font-size: 13px; color: var(--muted); text-align: center; max-width: 234px; }
.shelf .cap b { display: block; color: var(--ink); font-weight: 600; font-size: 14px; margin-bottom: 2px; }

/* ==========================================================================
   The early-access dialog.

   A <dialog>, not a hand-rolled overlay: the browser gives us the modal
   backdrop, focus containment, Escape to close, and inertness of the page
   behind, none of which is worth reimplementing badly.
   ========================================================================== */
dialog.early {
  border: none; padding: 0; background: none; color: var(--ink);
  max-width: min(440px, calc(100vw - 32px)); width: 100%;
}
/* ::backdrop sits outside the page tree, so it cannot read the tokens on
   :root — these two are literals on purpose. Light first, like everything
   else here. */
dialog.early::backdrop { background: rgba(16,16,18,.45); backdrop-filter: blur(6px); }
:root[data-theme="dark"] dialog.early::backdrop { background: rgba(6,6,8,.72); }
dialog.early .panel2 {
  background: var(--surface); border: 1px solid var(--line2); border-radius: 24px;
  padding: 30px 30px 26px; position: relative;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.6);
}
dialog.early[open] .panel2 { animation: dlg .28s cubic-bezier(.2,1.1,.4,1) both; }
@keyframes dlg { from { opacity: 0; transform: translateY(16px) scale(.97); } }
dialog.early .x {
  all: unset; cursor: pointer; position: absolute; top: 16px; right: 16px;
  width: 32px; height: 32px; border-radius: 999px; display: flex;
  align-items: center; justify-content: center; color: var(--muted);
  border: 1px solid var(--line);
}
dialog.early .x:hover { color: var(--ink); border-color: var(--line2); }
dialog.early .mark {
  width: 46px; height: 46px; border-radius: 15px; margin-bottom: 18px;
  background: var(--accent-grad); display: flex; align-items: center; justify-content: center;
}
dialog.early h2 { font-size: 26px; margin-bottom: 8px; }
dialog.early p.say { color: var(--muted); font-size: 14.5px; }
dialog.early form { display: flex; flex-direction: column; gap: 10px; margin-top: 22px; }
dialog.early input[type="email"] {
  font: 15.5px var(--sans); color: var(--ink); background: var(--bg);
  border: 1px solid var(--line2); border-radius: 13px; padding: 15px 16px; width: 100%;
}
dialog.early input[type="email"]::placeholder { color: var(--faint); }
dialog.early input[type="email"]:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
dialog.early .btn { width: 100%; }
dialog.early .btn[disabled] { opacity: .6; pointer-events: none; }
dialog.early .fine2 { font-size: 12px; color: var(--faint); margin-top: 14px; line-height: 1.5; }
dialog.early .fine2 a { color: var(--muted); }
dialog.early .err {
  font-size: 13px; color: var(--danger); margin-top: -2px;
}
/* The honeypot. Off-screen rather than display:none, because a field that is
   not rendered at all is one some bots know to skip. */
dialog.early .pot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
dialog.early .done { text-align: center; padding: 8px 0 4px; }
dialog.early .done .tick {
  width: 62px; height: 62px; border-radius: 999px; margin: 0 auto 18px;
  background: var(--good-soft); border: 2px solid var(--good);
  display: flex; align-items: center; justify-content: center;
}
.spin2 { animation: spin 1s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  dialog.early[open] .panel2 { animation: none; }
  .spin2 { animation: none; }
}

/* =====================================================================
   Menu drawer
   ---------------------------------------------------------------------
   The nav carried six inline links plus two buttons, which was tight at
   desktop width and had nowhere to go below it. The drawer takes those,
   the rest of the Alpha Zulu family, and the legal links, so the bar keeps
   only the wordmark and the one thing it wants people to press.

   Every colour here is a token, so the drawer follows the theme toggle in
   both directions without a second set of rules.
   ================================================================== */
.menubtn{
  display:inline-flex; align-items:center; justify-content:center;
  width:36px; height:36px; flex:none; margin-left:10px; cursor:pointer;
  background:transparent; border:1px solid var(--line2); border-radius:10px;
  color:var(--ink); padding:0;
}
.menubtn svg{width:17px; height:17px}
.menubtn:hover{border-color:var(--accent-border); background:var(--accent-soft)}
.menubtn:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

.scrim{
  position:fixed; inset:0; z-index:60; background:var(--dim);
  opacity:0; transition:opacity .26s ease;
}
.scrim.on{opacity:1}

.drawer{
  position:fixed; top:0; right:0; bottom:0; z-index:61;
  width:340px; max-width:88vw;
  background:var(--navbg); border-left:1px solid var(--line2);
  display:flex; flex-direction:column; overflow-y:auto;
  transform:translateX(101%);
  transition:transform .3s cubic-bezier(.22,.9,.28,1);
  visibility:hidden;
}
.drawer.on{transform:translateX(0); visibility:visible}
@media (prefers-reduced-motion:reduce){
  .drawer,.scrim{transition:none}
}

.drawerhead{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:15px 18px; border-bottom:1px solid var(--line);
}
.drawerclose{
  width:32px; height:32px; flex:none; padding:0; cursor:pointer;
  background:transparent; border:0; border-radius:8px; color:var(--muted);
  display:inline-flex; align-items:center; justify-content:center;
}
.drawerclose svg{width:17px; height:17px}
.drawerclose:hover{color:var(--ink); background:var(--surface2)}
.drawerclose:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

.dgroup{padding:15px 18px; border-bottom:1px solid var(--line)}
.dlabel{
  margin:0 0 10px; font-size:10px; font-weight:800; letter-spacing:.15em;
  text-transform:uppercase; color:var(--faint);
}

.dlinks{display:flex; flex-direction:column}
.dlinks a{
  padding:8px 0; font-size:14.5px; font-weight:500; color:var(--ink2);
  text-decoration:none;
}
.dlinks a:hover{color:var(--accent)}

/* One object repeated: same edges, same baselines, same inner padding. */
.dapps{display:flex; flex-direction:column; gap:2px}
.dapp{
  display:grid; grid-template-columns:38px 1fr; gap:11px; align-items:center;
  padding:9px 10px; margin:0 -10px; border-radius:12px;
  text-decoration:none; transition:background .16s ease;
}
.dapp:hover{background:var(--surface2)}
.dapp:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
.dapp img{width:38px; height:38px; border-radius:10px; display:block; border:1px solid var(--line2)}
.dapp span{display:block; min-width:0}
.dapp b{
  display:block; font-size:13.5px; font-weight:600; color:var(--ink);
  line-height:1.2;
}
.dapp i{
  display:block; margin-top:2px; font-style:normal;
  font-size:11.5px; line-height:1.35; color:var(--muted);
}

.dmeta{display:flex; flex-wrap:wrap; gap:7px 16px}
.dmeta a{font-size:13px; color:var(--muted); text-decoration:none}
.dmeta a:hover{color:var(--ink)}

.dcta{padding:16px 18px; margin-top:auto}
.btn.wide{display:block; width:100%; text-align:center}
.dmail{margin:11px 0 0; text-align:center; font-size:12px; color:var(--faint)}
.dmail a{color:var(--muted); text-decoration:none}
.dmail a:hover{color:var(--ink)}

/* Below this the inline links are gone and the drawer is the only way to
   them, so the button stops being optional. */
@media (max-width:820px){
  .top .links{display:none}
}
