/* ============================================================================
   Corinne — public site stylesheet.

   Built on the SHIPPING portal tokens (web/portal/styles.css), not on
   docs/DESIGN_SYSTEM.md. That document is from 2026-07-29, predates the Corinne
   rename, and names a different brand blue (#1E70E6 vs the shipping
   #00bfff -> #0052dc gradient). Where the two disagree, the running product
   wins, so a visitor who signs in sees the same brand they were sold.

   Tokens are redefined for dark under BOTH prefers-color-scheme and
   :root[data-theme="dark|light"], so an explicit toggle wins in either
   direction — the same double-definition the consoles use.
   ========================================================================= */

/* Jost is the display/wordmark face: the OFL Futura revival that matches the
   Reverie logo's letterforms. Self-hosted rather than pulled from Google Fonts
   so the site makes no third-party request and keeps working if fonts.gstatic
   is blocked. Variable 300-700 in one 26KB file. */
@font-face {
  font-family: 'Jost';
  src: url('../font/jost-var-latin.woff2') format('woff2-variations');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Brand — from the shipping portal. The gradient is the brand; the solid
     cobalt is what you use when a gradient cannot carry contrast (text, rules,
     focus rings). */
  --brand-cyan: #00bfff;
  --brand-cobalt: #0052dc;
  --brand: #0052dc;
  --ink-navy: #1b1b4f;          /* the mark's field color; deep sections */
  --grad: linear-gradient(135deg, var(--brand-cyan) 0%, var(--brand-cobalt) 100%);
  --grad-h: linear-gradient(90deg, var(--brand-cyan) 0%, var(--brand-cobalt) 100%);

  /* Neutrals (light) — a slight cool bias, never pure grey. */
  --bg: #eef2f8;
  --panel: #ffffff;
  --panel-2: #f6f9fd;
  --panel-3: #eaf0f9;
  --line: #dbe3ee;
  --line-2: #e8eef6;
  --fg: #0c1730;
  --fg-soft: #425069;
  --fg-mute: #606f89;

  /* Semantic — a separate system from the accent. Never used decoratively. */
  --ok: #1f9d6b;   --ok-bg: #e2f4ec;   --ok-ink: #187b54;
  --warn: #c98a1e; --warn-bg: #fbf0da; --warn-ink: #926416;
  --crit: #d64550; --crit-bg: #fbe4e6; --crit-ink: #c62c37;
  --info: #0052dc; --info-bg: #e5eefc;

  /* Type */
  --font: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --wordmark: 'Jost', var(--font);
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Shape */
  --radius: 14px;
  --radius-s: 10px;
  --radius-l: 20px;
  --shadow: 0 1px 2px rgba(12, 23, 48, .05), 0 4px 16px rgba(12, 23, 48, .05);
  --shadow-lg: 0 18px 48px rgba(12, 23, 48, .13);

  /* Rhythm. One scale, so vertical spacing between sections is never ad hoc. */
  --gutter: 24px;
  --measure: 1160px;   /* full content width */
  --measure-text: 68ch; /* prose width — long lines are the #1 readability bug */
  --sec-y: 92px;       /* section padding, collapsed on small screens */

  color-scheme: light dark;
}

/* Dark — once for the system preference, once for the explicit toggle. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #070d1c;
    --panel: #0e1730;
    --panel-2: #101c39;
    --panel-3: #132145;
    --line: #20305a;
    --line-2: #1a2748;
    --fg: #eaf1fc;
    --fg-soft: #a9b8d6;
    --fg-mute: #7b8aab;
    --ok: #37c98d;   --ok-bg: #0f2a22;
    --warn: #e0a63a; --warn-bg: #2c2413;
    --crit: #f0616b; --crit-bg: #2c1418;
    --ok-ink: var(--ok); --warn-ink: var(--warn); --crit-ink: var(--crit);
    --info: #4f9bef; --info-bg: #0f2244;
    --brand: #4f9bef;  /* cobalt on near-black fails contrast; lift it */
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 16px rgba(0, 0, 0, .3);
    --shadow-lg: 0 18px 48px rgba(0, 0, 0, .5);
  }
}

:root[data-theme="dark"] {
  --bg: #070d1c;
  --panel: #0e1730;
  --panel-2: #101c39;
  --panel-3: #132145;
  --line: #20305a;
  --line-2: #1a2748;
  --fg: #eaf1fc;
  --fg-soft: #a9b8d6;
  --fg-mute: #7b8aab;
  --ok: #37c98d;   --ok-bg: #0f2a22;
  --warn: #e0a63a; --warn-bg: #2c2413;
  --crit: #f0616b; --crit-bg: #2c1418;
  --ok-ink: var(--ok); --warn-ink: var(--warn); --crit-ink: var(--crit);
  --info: #4f9bef; --info-bg: #0f2244;
  --brand: #4f9bef;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 16px rgba(0, 0, 0, .3);
  --shadow-lg: 0 18px 48px rgba(0, 0, 0, .5);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 88px; /* so an #anchor never lands under the sticky header */
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; }
svg { display: block; }

