/*
 * The landing page's stylesheet.
 *
 * Hand-written and standalone, because this page is deliberately outside the
 * Vite build: it is the first thing a stranger loads, and it should be two
 * files and a few lines of script rather than a 155KB bundle that renders a
 * headline — and it should be readable by a crawler without running any of
 * it, which a client-rendered SPA is not.
 *
 * TWO THEMES. This was dark-only, with a comment warning that bolting on a
 * `prefers-color-scheme` block would invert half the page and leave the rest.
 * That warning was correct and is the reason this file is shaped the way it
 * now is: every colour resolves through a variable, INCLUDING the translucent
 * ones, which were the half that would not have flipped.
 *
 * The trick is `--tint` and `--ground`: a lift like `rgb(var(--tint) / 0.04)`
 * is white-on-dark in one theme and near-black-on-light in the other, so one
 * declaration serves both. A literal `rgb(var(--tint) / 0.04)` anywhere below
 * is a bug — it disappears entirely on the light ground.
 *
 * The palettes are the APP's, copied from frontend/src/index.css rather than
 * invented here (this page is outside the build, so there is no import). The
 * two must be changed together; there is no third place.
 */

:root {
  /* Ground and surfaces — the SAME values as the app's dark palette in
     frontend/src/index.css. Copied rather than imported (this page is
     deliberately outside the Vite build), so the two must be changed
     together; there is no third place. */
  --bg: #111214;
  --bg-lift: #16181b;
  --surface: #1a1c1f;
  --surface-2: #212428;

  --line: #2e3238;
  --line-strong: #3d424a;

  --ink: #e8eaed;
  --muted-ink: #a1a8b2;
  --muted: #7c838d;

  /* Brand, from the mark's own gradient stops. The ramp is the app's dark
     ramp: its HIGH end is the light blue, because a dark ground needs the
     bright end for text and fills. */
  --brand: #3f9bff;
  --brand-lift: #5aa9ff;
  --brand-pale: #93cdff;
  --brand-deep: #1a7ae4;
  --brand-dim: rgb(var(--brand-rgb) / 0.13);

  /* Bare channels, for the translucent values. A lift is white on a dark
     ground and near-black on a light one; writing the literal is what made
     this file dark-only. */
  --tint: 255 255 255;
  --ground: 17 18 20;
  --brand-rgb: 63 155 255;
  --shadow-a: 0.9;
  /* Text ON a filled brand surface. Dark, not white — the app's palette makes
     the same call for the same reason: white on #5aa9ff is about 2.6:1. */
  --on-brand: #0b1a2b;
  --ok: #4ade80;

  /* Two gradients, and they are not interchangeable:
       --grad       a pale brand fill, which takes DARK text
       --grad-panel deep brand, which takes WHITE text
     Mixing them up is how a button ends up at 2.6:1. */
  --grad: linear-gradient(135deg, #5aa9ff 0%, #3f9bff 100%);
  --grad-panel: linear-gradient(135deg, #1a7ae4 0%, #1663bd 38%, #17539a 100%);
  --grad-text: linear-gradient(100deg, #2189f2 0%, #4da2ff 42%, #93cdff 100%);

  /* The bloom behind a primary button. Big and soft — at this size it reads
     as the button being lit rather than as a drop shadow. */
  --glow: 0 10px 40px -8px rgb(var(--brand-rgb) / 0.4);

  --radius: 16px;
  --gutter: 16px;
  --shell: 1200px;
}

/* ── light ───────────────────────────────────────────────────────────────
   Applied by `data-theme="light"` on <html>, set by the toggle and by the
   inline script in <head> before first paint — see index.html on why that
   script has to run there and not at the end of the body.

   Values from the app's light palette (frontend/src/index.css), not invented
   here. `--on-brand` flips to WHITE: the dark palette's near-black sits on a
   bright #5aa9ff fill, while this theme's fill is the deeper #1a7ae4, where
   white is the legible choice and near-black is not. */
:root[data-theme="light"] {
  --bg: #ffffff;
  --bg-lift: #f3f6fb;
  --surface: #ffffff;
  --surface-2: #f3f6fb;

  --line: #ecedef;
  --line-strong: #dfe1e5;

  --ink: #232222;
  --muted-ink: #5b6169;
  --muted: #a5acb4;

  --brand: #1a7ae4;
  --brand-lift: #2189f2;
  --brand-pale: #1663bd;
  --brand-deep: #17539a;
  --on-brand: #ffffff;
  --ok: #15803d;

  /* A lift is now a DARKENING, and the ground it sits on is white. Getting
     these two backwards is what the old comment warned about. */
  --tint: 16 24 40;
  --ground: 255 255 255;
  --brand-rgb: 26 122 228;
  /* Shadows that read as depth on near-black are bruises on white. */
  --shadow-a: 0.14;
}


*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Anchored jumps clear the sticky header instead of hiding under it. */
  scroll-padding-top: 84px;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Nothing in this layout should ever produce sideways scroll; if something
     does, clip it rather than hand the visitor a broken page. */
  overflow-x: clip;
}

img, svg { display: block; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--brand-lift);
  outline-offset: 3px;
  border-radius: 6px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Display type: tighter tracking and a heavier cut than the body face. The
   two families are one Google Fonts request; see index.html. */
h1, h2, .display {
  font-family: "Inter Tight", Inter, ui-sans-serif, system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.04;
  margin: 0;
  text-wrap: balance;
}

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand-lift);
}
.kicker svg { width: 14px; height: 14px; }

.lede { color: var(--muted-ink); font-size: 1.0625rem; margin: 0; }

/* ── buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: 12px;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  cursor: pointer;
  transition: transform 0.15s, box-shadow 0.15s, background-color 0.15s, border-color 0.15s;
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn:hover { transform: translateY(-1px); }
@media (prefers-reduced-motion: reduce) { .btn:hover { transform: none; } }

.btn-primary { background: var(--grad); color: var(--on-brand); box-shadow: var(--glow); }
.btn-primary:hover { box-shadow: 0 14px 46px -8px rgb(var(--brand-rgb) / 0.7); }

.btn-ghost { background: var(--surface-2); color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--line-strong); box-shadow: inset 0 0 0 100vmax rgb(var(--tint) / 0.05); }


.btn-sm { padding: 9px 16px; font-size: 0.875rem; border-radius: 10px; }

/* ── header ─────────────────────────────────────────────────────────── */
/* A floating glass bar: the sticky <header> is a transparent 12px frame
   (clicks pass through it), and the shell inside is the rounded pill. It
   firms up once the page scrolls under it. */
.top {
  position: sticky; top: 0; z-index: 50;
  padding: 12px var(--gutter) 0;
  pointer-events: none;
}
.top .shell {
  display: flex; align-items: center; gap: 16px;
  min-height: 60px; padding: 0 10px 0 16px;
  max-width: min(var(--shell), 100%);
  pointer-events: auto;
  border: 1px solid var(--line); border-radius: 18px;
  background: rgb(var(--ground) / 0.7);
  backdrop-filter: blur(16px) saturate(1.4); -webkit-backdrop-filter: blur(16px) saturate(1.4);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06), 0 10px 30px -18px rgb(0 0 0 / calc(0.6 * var(--shadow-a)));
  transition: background-color 0.25s, box-shadow 0.25s, border-color 0.25s;
}
.top.scrolled .shell {
  background: rgb(var(--ground) / 0.85); border-color: var(--line-strong);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06), 0 18px 44px -20px rgb(0 0 0 / calc(0.8 * var(--shadow-a)));
}

.brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; font-size: 1.0625rem; letter-spacing: -0.02em; }
.brand img { width: 30px; height: 30px; border-radius: 9px; }

