/* ==========================================================================
   SpyPublic — landing page styles
   Brand: navy #0e192d, blue #0c59c8 (sampled from public/logo.svg)

   THEMING
   Light is the default and lives on bare :root. Dark is a single override
   block keyed to prefers-color-scheme. Every colour in the sheet resolves
   through a token — the only literal colours below are inside the two blocks
   that stay dark in both themes (the closing CTA band and the footer), which
   are deliberate brand accents rather than themed surfaces.
   ========================================================================== */

:root {
  /* The page body is white in BOTH themes (dark only re-skins the navy chrome),
     so the UA keeps light scrollbars either way. This does not affect the
     prefers-color-scheme query below — that reads the user's preference and is
     independent of this property. */
  color-scheme: light;

  /* ---- invariant brand ------------------------------------------------- */
  --brand-navy: #0e192d;
  --brand-blue: #0c59c8;
  --brand-green: #0a7a43;
  --brand-green-hover: #0d8f4f;

  /* ---- LIGHT THEME ----------------------------------------------------- */
  /* surfaces */
  --bg: #ffffff;
  --bg-soft: #f6f8fc;
  --card: #ffffff;
  --card-line: #e3e9f3;
  --card-line-hover: #cfdcf3;
  --line: #e3e9f3;
  --line-soft: #eef1f7;

  /* text */
  --text: #0e192d;
  --text-body: #40506b;
  --text-muted: #5d6b84;

  /* accent */
  --accent: #0c59c8;
  --accent-hover: #1a6ce0;
  --accent-chip: #eef4fe;
  --accent-on: #ffffff;
  --focus-ring: rgba(12, 89, 200, .16);
  --hl-from: #0c59c8;
  --hl-to: #4a8ff5;

  /* header */
  --header-bg: #ffffff;
  --header-bg-stuck: rgba(255, 255, 255, .88);
  --header-line: #e8edf6;
  --header-link: #40506b;
  --header-link-hover: #0e192d;
  --header-link-bg: #f1f5fb;
  --header-shadow: 0 8px 30px rgba(14, 25, 45, .09);

  /* hero */
  --hero-bg:
    radial-gradient(900px 520px at 82% 6%, rgba(12, 89, 200, .11), transparent 62%),
    radial-gradient(700px 460px at 6% 96%, rgba(12, 89, 200, .07), transparent 60%),
    linear-gradient(180deg, #fbfcfe 0%, #ecf2fc 100%);
  --hero-grid: rgba(14, 25, 45, .05);
  --hero-glow: rgba(63, 139, 245, .16);
  --pill-line: #d3e0f6;

  /* product mock */
  --mock-bg: #ffffff;
  --mock-line: #e3e9f3;
  --mock-shadow: 0 10px 24px rgba(14, 25, 45, .08), 0 30px 70px rgba(14, 25, 45, .12);
  --mock-chrome: #f6f8fc;
  --mock-chrome-line: #e8edf6;
  --mock-dot: #d6deec;
  --mock-input-bg: #ffffff;
  --mock-input-line: #dbe4f2;
  --mock-card-bg: #fbfcfe;
  --mock-card-line: #e8edf6;
  --mock-divider: #e3e9f3;
  --mock-text: #0e192d;
  --mock-sub: #5d6b84;
  --mock-label: #5d6b84;   /* 5.2:1 on --mock-card-bg; the labels are 11px so need 4.5 */
  --mock-tag-bg: #f1f5fb;
  --mock-tag-line: #e0e8f5;

  /* pricing */
  --price-section-bg: #f6f8fc;
  --price-card-bg: #ffffff;
  --price-card-line: #dde6f4;
  --price-card-shadow: 0 8px 24px rgba(14, 25, 45, .08), 0 28px 60px rgba(14, 25, 45, .10);
  --price-aside-bg: #ffffff;
  --price-aside-line: #e3e9f3;
  --chip-bg: #f1f5fb;
  --chip-line: #dde6f4;
  --chip-text: #40506b;

  /* buttons */
  --outline-text: #0e192d;
  --outline-line: rgba(14, 25, 45, .2);
  --outline-bg: rgba(14, 25, 45, .02);
  --outline-line-hover: rgba(14, 25, 45, .38);
  --outline-bg-hover: rgba(14, 25, 45, .05);

  /* icons drawn as background images need a colour baked in */
  --tick-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230c59c8' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5L20 6.5'/%3E%3C/svg%3E");
  --chevron-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230c59c8' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");

  /* elevation */
  --shadow-sm: 0 1px 2px rgba(14, 25, 45, .06), 0 2px 8px rgba(14, 25, 45, .04);
  --shadow-md: 0 4px 12px rgba(14, 25, 45, .07), 0 12px 32px rgba(14, 25, 45, .07);

  /* type */
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;

  /* rhythm */
  --wrap: 1140px;
  --gutter: 24px;
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ---- DARK THEME ---------------------------------------------------------
   Dark restores the original alternating design: navy chrome (header, hero,
   strip, pricing) against bluish-white content sections, plus the navy CTA
   and footer that are dark in both themes.

   So the light content surfaces on :root above are NOT overridden here — the
   how-it-works / features / why / faq bands stay #ffffff and #f6f8fc. Only
   the four navy regions change, and because custom properties inherit, the
   shared text/accent/line tokens are re-pointed on those four elements (see
   the scoped block below) rather than on :root. That keeps every rule in the
   sheet unchanged: a section is light or dark purely by which tokens reach it.
   ------------------------------------------------------------------------ */
@media (prefers-color-scheme: dark) {
  :root {
    /* Tokens below are only ever consumed inside the navy regions, so
       they are safe to set globally. */
    --hl-from: #3f8bf5;
    --hl-to: #9fc7ff;

    --header-bg: #0e192d;
    --header-bg-stuck: rgba(14, 25, 45, .9);
    --header-line: rgba(255, 255, 255, .08);
    --header-link: #c6d2e6;
    --header-link-hover: #ffffff;
    --header-link-bg: rgba(255, 255, 255, .08);
    --header-shadow: 0 8px 30px rgba(4, 9, 20, .45);

    --hero-bg:
      radial-gradient(900px 520px at 82% 8%, rgba(12, 89, 200, .32), transparent 62%),
      radial-gradient(700px 460px at 6% 96%, rgba(12, 89, 200, .16), transparent 60%),
      linear-gradient(180deg, #0e192d 0%, #080f1d 100%);
    --hero-grid: rgba(255, 255, 255, .05);
    --hero-glow: rgba(63, 139, 245, .3);
    --pill-line: rgba(255, 255, 255, .16);

    --mock-bg: #101c31;
    --mock-line: rgba(255, 255, 255, .12);
    --mock-shadow: 0 30px 70px rgba(4, 9, 20, .6);
    --mock-chrome: rgba(8, 15, 29, .6);
    --mock-chrome-line: rgba(255, 255, 255, .09);
    --mock-dot: rgba(255, 255, 255, .2);
    --mock-input-bg: rgba(255, 255, 255, .06);
    --mock-input-line: rgba(255, 255, 255, .14);
    --mock-card-bg: rgba(8, 15, 29, .45);
    --mock-card-line: rgba(255, 255, 255, .11);
    --mock-divider: rgba(255, 255, 255, .12);
    --mock-text: #eaf1fb;
    --mock-sub: #8ea1be;
    --mock-label: #8093b1;
    --mock-tag-bg: rgba(255, 255, 255, .04);
    --mock-tag-line: rgba(255, 255, 255, .12);

    /* the blue wash off the top edge sets pricing apart as its own block */
    --price-section-bg:
      radial-gradient(720px 420px at 50% -10%, rgba(12, 89, 200, .26), transparent 65%),
      #080f1d;
    --price-card-bg: #1a2a47;
    --price-card-line: rgba(255, 255, 255, .13);
    --price-card-shadow: 0 24px 60px rgba(4, 9, 20, .5);
    --price-aside-bg: rgba(8, 15, 29, .5);
    --price-aside-line: rgba(255, 255, 255, .1);
  }

  /* The navy regions. These tokens are shared with the light content
     sections, so they are re-pointed here rather than on :root — inheritance
     carries them to every descendant, and nothing outside these regions sees
     the dark values. */
  .site-header,
  .hero,
  .strip,
  .section-pricing,
  .welcome {
    --text: #f1f5fc;
    --text-body: #b7c5db;
    --text-muted: #93a6c3;

    /* brand blue lacks contrast on navy at body sizes, so lift it */
    --accent: #5b9bf8;
    --accent-chip: rgba(63, 139, 245, .15);
    --focus-ring: rgba(91, 155, 248, .26);

    --line: rgba(255, 255, 255, .11);
    --line-soft: rgba(255, 255, 255, .08);
    --bg-soft: #080f1d;                    /* the strip's own fill */

    --chip-bg: rgba(255, 255, 255, .05);
    --chip-line: rgba(255, 255, 255, .14);
    --chip-text: #cfdcf1;

    --outline-text: #eaf0fa;
    --outline-line: rgba(255, 255, 255, .26);
    --outline-bg: rgba(255, 255, 255, .04);
    --outline-line-hover: rgba(255, 255, 255, .5);
    --outline-bg-hover: rgba(255, 255, 255, .1);

    --tick-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b9bf8' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5L20 6.5'/%3E%3C/svg%3E");
  }
}

/* ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

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

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

h1, h2, h3, h4 {
  margin: 0;
  color: var(--text);
  font-weight: 700;
  letter-spacing: -.022em;
  line-height: 1.12;
}
p { margin: 0; }
a { color: var(--accent); text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--brand-navy);
  color: #fff;
  padding: 12px 18px;
  border-radius: 0 0 var(--r-sm) 0;
}
.skip-link:focus { left: 0; }

/* visually hidden, still announced */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------- buttons -- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 20px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.01em;
  white-space: nowrap;
  cursor: pointer;
  transition: transform .18s var(--ease), background-color .18s var(--ease),
              box-shadow .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--brand-blue);
  color: var(--accent-on);
  box-shadow: 0 1px 2px rgba(12, 89, 200, .28), 0 8px 20px rgba(12, 89, 200, .26);
}
.btn-primary:hover {
  background: var(--accent-hover);
  box-shadow: 0 2px 4px rgba(12, 89, 200, .3), 0 14px 30px rgba(12, 89, 200, .34);
}

/* Sign-up CTA: green so it reads apart from the blue Log in button */
.btn-success {
  background: var(--brand-green);
  color: var(--accent-on);
  box-shadow: 0 1px 2px rgba(10, 122, 67, .28), 0 8px 20px rgba(10, 122, 67, .26);
}
.btn-success:hover {
  background: var(--brand-green-hover);
  box-shadow: 0 2px 4px rgba(10, 122, 67, .3), 0 14px 30px rgba(10, 122, 67, .34);
}

.btn-ghost { color: var(--header-link); }
.btn-ghost:hover { color: var(--header-link-hover); background: var(--header-link-bg); }

.btn-outline {
  color: var(--outline-text);
  border-color: var(--outline-line);
  background: var(--outline-bg);
}
.btn-outline:hover {
  border-color: var(--outline-line-hover);
  background: var(--outline-bg-hover);
}

.btn-lg { padding: 15px 30px; font-size: 16.5px; }
.btn-block { width: 100%; }

/* ---------------------------------------------------------------- header -- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--header-bg);
  border-bottom: 1px solid var(--header-line);
  transition: box-shadow .25s var(--ease), background-color .25s var(--ease);
}
.site-header.is-stuck {
  background: var(--header-bg-stuck);
  backdrop-filter: saturate(160%) blur(12px);
  box-shadow: var(--header-shadow);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  min-height: 72px;
}

/* The supplied logo is a square stacked lockup, too tall for a nav bar. The header
   uses logo-mark*.svg (viewBox cropped to the mascot) beside an HTML wordmark; the
   full lockup is kept for the footer. <picture> swaps the navy/white artwork by
   colour scheme so only the matching file is fetched. */
.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  flex: 0 0 auto;
  transition: opacity .18s var(--ease);
}
.brand:hover { opacity: .84; }
.brand-mark { width: auto; height: 40px; }
.brand-name {
  color: var(--text);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -.035em;
}
.brand-name span { color: var(--accent); }

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-inline: auto;
}
.nav-links a {
  position: relative;
  padding: 8px 14px;
  border-radius: 999px;
  color: var(--header-link);
  font-size: 15px;
  font-weight: 500;
  transition: color .18s var(--ease), background-color .18s var(--ease);
}
.nav-links a:hover { color: var(--header-link-hover); background: var(--header-link-bg); }
/* Log in lives in the header on desktop, inside the drawer on mobile */
.nav-login { display: none; }