/* Base size for every inline icon. Deliberately LOW specificity so the many
   context rules below (.btn svg, .lnk svg, .card-icon svg, .checks .tick svg,
   .nav-top .caret) all still win. Its job is to be the floor: an icon that
   matches no other rule must not balloon to its natural size, which is what
   happened to the footer's external-link icon. */
.ic { width: 1em; height: 1em; flex: none; }

/* In running text an icon should sit on the baseline rather than on its own
   line, and match the text it follows. */
.ftr a .ic, p .ic, li .ic { display: inline-block; vertical-align: -.125em; margin-left: .3em; }

h1, h2, h3, h4 {
  font-family: var(--wordmark);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0 0 .5em;
  text-wrap: balance; /* stops a two-word orphan on a heading */
}

h1 { font-size: clamp(34px, 5.2vw, 56px); }
h2 { font-size: clamp(26px, 3.4vw, 38px); }
h3 { font-size: clamp(19px, 2vw, 23px); }
h4 { font-size: 17px; font-weight: 600; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }

/* WCAG 1.4.1: a link surrounded by text cannot be signaled by color alone.
   Underline it wherever it sits in running prose. Navigation lists, cards and
   anything already shaped like a control are excluded — they are not text
   blocks, and axe does not treat them as such either. */
p a:not(.btn):not(.lnk):not(.card),
li a:not(.btn):not(.lnk):not(.card),
.prose a:not(.btn):not(.lnk):not(.card),
.note a, .faq-a a, .form-note a, .field .hint a {
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.nav a, .nav-menu a, .ftr a, .docs-side a, .crumb a, .brand, .hero-trust a { text-decoration: none; }

/* One focus treatment for everything. :focus-visible so a mouse click on a
   button does not leave a ring behind, but a keyboard user always sees one. */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}

strong, b { font-weight: 650; }
code, kbd { font-family: var(--mono); font-size: .92em; }

code {
  background: var(--panel-3);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: .1em .38em;
}

hr { border: 0; border-top: 1px solid var(--line); margin: 2.4em 0; }

/* Any run of digits a reader might compare down a column. */
.num, table td, .stat-v { font-variant-numeric: tabular-nums; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: 12px; top: -60px;
  background: var(--panel); color: var(--fg);
  border: 1px solid var(--line); border-radius: var(--radius-s);
  padding: 10px 16px; z-index: 200; font-weight: 600;
  transition: top .15s ease;
}
.skip:focus { top: 12px; text-decoration: none; }

/* --------------------------------------------------------------------------
   3. Layout
   -------------------------------------------------------------------------- */

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

.wrap-narrow { max-width: 860px; }

section { position: relative; }

.sec { padding-block: var(--sec-y); }
.sec-tight { padding-block: 56px; }
.sec-alt { background: var(--panel-2); }
.sec-line { border-top: 1px solid var(--line); }

/* The deep navy band. Text on it is fixed light, independent of theme, because
   the background is fixed too — theme tokens would break contrast here. */