.nav-links { display: none; gap: 4px; margin-inline: auto; }
.nav-links a { padding: 8px 14px; border-radius: 9px; font-size: 0.9375rem; color: var(--muted-ink); white-space: nowrap; }
@media (min-width: 860px) and (max-width: 1040px) { .nav-links a { padding-inline: 9px; } }
.nav-links a:hover { color: var(--ink); background: rgb(var(--tint) / 0.05); }
@media (min-width: 860px) { .nav-links { display: flex; } }
/* Below 860px the links move into the menu dropdown (see "mobile menu"). */

/* ── hero ───────────────────────────────────────────────────────────── */
/* Copy plus the product card. Stacked and centred on a phone; side by side
   from 640px, with the card on a tilted 3D plane bleeding off the right. */
.hero {
  position: relative;
  padding: clamp(56px, 9vw, 112px) 0 clamp(40px, 5vw, 64px);
  text-align: center;
  isolation: isolate;
  overflow-x: clip;
}
/* Two layers behind the hero and nothing else: a faint grid for texture, and
   one bloom so the headline has something to sit in front of. Both are -1 in
   the hero's own stacking context, so they cannot cover content. */
.hero::before,
.hero::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.hero::before {
  background-image:
    linear-gradient(to right, rgb(var(--tint) / 0.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(var(--tint) / 0.035) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 40%, transparent 78%);
}
.hero::after {
  background: radial-gradient(ellipse 60% 44% at 50% -6%, rgb(var(--brand-rgb) / 0.3), transparent 70%);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 16px;
  border: 1px solid rgb(var(--brand-rgb) / 0.35);
  background: var(--brand-dim);
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--brand-pale);
}
.badge .dot { position: relative; width: 7px; height: 7px; border-radius: 999px; background: var(--ok); }

.hero h1 {
  margin: 26px auto 0;
  max-width: 15ch;
  font-size: clamp(2.5rem, 7.6vw, 5.25rem);
  font-weight: 800;
}
/* Gradient headline words, shared by every section that uses .grad. */
.grad {
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero .lede { margin: 22px auto 0; max-width: 58ch; font-size: clamp(1rem, 2vw, 1.125rem); }

.cta-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 30px; }

.ticks {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 8px 26px; margin: 18px 0 0;
  padding: 0; list-style: none;
  font-size: 0.875rem; color: var(--muted-ink);
}
.ticks li { display: inline-flex; align-items: center; gap: 8px; }
.ticks svg { width: 14px; height: 14px; color: var(--ok); }

/* The card is laid out once at 720px and scaled with `zoom`, like a picture
   of the app, so every device gets the same composition. */
.hero-visual { margin-top: clamp(40px, 6vw, 64px); perspective: 1800px; text-align: left; }
.hero-visual .shot-stage {
  width: 720px; max-width: none; zoom: 0.46;
  transform: rotateY(-12deg) rotateX(5deg) rotateZ(1deg);
}
@media (min-width: 480px) { .hero-visual .shot-stage { zoom: 0.6; } }
@media (min-width: 640px) {
  .hero { text-align: left; }
  .hero-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: 28px; }
  .hero h1 { margin-left: 0; max-width: 12ch; font-size: clamp(2.2rem, 4.8vw, 4.4rem); }
  .hero .lede { margin-left: 0; max-width: 46ch; }
  .hero .cta-row, .hero .ticks { justify-content: flex-start; }
  .hero-visual { margin: 0 -40px 0 0; }
  .hero-visual .shot-stage { zoom: 0.5; }
}
@media (min-width: 780px) { .hero-visual .shot-stage { zoom: 0.62; } }
@media (min-width: 900px) {
  .hero { padding-bottom: clamp(64px, 7vw, 96px); }
  .hero-split { gap: 48px; }
  .hero-visual .shot-stage {
    zoom: 0.78;
    transform-style: preserve-3d;
    transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .hero-visual:hover .shot-stage { transform: rotateY(-6deg) rotateX(3deg); }
  .hero-visual .float { display: flex; animation: bob 6s ease-in-out infinite; }
  .hero-visual .float-b { animation-delay: -3s; }
}
@media (min-width: 1180px) {
  .hero-visual { margin-right: -120px; }
  .hero-visual .shot-stage { zoom: 0.95; }
}
@keyframes bob { 50% { transform: translateY(-8px); } }

/* ── product shot ───────────────────────────────────────────────────── */
/* An HTML mock of the app, not a screenshot: it stays crisp at any density
   and never goes stale against a UI change the way a pasted PNG does.
   Marked aria-hidden — it is an illustration of sample data. */
/* The positioning context for the floating cards — NOT .shot, which clips. */
.shot-stage { position: relative; isolation: isolate; max-width: 1000px; margin-inline: auto; perspective: 1600px; }
/* Glass frame shared by every product mock: a top-edge highlight over the
   theme surface. Follows the theme, because the app has both. */
.shot, .tile-mock, .dash {
  border: 1px solid var(--line);
  background:
    linear-gradient(180deg, rgb(var(--tint) / 0.045), transparent 38%),
    linear-gradient(180deg, var(--surface), var(--bg-lift));
}
.shot {
  position: relative;
  border-radius: 20px;
  box-shadow:
    inset 0 1px 0 rgb(var(--tint) / 0.08),
    0 1px 2px rgb(0 0 0 / calc(0.3 * var(--shadow-a))),
    0 40px 90px -30px rgb(0 0 0 / calc(0.9 * var(--shadow-a))),
    0 0 80px -40px rgb(var(--brand-rgb) / 0.5);
  overflow: hidden;
}
.shot-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--line);
  font-size: 0.8125rem;
  color: var(--muted-ink);
}
.shot-dots { display: flex; gap: 6px; }
.shot-dots i { width: 9px; height: 9px; border-radius: 999px; background: var(--line-strong); }
.pill-live {
  justify-self: end;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 4px 11px; border-radius: 999px;
  background: rgb(74 222 128 / 0.12); color: var(--ok);
  font-size: 0.75rem; font-weight: 600;
}
.pill-live i { position: relative; width: 6px; height: 6px; border-radius: 999px; background: currentColor; }

.shot-body { display: flex; }
.rail { display: none; flex-direction: column; gap: 10px; padding: 18px 12px; border-right: 1px solid var(--line); }
.rail i {
  display: block; width: 34px; height: 34px; border-radius: 10px;
  background: rgb(var(--tint) / 0.04);
}
.rail i:first-child { background: var(--brand-dim); box-shadow: inset 0 0 0 1px rgb(var(--brand-rgb) / 0.4); }
@media (min-width: 720px) { .rail { display: flex; } }

.shot-main { flex: 1; min-width: 0; padding: clamp(16px, 2.4vw, 26px); }
.shot-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px; }
.shot-head p { margin: 0; font-size: 0.8125rem; color: var(--muted); }
.shot-head h3 { margin: 3px 0 0; font-size: clamp(1.05rem, 2.2vw, 1.4rem); font-weight: 600; letter-spacing: -0.02em; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px; border: 1px solid var(--line); border-radius: 10px;
  font-size: 0.8125rem; color: var(--muted-ink); background: rgb(var(--tint) / 0.02);
  white-space: nowrap;
}

/* Inner glass panels: translucent over the ambient bloom, tinting on hover. */
.kpi, .panel {
  border: 1px solid var(--line); border-radius: 13px;
  background: rgb(var(--tint) / 0.03);
  backdrop-filter: blur(12px) saturate(1.2);
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06);
  transition: border-color 0.25s ease, transform 0.25s ease, background 0.25s ease;
}
.kpi:hover, .panel:hover { border-color: rgb(var(--brand-rgb) / 0.35); background: rgb(var(--brand-rgb) / 0.05); }
.kpi:hover { transform: translateY(-2px); }