.header-actions { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }

.nav-toggle {
  display: none;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--outline-line);
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 18px;
  height: 1.5px;
  margin: 3.5px auto;
  background: var(--text);
  border-radius: 2px;
  transition: transform .22s var(--ease), opacity .18s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* ------------------------------------------------------------------ hero -- */
/* No overflow:hidden here on purpose — it used to clip the address suggestion
   dropdown at the section edge (1px at 1280x720, 4px of headroom at 1440x900).
   The overflowing glow is clipped by .hero-decor instead, which also stops the
   result panel's shadow being sliced off at the hero boundary. */
.hero {
  position: relative;
  background: var(--hero-bg);
  padding: clamp(56px, 8vw, 104px) 0 clamp(72px, 9vw, 120px);
}
.hero-decor {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.hero::after {
  /* faint grid, like a plat map */
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--hero-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--hero-grid) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(1000px 640px at 50% 20%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(1000px 640px at 50% 20%, #000 30%, transparent 78%);
  pointer-events: none;
}
.hero-glow {
  position: absolute;
  top: -140px; right: -120px;
  display: block;
  width: 620px; height: 620px;
  background: radial-gradient(circle, var(--hero-glow), transparent 66%);
  filter: blur(20px);
}

/* ---------------------------------------------------- hero: two layouts ----
   Idle is a single centred column with the result panel hidden. Submitting a
   search adds .is-split, which opens the second column and moves the copy left.
   JS animates the copy between the two positions (a FLIP in main.js), so the
   layout change reads as one movement rather than a jump.

   The copy keeps the same max-width in both states on purpose: only its
   position changes, so nothing inside it re-wraps mid-animation. */
.hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(32px, 4vw, 56px);
  align-items: center;
  align-content: center;
  justify-items: center;
}
.hero-copy { width: 100%; max-width: 520px; text-align: center; }

.hero-inner:not(.is-split) .hero-mock { display: none; }

.hero-inner.is-split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  justify-items: stretch;
}
.hero-inner.is-split .hero-copy { text-align: left; }