.sec-deep {
  background:
    radial-gradient(ellipse 90% 70% at 15% -10%, rgba(0, 191, 255, .20), transparent 60%),
    radial-gradient(ellipse 70% 60% at 92% 8%, rgba(0, 82, 220, .28), transparent 62%),
    var(--ink-navy);
  color: #eaf1fc;
}
.sec-deep h1, .sec-deep h2, .sec-deep h3 { color: #fff; }
.sec-deep .lede, .sec-deep p { color: #c3d0e8; }
.sec-deep a:not(.btn) { color: #7fd4ff; }
.sec-deep .eyebrow { color: #8ab4e8; }

.lede {
  font-size: clamp(18px, 2.1vw, 21px);
  line-height: 1.55;
  color: var(--fg-soft);
  max-width: 62ch;
}

.eyebrow {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--brand);
  margin: 0 0 14px;
}

.sec-head { max-width: 72ch; margin-bottom: 44px; }
.sec-head.center { margin-inline: auto; text-align: center; }
.sec-head.center .lede { margin-inline: auto; }

/* Prose — docs and legal pages. Capped measure, generous heading space. */
.prose { max-width: var(--measure-text); font-size: 17.5px; }
.prose > h2 { margin-top: 2em; }
.prose > h3 { margin-top: 1.7em; }
.prose > ul, .prose > ol { padding-left: 1.3em; margin: 0 0 1.2em; }
.prose li { margin-bottom: .45em; }
.prose li::marker { color: var(--fg-mute); }

/* Grids. `.cols` auto-fits, so one card in a row is centred rather than
   stranded at the left edge. */
.cols {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
/* These are used ON THEIR OWN, not alongside .cols — so they must carry
   display and gap themselves. They did not, and every .cols-2 block on the site
   rendered as a single stacked column at every width. */
.cols-2 {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}
.cols-4 {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}

.split {
  display: grid;
  gap: clamp(32px, 5vw, 68px);
  grid-template-columns: 1fr 1fr;
  align-items: center;
}
.split-wide { grid-template-columns: 1.15fr .85fr; }
@media (max-width: 860px) {
  .split, .split-wide { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   4. Header / nav
   -------------------------------------------------------------------------- */

.hdr {
  position: sticky; top: 0; z-index: 90;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(150%) blur(12px);
  border-bottom: 1px solid var(--line);
}
/* color-mix is well supported, but a browser without it must not get a
   transparent header over scrolling text. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .hdr { background: var(--bg); }
}

.hdr-in {
  display: flex; align-items: center; gap: 18px;
  height: 68px;
  max-width: var(--measure); margin-inline: auto;
  padding-inline: var(--gutter);
}

.brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.brand:hover { text-decoration: none; }
.brand-icon { width: 30px; height: 30px; border-radius: 8px; }
/* Matches the platform's own wordmark (.wm in web/portal/styles.css): Jost,
   weight 500, letter-spacing .01em, one flat color. The gradient lives in
   the icon's voice bars beside it — a second gradient here competes with it. */
.brand-name {
  font-family: var(--wordmark);
  font-size: 21px; font-weight: 500; letter-spacing: .01em;
  color: var(--fg);
}
.brand-by {
  font-size: 10px; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--fg-mute);
  margin-left: 2px; align-self: flex-end; padding-bottom: 5px;
}
@media (max-width: 600px) { .brand-by { display: none; } }

.nav { display: flex; align-items: center; gap: 2px; margin-left: auto; }

.nav a {
  display: block;
  padding: 8px 12px;
  border-radius: var(--radius-s);
  font-size: 15px; font-weight: 500;
  color: var(--fg-soft);
}
.nav a:hover { background: var(--panel-3); color: var(--fg); text-decoration: none; }
.nav a[aria-current="page"] { color: var(--fg); font-weight: 600; }

.nav-actions { display: flex; align-items: center; gap: 8px; margin-left: 10px; }

/* Dropdown. CSS-only on hover, JS-driven on click/keyboard, so it works with a
   keyboard and on touch where :hover is unreliable. */
.nav-group { position: relative; }
.nav-top {
  display: flex; align-items: center; gap: 5px;
  padding: 8px 12px; border: 0; background: none;
  border-radius: var(--radius-s);
  font: inherit; font-size: 15px; font-weight: 500;
  color: var(--fg-soft); cursor: pointer;
}
.nav-top:hover { background: var(--panel-3); color: var(--fg); }
.nav-top .caret { width: 9px; height: 9px; transition: transform .16s ease; }
.nav-top[aria-expanded="true"] .caret { transform: rotate(180deg); }

.nav-menu {
  position: absolute; top: calc(100% + 6px); left: 0;
  min-width: 268px; padding: 8px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  display: none;
}
.nav-group[data-open="true"] .nav-menu { display: block; }

/* The 6px gap between the button and the menu is OUTSIDE .nav-group's box, so
   moving the pointer down toward a menu item left the group, fired mouseleave,
   and shut the menu before it could be clicked. (Aaron, 2026-09-29.)

   This strip bridges the gap so the pointer never leaves the group. It is the
   SECOND line of defence, not the fix: MEASURED by removing each in turn, the
   load-bearing repair is the delayed close in site.js, because re-entering the
   group cancels the pending timer. Kept anyway — it costs nothing and covers a
   fast pointer exit and the case where the script has not run. */
.nav-menu::before {
  content: "";
  position: absolute;
  top: -10px; left: 0; right: 0; height: 10px;
}
.nav-menu a {
  display: block; padding: 9px 11px; border-radius: var(--radius-s);
  font-size: 15px; font-weight: 500; color: var(--fg);
}
.nav-menu a span {
  display: block; font-size: 12.5px; font-weight: 400;
  color: var(--fg-mute); margin-top: 1px; line-height: 1.4;
}

.icon-btn {
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border: 1px solid var(--line); border-radius: var(--radius-s);
  background: var(--panel); color: var(--fg-soft);
  cursor: pointer; padding: 0;
}
.icon-btn:hover { color: var(--fg); border-color: var(--fg-mute); }
.icon-btn svg { width: 17px; height: 17px; }

/* The theme toggle shows the icon for the mode it will switch TO. */
.theme-sun { display: none; }
:root[data-theme="dark"] .theme-sun { display: block; }
:root[data-theme="dark"] .theme-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-sun { display: block; }
  :root:not([data-theme="light"]) .theme-moon { display: none; }
}

.burger { display: none; }

@media (max-width: 960px) {
  .burger { display: grid; }
  .nav {
    position: fixed; inset: 68px 0 auto;
    flex-direction: column; align-items: stretch; gap: 2px;
    max-height: calc(100vh - 68px); overflow-y: auto;
    padding: 14px var(--gutter) 26px;
    background: var(--bg); border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow-lg);
    margin-left: 0;
  }
  .nav[data-mobile-open="false"] { display: none; }
  .nav a, .nav-top { padding: 12px 10px; font-size: 16px; width: 100%; }
  .nav-top { justify-content: space-between; }
  .nav-menu {
    position: static; display: block; min-width: 0;
    border: 0; box-shadow: none; padding: 0 0 6px 12px;
    background: none;
  }
  .nav-group:not([data-open="true"]) .nav-menu { display: none; }
  .nav-actions { margin: 12px 0 0; }
  .nav-actions .btn { flex: 1; justify-content: center; }
}

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px;                 /* touch target floor */
  padding: 11px 20px;
  border: 1px solid transparent; border-radius: var(--radius-s);
  font-family: var(--font); font-size: 15.5px; font-weight: 600;
  line-height: 1.2; text-align: center; cursor: pointer;
  transition: transform .12s ease, box-shadow .16s ease, background-color .16s ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn svg { width: 17px; height: 17px; flex-shrink: 0; }

.btn-primary {
  background: var(--grad); color: #fff;
  box-shadow: 0 1px 2px rgba(0, 82, 220, .28), 0 8px 22px rgba(0, 82, 220, .22);
}
.btn-primary:hover { box-shadow: 0 2px 4px rgba(0, 82, 220, .3), 0 12px 30px rgba(0, 82, 220, .3); }

.btn-ghost {
  background: var(--panel); color: var(--fg); border-color: var(--line);
}
.btn-ghost:hover { border-color: var(--fg-mute); background: var(--panel-2); }

/* On the deep navy band the neutral tokens are wrong — spell these out. */
.sec-deep .btn-ghost {
  background: rgba(255, 255, 255, .07); color: #fff;
  border-color: rgba(255, 255, 255, .28);
}
.sec-deep .btn-ghost:hover { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .5); }

.btn-lg { min-height: 52px; padding: 14px 28px; font-size: 16.5px; }
.btn-sm { min-height: 38px; padding: 8px 14px; font-size: 14px; }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.btn-row.center { justify-content: center; }

/* A text link that reads as an action. */
.lnk {
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 600; font-size: 15.5px;
}
.lnk svg { width: 15px; height: 15px; transition: transform .16s ease; }
.lnk:hover { text-decoration: none; }
.lnk:hover svg { transform: translateX(3px); }

/* --------------------------------------------------------------------------
   6. Cards, features, stats
   -------------------------------------------------------------------------- */

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px;
  box-shadow: var(--shadow);
}
.card h3 { margin-bottom: .4em; }
.card p { color: var(--fg-soft); font-size: 16px; margin-bottom: 0; }

/* A card that is a link: the whole surface is the target. */
a.card { display: block; color: inherit; transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
a.card:hover {
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
  border-color: color-mix(in srgb, var(--brand) 40%, var(--line));
}
a.card h3 { color: var(--fg); }

.card-icon {
  display: grid; place-items: center;
  width: 44px; height: 44px; margin-bottom: 18px;
  border-radius: 12px;
  background: var(--info-bg); color: var(--brand);
}
.card-icon svg { width: 22px; height: 22px; }
.sec-deep .card-icon { background: rgba(0, 191, 255, .16); color: #7fd4ff; }

/* Stat tiles — summary before detail. The value carries form, not just a
   number, so what matters reads at a glance. */
.stats { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.stat {
  padding: 22px 24px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel);
}
.stat-v {
  font-family: var(--wordmark); font-size: 34px; font-weight: 500;
  line-height: 1.05; letter-spacing: -.02em;
  background: var(--grad); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--brand);
}
.stat-k { font-size: 14px; color: var(--fg-soft); margin-top: 7px; }
.sec-deep .stat { background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .14); }
.sec-deep .stat-k { color: #c3d0e8; }

/* A checked list — the workhorse of a features page. */
.checks { list-style: none; padding: 0; margin: 0; display: grid; gap: 13px; }
.checks li {
  display: grid; grid-template-columns: 22px 1fr; gap: 12px;
  align-items: start; font-size: 16.5px; color: var(--fg-soft);
}
.checks li strong { color: var(--fg); font-weight: 600; }
.checks .tick {
  width: 22px; height: 22px; margin-top: 1px;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--ok-bg); color: var(--ok);
}
.checks .tick svg { width: 12px; height: 12px; }
.checks .tick-warn { background: var(--warn-bg); color: var(--warn-ink); }
.checks .tick-crit { background: var(--crit-bg); color: var(--crit-ink); }
.sec-deep .checks li { color: #c3d0e8; }
.sec-deep .checks li strong { color: #fff; }

/* --------------------------------------------------------------------------
   7. Pills, badges, notes
   -------------------------------------------------------------------------- */

.pill {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 13px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel);
  font-size: 13px; font-weight: 600; color: var(--fg-soft);
}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pill-ok { color: var(--ok-ink); border-color: color-mix(in srgb, var(--ok) 34%, var(--line)); background: var(--ok-bg); }
.pill-warn { color: var(--warn-ink); border-color: color-mix(in srgb, var(--warn) 34%, var(--line)); background: var(--warn-bg); }
.pill-brand { color: var(--brand); border-color: color-mix(in srgb, var(--brand) 34%, var(--line)); background: var(--info-bg); }
.sec-deep .pill {
  background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .22); color: #dbe7f8;
}

/* A short aside that must not read as body copy. Left edge carries the meaning
   as well as the color, so it survives a greyscale print. */
.note {
  padding: 15px 18px;
  border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: var(--radius-s);
  background: var(--panel-2);
  font-size: 16px; color: var(--fg-soft);
}
.note strong { color: var(--fg); }
.note-warn { border-left-color: var(--warn); background: var(--warn-bg); }
.note-ok { border-left-color: var(--ok); background: var(--ok-bg); }

/* --------------------------------------------------------------------------
   8. Pricing
   -------------------------------------------------------------------------- */

.tiers { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); align-items: start; }