.kpis { display: grid; gap: 12px; margin-top: 18px; grid-template-columns: repeat(3, 1fr); }
.kpi { padding: 14px; }
.kpi span { font-size: 0.8125rem; color: var(--muted); }
.kpi .row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 6px; }
.kpi b {
  display: inline-block;
  font-size: clamp(1.1rem, 2.6vw, 1.6rem); font-weight: 700; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.kpi em { font-style: normal; font-size: 0.75rem; color: var(--ok); }

.panels { display: grid; gap: 12px; margin-top: 12px; }
@media (min-width: 880px) { .panels { grid-template-columns: 1.15fr 1fr; } }
.panel { padding: 14px 16px; }
.panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.panel-head h4 { margin: 0; font-size: 0.875rem; font-weight: 600; }
.panel-head span { font-size: 0.75rem; color: var(--muted); }

.bars { display: grid; grid-template-columns: repeat(7, 1fr); gap: 10px; align-items: end; height: 132px; margin-top: 16px; }
.bars div { display: flex; flex-direction: column; justify-content: flex-end; height: 100%; gap: 8px; }
.bars i {
  position: relative; overflow: hidden;
  display: block; width: 100%; border-radius: 6px 6px 3px 3px;
  background: linear-gradient(180deg, #5aa9ff, #3f9bff);
  box-shadow: 0 6px 18px -8px rgb(var(--brand-rgb) / 0.7);
  transform-origin: bottom;
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1), filter 0.2s;
}
/* A sheen on the hovered bar. */
.bars i::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgb(255 255 255 / 0.35), transparent 40%);
  opacity: 0; transition: opacity 0.2s;
}
.bars div:hover i { filter: brightness(1.18); }
.bars div:hover i::after { opacity: 1; }
.bars small { text-align: center; font-size: 0.6875rem; color: var(--muted); }

.av {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 999px;
  background: rgb(var(--brand-rgb) / 0.18); color: var(--brand-pale);
  font-size: 0.6875rem; font-weight: 700; line-height: 1;
}
.replies { list-style: none; margin: 14px 0 0; padding: 0; }
.replies li { display: flex; align-items: center; gap: 11px; padding: 9px 0; border-top: 1px solid var(--line); }
.replies li:first-child { border-top: 0; padding-top: 4px; }
.replies b { display: block; font-size: 0.8125rem; font-weight: 600; }
/* `div span`, not `span`: the avatar is a span too and must keep its circle. */
.replies div span { display: block; font-size: 0.75rem; color: var(--muted); }
.replies .unread { position: relative; margin-inline-start: auto; width: 7px; height: 7px; border-radius: 999px; background: var(--ok); }

/* The two cards that float off the frame — only from 900px (see hero),
   where there is room around the card for them. */
.float { display: none; position: absolute; z-index: 2; align-items: center; gap: 11px;
  padding: 11px 15px; border: 1px solid var(--line-strong); border-radius: 13px;
  background: var(--surface-2); box-shadow: 0 20px 44px -16px rgb(0 0 0 / calc(0.85 * var(--shadow-a))); }
.float div span { display: block; font-size: 0.6875rem; color: var(--muted); }
.float b { display: block; font-size: 0.8125rem; font-weight: 600; }
.float .ok { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px;
  background: rgb(74 222 128 / 0.18); color: var(--ok); }
.float .ok svg { width: 14px; height: 14px; }
.float-a { top: -30px; right: 150px; }
.float-b { left: 40px; bottom: -28px; }

/* ── hero motion ────────────────────────────────────────────────────── */
/* Status dots breathe: a ring expands out of the dot and fades. Drawn on
   ::after so the dot itself never moves. */
.badge .dot::after,
.pill-live i::after,
.replies .unread::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--ok);
  animation: ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
}
.replies .unread::after { animation-duration: 2.4s; }
@keyframes ping { 75%, 100% { transform: scale(2.6); opacity: 0; } }

/* A slow ambient bloom behind the product card. */
.shot-stage::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  inset: -12% 8% auto; height: 70%;
  background: radial-gradient(closest-side, rgb(var(--brand-rgb) / 0.28), transparent);
  filter: blur(40px);
  animation: drift 14s ease-in-out infinite alternate;
}
@keyframes drift { to { transform: translate3d(4%, 6%, 0) scale(1.08); } }

/* The card rises in on a slight 3D plane and settles flat; pointer tilt
   (script) then nudges it a few degrees. Bars grow from zero, staggered.
   Every "before" state is gated on .js, so a visitor without JavaScript
   still sees the finished card. */
