/* doch! landing: AlphaOS-style layout (Space Grotesk display and body, the
   app's beige canvas, white sticky nav, gradient stage cards). Colours mirror
   lib/design_system/app_palette.dart; the stage gradients mirror
   AppLiquidGradient's light → mid → deep wash with its glow and pools. */

:root {
  color-scheme: light;
  --canvas: #F5F4F1;
  --paper: #FFFFFF;
  --soft: #F2EFED;
  --ink: #222222;
  --ink-2: #6F6A66;
  --ink-3: #716E6A;  /* the lightest grey that keeps 4.5:1 on white and on the beige canvas */
  --line: #E8E4E1;
  --dark: #231F23;
  /* app palette */
  --sky-l: #B9D4FB; --sky-m: #48BAED; --sky-d: #1E8FC3; --sky-wash: #E6F3FA;
  --rose-l: #F9CCD8; --rose-m: #F58EAB; --rose-d: #D9557F;
  --meadow-l: #E4EC45; --meadow-m: #4CC63E; --meadow-d: #26A036;
  --green: #27633F; --red: #D9557F; --red-text: #912018;
  --navy: #2F3654; --navy-d: #181D2F;
  /* PRO banner set: bannerSkyHaze / Light / Mid / Deep */
  --pro-h: #B4D7FF; --pro-l: #7FBEFF; --pro-m: #47A3FF; --pro-d: #2F8FEE;
  --tag-bg: #D6E9FF; --tag-ink: #175CD3;
  --glow: #F5F4F1;

  --sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ease: cubic-bezier(.32, .72, 0, 1);          /* iOS drawer curve: reveals */
  --ease-out: cubic-bezier(.23, 1, .32, 1);       /* entering / exiting elements */
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);   /* elements moving on screen */
  --r-lg: 24px; --r-md: 16px; --r-sm: 12px;
  /* Full-bleed panels (hero demo, closing CTA): one corner radius, one side gutter. */
  --r-panel: clamp(32px, 5vw, 60px); --bleed: clamp(10px, 2.6vw, 50px);
  /* Reading sizes, after northmail.app: 21px body at laptop width, fluid below. */
  --fs-body: clamp(1.0625rem, 1.9vw, 1.3125rem);
  --fs-sm: clamp(1rem, 1.6vw, 1.125rem);
  --max: 1200px;
  --edge: 30px;
}