.tier {
  position: relative;
  display: flex; flex-direction: column;
  padding: 28px;
  background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.tier-featured {
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand), var(--shadow-lg);
}
.tier-flag {
  position: absolute; top: -12px; left: 28px;
  padding: 4px 13px; border-radius: 999px;
  background: var(--grad); color: #fff;
  font-size: 11.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
}
.tier-name { font-family: var(--wordmark); font-size: 21px; font-weight: 500; margin: 0 0 4px; }
.tier-for { font-size: 14.5px; color: var(--fg-mute); margin: 0 0 20px; min-height: 2.9em; }
.tier-price { display: flex; align-items: baseline; gap: 6px; margin-bottom: 4px; }
.tier-amt {
  font-family: var(--wordmark); font-size: 40px; font-weight: 500;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.tier-per { font-size: 14.5px; color: var(--fg-mute); }
.tier-sub { font-size: 13.5px; color: var(--fg-mute); margin: 0 0 22px; }
.tier .checks { margin: 0 0 26px; gap: 10px; }
.tier .checks li { font-size: 15.5px; }
.tier .btn { margin-top: auto; width: 100%; }

/* A price nobody has set yet must look unset, not look like a price. */
.tier-tbd .tier-amt { color: var(--fg-mute); font-size: 30px; letter-spacing: 0; }

/* --------------------------------------------------------------------------
   9. Tables
   -------------------------------------------------------------------------- */

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-block: 8px 4px; }