.js .shot {
  opacity: 0; transform: translateY(24px) rotateX(8deg); transform-origin: 50% 0;
  transition: opacity 0.8s ease, transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
.js .shot.in {
  opacity: 1; transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: opacity 0.8s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.shot.tilting { transition: transform 0.15s ease-out; }
.js .bars i { transform: scaleY(0); }
.js .shot.in .bars i { transform: scaleY(1); }
.bars div:nth-child(2) i { transition-delay: 0.07s; }
.bars div:nth-child(3) i { transition-delay: 0.14s; }
.bars div:nth-child(4) i { transition-delay: 0.21s; }
.bars div:nth-child(5) i { transition-delay: 0.28s; }
.bars div:nth-child(6) i { transition-delay: 0.35s; }
.bars div:nth-child(7) i { transition-delay: 0.42s; }
.shot.in .bars div:hover i { transform: scaleY(1.05); transition-delay: 0s; }

/* KPI numbers breathe once settled, and flash when the live ticker bumps one. */
.shot.in .kpi b { animation: breathe 4.5s ease-in-out 2.2s infinite; }
.shot.in .kpi:nth-child(2) b { animation-delay: 3.7s; }
.shot.in .kpi:nth-child(3) b { animation-delay: 5.2s; }
.shot.in .kpi b.bump { animation: bump 0.6s ease; }
@keyframes breathe { 50% { text-shadow: 0 0 18px rgb(var(--brand-rgb) / 0.55); } }
@keyframes bump { 0% { transform: translateY(-4px); opacity: 0.4; color: var(--ok); } 100% { transform: none; opacity: 1; } }

/* ── sections ───────────────────────────────────────────────────────── */
section { padding: clamp(40px, 5vw, 72px) 0; }
.center { text-align: center; }
.center .kicker { justify-content: center; }
.center h2 { margin: 14px auto 0; max-width: 18ch; }
.center .lede { margin: 18px auto 0; max-width: 52ch; }
h2 { font-size: clamp(1.85rem, 4.6vw, 3.1rem); }

/* Standalone card with a soft top highlight and a hover lift — shared by
   the feature, motivation and safety cards. */
.feature, .why-card, .guard {
  border: 1px solid var(--line); border-radius: 20px;
  background: linear-gradient(180deg, rgb(var(--tint) / 0.04), transparent 50%), var(--surface);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06);
  transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

/* ── features ───────────────────────────────────────────────────────── */
.features { display: grid; gap: 16px; margin-top: clamp(36px, 5vw, 56px); }
@media (min-width: 640px) { .features { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .features { grid-template-columns: repeat(4, 1fr); } }
.feature {
  position: relative; padding: 24px 22px 30px;
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06), 0 18px 40px -30px rgb(0 0 0 / calc(0.7 * var(--shadow-a)));
}
.feature:hover {
  transform: translateY(-4px); border-color: rgb(var(--brand-rgb) / 0.4);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06), 0 24px 50px -28px rgb(var(--brand-rgb) / 0.5);
}
.feature .n { position: absolute; top: 24px; right: 22px; font-size: 0.75rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.feature .ico {
  display: grid; place-items: center; width: 42px; height: 42px;
  border-radius: 12px; background: var(--brand-dim); color: var(--brand-lift);
  box-shadow: inset 0 0 0 1px rgb(var(--brand-rgb) / 0.22);
}
.feature .ico svg { width: 19px; height: 19px; }
.feature h3 { margin: 56px 0 0; font-size: 1rem; font-weight: 700; letter-spacing: -0.015em; }
.feature p { margin: 9px 0 0; font-size: 0.9375rem; color: var(--muted-ink); }

/* ── how it works ───────────────────────────────────────────────────── */
.how-grid { display: grid; gap: clamp(32px, 5vw, 64px); align-items: start; }
@media (min-width: 960px) { .how-grid { grid-template-columns: 0.95fr 1.05fr; } }
.how-grid h2 { margin-top: 16px; }
.how-grid .lede { margin-top: 20px; max-width: 42ch; }

.steps { display: grid; gap: 12px; position: relative; }
.step {
  display: flex; align-items: center; gap: 15px;
  padding: 18px 20px;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--surface);
}
/* The third step is lit in the design — it is the one people worry about
   (handing over a list), so it is worth the emphasis. */
.step.is-on { border-color: rgb(var(--brand-rgb) / 0.5); box-shadow: 0 0 0 1px rgb(var(--brand-rgb) / 0.12), 0 14px 40px -20px rgb(var(--brand-rgb) / 0.9); }
.step .n {
  flex: none; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 999px;
  background: var(--brand-dim); color: var(--brand-pale);
  font-size: 0.75rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.step div { min-width: 0; }
.step b { display: block; font-size: 0.9375rem; font-weight: 700; letter-spacing: -0.01em; }
.step span { display: block; font-size: 0.875rem; color: var(--muted-ink); }
.step .tick { flex: none; margin-inline-start: auto; color: var(--ok); }
.step .tick svg { width: 16px; height: 16px; }

/* ── faq ────────────────────────────────────────────────────────────── */
.faq-grid { display: grid; gap: clamp(28px, 4vw, 56px); align-items: start; }
@media (min-width: 960px) { .faq-grid { grid-template-columns: 0.85fr 1.15fr; } }
.faq-grid h2 { margin-top: 14px; }
.faq-grid .lede { margin-top: 16px; font-size: 1rem; max-width: 34ch; }

.faq details { border-bottom: 1px solid var(--line); }
.faq details:first-child { border-top: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer; position: relative;
  padding: 19px 40px 19px 0;
  font-size: 1rem; font-weight: 600; letter-spacing: -0.01em;
}
.faq summary::-webkit-details-marker { display: none; }
/* A chevron drawn from two rules, rotating to point up when open. Cheaper
   than two icon files and it animates for free. */
.faq summary::after {
  content: ""; position: absolute; right: 8px; top: 50%;
  width: 9px; height: 9px; margin-top: -6px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: rotate(45deg); transform-origin: center;
  transition: transform 0.2s;
}
.faq details[open] summary::after { transform: rotate(-135deg); margin-top: -2px; }
.faq details[open] summary { color: var(--ink); }
.faq p { margin: 0 0 20px; max-width: 62ch; color: var(--muted-ink); font-size: 0.9375rem; }

/* ── closing call to action ─────────────────────────────────────────── */
.closer {
  position: relative; overflow: hidden;
  border-radius: 26px;
  background: var(--grad-panel);
  padding: clamp(40px, 7vw, 84px) clamp(20px, 4vw, 40px);
  text-align: center;
  box-shadow: 0 40px 90px -40px rgb(var(--brand-rgb) / 0.9);
}
/* A soft light from the top-left, so the panel is not a flat slab of violet. */
.closer::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(62% 80% at 18% 0%, rgb(var(--tint) / 0.14), transparent 55%);
  pointer-events: none;
}
.closer > * { position: relative; }
/* Literal white, NOT --tint: this panel keeps its blue gradient in both
   themes, so text on it is always on a dark ground. --tint flips to
   near-black in light mode, which would put dark text on blue. */
.closer .kicker { color: rgb(255 255 255 / 0.9); justify-content: center; }
.closer h2 { margin: 16px auto 0; max-width: 17ch; color: #fff; }
.closer p { margin: 18px auto 0; max-width: 46ch; color: rgb(255 255 255 / 0.93); }

/* ── footer ─────────────────────────────────────────────────────────── */
footer { border-top: 1px solid var(--line); margin-top: clamp(56px, 8vw, 96px); padding: 28px 0 44px; }
footer .shell {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 14px 24px; font-size: 0.875rem; color: var(--muted);
}
footer .brand { font-size: 0.9375rem; }
footer .brand img { width: 26px; height: 26px; border-radius: 8px; }

/* ── sign-in dialog ──────────────────────────────────────────────────── */
/* A native <dialog>, so the browser owns focus trapping, inertness of the
   page behind, and the top layer — none of which is worth reimplementing.
   `.modal` styles the element itself, which IS the panel; the backdrop is a
   pseudo-element and cannot be selected any other way. */
.modal {
  width: min(420px, calc(100vw - 2 * var(--gutter)));
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--surface);
  color: var(--ink);
  /* The panel is ~630px tall once the password form is in it, which clears a
     375x667 phone by 19px and clips on anything shorter — a landscape phone,
     or a browser with more chrome than the emulator. Cap it and let it
     scroll rather than losing the submit button off the bottom edge. */
  max-height: calc(100dvh - 32px);
  overflow-x: hidden;            /* keeps .modal-edge inside the corner radius */
  overflow-y: auto;
  box-shadow: 0 32px 90px -20px rgb(0 0 0 / calc(0.75 * var(--shadow-a)));
}
.modal::backdrop {
  background: rgb(var(--ground) / 0.72);
  backdrop-filter: blur(3px);
}
/* The lit hairline across the top. A separate element rather than a border,
   because a gradient border-image would not follow the radius. */
.modal-edge {
  height: 3px;
  background: linear-gradient(90deg, var(--brand-deep), var(--brand-lift) 45%, #7ee0ff);
}
.modal-close {
  position: absolute;
  top: 16px; right: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  padding: 0;
  border: 0; border-radius: 50%;
  background: var(--surface-2);
  color: var(--muted);
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s;
}
.modal-close:hover { background: #2b2f35; color: var(--ink); }
.modal-close svg { width: 15px; height: 15px; }

.modal-body { padding: 34px 30px 28px; text-align: center; }
/* The mark sits on its own brand tile, the one place on the page it is shown
   at button size rather than as a small brand glyph. */
.modal-mark {
  /* `img, svg { display: block }` up top means the body's text-align cannot
     centre this; a block element needs auto margins. */
  margin-inline: auto;
  width: 46px; height: 46px;
  padding: 10px;
  border-radius: 13px;
  background: var(--grad);
  box-shadow: var(--glow);
}
.modal-body h2 {
  margin: 18px 0 6px;
  font-size: 1.6rem;
  letter-spacing: -0.03em;
}
.modal-sub { margin: 0 0 22px; font-size: 0.9375rem; color: var(--muted-ink); }

.providers { display: grid; gap: 10px; }
.providers .btn { width: 100%; }
/* The provider's own mark keeps its brand colours, so it needs a light chip
   to sit on — it is drawn for white, not for a blue button. */
.provider-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border-radius: 6px;
  background: #fff;
}
.provider-mark svg { width: 14px; height: 14px; }
.providers .btn .go { margin-left: auto; }   /* arrow to the trailing edge */

.modal-note {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  margin: 16px 0 0;
  font-size: 0.75rem; color: var(--muted);
}
.modal-note svg { width: 13px; height: 13px; flex: none; }

.modal-foot {
  margin: 14px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 0.8125rem; color: var(--muted);
}
.modal-foot + .modal-foot { margin-top: 8px; padding-top: 0; border-top: 0; }
.modal-foot a { color: var(--brand-lift); }
.modal-foot b { color: var(--muted-ink); font-weight: 600; }

/* ── sign-in form ───────────────────────────────────────────────────── */
.or {
  display: flex; align-items: center; gap: 12px;
  margin: 18px 0 16px;
  font-size: 0.75rem; color: var(--muted);
}
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.field { text-align: left; }
.field + .field { margin-top: 12px; }
.field span {
  display: block; margin-bottom: 6px;
  font-size: 0.75rem; font-weight: 600; color: var(--muted-ink);
}
.field input {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: rgb(var(--tint) / 0.03);
  color: var(--ink);
  font: inherit;
  font-size: 0.9375rem;
}
.field input::placeholder { color: var(--muted); }
.field input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgb(var(--brand-rgb) / 0.18);
}

.signin-form .btn { width: 100%; margin-top: 16px; }
.signin-form .btn[disabled] { opacity: 0.6; cursor: not-allowed; transform: none; }

/* Hidden until there is something to say — an empty red box on first paint
   is its own kind of error message. */
.form-error {
  display: none;
  margin: 14px 0 0;
  padding: 10px 12px;
  border: 1px solid rgb(248 113 113 / 0.35);
  border-radius: 10px;
  background: rgb(248 113 113 / 0.1);
  color: #f87171;
  font-size: 0.8125rem;
  text-align: left;
}
.form-error[data-shown] { display: block; }

/* Success, mirroring .form-error exactly — same hidden-until-set rule, so a
   fresh dialog shows neither box. */
.form-ok {
  display: none;
  margin: 14px 0 0;
  padding: 10px 12px;
  border: 1px solid rgb(52 211 153 / 0.35);
  border-radius: 10px;
  background: rgb(52 211 153 / 0.1);
  color: #34d399;
  font-size: 0.8125rem;
  text-align: left;
}
.form-ok[data-shown] { display: block; }

/* The contact form's textarea. Inherits everything the inputs get; only the
   things a single-line field has no opinion about are set here. */
.field textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: rgb(var(--tint) / 0.03);
  color: var(--ink);
  font: inherit;
  font-size: 0.9375rem;
  resize: vertical;
  min-height: 84px;
}
.field textarea::placeholder { color: var(--muted); }
.field textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgb(var(--brand-rgb) / 0.18);
}