/* "Reverse Property Search" must hold ONE line in both hero layouts.
   Measured cost: 10.647px of width per 1px of font-size. The tightest container
   is the split layout's left column (513px at 1440px wide → 48px max), so the
   sizes below sit ~10% under the limit at every viewport. That margin matters:
   the type is the system UI stack, so glyph widths differ by platform (Segoe UI
   vs SF Pro etc.) and an exact fit here would wrap on someone else's machine.
   No white-space:nowrap on purpose — if it ever doesn't fit, wrapping is a far
   better failure than overflowing the page. */
.hero h1 {
  font-size: clamp(22px, 7.2vw, 44px);
  letter-spacing: -.034em;
  line-height: 1.06;
}
/* centred layout: the capped children need auto margins to actually centre */
.hero-inner:not(.is-split) .hero-copy > * { margin-inline: auto; }
.hero h1 .hl {
  background: linear-gradient(100deg, var(--hl-from), var(--hl-to));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.lede {
  max-width: 46ch;
  margin-top: 22px;
  color: var(--text-body);
  font-size: clamp(16.5px, 1.5vw, 19px);
  line-height: 1.62;
}
.lede-sm { font-size: 17px; max-width: 44ch; }

.hero-note { margin-top: 18px; color: var(--text-muted); font-size: 14px; }

/* --------------------------------------------------------- hero search --- */
/* Reuses the --mock-input-* tokens, so the field is a white pill on the light
   hero and a translucent one on the navy hero without extra tokens. */
.hero-search {
  display: flex;
  gap: 10px;
  max-width: 550px;
  margin-top: 30px;
}
.search-field {
  position: relative;                /* anchors the suggestion list */
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  padding: 0 18px;
  border: 1px solid var(--mock-input-line);
  border-radius: 999px;
  background: var(--mock-input-bg);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.search-field:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--focus-ring);
}
.search-field > svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
}
.search-field input {
  flex: 1;
  min-width: 0;
  padding: 15px 0;
  border: 0;
  background: none;
  color: var(--mock-text);
  font: inherit;
  font-size: 16px;
  appearance: none;
  -webkit-appearance: none;
}
/* the wrapper carries the focus ring instead, via :focus-within above */
.search-field input:focus { outline: none; }
.search-field input::placeholder { color: var(--mock-label); opacity: 1; }
.search-field input::-webkit-search-decoration,
.search-field input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ---------------------------------------------- address suggestions ------- */
/* max-height matters: .hero clips overflow, so an unbounded list would be cut
   off at the section edge on short viewports. It scrolls instead. */