table {
  width: 100%; border-collapse: collapse;
  font-size: 15.5px; text-align: left;
  min-width: 540px;
}
caption { text-align: left; font-size: 14px; color: var(--fg-mute); padding-bottom: 10px; }
th, td { padding: 13px 16px; border-bottom: 1px solid var(--line); vertical-align: top; }
thead th {
  font-size: 11.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--fg-mute); border-bottom: 1px solid var(--line);
  background: var(--panel-2); white-space: nowrap;
}
tbody tr:last-child td { border-bottom: 0; }
tbody th { font-weight: 600; color: var(--fg); }
table .yes { color: var(--ok-ink); font-weight: 600; }
table .no { color: var(--fg-mute); }

.table-card {
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--panel);
}
.table-card table { min-width: 600px; }

/* --------------------------------------------------------------------------
   10. FAQ (details/summary — no JS needed)
   -------------------------------------------------------------------------- */

.faq { display: grid; gap: 12px; max-width: 840px; }

.faq details {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); overflow: hidden;
}
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 22px; cursor: pointer;
  font-size: 17px; font-weight: 600; color: var(--fg);
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex-shrink: 0;
  width: 11px; height: 11px;
  border-right: 2px solid var(--fg-mute); border-bottom: 2px solid var(--fg-mute);
  transform: rotate(45deg) translateY(-2px);
  transition: transform .18s ease;
}
.faq details[open] summary::after { transform: rotate(225deg) translateY(-2px); }
.faq summary:hover { background: var(--panel-2); }
.faq .faq-a { padding: 0 22px 20px; color: var(--fg-soft); font-size: 16.5px; max-width: 70ch; }

/* --------------------------------------------------------------------------
   11. Forms
   -------------------------------------------------------------------------- */

.form { display: grid; gap: 18px; }
.form-row { display: grid; gap: 18px; grid-template-columns: 1fr 1fr; }
@media (max-width: 640px) { .form-row { grid-template-columns: 1fr; } }

.field { display: grid; gap: 6px; }
.field label { font-size: 14.5px; font-weight: 600; color: var(--fg); }
.field .hint { font-size: 13.5px; color: var(--fg-mute); }
.req { color: var(--crit); font-weight: 700; }

.field input, .field select, .field textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--line); border-radius: var(--radius-s);
  background: var(--panel); color: var(--fg);
  font-family: var(--font);
  font-size: 16px; /* 16px minimum stops iOS zooming on focus */
  line-height: 1.45;
}
.field textarea { resize: vertical; min-height: 128px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--brand); outline-offset: 1px; border-color: var(--brand);
}
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"], .field select[aria-invalid="true"] {
  border-color: var(--crit);
}
.field .err { font-size: 13.5px; color: var(--crit); font-weight: 600; }
.field .err:empty { display: none; }

.form-note { font-size: 14px; color: var(--fg-mute); }

/* Submission outcome. Announced by aria-live in the markup; the color is
   reinforcement, never the only signal. */
.form-out {
  padding: 14px 18px; border-radius: var(--radius-s);
  border: 1px solid var(--line); border-left: 3px solid var(--line);
  font-size: 16px;
}
.form-out:empty { display: none; }
.form-out.is-ok { background: var(--ok-bg); border-left-color: var(--ok); }
.form-out.is-err { background: var(--crit-bg); border-left-color: var(--crit); }

/* --------------------------------------------------------------------------
   12. Hero
   -------------------------------------------------------------------------- */

.hero { padding-block: clamp(64px, 9vw, 116px) clamp(64px, 8vw, 100px); overflow: hidden; }
.hero h1 { margin-bottom: 20px; }
.hero .lede { font-size: clamp(18px, 2.3vw, 22px); margin-bottom: 32px; }
.hero .btn-row { margin-bottom: 26px; }