@font-face { font-family: "Space Grotesk"; font-weight: 400; font-display: swap; src: url("assets/fonts/SpaceGrotesk-Regular.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-weight: 500; font-display: swap; src: url("assets/fonts/SpaceGrotesk-Medium.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-weight: 600; font-display: swap; src: url("assets/fonts/SpaceGrotesk-SemiBold.woff2") format("woff2"); }
@font-face { font-family: "Space Grotesk"; font-weight: 700; font-display: swap; src: url("assets/fonts/SpaceGrotesk-Bold.woff2") format("woff2"); }
/* Manrope carries the Cyrillic that Space Grotesk lacks. A Russian page is set
   in it throughout, Latin fragments included, exactly as the app's Russian
   interface is (lib/design_system/app_typefaces.dart). */
@font-face { font-family: "Manrope"; font-weight: 400; font-display: swap; src: url("assets/fonts/Manrope-Regular.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 500; font-display: swap; src: url("assets/fonts/Manrope-Medium.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 600; font-display: swap; src: url("assets/fonts/Manrope-SemiBold.woff2") format("woff2"); }
@font-face { font-family: "Manrope"; font-weight: 700; font-display: swap; src: url("assets/fonts/Manrope-Bold.woff2") format("woff2"); }
html[lang="ru"] { --sans: "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
/* The landing sits on white, as the blog does; the grain stays, so the
   paper is the same paper, only whiter. The legal pages keep the beige. */
.page-home { --canvas: #fff; --glow: #fff; --soft: #F5F4F1; }
body {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.5;
  letter-spacing: -.02em;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img, svg { display: block; max-width: 100%; }
/* Film grain: one fixed, non-interactive layer of SVG turbulence tiled across
   the viewport, multiplied in at low opacity. Fixed so it never repaints on
   scroll; below the nav (z 20) and the cursor trail (z 40). */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 10; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
  opacity: .11; mix-blend-mode: multiply;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, h3, h4, p, ul, dl, dd, figure { margin: 0; }
ul { padding: 0; list-style: none; }
:focus-visible { outline: 2px solid var(--sky-m); outline-offset: 3px; border-radius: 6px; }

/* Anchored sections stop below the fixed header pill, not under it. */
[id] { scroll-margin-top: 96px; }
.wrap { max-width: var(--max); margin: 0 auto; padding-inline: var(--edge); }
@media (max-width: 720px) { :root { --edge: 20px; } }

/* ── Type ── */
.h1, .h2 { font-family: var(--sans); font-weight: 500; text-wrap: balance; color: var(--navy); }
.h1 { font-size: clamp(2.75rem, 5.6vw, 4.25rem); line-height: 1.02; letter-spacing: -.035em; }
.h2 { font-size: clamp(2.2rem, 4.2vw, 3.5rem); line-height: 1.08; letter-spacing: -.03em; }
.h2--center { text-align: center; margin-inline: auto; }
.h3 { font-family: var(--sans); font-size: 1.05rem; font-weight: 600; letter-spacing: -.01em; line-height: 1.35; }
.sub { color: var(--ink-2); margin-top: 18px; max-width: 34em; text-wrap: pretty; }
/* The small words above every headline: the app's AppTag, info variant
   (statusInfo fill, info ink, radius.md, space300/space200, labelMd). */
.eyebrow {
  display: inline-block; padding: 8px 12px; border-radius: 8px;
  font-size: 13px; line-height: 16px; letter-spacing: .2px; font-weight: 400;
  color: var(--tag-ink); background: var(--tag-bg);
  margin-bottom: 24px;
}
.eyebrow--center { display: table; margin-inline: auto; }
.head { max-width: 640px; }
.head--center { margin-inline: auto; text-align: center; }
.head--center .sub { margin-inline: auto; }

/* ── Buttons ── */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 50px; padding: 0 18px;
  border-radius: var(--r-sm);
  font-size: 16px; font-weight: 500; letter-spacing: -.01em; white-space: nowrap;
  transition: transform 160ms var(--ease-out), background-color .25s var(--ease), border-color .25s var(--ease);
}
@media (hover: hover) and (pointer: fine) { .btn:hover { transform: translateY(-1px); } }
.btn:active { transform: scale(.97); transition-duration: 100ms; }
.btn--dark { background: var(--navy); color: #fff; }
.btn--dark:hover { background: var(--navy-d); }
.btn--ghost { background: var(--soft); color: var(--ink); }
.btn--ghost:hover { background: #E9E5E2; }
.btn--light { background: #fff; color: var(--ink); }
/* Liquid Glass pill, a port of AppLiquidGlass + ProGlassPill: blurred backdrop,
   faint frosted fill, a diagonal highlight from the top-left, a rim that is
   bright along the top and fades toward the bottom, and a blue outer shadow.
   The highlight breathes slowly, like the glass distortion in the app. */
.btn--glass {
  position: relative; isolation: isolate; overflow: hidden;
  border-radius: 999px; padding: 0 24px; color: #fff;
  background: rgba(255,255,255,.12);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.65), inset 0 -1px 0 rgba(255,255,255,.2),
    inset 1px 0 0 rgba(255,255,255,.35), inset -1px 0 0 rgba(255,255,255,.35),
    0 5px 14px rgba(47,143,238,.3);
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.btn--glass::before {
  content: ""; position: absolute; inset: -40%; z-index: -1;
  background: linear-gradient(135deg, rgba(255,255,255,.28), rgba(255,255,255,0) 60%);
  animation: glass-breath 3s ease-in-out infinite alternate;
}
.btn--glass:hover { box-shadow:
    inset 0 1px 0 rgba(255,255,255,.75), inset 0 -1px 0 rgba(255,255,255,.25),
    inset 1px 0 0 rgba(255,255,255,.4), inset -1px 0 0 rgba(255,255,255,.4),
    0 8px 20px rgba(47,143,238,.38); }
@keyframes glass-breath { from { transform: skew(-4deg, 1deg); } to { transform: skew(4deg, -1deg) translateX(3%); } }
.btn--sm { height: 40px; padding: 0 14px; font-size: 14px; }
.btn__lead { width: 17px; height: 17px; }
.btn__tail { width: 17px; height: 17px; margin-right: -2px; }
.actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 30px; }

/* ── Floating pill nav (ugly.cash style) ── */
.nav {
  position: fixed; top: 20px; left: 50%; transform: translateX(-50%); z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 28px;
  width: min(640px, calc(100% - 2 * var(--edge)));
  height: 62px; padding: 0 6px 0 18px;
  background: rgba(226, 222, 219, .55);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  border-radius: 16px;
  box-shadow: 0 1px 0 rgba(255,255,255,.5) inset, 0 10px 30px -18px rgba(35,31,35,.35);
}
.nav__logo svg { height: 22px; width: auto; fill: var(--navy); }
.nav__links { display: flex; gap: 2px; margin-left: auto; }
.nav__links a {
  padding: 8px 14px; border-radius: 999px;
  font-size: 15px; font-weight: 500; color: var(--ink); white-space: nowrap;
  transition: background-color .3s var(--ease), color .3s var(--ease);
}
.nav__links a:hover { background: rgba(255,255,255,.35); }
.nav__links a.is-active { background: rgba(255,255,255,.55); box-shadow: 0 1px 0 rgba(255,255,255,.6) inset; }
.nav__cta {
  position: relative; isolation: isolate; overflow: hidden;
  display: block; padding: 2px; border-radius: 14px;
  background: #E3E0DD;
  box-shadow: 0 0 22px -6px rgba(29, 139, 255, .5), 0 0 6px -2px rgba(112, 82, 170, .4);
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.nav__cta:hover { transform: translateY(-1px); box-shadow: 0 0 28px -6px rgba(29, 139, 255, .65), 0 0 8px -2px rgba(112, 82, 170, .55); }
/* the moving light behind the button, visible only through the 2 px gap */
.nav__ring {
  position: absolute; inset: -120%; z-index: -1;
  background: conic-gradient(from 0deg,
    transparent 0 12%, #00A9FF 22%, #1D8BFF 30%, #7052AA 38%, transparent 48%,
    transparent 55%, #00A9FF 68%, #1D8BFF 76%, transparent 88%);
  filter: blur(6px);
  animation: ring 5s linear infinite;
}
@keyframes ring { to { transform: rotate(1turn); } }
.nav__cta-inner {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 10px;
  height: 46px; padding: 0 14px 0 8px;
  border-radius: 12px; background: #E9E6E3;
  font-size: 14px; font-weight: 500; color: var(--ink); white-space: nowrap;
}
.nav__cta-inner img { width: 30px; height: 30px; border-radius: 8px; box-shadow: 0 2px 6px -2px rgba(35,31,35,.4); }
/* On a phone the landing's section links go, but the page links stay: the
   logo already leads home, so only the blog is left beside the CTA. */
@media (max-width: 720px) {
  .nav__links:not(.nav__links--pages), .nav__wide { display: none; }
  .nav { gap: 12px; }
  .nav__links a { padding: 8px 12px; }
}
@media (max-width: 380px) {
  .nav { gap: 6px; padding-left: 14px; }
  .nav__links a { padding: 8px 10px; }
  .nav__logo svg { height: 19px; }
  .nav__cta-inner { gap: 6px; }
}

/* ── Hero: centred lockup over a row of app screens ── */
.hero { padding-block: clamp(104px, 9vw, 118px) 0; overflow-x: clip; }
.hero__copy { text-align: center; display: flex; flex-direction: column; align-items: center; }
.hero__copy .h1 { max-width: 12em; }
.hero__copy .sub { margin-inline: auto; }
.hero__copy .actions { justify-content: center; }
/* The handwritten wordmark as the headline's second line. */
.h1__doch { display: inline-block; height: .92em; width: auto; aspect-ratio: 1388 / 473; margin-top: .14em; vertical-align: top; fill: currentColor; overflow: visible; }
.hero .sub { font-size: clamp(1.125rem, 2.1vw, 1.4375rem); max-width: 30em; }
/* The supporting paragraph under the lead, and the reassurance line under the button. */
.hero__more { margin: 14px auto 0; max-width: 36em; color: var(--ink-2); font-size: var(--fs-sm); text-wrap: pretty; }
.hero__note { margin-top: 14px; color: var(--ink-3); font-size: 14px; }

/* Showcase: a flat row of five screens. The middle one wears a phone frame
   and stands taller; the pair beside it are plain rounded cards; the outer
   pair fade and shrink so the row reads as receding. Two tilted stat chips
   float over the phone. Cards enter with the reveal stagger. */
.show { --cw: clamp(120px, 15vw, 210px); margin-top: clamp(32px, 4vw, 56px); }
.show__row { position: relative; display: flex; align-items: center; justify-content: center; gap: clamp(12px, 2vw, 28px); margin: 0; padding: 0 var(--edge); list-style: none; }
.show__card { flex: none; width: var(--cw); transform: translateX(var(--tx, 0)) scale(var(--s, 1)); transition: transform .7s var(--ease-out) var(--cd, 0s), opacity .5s var(--ease-out) var(--cd, 0s); }
/* Entrance: the side cards travel in toward the phone from further out while
   the phone grows into place; inner pair first, outer pair after. */
.js .show:not(.is-in) .show__card { opacity: 0; }
.js .show:not(.is-in) .show__card--l2 { --tx: -220px; }
.js .show:not(.is-in) .show__card--l1 { --tx: -140px; }
.js .show:not(.is-in) .show__card--r1 { --tx: 140px; }
.js .show:not(.is-in) .show__card--r2 { --tx: 220px; }
.js .show:not(.is-in) .show__card--phone { --s: .92; }
.show__card--l1, .show__card--r1 { --cd: .06s; }
.show__card--l2, .show__card--r2 { --cd: .14s; }
.show__card button { display: block; width: 100%; border-radius: clamp(16px, 2vw, 24px); overflow: hidden; background: var(--dark); box-shadow: 0 30px 60px -32px rgba(35,31,35,.5); cursor: zoom-in; transition: transform 160ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .show__card button:hover { transform: translateY(-3px); } }
.show__card button:active { transform: scale(.97); }
.show__card button:focus-visible { outline: 2px solid var(--sky-m); outline-offset: 4px; }
.show__card img { display: block; width: 100%; height: auto; aspect-ratio: 9 / 16; object-fit: cover; pointer-events: none; -webkit-user-drag: none; }
.show__card--edge { opacity: .55; --s: .94; }
.show__card--phone { position: relative; width: calc(var(--cw) * 1.32); }
.show__card--phone button { padding: 8px; border-radius: 40px; box-shadow: 0 40px 70px -30px rgba(35,31,35,.55), 0 10px 22px -14px rgba(35,31,35,.35); }
.show__card--phone img { border-radius: 32px; }
.show__card--phone button { position: relative; }
/* The incoming screen crossfades in over the current one while its card
   slides into the frame. */
.show__next { position: absolute; inset: 8px; width: calc(100% - 16px); height: calc(100% - 16px); opacity: 0; filter: blur(3px); transition: opacity .35s var(--ease-out) .2s, filter .35s var(--ease-out) .2s; }
.show__next.is-on { opacity: 1; filter: blur(0); }
/* Ring states: every card slides one slot to the left on a step. The card
   entering the phone fades under the frame; the ghost carries the phone's old
   screen out to the left slot; .no-t resets a card without animating. */
.show__card.is-entering { opacity: 0; filter: blur(2px); transition: transform .55s var(--ease-in-out), opacity .3s var(--ease-out) .2s, filter .4s var(--ease-out); }
.show__card.is-shifting { transition: transform .55s var(--ease-in-out), opacity .4s var(--ease-out); }
.show__card.no-t { transition: none !important; }
.show__card--ghost { position: absolute; display: none; pointer-events: none; z-index: 1; }
.show__card--ghost.is-live { display: block; }
.show__ghost { display: block; border-radius: clamp(16px, 2vw, 24px); overflow: hidden; background: var(--dark); box-shadow: 0 30px 60px -32px rgba(35,31,35,.5); }
.show__ghost img { display: block; width: 100%; height: auto; aspect-ratio: 9 / 16; object-fit: cover; }
.show__chip {
  position: absolute; z-index: 2; display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: 12px; background: #fff; color: var(--ink);
  box-shadow: 0 14px 30px -18px rgba(35,31,35,.45); font-size: 13px; font-weight: 500; white-space: nowrap;
}
.show__chip b { font-weight: 600; font-size: 1.1em; } .show__chip small { font-size: .8em; color: var(--ink-3); }
.show__chip svg { width: 18px; height: 18px; color: var(--sky-d); }
.show__chip.is-swap { animation: chip-pop .28s var(--ease-out); }
@keyframes chip-pop { 0% { opacity: 0; filter: blur(2px); transform: translateY(6px) rotate(var(--rot, 0)); } 100% { opacity: 1; filter: blur(0); } }
.show__chip--a { --rot: -6deg; left: -22%; top: 14%; transform: rotate(-6deg); }
.show__chip--b { --rot: 5deg; right: -24%; bottom: 16%; transform: rotate(5deg); }
@media (max-width: 860px) { .show__card--edge { display: none; } .show { --cw: clamp(120px, 24vw, 200px); } }
@media (max-width: 520px) { .show__row { gap: 10px; } .show { --cw: 27vw; } .show__chip { font-size: 11px; padding: 8px 10px; } }

/* Lightbox: the tapped screen grows into a fixed overlay; tap anywhere or
   press Escape to put it back. */
.lightbox {
  position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center;
  padding: clamp(20px, 6vw, 96px); background: rgba(35,31,35,.35); cursor: zoom-out;
  opacity: 0; transition: opacity 150ms var(--ease-out);
}
.lightbox[hidden] { display: none; }
.lightbox.is-open { opacity: 1; transition-duration: 220ms; }
.lightbox img { max-width: 100%; max-height: 100%; width: auto; height: auto; border-radius: 20px; box-shadow: 0 40px 80px -30px rgba(0,0,0,.6); transform: scale(.96); transition: transform 150ms var(--ease-out); }
.lightbox.is-open img { transform: scale(1); transition-duration: 220ms; }

/* ── Stage (gradient card) ── */
.stage {
  --c1: var(--sky-l); --c2: var(--sky-m); --c3: var(--sky-d); --c4: var(--glow);
  /* clip, not hidden: a hidden box is still a scroll container, so an anchor
     jump to anything inside would scroll the panel's own content. */
  position: relative; isolation: isolate; overflow: hidden; overflow: clip;
  border-radius: var(--r-lg);
  min-height: 420px;
  background: linear-gradient(128deg, color-mix(in srgb, var(--c1) 85%, #fff) 0%, var(--c2) 55%, var(--c3) 100%);
}
/* Motion mirrors AppLiquidGradient's 10 s drift: the two pools translate,
   turn and squash; the highlight wanders the upper right on a looping path;
   the glow slides along the bottom. Transform-only, so no repaint per frame. */
.stage::before {
  content: ""; position: absolute; inset: -35%; z-index: -1;
  background:
    radial-gradient(34% 26% at 40% 44%, color-mix(in srgb, var(--c3) 80%, transparent) 0 35%, transparent 100%),
    radial-gradient(30% 24% at 64% 62%, color-mix(in srgb, var(--c1) 85%, transparent) 0 35%, transparent 100%);
  animation: pools 10s ease-in-out infinite alternate;
}
.stage__light {
  position: absolute; inset: -30%; z-index: -1; pointer-events: none;
  background: radial-gradient(26% 26% at 64% 40%, color-mix(in srgb, #fff 55%, transparent), transparent 100%);
  animation: light 10s ease-in-out infinite;
}
.stage::after {
  content: ""; position: absolute; left: -40%; right: -10%; bottom: -70%; height: 120%; z-index: -1;
  background: radial-gradient(60% 55% at 30% 62%, color-mix(in srgb, var(--c4) 80%, transparent) 0 18%, transparent 100%);
  animation: glow 10s ease-in-out infinite alternate;
}
.stage--rose   { --c1: var(--rose-l);   --c2: var(--rose-m);   --c3: var(--rose-d); }
.stage--meadow { --c1: var(--meadow-l); --c2: var(--meadow-m); --c3: var(--meadow-d); }
.stage--pro    { --c1: var(--pro-l);    --c2: var(--pro-m);    --c3: var(--pro-d); --c4: var(--pro-h); }
.stage--mesh {
  background:
    radial-gradient(70% 60% at 15% 20%, var(--sky-l), transparent 70%),
    radial-gradient(60% 60% at 85% 25%, var(--rose-l), transparent 70%),
    radial-gradient(70% 60% at 50% 100%, color-mix(in srgb, var(--meadow-l) 70%, #fff), transparent 70%),
    linear-gradient(160deg, #FFF6F0, #F1EEFB);
}
.stage--mesh::before, .stage--mesh::after, .stage--mesh .stage__light { display: none; }
@keyframes pools {
  0%   { transform: translate(-4%, 3%) rotate(-9deg) scale(1, .94); }
  35%  { transform: translate(3%, -2%) rotate(3deg) scale(1.06, 1); }
  70%  { transform: translate(-1%, -5%) rotate(10deg) scale(.96, 1.08); }
  100% { transform: translate(5%, 4%) rotate(-3deg) scale(1.08, .96); }
}
@keyframes light {
  0%   { transform: translate(0, 0) scale(1); }
  25%  { transform: translate(7%, -5%) scale(1.12); }
  50%  { transform: translate(-6%, 3%) scale(.94); }
  75%  { transform: translate(4%, 7%) scale(1.1); }
  100% { transform: translate(0, 0) scale(1); }
}
@keyframes glow { from { transform: translateX(-3%); } to { transform: translateX(8%) scale(1.12, 1.06); } }

/* ── Intro ── */
.intro { padding-block: clamp(72px, 9vw, 130px) clamp(40px, 5vw, 64px); }
/* Left-aligned text in a column narrow enough that its lines fill it, so the
   block itself reads as centred on the page. */
/* One column for the copy and the card under it: 16.5em of the copy's type. */
.intro { --intro-type: clamp(1.5rem, 3.1vw, 2.375rem); --intro-col: calc(var(--intro-type) * 16.5); }
.intro__text { font-size: var(--intro-type); max-width: min(100%, var(--intro-col)); margin-inline: auto; }
.intro__text p { font-size: 1em; font-weight: 500; line-height: 1.2; letter-spacing: -.035em; margin-bottom: .95em; text-wrap: pretty; }
.intro__text p:last-child { margin-bottom: 0; }
.intro__text .w { color: color-mix(in srgb, var(--navy) 22%, transparent); transition: color .35s var(--ease); }
.intro__text .w.lit { color: var(--navy); }
/* The handwritten wordmark standing in for the word "doch!"; lights like a word. */
.intro__logo { display: inline-block; height: .78em; width: auto; aspect-ratio: 1388 / 473; vertical-align: -.1em; margin-right: .08em; fill: currentColor; overflow: visible; }
/* Inline glyphs: the app's sketch icons, all drawn in the one PRO sky gradient,
   no tile or glow behind them.
   They light with the words. */
.intro__ico {
  display: inline-block; vertical-align: -.2em; overflow: visible;
  width: 1.12em; height: 1.12em; margin-inline: .03em;
  fill: none; stroke: url(#ink-pro); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round;
  opacity: .25; transform: scale(.88) rotate(-8deg);
  transition: opacity .45s var(--ease), transform .6s var(--ease-out);
}
.intro__ico.lit { opacity: 1; transform: none; }
.intro__ico--pro    { fill: url(#ink-pro); stroke-width: 1.2; }

/* ── Built to be honest ── */
.honest { padding-block: clamp(48px, 6vw, 96px); }
.honest .h2 { max-width: 13em; }
.honest__list { list-style: none; padding: 0; margin: clamp(40px, 5vw, 64px) 0 0; border-bottom: 1px solid var(--line); }
.honest__list li {
  display: grid; grid-template-columns: 96px minmax(0, 1fr) minmax(0, 1.15fr);
  column-gap: clamp(24px, 4vw, 64px); align-items: baseline;
  padding-block: clamp(24px, 2.6vw, 36px); border-top: 1px solid var(--line);
}
.honest__no { font-size: 13px; letter-spacing: .02em; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.honest__list h3 { margin: 0; font-weight: 400; font-size: clamp(1.375rem, 2.4vw, 1.75rem); line-height: 1.2; letter-spacing: -.04em; text-wrap: balance; }
.honest__list p { margin: 0; color: var(--ink); font-size: var(--fs-sm); line-height: 1.5; letter-spacing: -.025em; max-width: 34em; text-wrap: pretty; }
/* Hovering a row dims its neighbours and floats that row's app screen beside
   the pointer. Fine pointers only; the script adds .peek and drives --x/--y. */
@media (hover: hover) and (pointer: fine) {
  .honest__list li > * { transition: opacity .3s var(--ease-out), transform .45s var(--ease-out); }
  .honest__list.is-peeking li:not(.is-peeked) > * { opacity: .38; }
  .honest__list li.is-peeked h3 { transform: translateX(10px); }
}
.peek {
  position: fixed; left: 0; top: 0; z-index: 40; pointer-events: none;
  width: clamp(180px, 16vw, 232px); aspect-ratio: 1320 / 2868;
  transform: translate3d(var(--x, 0), var(--y, 0), 0) rotate(var(--tilt, 0deg));
  will-change: transform;
}
.peek__card {
  position: absolute; inset: 0; border-radius: 28px; overflow: hidden; background: var(--dark);
  box-shadow: 0 0 0 1px rgba(35,31,35,.08), 0 36px 70px -28px rgba(35,31,35,.55);
  opacity: 0; transform: scale(.86); transform-origin: 0 50%;
  transition: opacity .2s var(--ease-out), transform .2s var(--ease-out);
}
.peek.is-on .peek__card { opacity: 1; transform: none; transition-duration: .28s, .4s; }
.peek img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .25s var(--ease-out); }
.peek img.is-on { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .peek__card, .peek img, .honest__list li > * { transition-duration: .01s !important; }
  .honest__list li.is-peeked h3 { transform: none; }
}
/* "Try it before you pay": the pitch on the left, the button and its small print on the right. */
.honest__cta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 20px 40px; margin-top: clamp(28px, 3vw, 40px); }
.honest__pitch { max-width: 32em; }
.honest__pitch h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); font-weight: 500; color: var(--navy); }
.honest__pitch p { margin-top: 8px; color: var(--ink-2); font-size: var(--fs-sm); }
.honest__go { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.honest__go p { margin: 0; color: var(--ink-3); font-size: 14px; }
@media (max-width: 860px) {
  .honest__list li { grid-template-columns: 48px minmax(0, 1fr); row-gap: 10px; }
  .honest__list p { grid-column: 2; }
}
@media (max-width: 520px) {
  .honest__list li { grid-template-columns: 1fr; }
  .honest__list p { grid-column: 1; }
}

/* ── Feature splits ── */
.feature { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: clamp(32px, 5vw, 80px); align-items: center; padding-block: clamp(40px, 5vw, 72px); }
.feature--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
/* Feature stages hold one crisp app card over blurred
   ghosts of itself, and carry a caption on a shade of their own deep stop. */
.feature .stage {
  min-height: clamp(420px, 40vw, 560px); display: grid; place-items: center; padding: 44px 32px 104px;
}
.stage__cap {
  position: absolute; z-index: 0; left: 0; right: 0; bottom: 0; padding: 0 28px 24px;
  color: #fff; font-size: var(--fs-sm); font-weight: 500; line-height: 1.4; text-wrap: balance;
}
.stage__cap { isolation: isolate; }
.stage__cap::before { content: ""; position: absolute; z-index: -1; inset: -72px 0 0; background: linear-gradient(transparent, color-mix(in srgb, var(--c3) 72%, transparent)); pointer-events: none; }
/* main.js wraps a [data-ghost] card in .stack with two inert clones of itself. */
.stack { position: relative; z-index: 1; display: grid; width: min(100%, 360px); }
.stack > .ui { width: 100%; }
.stack > .stack__ghost { position: absolute; inset: 0; z-index: 0; opacity: .5; filter: blur(4px); pointer-events: none; box-shadow: none; }
.stack > .stack__ghost--up { transform: translateY(-24%) scale(.86); }
.stack > .stack__ghost--down { transform: translateY(24%) scale(.86); }
@media (max-width: 860px) {
  .feature, .feature--flip { grid-template-columns: 1fr; }
  /* Stacked: copy always first, its picture after it. */
  .feature .feature__copy { order: 1; } .feature .stage { order: 2; }
}
.checks { margin-top: 28px; display: flex; flex-direction: column; gap: 14px; color: var(--ink-2); font-size: var(--fs-sm); }
.checks li { display: flex; gap: 12px; align-items: center; }
.checks svg { flex: none; width: 22px; height: 22px; color: var(--ink); }
.feature__copy .btn { margin-top: 28px; }
/* A line of exam formats set apart from the prose, and a closing aside under the list. */
.feature__formats { margin-top: 16px; font-weight: 500; color: var(--navy); font-size: var(--fs-sm); }
.feature__aside { margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--line); color: var(--ink-2); font-size: var(--fs-sm); max-width: 34em; }
.feature__aside b { color: var(--ink); font-weight: 500; }
/* The flagship feature runs as one full-width band: copy stacked on top, the
   two preview cards side by side in the stage below. Breaks the split rhythm
   before the Lesen and Hören splits. */
.feature--wide { grid-template-columns: 1fr; gap: 32px; }
.feature--wide .feature__copy { order: -1; max-width: 640px; }
.feature--wide .checks { flex-direction: row; flex-wrap: wrap; gap: 12px 32px; }
.feature--wide .stage { padding-top: 56px; padding-bottom: 150px; }

/* mini UI: cards redrawn from the app's own screens */
.ui { position: relative; z-index: 1; background: #fff; border-radius: var(--r-md); padding: 20px; box-shadow: 0 30px 60px -30px rgba(35,31,35,.45); width: min(100%, 360px); font-size: 16px; letter-spacing: 0; color: var(--ink); }
.ui__title { font-size: 17px; font-weight: 500; margin-bottom: 14px; }
.ui__title span { color: var(--ink-3); }
.tag { flex: none; font-style: normal; font-size: 12px; font-weight: 500; padding: 5px 9px; border-radius: 8px; }
.tag--ok { color: var(--green); background: #C3EED0; }
.tag--no { color: var(--red-text); background: #FAD4D4; }
/* Schreiben: a deck that deals the corrected text, then the four scored
   criteria, one after another. Every card fills one grid cell, so the deck is
   as tall as its tallest card; main.js sets data-pos (0 front, 1 and 2 the
   blurred cards waiting below it, the rest hidden) and .is-leaving on the card
   going out over the top. Without JS the first card simply shows. */
.deck { position: relative; z-index: 1; display: grid; width: min(100%, 440px); }
.deck > .ui { grid-area: 1 / 1; width: 100%; display: flex; flex-direction: column; opacity: 0; pointer-events: none; transform: translateY(24%) scale(.78); transition: transform .5s var(--ease-out), opacity .4s var(--ease-out), filter .4s var(--ease-out); }
.deck > .ui:first-child { opacity: 1; transform: none; }
.deck[data-live] > .ui:first-child { opacity: 0; transform: translateY(24%) scale(.78); }
.deck[data-live] > .ui[data-pos="0"] { z-index: 3; opacity: 1; transform: none; filter: none; pointer-events: auto; }
.deck[data-live] > .ui[data-pos="1"] { z-index: 2; opacity: .65; transform: translateY(11%) scale(.93); filter: blur(3px); box-shadow: none; }
.deck[data-live] > .ui[data-pos="2"] { z-index: 1; opacity: .4; transform: translateY(21%) scale(.86); filter: blur(5px); box-shadow: none; }
.deck[data-live] > .ui.is-leaving { z-index: 4; opacity: 0; transform: translateY(-12%) scale(.97); filter: blur(4px); transition-duration: .35s, .25s, .25s; }
.ui--crit { padding: 0; overflow: hidden; background: var(--soft); font-size: 14px; line-height: 1.45; }
.crit__body { flex: 1; padding: 18px 20px 20px; background: #fff; border-radius: var(--r-md); }
.crit__head { display: flex; align-items: flex-start; gap: 12px; }
.crit__head > div { flex: 1; }
.crit__head h3 { font-size: 16px; font-weight: 500; }
.crit__head p { margin-top: 2px; font-size: 13px; color: var(--ink-2); }
.crit__ico { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 10px; background: var(--soft); }
.crit__ico svg { width: 20px; height: 20px; }
.crit__score { flex: none; text-align: right; }
.crit__score b { display: block; font-size: 24px; font-weight: 500; line-height: 1; }
.crit__score span { font-size: 12px; color: var(--ink-3); }
.crit__bar { margin-top: 14px; height: 4px; border-radius: 99px; background: #E3E2DA; }
.crit__bar i { display: block; height: 100%; border-radius: inherit; background: var(--navy); }
.crit__label { margin-top: 14px; font-size: 12px; color: var(--ink-3); }
.crit__bullet { display: flex; gap: 8px; margin-top: 4px; }
.crit__bullet svg { flex: none; width: 18px; height: 18px; margin-top: 1px; }
.crit__bullet .is-ok { color: var(--green); } .crit__bullet .is-no { color: var(--red-text); }
/* The grey strip a criterion card stands on: its recommendations. */
.ui__foot { padding: 14px 20px 18px; font-size: 14px; line-height: 1.45; }
.ui__footlabel { margin-bottom: 3px; font-size: 12px; color: var(--ink-3); }
.ui--text { font-size: 14px; line-height: 1.6; }
.deck > .ui--text { padding: 22px 24px; }
.ui--text p + p { margin-top: .8em; }
.ui--text .ui__title { margin-bottom: 10px; }
.ui--text del { text-decoration: none; color: var(--red-text); background: #FAD4D4; border-radius: 3px; padding: 0 2px; }
.ui--text ins { text-decoration: none; color: var(--green); }
/* A card whose lower edge runs out into the stage. */
.ui--fade { -webkit-mask-image: linear-gradient(#000 66%, transparent 98%); mask-image: linear-gradient(#000 66%, transparent 98%); box-shadow: none; }
/* Lesen: a source text with one glossed word open. The popover hangs from the
   word itself, which a forced break keeps at the start of the paragraph's last
   line: the tail meets it at every card width, and lands in the gap between
   paragraphs instead of across a line of text. */
.ui--gloss { font-size: 15px; line-height: 1.6; }
/* The fade is painted, not masked: a mask on the card would clip the popover
   where it overhangs the edge and cut its backdrop off from the stage. */
.ui--gloss { background: linear-gradient(#fff 80%, rgba(255,255,255,0)); box-shadow: none; }
.ui--gloss .gloss__text:last-child { -webkit-mask-image: linear-gradient(#000 30%, transparent 100%); mask-image: linear-gradient(#000 30%, transparent 100%); }
.gloss__text + .gloss__text { margin-top: 12px; }
.gloss__word { position: relative; display: inline-block; margin: 0 -5px; padding: 0 5px; border-radius: 7px; background: color-mix(in srgb, var(--rose-m) 30%, transparent); }
/* The popover is one outline, card and tail together, at a fixed size: the
   glass is masked to it (a clip-path leaves the backdrop blur a full
   rectangle in Chromium), and the rim and hairline are the same path stroked
   (the mask keeps the inner half), so nothing has to line up with anything.
   The shadow is a layer of its own beneath, since a clip would cut it off. */
.gloss__pop { position: absolute; z-index: 2; top: calc(100% + 2px); left: -43px; width: 256px; height: 134px; line-height: 1.4; }
.gloss__pop::before { content: ""; position: absolute; inset: 10px 0 0; border-radius: 20px; box-shadow: 0 18px 36px -14px rgba(35,31,35,.45), 0 2px 10px rgba(35,31,35,.1); }
.gloss__glass { position: absolute; inset: 0; display: flex; flex-direction: column; padding: 22px 12px 0 16px; white-space: nowrap; background: linear-gradient(160deg, rgba(255,255,255,.66), rgba(255,255,255,.42)); -webkit-backdrop-filter: blur(9px) saturate(1.8); backdrop-filter: blur(9px) saturate(1.8); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 134'%3E%3Cpath d='M20 10 H65.5 Q67.5 10 69 8.4 L74.3 2 Q76 0 77.7 2 L83 8.4 Q84.5 10 86.5 10 H236 A20 20 0 0 1 256 30 V114 A20 20 0 0 1 236 134 H20 A20 20 0 0 1 0 114 V30 A20 20 0 0 1 20 10 Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 134'%3E%3Cpath d='M20 10 H65.5 Q67.5 10 69 8.4 L74.3 2 Q76 0 77.7 2 L83 8.4 Q84.5 10 86.5 10 H236 A20 20 0 0 1 256 30 V114 A20 20 0 0 1 236 134 H20 A20 20 0 0 1 0 114 V30 A20 20 0 0 1 20 10 Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat; }
.gloss__glass::after { content: ""; position: absolute; inset: 0; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 134' fill='none'%3E%3Cpath d='M20 10 H65.5 Q67.5 10 69 8.4 L74.3 2 Q76 0 77.7 2 L83 8.4 Q84.5 10 86.5 10 H236 A20 20 0 0 1 256 30 V114 A20 20 0 0 1 236 134 H20 A20 20 0 0 1 0 114 V30 A20 20 0 0 1 20 10 Z' stroke='%23fff' stroke-opacity='.95' stroke-width='4'/%3E%3Cpath d='M20 10 H65.5 Q67.5 10 69 8.4 L74.3 2 Q76 0 77.7 2 L83 8.4 Q84.5 10 86.5 10 H236 A20 20 0 0 1 256 30 V114 A20 20 0 0 1 236 134 H20 A20 20 0 0 1 0 114 V30 A20 20 0 0 1 20 10 Z' stroke='%23231F23' stroke-opacity='.14' stroke-width='1.5'/%3E%3C/svg%3E") center / 100% 100% no-repeat; }
.gloss__head { display: flex; align-items: flex-start; gap: 12px; }
.gloss__head b { flex: 1; padding-top: 8px; font-size: 18px; font-weight: 600; }
.gloss__head i { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: rgba(34,34,34,.12); }
.gloss__head svg { width: 20px; height: 20px; }
.gloss__ipa { margin-top: 2px; font-family: system-ui, -apple-system, "Segoe UI", sans-serif; font-size: 14px; color: rgba(34,34,34,.75); }
.gloss__tr { margin-top: 10px; font-size: 16px; }
/* Hören: the navy audio card over a question with its hand-struck mark boxes. */
.player { display: grid; grid-template-columns: auto 1fr; gap: 10px 14px; align-items: center; padding: 16px; border-radius: 14px; background: var(--navy); color: #fff; }
.player__btn { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: #fff; color: var(--navy); }
.player__btn svg { width: 18px; height: 18px; }
.wave { display: flex; align-items: center; gap: 2px; height: 16px; }
.wave i { flex: 1; height: 100%; border-radius: 1px; background: #fff; }
.wave i:nth-child(n+14) { opacity: .32; }
.player__time { display: flex; justify-content: space-between; margin-top: 6px; font-size: 12px; color: rgba(255,255,255,.7); font-variant-numeric: tabular-nums; }
.player__note { grid-column: 1 / -1; font-size: 12px; color: rgba(255,255,255,.7); }
.ui__q { margin-top: 16px; font-size: 14px; font-weight: 500; line-height: 1.4; }
.ui__picks { display: flex; gap: 8px; margin-top: 12px; }
.ui__picks span { display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px 9px 10px; border-radius: 999px; background: var(--soft); font-size: 13px; font-weight: 500; }
.ui__picks i { position: relative; flex: none; width: 18px; height: 18px; border-radius: 4px; box-shadow: inset 0 0 0 1.5px var(--ink-3); }
.ui__picks svg { position: absolute; left: 50%; top: 50%; width: 28px; height: 28px; margin: 0; transform: translate(-50%, -50%); color: var(--navy); overflow: visible; }
/* Readiness card: the app's home summary, redrawn under the intro. Its entrance
   follows the scroll (--r, set by main.js), then --p runs 0 → its score: the figure counts, the
   green segment grows and the caret rides its leading edge. main.js drives --p;
   without JS or under reduced motion the card sits at its final value. */
.ready {
  --p: 64;
  width: min(100%, var(--intro-col, 540px)); margin: clamp(32px, 4.4vw, 52px) auto 0; padding: clamp(18px, 2.4vw, 24px);
  background: var(--soft); border-radius: var(--r-lg); box-shadow: 0 0 0 1px var(--line);
  font-size: 16px; letter-spacing: 0;
}
.js .ready { --r: 0; --shift: 48; opacity: var(--r); transform: translateY(calc(var(--shift) * 1px)) scale(calc(.94 + .06 * var(--r))); will-change: opacity, transform; }
@media (prefers-reduced-motion: reduce) { .js .ready { --r: 1; --shift: 0; } }
.ready__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.ready__title { font-size: clamp(17px, 1.8vw, 20px); font-weight: 500; line-height: 1.2; }
.ready__sub { margin-top: 3px; font-size: clamp(13px, 1.3vw, 14px); color: var(--ink-3); }
.ready__head em { font-style: normal; font-size: 12px; font-weight: 500; white-space: nowrap; color: var(--green); background: #C3EED0; padding: 6px 10px; border-radius: 10px; } /* AppTag success: green200 under green800 */
.ready__big { margin-top: 18px; font-size: clamp(36px, 3.8vw, 44px); font-weight: 500; letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
/* The bar is AppProgressBar's emphasised variant, value for value: a 40px
   track of two 8px-radius segments 2px apart, the fill edge at W·p − 1px and
   never narrower than 10px, a flat green300 fill under the Figma inset glow
   (inset 0 0 15px 2px in the surface colour, scaled down on a narrow sliver),
   a neutral200 track, and a 16px caret in an 8px band, centred on the fill
   edge and clamped inside the bar. At 0 the app draws the track alone. */
.ready__track { --edge: clamp(10px, calc(var(--p) * 1% - 1px), calc(100% - 2px)); position: relative; margin-top: 6px; padding-top: 8px; }
.ready__caret { position: absolute; top: -4px; left: clamp(0px, calc(var(--edge) - 8px), calc(100% - 16px)); width: 16px; height: 16px; color: var(--ink-2); }
.ready__bar { display: flex; gap: 2px; height: 40px; }
.ready__bar i, .ready__bar b { display: block; height: 100%; border-radius: 8px; }
.ready__bar i { position: relative; flex: 0 0 var(--edge); overflow: hidden; background: #86EFAC; container-type: inline-size; }
.ready__bar i::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 min(50cqw, 15px) min(10cqw, 2px) var(--canvas); }
.ready__bar b { flex: 1; background: #E3E2DA; }
.ready.is-empty .ready__bar i { display: none; }
.ready.is-empty .ready__caret { left: 0; }
.ready__why { margin-top: 16px; font-size: clamp(14px, 1.4vw, 15px); line-height: 1.45; color: var(--ink); text-wrap: pretty; }

/* ── Hero demo: a phone showing the AI feedback screen, standing on a soft rounded
   panel over the writing skill's glow. The phone is a device render
   (544x1116) with an opaque black screen; the screenshot lies over it, inset
   to the glass and rounded in cqw so bezel and radii scale with the rig. ── */
.demo__stage {
  --rig: clamp(440px, 50vw, 660px);
  position: relative; isolation: isolate; overflow: hidden;
  margin-top: clamp(36px, 4.5vw, 64px);
  height: calc(var(--rig) * 1.32);
  border-radius: var(--r-panel);
  background: color-mix(in srgb, var(--ink) 3%, transparent);
}
/* The writing skill's liquid gradient, blurred out to nothing at its edges. */
.demo__glow {
  position: absolute; z-index: -1; left: 50%; top: 46%; width: min(980px, 100%); height: 80%;
  transform: translate(-50%, -50%);
  background:
    radial-gradient(38% 46% at 34% 40%, color-mix(in srgb, var(--sky-m) 70%, transparent), transparent 100%),
    radial-gradient(40% 50% at 68% 58%, color-mix(in srgb, var(--pro-m) 60%, transparent), transparent 100%),
    radial-gradient(34% 40% at 52% 78%, color-mix(in srgb, var(--sky-l) 90%, transparent), transparent 100%);
  filter: blur(48px); opacity: .6;
  animation: demo-glow 12s ease-in-out infinite alternate;
}
@keyframes demo-glow { from { transform: translate(-52%, -50%) scale(1); } to { transform: translate(-48%, -51%) scale(1.06, .96); } }
@media (prefers-reduced-motion: reduce) { .demo__glow { animation: none; } }
.hand-rig {
  container-type: inline-size;
  position: absolute; left: 50%; top: calc(var(--rig) * .12);
  width: calc(var(--rig) * .68); aspect-ratio: 544 / 1116;
  transform: translateX(-50%);
}
.phone {
  position: absolute; inset: 0;
  background: url("assets/img/hero-phone.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 34px 44px rgba(24,29,47,.2)) drop-shadow(0 6px 12px rgba(24,29,47,.1));
}
.phone__screen {
  position: absolute; left: 4.41%; top: 1.75%; width: 91.18%; height: auto; aspect-ratio: 590 / 1280;
  display: block; border-radius: 13.5cqw; background: var(--navy-d); object-fit: cover;
}
/* The app's own celebration, fired across the whole panel rather than inside
   the screen. It sits above the blur bands so the paper stays crisp. */
.demo__confetti { position: absolute; z-index: 3; inset: 0; width: 100%; height: 100%; pointer-events: none; }
/* Progressive blur where the phone meets the panel's bottom edge: four
   backdrop-blur bands, each starting lower and blurring harder than the one
   before, each masked in from transparent so no band has a visible top.
   backdrop-filter samples transparent black while an ancestor is fading in
   and flashes a dark band, one more reason the panel slides without fading. */
/* The bands overrun the panel by 40px: a backdrop blur goes sharp along its
   own bottom edge, where it has nothing beyond to sample, and the overrun puts
   that strip where the panel clips it. */
.demo__blur { position: absolute; z-index: 2; inset: auto 0 -40px 0; height: calc(30% + 40px); pointer-events: none; }
.demo__blur i {
  position: absolute; inset: auto 0 0 0; height: var(--h);
  -webkit-backdrop-filter: blur(var(--b)); backdrop-filter: blur(var(--b));
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 45%); mask-image: linear-gradient(to bottom, transparent, #000 45%);
}
.demo__blur i:nth-child(1) { --h: 100%; --b: 1.5px; }
.demo__blur i:nth-child(2) { --h: 76%;  --b: 3px; }
.demo__blur i:nth-child(3) { --h: 52%;  --b: 6px; }
.demo__blur i:nth-child(4) { --h: 28%;  --b: 12px; }
@media (max-width: 640px) { .demo__stage { --rig: 118vw; } }

/* A panel that runs nearly edge to edge rather than sitting in the text column. */
.bleed { padding-inline: var(--bleed); }
/* ── FAQ ── */
.faq { padding-block: clamp(40px, 5vw, 72px); }
.faq__list { width: min(100%, 880px); margin: 40px auto 0; display: flex; flex-direction: column; gap: 10px; }
.faq details { background: var(--soft); border-radius: var(--r-md); padding: 0 22px; }
.faq summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 20px 0; font-weight: 500; cursor: pointer; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary svg { flex: none; width: 20px; height: 20px; color: var(--ink-2); transition: transform .4s var(--ease); }
.faq details[open] summary svg { transform: rotate(180deg); }
.faq details p { padding: 0 0 22px; margin-top: -4px; color: var(--ink-2); font-size: var(--fs-sm); }
/* Answers may run to several short paragraphs; only the last one carries the row's bottom padding. */
.faq details p:not(:last-child) { padding-bottom: 10px; }
.faq details p + p { margin-top: 0; }

/* ── CTA ── */
.cta { padding: clamp(56px, 8vw, 110px) var(--edge); text-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center; margin-block: clamp(24px, 4vw, 48px) 0; }
.cta { border-radius: var(--r-panel); }
.cta .h2 { color: #fff; }
.cta p { color: rgba(255,255,255,.85); margin-top: 16px; max-width: 30em; text-wrap: balance; }
.cta .actions { justify-content: center; }
.cta .cta__note { margin-top: 18px; font-size: 14px; color: rgba(255,255,255,.75); }

/* ── Footer ── */
.footer { padding-block: clamp(48px, 6vw, 80px) 40px; }
.footer__grid { display: grid; grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); gap: 32px; }
.footer__grid--5 { grid-template-columns: 1.4fr repeat(4, minmax(0, 1fr)); }
@media (max-width: 860px) { .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.footer__home { display: inline-block; vertical-align: top; transition: opacity .25s var(--ease); }
@media (hover: hover) and (pointer: fine) { .footer__home:hover { opacity: .7; } }
.footer__logo { display: block; height: 26px; width: auto; fill: var(--navy); }
.footer__brand p { margin-top: 14px; font-size: 15px; color: var(--ink-2); max-width: 22em; }
.footer__col { display: flex; flex-direction: column; gap: 10px; font-size: 15px; }
.footer__col h2 { margin: 0 0 4px; font-size: 13px; font-weight: 500; color: var(--ink-3); }
.footer__col a { overflow-wrap: anywhere; }
.footer__col a:hover { color: var(--sky-d); }
.footer__fine { margin-top: 48px; padding-top: 24px; border-top: 1px solid var(--line); font-size: 13px; color: var(--ink-3); }

/* ── Motion ── */
.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity .7s var(--ease), transform .7s var(--ease); transition-delay: var(--d, 0s); }
.js .reveal.is-in { opacity: 1; transform: none; }
/* The hero is on screen from the first frame, so it rises on load in CSS
   rather than waiting for main.js to hide it and fade it back in. The phone's
   panel is the page's largest paint, and Chrome does not count a paint made
   at opacity 0 (a composited fade is not repainted until it ends), so the
   panel slides without fading and its paint counts from the first frame. */
.rise { animation: rise .7s var(--ease) backwards; animation-delay: var(--d, 0s); }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }
.bleed.rise { animation-name: rise-slide; }
@keyframes rise-slide { from { transform: translateY(14px); } }
@media (prefers-reduced-motion: reduce) {
  .rise { animation: none; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .show__card { transition: none; }
  .stage::before, .stage::after, .stage__light, .nav__ring, .btn--glass::before { animation: none; }
}

/* Cursor trail: small pretzels spawn along the pointer path and fade where
   they landed. Fixed layer under the nav, never hit-testable. */
.trail { position: fixed; inset: 0; z-index: 40; pointer-events: none; overflow: hidden; }
.trail__item {
  position: absolute; left: 0; top: 0;
  width: 34px; height: 28px; margin: -14px 0 0 -17px;
  background: url("assets/img/pretzel.webp") center / contain no-repeat;
  filter: drop-shadow(0 2px 3px rgb(35 31 35 / .18));
  transform: translate(var(--x), var(--y)) rotate(var(--r)) scale(.5);
  opacity: 0;
  will-change: transform, opacity;
  animation: trail-item .8s var(--ease) forwards;
}
@keyframes trail-item {
  0%   { opacity: 0; transform: translate(var(--x), var(--y)) rotate(var(--r)) scale(.5); }
  14%  { opacity: 1; transform: translate(var(--x), var(--y)) rotate(var(--r)) scale(1); }
  45%  { opacity: 1; transform: translate(var(--x), var(--y)) rotate(var(--r)) scale(1); }
  100% { opacity: 0; transform: translate(var(--x), var(--y)) rotate(var(--r)) scale(.85); }
}