.suggestions {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  z-index: 20;
  max-height: min(272px, 38vh);
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--mock-line);
  border-radius: var(--r-md);
  background: var(--mock-bg);
  box-shadow: var(--shadow-md);
  overscroll-behavior: contain;
}
.suggestions[hidden] { display: none; }

.suggestions li {
  display: grid;
  gap: 1px;
  padding: 9px 12px;
  border-radius: 9px;
  cursor: pointer;
}
.suggestions li[aria-selected="true"] { background: var(--accent-chip); }
.suggestions li:hover { background: var(--accent-chip); }

.s-name {
  color: var(--mock-text);
  font-size: 14.5px;
  font-weight: 550;
  letter-spacing: -.01em;
}
.s-ctx {
  color: var(--mock-sub);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ------------------------------------------------------------ hero mock -- */
/* Above the fold, so it animates in on load rather than waiting for a scroll. */
.hero-mock {
  position: relative;
  animation: mockIn .85s var(--ease) .1s both;
}
@keyframes mockIn {
  from { opacity: 0; transform: translateY(22px) }
  to { opacity: 1; transform: none }
}

.mock {
  border: 1px solid var(--mock-line);
  border-radius: var(--r-lg);
  background: var(--mock-bg);
  box-shadow: var(--mock-shadow);
  overflow: hidden;
}

.mock-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 12px 14px;
  background: var(--mock-chrome);
  border-bottom: 1px solid var(--mock-chrome-line);
}
.mock-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--mock-dot);
  flex: 0 0 auto;
}
.mock-crumb {
  min-width: 0;
  margin-left: 8px;
  overflow: hidden;
  color: var(--mock-sub);
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mock-crumb strong { color: var(--mock-text); font-weight: 600; }

.mock-body { position: relative; padding: 16px; }

/* ------------------------------------------------------- panel states ----
   idle (panel hidden entirely by .hero-inner:not(.is-split)), loading, result.

   Loading keeps the result's box via visibility:hidden and overlays itself on
   top. That pins the panel to the result's height at every viewport, so nothing
   moves once a search runs — a min-height guess shifted the panel 182px
   whenever the field grid reflowed. visibility also takes the hidden result out
   of the a11y tree and stops the Reveal link being focusable before there is a
   result. */
[data-state="idle"] .mock-result,
[data-state="loading"] .mock-result { visibility: hidden; }

[data-state="idle"] .mock-loading,
[data-state="result"] .mock-loading { display: none; }

.mock-loading {
  position: absolute;
  inset: 16px;
  display: grid;
  gap: 16px;
  place-content: center;
  place-items: center;
  text-align: center;
}
.mock-loading p { color: var(--mock-sub); font-size: 13.5px; }
.spinner {
  width: 30px;
  height: 30px;
  border: 2.5px solid var(--mock-divider);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg) } }

.skel-rows { display: grid; gap: 10px; width: 100%; max-width: 300px; }
.skel {
  height: 10px;
  border-radius: 999px;
  background:
    linear-gradient(90deg, var(--mock-divider) 25%, var(--mock-tag-bg) 37%, var(--mock-divider) 63%)
    0 0 / 400% 100%;
  animation: shimmer 1.5s ease-in-out infinite;
}
.skel:nth-child(2) { width: 84% }
.skel:nth-child(3) { width: 62% }
.skel:nth-child(4) { width: 73% }
@keyframes shimmer { from { background-position: 100% 0 } to { background-position: 0 0 } }

.mock-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.mock-head {
  margin-bottom: 12px;
  color: var(--mock-sub);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.mock-head .tag {
  padding: 3px 9px;
  border: 1px solid var(--mock-tag-line);
  border-radius: 999px;
  background: var(--mock-tag-bg);
  font-size: 11.5px;
}

.mock-card {
  padding: 16px;
  border: 1px solid var(--mock-card-line);
  border-radius: var(--r-md);
  background: var(--mock-card-bg);
}
/* single-line now that the beds/baths line is gone, so centre against the pill */
.mock-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 14px;
  border-bottom: 1px dashed var(--mock-divider);
}
.mock-card .addr {
  color: var(--mock-text);
  font-size: 16.5px;
  font-weight: 650;
  letter-spacing: -.015em;
}

.pill {
  padding: 4px 11px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  white-space: nowrap;
}
.pill-blue { background: var(--accent-chip); color: var(--accent); border: 1px solid var(--pill-line); }
.pill-light { background: var(--chip-bg); color: var(--chip-text); border: 1px solid var(--chip-line); }