/* The gradient-clipped phrase in a headline. -webkit-text-fill-color is what
   actually does the clipping; `color` is the fallback if it is unsupported. */
.grad-text {
  background: var(--grad-h);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--brand-cyan);
}

.hero-trust { display: flex; flex-wrap: wrap; gap: 10px 22px; font-size: 14.5px; color: #9fb2d2; }
.hero-trust span { display: inline-flex; align-items: center; gap: 7px; }
.hero-trust svg { width: 15px; height: 15px; color: #7fd4ff; flex-shrink: 0; }

/* The hero's visual: a mock call panel. Deliberately schematic — it shows the
   shape of the product without pretending to be a screenshot of a screen that
   may still change. */
.mock {
  background: rgba(10, 18, 42, .72);
  border: 1px solid rgba(255, 255, 255, .13);
  border-radius: var(--radius-l);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .42);
  padding: 20px;
  backdrop-filter: blur(6px);
}
.mock-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 18px; }
.mock-bar .d { width: 9px; height: 9px; border-radius: 50%; background: rgba(255, 255, 255, .22); }
.mock-bar .t { margin-left: 6px; font-size: 12.5px; color: #8ea4c8; font-family: var(--mono); }
.mock-row {
  display: flex; align-items: center; gap: 13px;
  padding: 13px 14px; border-radius: 12px;
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .08);
  margin-bottom: 9px;
}
.mock-row:last-child { margin-bottom: 0; }
.mock-av {
  width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--grad); color: #fff;
  font-weight: 700; font-size: 13.5px; font-family: var(--wordmark);
}
.mock-who { font-size: 15px; font-weight: 600; color: #eaf1fc; }
.mock-sub { font-size: 12.5px; color: #8ea4c8; font-variant-numeric: tabular-nums; }
.mock-tag {
  margin-left: auto; flex-shrink: 0;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
}
.mock-tag.live { background: rgba(55, 201, 141, .18); color: #6ee7b0; }
.mock-tag.enc { background: rgba(0, 191, 255, .16); color: #7fd4ff; }
.mock-tag.vm { background: rgba(224, 166, 58, .18); color: #f0c97a; }

/* Equaliser bars — the brand mark in motion. Purely decorative, so it is
   aria-hidden in the markup and stops dead under reduced-motion. */
.bars { display: flex; align-items: flex-end; gap: 3px; height: 20px; }
.bars i {
  display: block; width: 3px; border-radius: 2px;
  background: var(--grad); animation: eq 1.1s ease-in-out infinite;
}
.bars i:nth-child(1) { height: 30%; animation-delay: 0s; }
.bars i:nth-child(2) { height: 62%; animation-delay: .13s; }
.bars i:nth-child(3) { height: 100%; animation-delay: .26s; }
.bars i:nth-child(4) { height: 48%; animation-delay: .39s; }
.bars i:nth-child(5) { height: 24%; animation-delay: .52s; }
@keyframes eq {
  0%, 100% { transform: scaleY(.45); }
  50% { transform: scaleY(1); }
}
.bars i { transform-origin: bottom; }
@media (prefers-reduced-motion: reduce) { .bars i { animation: none; } }

/* --------------------------------------------------------------------------
   13. Steps / timeline
   -------------------------------------------------------------------------- */

.steps { counter-reset: step; display: grid; gap: 26px; }
.step {
  display: grid; grid-template-columns: 46px 1fr; gap: 20px;
  align-items: start;
}
.step::before {
  counter-increment: step; content: counter(step);
  display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--grad); color: #fff;
  font-family: var(--wordmark); font-size: 19px; font-weight: 600;
}
.step h3 { margin-bottom: .3em; }
.step p { color: var(--fg-soft); margin-bottom: 0; font-size: 16.5px; }
.sec-deep .step p { color: #c3d0e8; }

/* --------------------------------------------------------------------------
   14. CTA band
   -------------------------------------------------------------------------- */

.cta {
  text-align: center;
  padding: clamp(48px, 6vw, 72px) clamp(24px, 5vw, 60px);
  border-radius: var(--radius-l);
  background:
    radial-gradient(ellipse 80% 90% at 20% 0%, rgba(0, 191, 255, .22), transparent 62%),
    var(--ink-navy);
  border: 1px solid rgba(255, 255, 255, .1);
  color: #eaf1fc;
}
.cta h2 { color: #fff; }
.cta p { color: #c3d0e8; max-width: 56ch; margin-inline: auto; }
.cta .btn-row { margin-top: 28px; }
.cta .btn-ghost { background: rgba(255, 255, 255, .08); color: #fff; border-color: rgba(255, 255, 255, .3); }
.cta .btn-ghost:hover { background: rgba(255, 255, 255, .15); }

/* --------------------------------------------------------------------------
   15. Breadcrumb / page head
   -------------------------------------------------------------------------- */

.crumb { font-size: 14px; color: var(--fg-mute); padding-block: 22px 0; }
.crumb ol { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; padding: 0; margin: 0; }
.crumb li::after { content: "/"; margin-left: 8px; color: var(--line); }
.crumb li:last-child::after { content: none; }
.crumb a { color: var(--fg-soft); font-weight: 500; }
.crumb [aria-current="page"] { color: var(--fg); }

.page-head { padding-block: 34px 8px; }
.page-head h1 { margin-bottom: 14px; }

/* --------------------------------------------------------------------------
   16. Docs layout
   -------------------------------------------------------------------------- */

.docs-grid {
  display: grid; gap: 48px;
  grid-template-columns: 236px minmax(0, 1fr);
  align-items: start;
}
@media (max-width: 900px) { .docs-grid { grid-template-columns: 1fr; gap: 28px; } }

.docs-side {
  position: sticky; top: 92px;
  font-size: 15px;
}
@media (max-width: 900px) {
  .docs-side {
    position: static;
    border: 1px solid var(--line); border-radius: var(--radius);
    padding: 16px 18px; background: var(--panel);
  }
}
.docs-side .docs-side-h {
  font-family: var(--font);
  font-size: 11.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fg-mute); margin: 0 0 10px;
}
.docs-side ul { list-style: none; padding: 0; margin: 0 0 24px; display: grid; gap: 1px; }
.docs-side a {
  display: block; padding: 7px 11px; border-radius: 8px;
  color: var(--fg-soft); font-weight: 500;
}
.docs-side a:hover { background: var(--panel-3); color: var(--fg); text-decoration: none; }
.docs-side a[aria-current="page"] {
  background: var(--info-bg); color: var(--brand); font-weight: 600;
}

/* --------------------------------------------------------------------------
   17. Footer
   -------------------------------------------------------------------------- */

.ftr {
  border-top: 1px solid var(--line);
  background: var(--panel-2);
  padding-block: 56px 28px;
  margin-top: 0;
}
.ftr-grid {
  display: grid; gap: 38px;
  grid-template-columns: 1.5fr repeat(4, 1fr);
}
@media (max-width: 900px) { .ftr-grid { grid-template-columns: 1fr 1fr; gap: 30px; } }
@media (max-width: 520px) { .ftr-grid { grid-template-columns: 1fr; } }

.ftr h2 {
  font-family: var(--font);
  font-size: 11.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fg-mute); margin: 0 0 14px;
}
.ftr ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 9px; }
.ftr a { color: var(--fg-soft); font-size: 15px; }
.ftr a:hover { color: var(--brand); }
.ftr-about p { font-size: 15px; color: var(--fg-soft); max-width: 34ch; margin: 14px 0 0; }

.ftr-base {
  display: flex; flex-wrap: wrap; gap: 10px 24px; align-items: center;
  margin-top: 44px; padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: 14px; color: var(--fg-mute);
}
.ftr-base .tag { font-family: var(--wordmark); letter-spacing: .01em; }
.ftr-base .spacer { margin-left: auto; }
@media (max-width: 700px) { .ftr-base .spacer { margin-left: 0; } }

/* --------------------------------------------------------------------------
   18. Small utilities
   -------------------------------------------------------------------------- */

.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mt-s { margin-top: 12px; }
.mt-m { margin-top: 24px; }
.mt-l { margin-top: 40px; }
.mb-0 { margin-bottom: 0; }
.muted { color: var(--fg-mute); }
.soft { color: var(--fg-soft); }
.small { font-size: 14.5px; }
.nowrap { white-space: nowrap; }

@media (max-width: 700px) {
  :root { --sec-y: 60px; --gutter: 20px; }
  body { font-size: 16.5px; }
}

/* Print: drop the furniture, keep the words. */
@media print {
  .hdr, .ftr, .skip, .cta, .btn-row, .docs-side { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  a { color: #000; text-decoration: underline; }
  .sec, .sec-tight { padding-block: 12pt; }
}

/* --------------------------------------------------------------------------
   19. Photography and product screenshots

   Emitted by the {{img:...}} helper in tools/build.mjs, which supplies srcset,
   intrinsic width/height and loading="lazy" on every one. The rules here only
   decide shape and framing.
   -------------------------------------------------------------------------- */

/* A photo occupying one half of a .split. object-fit keeps the subject sane
   when the column is a different shape from the source. */
.photo {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  background: var(--panel-3);   /* holds the space while it decodes */
}

.photo-split {
  aspect-ratio: 4 / 3;
  object-fit: cover;
  box-shadow: var(--shadow);
}
.photo-tall { aspect-ratio: 3 / 4; }
.photo-square { aspect-ratio: 1 / 1; }

/* Full-width band. Deliberately not inside .wrap — it runs edge to edge, with
   the text that belongs to it sitting above or below rather than on top, so
   nothing depends on the photo's own contrast for legibility. */
.photo-band {
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
  border-radius: 0;
  display: block;
}
@media (max-width: 700px) {
  /* 21:9 becomes a letterbox slit on a phone. */
  .photo-band { aspect-ratio: 16 / 9; }
}

.band { position: relative; overflow: hidden; background: var(--ink-navy); }

/* A caption under a band, in the band's own dark field. */
.band-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 44px var(--gutter) 20px;
  background: linear-gradient(to top, rgba(11, 16, 38, .88), transparent);
  color: #eaf1fc;
  font-size: 15px;
}
.band-cap .wrap { padding-inline: 0; }
@media (max-width: 700px) { .band-cap { font-size: 13.5px; padding-bottom: 14px; } }

/* Product screenshots. Framed like a window so they read as software rather
   than as another photograph, and never cropped — a cropped UI looks broken. */
.shot {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  background: var(--panel);
}
.sec-deep .shot { border-color: rgba(255, 255, 255, .16); }

/* A screenshot shown wider than the text column, so the UI is legible. */
.shot-wide {
  max-width: 1100px;
  margin-inline: auto;
}

.shot-cap {
  margin: 12px auto 0;
  max-width: 1100px;
  font-size: 14px;
  color: var(--fg-mute);
  text-align: center;
}
.sec-deep .shot-cap { color: #8ea4c8; }

/* A photo and a caption as one unit in a column. */
figure { margin: 0; }
figure .photo, figure .shot { margin-bottom: 10px; }
figcaption { font-size: 14px; color: var(--fg-mute); line-height: 1.5; }

/* --------------------------------------------------------------------------
   20. The official lockup

   Same two SVGs the platform's sign-in pages use. The "dark" file has a
   near-white wordmark for dark surfaces; the "light" file's wordmark is the
   brand navy. Show exactly one, per theme — the same swap the consoles do.
   -------------------------------------------------------------------------- */

.brand-lockup { display: block; }
.brand-lockup:hover { text-decoration: none; }

.lockup { width: 210px; height: auto; display: block; }

/* In the header the lockup has to sit inside a 68px bar, so it is smaller than
   the footer's. Below 185px the "BY REVERIE" line stops being readable, which
   is the floor this width is chosen against. */
.hdr .lockup { width: 185px; }
@media (max-width: 420px) { .hdr .lockup { width: 158px; } }

.lockup-dark { display: none; }
.lockup-light { display: block; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .lockup-dark { display: block; }
  :root:not([data-theme="light"]) .lockup-light { display: none; }
}
:root[data-theme="dark"] .lockup-dark { display: block; }
:root[data-theme="dark"] .lockup-light { display: none; }
:root[data-theme="light"] .lockup-dark { display: none; }
:root[data-theme="light"] .lockup-light { display: block; }

/* --------------------------------------------------------------------------
   21. Hero composition

   The photograph, the gradient field and the product panel are one picture.
   The photo is a LAYER on the section rather than a cell in the grid, so it
   spans the hero's full height and has no top or bottom edge of its own. Its
   left edge feathers into the navy, and the product panel overlaps it: context
   behind, proof in front.
   -------------------------------------------------------------------------- */

.hero { position: relative; overflow-x: clip; }
@supports not (overflow-x: clip) { .hero { overflow-x: hidden; } }

.hero > .wrap { position: relative; z-index: 3; }

/* A navy scrim laid over the photo, under the copy. The mask alone dissolves
   the photo's edge but cannot guarantee contrast: at some viewport widths the
   lede ran over the brighter part of the picture and became hard to read. This
   keeps the left side solidly navy and lets the photograph emerge on the right,
   so legibility does not depend on what the photo happens to contain. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(100deg,
    var(--ink-navy) 0%,
    rgba(27, 27, 79, .94) 30%,
    rgba(27, 27, 79, .62) 45%,
    rgba(27, 27, 79, .18) 58%,
    transparent 70%);
}
@media (max-width: 860px) {
  /* Stacked, the photo is below the copy and nothing sits on it. */
  .hero::after { display: none; }
}

.hero-photo {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 62%;
  height: 100%;
  object-fit: cover;
  object-position: 58% center;   /* keeps the subject clear of the panel */
  filter: saturate(.92) brightness(.94);
  z-index: 1;

  /* Dissolve the edge that faces the copy. Both properties: Safari wants the
     prefix, and a single horizontal gradient is all that is needed now the
     photo runs the full height. */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.55) 18%, #000 42%);
  mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.55) 18%, #000 42%);
}

/* The panel sits in the grid's right-hand cell, overlapping the photo's left
   edge so the two are interleaved rather than adjacent. */
.mock-float {
  position: relative;
  z-index: 3;
  margin-left: -58px;
  background: rgba(9, 14, 34, .78);
  backdrop-filter: blur(16px) saturate(150%);
  border-color: rgba(255, 255, 255, .16);
  box-shadow: 0 26px 64px rgba(0, 0, 0, .5);
}

@media (max-width: 1100px) {
  .hero-photo { width: 56%; }
  .mock-float { margin-left: -24px; }
}

/* Stacked. The photo becomes an ordinary band BELOW the copy — flex order puts
   it after .wrap without moving it in the markup, where it has to come first to
   be the layer. */
@media (max-width: 860px) {
  .hero { display: flex; flex-direction: column; padding-bottom: 0; }
  .hero > .wrap { order: 1; }
  .hero-photo {
    order: 2;
    position: static;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 10;
    margin-top: 30px;
    object-position: center;
    -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 14%);
    mask-image: linear-gradient(to top, transparent 0%, #000 14%);
  }
  .mock-float { margin-left: 0; }
}