/* "optional" beside a label, so the required fields read as the short list. */
.field span i { font-style: normal; font-weight: 400; color: var(--muted); }

/* The honeypot. Taken out of the layout entirely rather than
   `display:none` — some bots skip a field they can see is hidden that way,
   and this still keeps it off the screen and out of the tab order. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}


/* Sits between the Google button and the password form: a visitor with no
   workspace has to see this before scrolling past it into a form that cannot
   help them. */
.modal-signup { margin: 14px 0 0; text-align: center; font-size: 0.8125rem; color: var(--muted-ink); }
.modal-signup a { color: var(--brand); font-weight: 600; }
.modal-signup a:hover { text-decoration: underline; }

/* ── theme toggle ────────────────────────────────────────────────────────
   Both icons live in the DOM and CSS picks one, rather than JS swapping an
   SVG: the choice then follows the attribute automatically, including the
   pre-paint one set in <head> before any of our script has run. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border: 1px solid var(--line-strong); border-radius: 999px;
  background: transparent; color: var(--muted-ink);
  cursor: pointer; transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink); }
.theme-toggle svg { width: 16px; height: 16px; }
/* Show the destination, not the current state: dark shows a sun because
   pressing it brings the light one. */
.theme-toggle .icon-sun { display: block; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="light"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: block; }


/* ── footer ──────────────────────────────────────────────────────────────
   Four columns on desktop, stacking to one on a phone. The brand column is
   wider than the link columns because it carries a sentence, not a list. */
.foot-grid {
  display: grid;
  gap: 32px 24px;
  grid-template-columns: 1fr;
  padding-bottom: 32px;
}
@media (min-width: 720px) {
  .foot-grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 40px 32px; }
}
.foot-brand p {
  margin: 14px 0 0;
  max-width: 34ch;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--muted-ink);
}
.foot-col { display: flex; flex-direction: column; align-items: flex-start; gap: 11px; }
.foot-col h3 {
  margin: 0 0 3px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.foot-col a {
  font-size: 0.9375rem;
  color: var(--muted-ink);
  text-decoration: none;
  transition: color 0.15s;
}
.foot-col a:hover { color: var(--ink); }
.foot-base {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  font-size: 0.8125rem;
  color: var(--muted);
}

/* ── pricing ────────────────────────────────────────────────────────── */
/* Tier cards are rendered from /api/pricing; the card below them is the
   no-data fallback and, once tiers are shown, the shared feature list. */
#pricing { padding: clamp(40px, 5vw, 72px) 0 clamp(24px, 3vw, 40px); }
#pricing + section { padding-top: clamp(16px, 2vw, 24px); }
.price-card {
  max-width: 560px;
  margin: 32px auto 0;
  padding: clamp(28px, 4vw, 40px);
  border: 1px solid var(--line-strong);
  border-radius: 20px;
  background: var(--surface);
  box-shadow: 0 30px 70px -36px rgb(0 0 0 / calc(0.8 * var(--shadow-a)));
}
.price-row { display: grid; gap: 16px; }
.price-row > .price-card { margin-inline: auto; }
.tiers:not([hidden]) + .price-row { margin-top: 20px; }
.tiers:not([hidden]) + .price-row > .price-card { margin: 0; max-width: none; }
@media (min-width: 900px) { .price-row:has(.calc:not([hidden])) { grid-template-columns: 1.25fr 1fr; align-items: stretch; } }

/* Cost calculator, beside the "included" card. */
.calc {
  position: relative; overflow: hidden;
  padding: clamp(24px, 3.5vw, 36px);
  border: 1px solid rgb(var(--brand-rgb) / 0.35); border-radius: 20px;
  background: linear-gradient(180deg, rgb(var(--brand-rgb) / 0.08), transparent 60%), var(--surface);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06), 0 30px 70px -36px rgb(var(--brand-rgb) / 0.5);
}
.calc[hidden] { display: none; }
.calc h3 { margin: 6px 0 0; font-size: 1.2rem; font-weight: 700; letter-spacing: -0.015em; }
.calc-plans { display: flex; gap: 4px; margin-top: 18px; padding: 4px; border: 1px solid var(--line); border-radius: 12px; background: rgb(var(--tint) / 0.03); }
.calc-plans button {
  flex: 1; padding: 8px 10px; border: 0; border-radius: 9px; background: transparent;
  font: inherit; font-size: 0.875rem; font-weight: 600; color: var(--muted-ink); cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}