.mock-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 18px;
  padding: 16px 0;
}
.field { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.field .label {
  color: var(--mock-label);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.field .value {
  color: var(--mock-text);
  font-size: 14.5px;
  font-weight: 550;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Withheld values. Stays blurred — the reveal is the signup, not an animation,
   so this is deliberately not disabled under prefers-reduced-motion.
   overflow is unclipped because .field .value hides overflow, which would chop
   the blur bleed into a hard edge. */
.locked {
  overflow: visible;
  filter: blur(5.5px);
  opacity: .62;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
}

.mock-foot {
  display: grid;
  gap: 11px;
  padding-top: 16px;
  border-top: 1px dashed var(--mock-divider);
}
.reveal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 13px 22px;
  border-radius: 999px;
  background: var(--brand-blue);
  color: var(--accent-on);
  font-size: 15.5px;
  font-weight: 650;
  letter-spacing: -.01em;
  box-shadow: 0 2px 6px rgba(12, 89, 200, .3), 0 10px 24px rgba(12, 89, 200, .28);
  transition: background-color .18s var(--ease), box-shadow .18s var(--ease),
              transform .18s var(--ease);
}
.reveal:hover {
  background: var(--accent-hover);
  box-shadow: 0 3px 8px rgba(12, 89, 200, .34), 0 16px 32px rgba(12, 89, 200, .34);
}
.reveal:active { transform: translateY(1px); }
.reveal svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linejoin: round;
}
.reveal-note { color: var(--mock-label); font-size: 12px; text-align: center; }

.mock-caption {
  margin-top: 12px;
  color: var(--text-muted);
  font-size: 12px;
  text-align: center;
}

/* ----------------------------------------------------------------- strip -- */
.strip { background: var(--bg-soft); border-block: 1px solid var(--line-soft); }
.strip-inner {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
  padding-block: 30px;
}
.strip-item { display: flex; flex-direction: column; gap: 3px; }
.strip-item strong {
  color: var(--text);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.02em;
}
.strip-item span { color: var(--text-muted); font-size: 13.5px; line-height: 1.45; }

/* -------------------------------------------------------------- sections -- */
.section { padding: clamp(64px, 8.5vw, 110px) 0; }
.section-soft { background: var(--bg-soft); border-block: 1px solid var(--line-soft); }

.section-head { max-width: 640px; margin: 0 auto clamp(40px, 5vw, 60px); text-align: center; }
.section-head-left { margin-inline: 0; text-align: left; }
.section-head h2 { font-size: clamp(28px, 3.6vw, 42px); letter-spacing: -.03em; }

.kicker {
  margin-bottom: 12px;
  color: var(--accent);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
}

/* ----------------------------------------------------------------- steps -- */
.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 34px);
}
.step {
  position: relative;
  padding: 30px 26px 28px;
  border: 1px solid var(--card-line);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-sm);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease),
              border-color .25s var(--ease);
}
.step:hover {
  transform: translateY(-3px);
  border-color: var(--card-line-hover);
  box-shadow: var(--shadow-md);
}
/* connector line between steps */
.steps .step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: calc(-1 * clamp(20px, 3vw, 34px));
  width: clamp(20px, 3vw, 34px);
  height: 1px;
  background: linear-gradient(90deg, var(--card-line), transparent);
}
.step-num {
  position: absolute;
  top: -14px;
  left: 26px;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--brand-blue);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  box-shadow: 0 4px 12px rgba(12, 89, 200, .34);
}
.step-icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 18px;
  border-radius: 12px;
  background: var(--accent-chip);
}
.step-icon svg, .card-icon svg {
  width: 22px; height: 22px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.step h3, .card h3 { margin-bottom: 8px; font-size: 20px; letter-spacing: -.02em; }
.step p, .card p { color: var(--text-muted); font-size: 15.5px; line-height: 1.58; }

/* ----------------------------------------------------------------- cards -- */
.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 2.2vw, 26px);
}
.card {
  padding: 28px 26px;
  border: 1px solid var(--card-line);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-sm);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease),
              border-color .25s var(--ease);
}
.card:hover {
  transform: translateY(-3px);
  border-color: var(--card-line-hover);
  box-shadow: var(--shadow-md);
}
.card-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: 18px;
  border-radius: 12px;
  background: var(--accent-chip);
}

/* ------------------------------------------------------------------- why -- */
.why-inner {
  display: grid;
  grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
  gap: clamp(36px, 6vw, 76px);
  align-items: start;
}
.why-copy h2 { font-size: clamp(28px, 3.4vw, 40px); }
.why-copy .btn { margin-top: 26px; }

.why-list { display: grid; gap: 14px; }
.why-list li {
  display: flex;
  gap: 16px;
  padding: 22px 24px;
  border: 1px solid var(--card-line);
  border-radius: var(--r-md);
  background: var(--bg-soft);
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.why-list li:hover { border-color: var(--card-line-hover); background: var(--card); }
.why-list h3 { margin-bottom: 6px; font-size: 17.5px; letter-spacing: -.018em; }
.why-list p { color: var(--text-muted); font-size: 15.5px; line-height: 1.56; }
.check {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--brand-blue);
}
.check svg {
  width: 14px; height: 14px;
  fill: none;
  stroke: #fff;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------- pricing -- */
.section-pricing { background: var(--price-section-bg); border-block: 1px solid var(--line-soft); }

.price-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(20px, 3vw, 34px);
  align-items: start;
  max-width: 940px;
  margin-inline: auto;
}

.price-card {
  position: relative;
  padding: 34px 32px 30px;
  border: 1px solid var(--price-card-line);
  border-radius: var(--r-xl);
  background: var(--price-card-bg);
  box-shadow: var(--price-card-shadow);
}
.price-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
}
/* The price and its trial line share the right-hand side of .price-head, so
   they stack as one unit against the "Standard" pill. */
.price-block { display: grid; gap: 3px; justify-items: end; }
.price { display: flex; align-items: baseline; gap: 4px; }
.price .amount {
  color: var(--text);
  font-size: clamp(40px, 5vw, 52px);
  font-weight: 700;
  letter-spacing: -.04em;
}
.price .per { color: var(--text-muted); font-size: 16px; font-weight: 500; }
.price-trial { color: var(--text-muted); font-size: 13.5px; }

.price-list { display: grid; gap: 13px; padding: 24px 0 28px; }
.price-list li {
  position: relative;
  padding-left: 30px;
  color: var(--text-body);
  font-size: 16px;
  line-height: 1.5;
}
.price-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .32em;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent-chip) var(--tick-url) center / 11px 11px no-repeat;
}
.price-fine { margin-top: 16px; color: var(--text-muted); font-size: 13.5px; text-align: center; }

.price-aside {
  padding: 30px 28px;
  border: 1px solid var(--price-aside-line);
  border-radius: var(--r-lg);
  background: var(--price-aside-bg);
}
.price-aside h3 { margin-bottom: 10px; font-size: 19px; }
.price-aside p { color: var(--text-muted); font-size: 15.5px; line-height: 1.58; }
.addons { display: flex; flex-wrap: wrap; gap: 8px; margin: 20px 0 22px; }
.addons li {
  padding: 6px 12px;
  border: 1px solid var(--chip-line);
  border-radius: 999px;
  background: var(--chip-bg);
  color: var(--chip-text);
  font-size: 13px;
  font-weight: 500;
}
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--accent);
  font-size: 15px;
  font-weight: 600;
}
.link-arrow span { transition: transform .2s var(--ease); }
.link-arrow:hover span { transform: translateX(4px); }

/* ------------------------------------------------------------------- faq -- */
.faq-wrap {
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(32px, 5vw, 70px);
  align-items: start;
}
.faq-wrap .section-head { margin-bottom: 0; }

.faq { display: grid; gap: 0; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 20px 4px;
  cursor: pointer;
  color: var(--text);
  font-size: 17.5px;
  font-weight: 600;
  letter-spacing: -.015em;
  list-style: none;
  transition: color .18s var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary::after {
  content: "";
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent-chip) var(--chevron-url) center / 12px 12px no-repeat;
  transition: transform .25s var(--ease);
}
.faq details[open] summary { color: var(--accent); }
.faq details[open] summary::after { transform: rotate(180deg); }
.faq-body { padding: 0 44px 22px 4px; }
.faq-body p { color: var(--text-muted); font-size: 16px; line-height: 1.64; }
.faq details[open] .faq-body { animation: faqIn .28s var(--ease) both; }
@keyframes faqIn { from { opacity: 0; transform: translateY(-4px) } to { opacity: 1; transform: none } }

/* ============================================== long-form legal pages ======
   Used by privacy.html (and any future terms/about page). Content sections are
   light in both themes, so these resolve through the page tokens rather than
   the navy-region ones. */
.legal { padding: clamp(44px, 5.5vw, 76px) 0 clamp(64px, 8vw, 104px); }
.legal-inner { max-width: 760px; }

.legal-head h1 { font-size: clamp(30px, 3.8vw, 44px); letter-spacing: -.03em; }
.legal-updated { margin-top: 12px; color: var(--text-muted); font-size: 15px; }

/* clears the 72px sticky header when jumping to an anchor */
.legal section { margin-top: clamp(34px, 4vw, 50px); scroll-margin-top: 96px; }
.legal h2 {
  margin-bottom: 14px;
  font-size: clamp(19px, 2.1vw, 23px);
  letter-spacing: -.02em;
  line-height: 1.3;
}
.legal p { color: var(--text-body); font-size: 16.5px; line-height: 1.72; }
.legal p + p { margin-top: 15px; }
.legal strong { color: var(--text); font-weight: 650; }
.legal a { text-decoration: underline; text-underline-offset: 2px; }
.legal a:hover { color: var(--accent-hover); }

.legal ul { display: grid; gap: 10px; margin-top: 15px; }
.legal ul li {
  position: relative;
  padding-left: 22px;
  color: var(--text-body);
  font-size: 16.5px;
  line-height: 1.68;
}
.legal ul li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: .72em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}
.legal ul + p { margin-top: 15px; }

/* All-caps statutory blocks (warranty disclaimer, liability cap). Kept in caps for
   conspicuousness, but set a touch smaller with looser leading so a whole section of
   it stays readable. */
.legal-caps { font-size: 15.5px; line-height: 1.8; letter-spacing: .005em; }

.legal-address {
  margin-top: 4px;
  color: var(--text-body);
  font-size: 16.5px;
  font-style: normal;
  line-height: 1.72;
}
.legal-address + p { margin-top: 15px; }

/* the FCRA notice — emphasised because it governs how the Service may be used */
.legal-callout {
  padding: 20px 22px;
  border: 1px solid var(--card-line);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  background: var(--bg-soft);
}
.legal-callout p { color: var(--text); font-weight: 550; }

.legal-toc {
  margin-top: 30px;
  padding: 22px 26px;
  border: 1px solid var(--card-line);
  border-radius: var(--r-md);
  background: var(--bg-soft);
}
.legal-toc h2 {
  margin-bottom: 14px;
  color: var(--text-muted);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
}
.legal-toc ol { display: grid; gap: 9px; }
.legal-toc a {
  color: var(--text-body);
  font-size: 15.5px;
  line-height: 1.45;
  text-decoration: none;
}
.legal-toc a:hover { color: var(--accent); text-decoration: underline; }

@media (max-width: 620px) {
  .legal p, .legal ul li, .legal-address { font-size: 16px; }
  .legal-toc { padding: 18px 20px; }
}

/* ==================================================== contact page ========= */
.contact { padding: clamp(44px, 5.5vw, 76px) 0 clamp(64px, 8vw, 104px); }
.contact-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: clamp(32px, 4vw, 56px);
  align-items: start;
}
.contact-head h1 { font-size: clamp(30px, 3.8vw, 44px); letter-spacing: -.03em; }
.contact-head .lede { max-width: 42ch; }
.contact-main { min-width: 0; }

.contact-form {
  display: grid;
  gap: 20px;
  margin-top: 32px;
  padding: clamp(24px, 3vw, 32px);
  border: 1px solid var(--card-line);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--shadow-sm);
}