.calc-plans button:hover { color: var(--ink); }
.calc-plans button[aria-checked="true"] { background: var(--surface-2); color: var(--ink); box-shadow: 0 1px 0 rgb(var(--tint) / 0.06), 0 4px 12px -6px rgb(0 0 0 / calc(0.6 * var(--shadow-a))); }
.calc-slider { display: flex; justify-content: space-between; align-items: baseline; margin-top: 22px; font-size: 0.875rem; color: var(--muted-ink); }
.calc-slider b { font-size: 1.1rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.calc input[type="range"] {
  --fill: 10%;
  width: 100%; height: 6px; margin: 12px 0 0; appearance: none; -webkit-appearance: none; cursor: pointer;
  border-radius: 999px; background: linear-gradient(90deg, var(--brand) var(--fill), rgb(var(--tint) / 0.1) var(--fill));
}
.calc input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 20px; height: 20px; border-radius: 999px;
  background: #fff; border: 2px solid var(--brand); box-shadow: 0 2px 8px rgb(var(--brand-rgb) / 0.5);
}
.calc input[type="range"]::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 999px;
  background: #fff; border: 2px solid var(--brand); box-shadow: 0 2px 8px rgb(var(--brand-rgb) / 0.5);
}
.calc-out { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 22px; }
.calc-out > div { padding: 14px; border: 1px solid var(--line); border-radius: 14px; background: rgb(var(--tint) / 0.03); }
.calc-out b { display: block; font-size: 1.6rem; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.calc-out span { font-size: 0.75rem; color: var(--muted); }
.calc-note { margin: 14px 0 0; font-size: 0.8125rem; line-height: 1.5; color: var(--muted); }
.price-cur { font-size: 0.45em; font-weight: 600; vertical-align: 0.55em; color: var(--muted-ink); }
.price-list { margin: 22px 0 0; padding: 0; list-style: none; display: grid; gap: 12px; }
.price-list li {
  position: relative; padding-left: 28px;
  font-size: 0.9375rem; line-height: 1.5; color: var(--muted-ink);
}
/* The tick is drawn, not an <svg> per row. */
.price-list li::before {
  content: ""; position: absolute; left: 4px; top: 6px;
  width: 6px; height: 11px;
  border: solid var(--brand); border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.price-note {
  margin: 16px 0 0; font-size: 0.8125rem; line-height: 1.55; color: var(--muted);
}
.price-included { margin: 0 0 4px; font-size: 0.8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }

/* The "from" figures, which only appear once the API has confirmed them:
   the flat monthly fee and the price per sender, both set big because both
   are what you pay. The joining words stay small and inline so the line
   reads as one sentence. */
.price-from {
  margin: 0 0 22px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--line);
  font-size: clamp(1.9rem, 5vw, 2.6rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: var(--ink);
}
.price-from .price-join,
.price-from .price-per {
  display: inline;
  white-space: nowrap;
  margin: 0;
  font-size: 0.34em; font-weight: 500; letter-spacing: 0;
  color: var(--muted-ink);
}
.price-from[hidden], .trial-note[hidden], .tiers[hidden], .price-included[hidden] { display: none; }

/* Pill notes: the trial line here, "Replied" in the inbox mock. */
.trial-note, .tag {
  border-radius: 999px; font-weight: 600;
  background: rgb(74 222 128 / 0.14); color: var(--ok);
}
.trial-note { width: fit-content; margin: 26px auto 0; padding: 6px 14px; font-size: 0.8125rem; }

.tiers { display: grid; gap: 16px; margin-top: 32px; align-items: stretch; }
@media (min-width: 900px) { .tiers { grid-template-columns: repeat(3, 1fr); } }
.tier {
  display: flex; flex-direction: column;
  padding: 28px 24px; border: 1px solid var(--line); border-radius: 20px;
  background: var(--surface);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.tier:hover { transform: translateY(-3px); box-shadow: 0 30px 70px -36px rgb(0 0 0 / calc(0.8 * var(--shadow-a))); }
/* The featured tier (Enterprise): lifted, with a "Popular" badge. */
.tier-lift {
  position: relative; border-color: rgb(var(--brand-rgb) / 0.55);
  background: linear-gradient(180deg, rgb(var(--brand-rgb) / 0.1), var(--surface) 55%);
  box-shadow: 0 0 0 1px rgb(var(--brand-rgb) / 0.25), 0 30px 80px -36px rgb(var(--brand-rgb) / 0.6);
}
.tier-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tier h3 { margin: 0; font-size: 1.125rem; font-weight: 700; }
.tier-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: 999px;
  background: var(--grad); color: var(--on-brand);
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.02em;
  box-shadow: 0 6px 18px -8px rgb(var(--brand-rgb) / 0.8);
}
.tier-desc { margin: 6px 0 0; font-size: 0.875rem; color: var(--muted-ink); }
.tier-price { margin: 20px 0 0; font-size: 2.6rem; font-weight: 700; line-height: 1; letter-spacing: -0.03em; }
.tier-per { margin-left: 4px; font-size: 0.9375rem; font-weight: 500; letter-spacing: 0; color: var(--muted-ink); }
.tier-seat { margin: 10px 0 0; font-size: 0.8125rem; color: var(--muted-ink); }
.tier .price-list { flex: 1; padding-top: 20px; border-top: 1px solid var(--line); }


/* ── legal pages ─────────────────────────────────────────────────────────
   Long-form text, so a narrow measure and generous leading. Shares the site's
   palette and theme script; no separate stylesheet to drift. */
.legal { padding: clamp(40px, 7vw, 80px) 0 clamp(56px, 8vw, 96px); }
.legal .shell { max-width: 720px; }
.legal h1 { font-size: clamp(1.9rem, 4.5vw, 2.6rem); letter-spacing: -0.02em; margin: 0; }
.legal-meta { margin: 10px 0 0; font-size: 0.875rem; color: var(--muted); }
.legal h2 {
  margin: 40px 0 0; font-size: 1.125rem; letter-spacing: -0.01em; color: var(--ink);
}
.legal p, .legal li { color: var(--muted-ink); line-height: 1.7; }
.legal p { margin: 14px 0 0; }
.legal ul { margin: 14px 0 0; padding-left: 20px; display: grid; gap: 9px; }
.legal a { color: var(--brand); }
.legal strong { color: var(--ink); font-weight: 600; }
.legal .foot-base a { color: var(--muted); }

/* ── product showcase ───────────────────────────────────────────────── */
/* Four small mocks, each animated in when it scrolls into view (.reveal →
   .in, set by the script). Every "before" state is gated on .js. */
.showcase { display: grid; gap: 16px; margin-top: 40px; }
@media (min-width: 760px) { .showcase { grid-template-columns: repeat(2, 1fr); } }
.tile {
  padding: 14px 14px 22px; border: 1px solid var(--line); border-radius: 20px;
  background: rgb(var(--tint) / 0.02);
  transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.tile:hover {
  transform: translateY(-3px); border-color: rgb(var(--brand-rgb) / 0.35);
  box-shadow: 0 24px 60px -30px rgb(var(--brand-rgb) / 0.45);
}
.tile > h3 { margin: 18px 8px 0; font-size: 1rem; font-weight: 700; letter-spacing: -0.015em; }
.tile > p { margin: 6px 8px 0; font-size: 0.9375rem; color: var(--muted-ink); }
.tile-mock {
  min-height: 210px; padding: 16px; border-radius: 14px;
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.08), 0 18px 40px -28px rgb(0 0 0 / calc(0.8 * var(--shadow-a)));
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease;
}
.tile:hover .tile-mock {
  transform: translateY(-4px) scale(1.01);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.1), 0 30px 60px -30px rgb(var(--brand-rgb) / 0.45);
}

/* Funnel: horizontal bars grow from the left. */
.funnel { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 14px; }
.funnel li { display: grid; grid-template-columns: 74px 1fr 40px; align-items: center; gap: 12px; font-size: 0.8125rem; color: var(--muted-ink); }
.funnel b { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }
.funnel i {
  display: block; height: 10px; border-radius: 999px; width: var(--w);
  background: linear-gradient(90deg, #3f9bff, #5aa9ff);
  transform-origin: left; transition: transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}
.funnel li:nth-child(2) i { transition-delay: 0.1s; }
.funnel li:nth-child(3) i { transition-delay: 0.2s; }
.funnel li:nth-child(4) i { transition-delay: 0.3s; }
.js .reveal:not(.in) .funnel i { transform: scaleX(0); }

/* Sequence: steps arrive one after another. */
.seq { list-style: none; margin: 14px 0 0; padding: 0; }
.seq li { display: flex; align-items: center; gap: 11px; padding: 6px 0; transition: opacity 0.4s ease, transform 0.4s ease; }
.seq li div b { display: block; font-size: 0.8125rem; font-weight: 600; }
.seq li div span { display: block; font-size: 0.75rem; color: var(--muted); }
.seq-ico {
  flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px;
  font-style: normal; font-size: 0.8125rem; font-weight: 700;
  background: var(--brand-dim); color: var(--brand-pale);
}
.seq .seq-wait { margin-left: 13px; padding-left: 24px; border-left: 2px dashed var(--line-strong); font-size: 0.75rem; color: var(--muted); }
.seq li:nth-child(2) { transition-delay: 0.12s; }
.seq li:nth-child(3) { transition-delay: 0.24s; }
.seq li:nth-child(4) { transition-delay: 0.36s; }
.seq li:nth-child(5) { transition-delay: 0.48s; }
.js .reveal:not(.in) .seq li { opacity: 0; transform: translateY(6px); }

/* Inbox as a conversation. */
.thread { margin-top: 14px; display: grid; gap: 10px; }
.thread-who { display: flex; align-items: center; gap: 10px; }
.thread-who b { display: block; font-size: 0.8125rem; }
.thread-who span:not(.av) { display: block; font-size: 0.6875rem; color: var(--muted); }
.tag { margin-left: auto; padding: 3px 9px; font-style: normal; font-size: 0.6875rem; }
.bubble {
  margin: 0; max-width: 82%; padding: 9px 12px; border-radius: 14px; font-size: 0.8125rem; line-height: 1.45;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.bubble-out { justify-self: end; background: var(--grad); color: var(--on-brand); border-bottom-right-radius: 4px; }
.bubble-in { color: var(--muted-ink); background: rgb(var(--tint) / 0.06); border: 1px solid var(--line); border-bottom-left-radius: 4px; transition-delay: 0.6s; }
.thread-stop { margin: 2px 0 0; text-align: center; font-size: 0.6875rem; color: var(--muted); }
.js .reveal:not(.in) .bubble { opacity: 0; transform: translateY(8px); }

/* Pacing as ring gauges, sweeping in by animating a registered number. */
@property --p { syntax: "<number>"; inherits: false; initial-value: 0; }
.rings { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 18px; text-align: center; }
.ring > div {
  --c: var(--brand);
  position: relative; display: grid; place-content: center;
  width: 84px; height: 84px; margin: 0 auto; border-radius: 999px;
  background: conic-gradient(var(--c) calc(var(--p) * 1%), rgb(var(--tint) / 0.08) 0);
}
.ring:nth-child(1) > div { --p: 72; }
.ring:nth-child(2) > div { --p: 44; }
.ring:nth-child(3) > div { --p: 100; }
.ring-done > div { --c: var(--muted); }
.ring > div::before { content: ""; position: absolute; inset: 7px; border-radius: inherit; background: var(--surface); }
.ring > div > * { position: relative; }
.ring b { font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.ring small { font-size: 0.6875rem; color: var(--muted); }
.ring span { display: block; margin-top: 10px; font-size: 0.8125rem; font-weight: 600; }
.ring em { font-style: normal; font-size: 0.6875rem; color: var(--muted); }

/* ── ban-protection cards ───────────────────────────────────────────── */
/* Six hues, each a tint over the theme surface, so they read in both themes. */
.guard-head { display: grid; gap: 16px; align-items: end; }
@media (min-width: 860px) { .guard-head { grid-template-columns: 1.2fr 1fr; } }
.guard-head h2 { margin: 14px 0 0; }
.guards { display: grid; gap: 16px; margin-top: 36px; }
@media (min-width: 640px) { .guards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .guards { grid-template-columns: repeat(3, 1fr); } }
.guard {
  --h: 63 155 255;
  padding: 26px 24px;
  background: linear-gradient(180deg, rgb(var(--h) / 0.06), transparent 55%), var(--surface);
}
.guard:hover { transform: translateY(-4px); border-color: rgb(var(--h) / 0.45); box-shadow: 0 24px 50px -28px rgb(var(--h) / 0.55); }
.guard-ico {
  display: grid; place-items: center; width: 48px; height: 48px; border-radius: 14px;
  background: rgb(var(--h) / 0.14); color: rgb(var(--h)); box-shadow: inset 0 0 0 1px rgb(var(--h) / 0.25);
}
.guard-ico svg { width: 22px; height: 22px; }
.guard h3 { margin: 18px 0 0; font-size: 1.05rem; font-weight: 700; letter-spacing: -0.015em; }
.guard p { margin: 8px 0 0; font-size: 0.9375rem; color: var(--muted-ink); }
.g-blue   { --h: 63 155 255; }
.g-green  { --h: 34 197 94; }
.g-violet { --h: 139 92 246; }
.g-amber  { --h: 245 158 11; }
.g-rose   { --h: 244 63 94; }
.g-cyan   { --h: 6 182 212; }

/* ── why cards ──────────────────────────────────────────────────────── */
.why { padding-top: 0; }
.why-grid { display: grid; gap: 16px; }
@media (min-width: 760px) { .why-grid { grid-template-columns: repeat(3, 1fr); } .why-feature { grid-column: 1 / -1; } }
.why-card { position: relative; overflow: hidden; padding: 26px 24px; box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.07); }
.why-card:hover { transform: translateY(-3px); border-color: rgb(var(--brand-rgb) / 0.35); }
.why-card h3 { margin: 16px 0 0; font-size: 1.05rem; font-weight: 700; letter-spacing: -0.015em; }
.why-card p { margin: 8px 0 0; font-size: 0.9375rem; color: var(--muted-ink); }
.why-ico { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--brand-dim); color: var(--brand-pale); }
.why-ico svg { width: 20px; height: 20px; }
.why-feature { padding: clamp(28px, 4vw, 44px); background: var(--grad-panel); border-color: transparent; color: #fff; }
.why-feature::after {
  content: ""; position: absolute; right: -80px; top: -80px; width: 280px; height: 280px; border-radius: 999px;
  background: radial-gradient(closest-side, rgb(255 255 255 / 0.22), transparent); pointer-events: none;
}
.why-feature .kicker { color: rgb(255 255 255 / 0.85); }
.why-feature h3 { margin-top: 12px; font-size: clamp(1.4rem, 3vw, 2rem); line-height: 1.2; max-width: 24ch; color: #fff; }
.why-feature p { max-width: 62ch; color: rgb(255 255 255 / 0.88); font-size: 1rem; }

/* ── dashboard split ────────────────────────────────────────────────── */
.split { display: grid; gap: clamp(32px, 5vw, 64px); align-items: center; }
@media (min-width: 940px) { .split { grid-template-columns: 1.15fr 1fr; } }
.split-copy h2 { margin: 14px 0 0; }
.split-copy .lede { margin-top: 16px; }
.split-list { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 10px; }
.split-list li { position: relative; padding-left: 28px; color: var(--muted-ink); }
.split-list li::before {
  content: ""; position: absolute; left: 0; top: 3px; width: 18px; height: 18px; border-radius: 999px;
  background: var(--brand-dim) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233f9bff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 12 4 4 8-8'/%3E%3C/svg%3E") center / 12px no-repeat;
}

.split-mock { perspective: 1400px; }
.dash {
  display: flex; border-radius: 20px; overflow: hidden;
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.08), 0 50px 100px -40px rgb(0 0 0 / calc(0.9 * var(--shadow-a))), 0 0 90px -40px rgb(var(--brand-rgb) / 0.55);
  transform: rotateY(10deg) rotateX(4deg); transform-origin: 100% 50%;
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.split-mock:hover .dash { transform: rotateY(3deg) rotateX(1deg); }
.dash-nav { display: flex; flex-direction: column; gap: 10px; padding: 16px 12px; border-right: 1px solid var(--line); }
.dash-logo { width: 28px; height: 28px; border-radius: 9px; background: var(--grad); margin-bottom: 8px; }
.dash-nav i { width: 28px; height: 28px; border-radius: 9px; background: rgb(var(--tint) / 0.05); }
.dash-nav i.on { background: var(--brand-dim); box-shadow: inset 0 0 0 1px rgb(var(--brand-rgb) / 0.4); }
.dash-main { flex: 1; min-width: 0; padding: 18px; }
.dash-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.dash-top h4 { margin: 0; font-size: 0.95rem; font-weight: 700; }
.dash-search { padding: 6px 12px; border: 1px solid var(--line); border-radius: 9px; font-size: 0.75rem; color: var(--muted); }
.dash-kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 16px; }
.dash-kpis > div { padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: rgb(var(--tint) / 0.03); }
.dash-kpis span { display: block; font-size: 0.6875rem; color: var(--muted); }
.dash-kpis b { display: block; margin-top: 4px; font-size: 1.15rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.dash-kpis svg { display: block; width: 100%; height: 26px; margin-top: 8px; overflow: visible; }
.dash-kpis path { fill: none; stroke: var(--brand); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-dasharray: 200; stroke-dashoffset: 0; transition: stroke-dashoffset 1.4s ease; }
.js .reveal:not(.in) .dash-kpis path { stroke-dashoffset: 200; }
.dash-feed { margin-top: 14px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: rgb(var(--tint) / 0.03); }
.dash-feed h5 { margin: 0 0 8px; font-size: 0.8125rem; font-weight: 600; }
.dash-feed p { display: flex; align-items: center; gap: 8px; margin: 0; padding: 7px 0; border-top: 1px solid var(--line); font-size: 0.75rem; color: var(--muted-ink); }
.dash-feed p:first-of-type { border-top: 0; }
.dash-feed b { color: var(--ink); font-weight: 600; }
.dash-feed em { margin-left: auto; font-style: normal; color: var(--muted); }
.dot-ok, .dot-brand { flex: none; width: 7px; height: 7px; border-radius: 999px; background: var(--ok); }
.dot-brand { background: var(--brand); }
@media (max-width: 939px) { .dash, .split-mock:hover .dash { transform: none; } }

/* ── mobile menu ────────────────────────────────────────────────────── */
.menu-toggle {
  display: grid; place-items: center; width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--line); border-radius: 12px; background: transparent; color: var(--ink); cursor: pointer;
}
.menu-toggle svg { width: 20px; height: 20px; }
.menu-toggle path { transition: transform 0.25s ease, opacity 0.2s ease; transform-origin: 12px 12px; }
.top.open .menu-toggle .m1 { transform: translateY(5px) rotate(45deg); }
.top.open .menu-toggle .m2 { opacity: 0; }
.top.open .menu-toggle .m3 { transform: translateY(-5px) rotate(-45deg); }
@media (min-width: 860px) { .menu-toggle { display: none; } }
@media (max-width: 859px) {
  .top .shell { position: relative; }
  .top .brand { margin-inline-end: auto; }
  .top .nav-links {
    display: flex; flex-direction: column; gap: 2px;
    position: absolute; top: calc(100% + 8px); left: 0; right: 0; margin: 0;
    padding: 8px; border: 1px solid var(--line-strong); border-radius: 16px;
    background: var(--surface);
    backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 24px 50px -20px rgb(0 0 0 / calc(0.8 * var(--shadow-a)));
    opacity: 0; transform: translateY(-6px); visibility: hidden; pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
  }
  .top.open .nav-links { opacity: 1; transform: none; visibility: visible; pointer-events: auto; }
  .top .nav-links a { padding: 12px 14px; font-size: 1rem; }
}
.top .btn-sm { white-space: nowrap; }
@media (max-width: 420px) {
  .top .shell { gap: 8px; padding-inline: 12px 8px; }
  .top .btn-sm { padding: 9px 12px; }
  .top .btn-sm svg { display: none; }
}

/* ── scroll reveal ──────────────────────────────────────────────────── */
/* The script tags text and cards with .rise and adds .in as each scrolls
   into view. Uses `translate`, not `transform`, so card hover lifts (which
   use transform) keep working once the element has arrived. */
.js .rise {
  opacity: 0; translate: 0 22px;
  transition: opacity 0.7s ease var(--d, 0ms), translate 0.7s cubic-bezier(0.22, 1, 0.36, 1) var(--d, 0ms),
              transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.js .rise.in { opacity: 1; translate: none; }

/* ── bottom dock ────────────────────────────────────────────────────── */
/* The page's single call to action below the hero: a floating glass pill
   like the header, parked below the fold until the hero's buttons leave. */
body:has(.dock) { padding-bottom: 96px; }
.dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  padding: 0 var(--gutter) max(14px, env(safe-area-inset-bottom));
  pointer-events: none;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
}
/* Parked below the edge only when the script is there to bring it up. */
.js .dock:not(.up):not(.flying) { transform: translateY(130%); opacity: 0; }
.js .dock:not(.up) .dock-inner { pointer-events: none; }
.dock-how svg { width: 12px; height: 12px; }
.dock-inner {
  position: relative; isolation: isolate;
  pointer-events: auto;
  display: flex; align-items: center; gap: 8px;
  width: fit-content; max-width: 100%; margin: 0 auto;
  padding: 8px;
}
/* The glass lives on a layer of its own, so it can fade in during the
   fly-in (--fly, set by the script) without fading the buttons with it. */
.dock-inner::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  border: 1px solid var(--line-strong); border-radius: 18px;
  background: rgb(var(--ground) / 0.78);
  backdrop-filter: blur(16px) saturate(1.4); -webkit-backdrop-filter: blur(16px) saturate(1.4);
  box-shadow: inset 0 1px 0 rgb(var(--tint) / 0.06), 0 20px 50px -18px rgb(0 0 0 / calc(0.85 * var(--shadow-a))), 0 0 60px -30px rgb(var(--brand-rgb) / 0.6);
}
/* Mid-flight: the dock is in its final place (so its slots can be measured),
   the glass at the flight's progress, and nothing animates on its own. */
.dock.flying, .dock.parked { transition: none; }
.dock.flying .dock-inner::before { opacity: var(--fly, 0); }
.hero-flying { z-index: 45; }
.hero-flying .cta-row .btn { transition: none; will-change: transform, opacity; }
.dock .btn { white-space: nowrap; padding: 11px 20px; }
/* A slow light sweep across the trial button. */
.dock-cta { position: relative; overflow: hidden; }
.dock-cta::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.45) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: sweep 4.5s ease-in-out 1.5s infinite;
}
@keyframes sweep { 0%, 55% { transform: translateX(-120%); } 85%, 100% { transform: translateX(120%); } }
@media (max-width: 640px) {
  .dock-inner { width: 100%; padding: 6px; gap: 6px; }
  .dock .btn { padding: 11px 12px; font-size: 0.875rem; }
  .dock .dock-cta { flex: 1; }
  .dock .dock-cta svg { display: none; }
  /* "How it works" collapses to its play icon on a phone. */
  .dock-how span { display: none; }
  .dock-how { width: 46px; padding-inline: 0; align-self: stretch; }
}

/* ── reduced motion ─────────────────────────────────────────────────── */
/* One place for every motion opt-out: final states, no movement. */
@media (prefers-reduced-motion: reduce) {
  .badge .dot::after, .pill-live i::after, .replies .unread::after,
  .shot-stage::before, .shot.in .kpi b, .hero-visual .float { animation: none; }
  .js .shot, .js .shot.in, .js .bars i,
  .js .reveal:not(.in) .funnel i, .js .reveal:not(.in) .seq li, .js .reveal:not(.in) .bubble {
    opacity: 1; transform: none; transition: none;
  }
  .js .reveal:not(.in) .dash-kpis path { stroke-dashoffset: 0; transition: none; }
  .hero-visual .shot-stage, .hero-visual:hover .shot-stage,
  .dash, .split-mock:hover .dash { transform: none; transition: none; }
  .tile, .tier { transition: none; }
  .dock { transition: opacity 0.2s ease; }
  .dock-cta::after { animation: none; }
  .tile:hover, .tier:hover, .tile:hover .tile-mock, .kpi:hover,
  .feature:hover, .why-card:hover, .guard:hover { transform: none; }
}