/* Honeypot. Off-screen rather than display:none — some bots skip hidden inputs,
   and this keeps it out of the tab order and the a11y tree either way. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-field { display: grid; gap: 7px; min-width: 0; }
.form-label { color: var(--text); font-size: 14.5px; font-weight: 650; letter-spacing: -.01em; }
.form-hint, .form-route { color: var(--text-muted); font-size: 13px; }
.form-route a { color: var(--accent); font-weight: 600; }

.form-control {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--card-line);
  border-radius: 10px;
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 16px;                 /* 16px stops iOS zooming the page on focus */
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.form-control:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--focus-ring);
}
.form-control[aria-invalid="true"] { border-color: #c8382f; }
textarea.form-control { min-height: 128px; resize: vertical; line-height: 1.6; }

/* native select chevrons vary wildly, so draw our own */
.select-wrap { position: relative; }
.select-wrap select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 44px;
  cursor: pointer;
}
.select-wrap::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 15px;
  width: 16px;
  height: 16px;
  transform: translateY(-50%);
  background: var(--chevron-url) center / 16px 16px no-repeat;
  pointer-events: none;
}

.form-error {
  margin: -4px 0 0;
  color: #c8382f;
  font-size: 14px;
  font-weight: 600;
}
.form-note, .form-sent {
  color: var(--text-muted);
  font-size: 13.5px;
  line-height: 1.6;
}
.form-sent {
  margin-top: -6px;
  padding: 13px 15px;
  border: 1px solid var(--pill-line);
  border-radius: 10px;
  background: var(--accent-chip);
  color: var(--text-body);
}

.contact-aside { display: grid; gap: 16px; margin-top: 32px; }
.contact-card {
  padding: 24px 26px;
  border: 1px solid var(--card-line);
  border-radius: var(--r-md);
  background: var(--bg-soft);
}
.contact-card h2 { margin-bottom: 10px; font-size: 16.5px; letter-spacing: -.015em; }
.contact-card p { color: var(--text-muted); font-size: 15px; line-height: 1.65; }
.contact-card a { text-decoration: underline; text-underline-offset: 2px; }

.contact-emails { display: grid; gap: 14px; }
.contact-emails li { display: grid; gap: 2px; }
.ce-label {
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.contact-emails a { font-size: 15.5px; font-weight: 600; word-break: break-word; }

@media (max-width: 860px) {
  .contact-inner { grid-template-columns: minmax(0, 1fr); }
  .contact-aside { margin-top: 4px; }
}

/* ============================================== welcome / post-checkout ====
   welcome.html -> /welcome. Hidden confirmation page: nothing on the site
   links to it and it is noindex'd, so it exists only as the redirect target
   for the post-checkout trigger. Deliberately single-purpose — confirm the
   signup, say where the credentials went, offer one way forward.

   The entrance is a plain CSS animation rather than the [data-anim] scroll
   reveal used elsewhere: that one starts at opacity 0 and needs JS to clear
   it, and on the page someone lands on straight after paying, a JS failure
   must not leave a blank screen.
   ========================================================================== */
body.page-welcome {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}
.page-welcome .welcome { flex: 1 0 auto; }
.page-welcome .header-inner { justify-content: center; }

.welcome {
  display: grid;
  place-items: center;
  padding: clamp(48px, 7vw, 92px) 0 clamp(56px, 8vw, 100px);
  background: var(--hero-bg);
}
.welcome-inner {
  max-width: 600px;
  margin-inline: auto;
  text-align: center;
  animation: welcome-rise .5s var(--ease) both;
}

.welcome-badge {
  position: relative;
  display: grid;
  place-items: center;
  width: 82px;
  height: 82px;
  margin: 0 auto 28px;
  border-radius: 50%;
  background: linear-gradient(140deg, var(--hl-from), var(--hl-to));
  box-shadow: 0 10px 28px rgba(12, 89, 200, .3);
  animation: welcome-pop .45s var(--ease) both;
}
/* Halo ring. Drawn outside the disc via inset, so it adds no layout height. */
.welcome-badge::after {
  content: '';
  position: absolute;
  inset: -11px;
  border: 1px solid var(--pill-line);
  border-radius: 50%;
}
.welcome-badge svg { width: 36px; height: 36px; }
/* 34 ≈ the tick path length, so the stroke draws itself in. Under
   prefers-reduced-motion the global block collapses the duration and the
   `forwards` fill holds the end state — the tick still ends up drawn. */
.welcome-badge path {
  stroke-dasharray: 34;
  stroke-dashoffset: 34;
  animation: welcome-tick .45s var(--ease) .3s forwards;
}

.welcome h1 { font-size: clamp(29px, 4vw, 42px); letter-spacing: -.03em; }
.welcome .lede { max-width: 46ch; margin-inline: auto; }

.welcome-note {
  margin-top: 30px;
  padding: 15px 20px;
  border: 1px solid var(--pill-line);
  border-radius: var(--r-md);
  background: var(--accent-chip);
  color: var(--text-body);
  font-size: 14.5px;
  line-height: 1.62;
}

.welcome-actions { margin-top: 28px; }

.welcome-support {
  margin-top: 32px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
  color: var(--text-muted);
  font-size: 15px;
  line-height: 1.7;
}
.welcome-support a {
  color: var(--accent);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  word-break: break-word;
}

/* Slim footer — this page skips the full navy footer, which would outweigh it. */
.welcome-foot {
  padding: 22px 0;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
.welcome-foot-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 22px;
  color: var(--text-muted);
  font-size: 13.5px;
}
.welcome-foot nav { display: flex; gap: 20px; }
.welcome-foot a { color: var(--text-muted); }
.welcome-foot a:hover { color: var(--accent); }

@keyframes welcome-rise {
  from { opacity: 0; transform: translateY(14px); }
}
@keyframes welcome-pop {
  from { opacity: 0; transform: scale(.82); }
}
@keyframes welcome-tick {
  to { stroke-dashoffset: 0; }
}

@media (max-width: 620px) {
  .welcome-foot-inner { justify-content: center; text-align: center; }
  /* Trim the block padding so the whole confirmation clears a phone viewport
     without scrolling — it overshot by ~10px at 390x844. */
  .welcome { padding: 44px 0 40px; }
}

/* ================= always-dark blocks: closing CTA + footer ================
   These two stay navy in both themes as deliberate brand accents, so their
   colours are literal rather than tokenised. */

.cta {
  position: relative;
  overflow: hidden;
  padding: clamp(64px, 8vw, 100px) 0;
  background:
    radial-gradient(760px 400px at 50% 120%, rgba(12, 89, 200, .42), transparent 65%),
    linear-gradient(180deg, #080f1d, #0e192d);
  color: #fff;
  text-align: center;
}
.cta-glow {
  position: absolute;
  left: 50%;
  bottom: -220px;
  width: 700px;
  height: 420px;
  transform: translateX(-50%);
  background: radial-gradient(circle, rgba(63, 139, 245, .32), transparent 65%);
  filter: blur(24px);
  pointer-events: none;
}
.cta-inner { position: relative; z-index: 1; }
.cta h2 { color: #fff; font-size: clamp(30px, 4.2vw, 46px); letter-spacing: -.032em; }
.cta-lede { margin-top: 14px; color: #b7c5db; font-size: 18px; }
.cta .btn { margin-top: 30px; }
.cta .btn-primary { background: #0c59c8; color: #fff; }
.cta .btn-primary:hover { background: #1a6ce0; }
.cta-fine { margin-top: 16px; color: #8fa2bf; font-size: 13.5px; }

.site-footer { background: #080f1d; color: #a9bad4; }
.footer-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: clamp(32px, 5vw, 64px);
  padding-block: clamp(44px, 6vw, 68px) 40px;
}
.footer-brand img { width: 160px; opacity: .95; }
.footer-brand p { margin-top: 14px; color: #7e91b0; font-size: 14.5px; }

.footer-cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px;
}
.footer-cols h4 {
  margin-bottom: 14px;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.footer-cols a {
  display: block;
  margin-bottom: 10px;
  color: #a9bad4;
  font-size: 15px;
  transition: color .18s var(--ease);
}
.footer-cols a:hover { color: #fff; }

.footer-bottom {
  display: grid;
  gap: 14px;
  padding-block: 24px 34px;
  border-top: 1px solid rgba(255, 255, 255, .08);
}
.footer-bottom p { color: #6f83a3; font-size: 13px; }
.disclaimer { max-width: 90ch; line-height: 1.6; }

/* ------------------------------------------------------------ animations -- */
[data-anim] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
[data-anim].in { opacity: 1; transform: none; }

/* ---------------------------------------------------------- breakpoints -- */
/* Reserve the split layout's height up front so revealing the panel doesn't
   shove the rest of the page down. Also gives the idle hero the airiness a
   centred layout wants. Desktop only — reserving this on a phone would just be
   dead space above the fold. */
@media (min-width: 981px) {
  .hero-inner { min-height: 600px; }
  /* Two columns here, so the copy is narrower than the viewport implies and the
     headline needs a shallower slope to stay on one line. */
  .hero h1 { font-size: clamp(34px, 3.8vw, 44px); }
}

@media (max-width: 980px) {
  /* Single column in both states, so the copy never moves sideways.
     minmax(0, ...) not 1fr: a bare 1fr track takes its minimum from the
     content, and .mock-crumb's nowrap address (the echoed search) reports a
     ~470px min-content contribution even with min-width:0 — min-width sets the
     shrink floor, not the intrinsic contribution. That widened the track past
     the viewport and left dead space to the right of every phone-width search. */
  .hero-inner, .hero-inner.is-split { grid-template-columns: minmax(0, 1fr); }
  .hero-copy, .hero-inner.is-split .hero-copy { max-width: 620px; }
  .why-inner, .faq-wrap { grid-template-columns: minmax(0, 1fr); }
  .price-wrap { grid-template-columns: minmax(0, 1fr); }
  .cards, .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .steps .step:not(:last-child)::after { display: none; }
  .strip-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 24px; }
}

@media (max-width: 860px) {
  .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    margin: 0;
    padding: 12px var(--gutter) 20px;
    background: var(--header-bg);
    border-bottom: 1px solid var(--header-line);
    box-shadow: var(--header-shadow);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s var(--ease), transform .2s var(--ease), visibility .2s;
  }
  .nav-links.is-open { opacity: 1; visibility: visible; transform: none; }
  .nav-links a { padding: 13px 12px; border-radius: 10px; font-size: 16px; }
  .header-actions { margin-left: auto; }
  .header-actions .btn-login { display: none; }
  .nav-login {
    display: block;
    margin-top: 6px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    border-radius: 0;
  }
  .nav-toggle { display: block; }
  .footer-top { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  .cards, .steps { grid-template-columns: minmax(0, 1fr); }
  .mock-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; }
  .strip-inner { grid-template-columns: minmax(0, 1fr); }
  .price-card { padding: 28px 22px 26px; }
  .hero-search { flex-direction: column; gap: 12px; }
  .hero-search .btn { width: 100%; }
  .footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 400px) {
  .mock-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Very narrow phones (320px). The header row — brand + Start Free + menu toggle —
   overflowed by 25px, pushing the toggle off screen. Drop the wordmark back to the
   mascot alone and tighten the gutter. */
@media (max-width: 380px) {
  :root { --gutter: 18px; }
  .header-inner { gap: 12px; }
  .brand-name { display: none; }
  .header-actions .btn { padding: 10px 16px; font-size: 14.5px; }
}

/* --------------------------------------------------------------- a11y/os -- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  [data-anim] { opacity: 1; transform: none; }
  /* .locked stays blurred on purpose — it is a paywall, not an animation. */
}

@media print {
  .site-header, .cta, .hero-glow, .cta-glow { display: none; }
  body { background: #fff; color: #000; }
}
