@charset "utf-8";
/* ═══════════════════════════════════════════════════════════════════════════
   FindAndClose — design system
   Design language transplanted from stripe.com's HDS tokens (July 2026 build):
   brand #635BFF/#533AFD, ink #0A2540, slate #425466, 4px space grid,
   6/16/24/999 radii, two-layer low-opacity shadows, pill buttons,
   coloured eyebrow + large tightly-tracked heading, dark code artefact.

   CRAFT PASS (this revision) — the page had drifted: 23 font sizes, 25
   letter-spacing values, 8 card paddings, 3 competing card materials and 16
   dead tokens sitting beside 30 hard-coded copies of their own values. Every
   one of those is now a single token, declared once, below. If you need a size
   or a tracking value that is not on these ladders, the answer is almost always
   that you need a different step, not a new value.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── tokens ─────────────────────────────────────────────────────────────── */
:root{
  /* brand ramp (stripe hds core-brand + the classic #635BFF) */
  --brand-25:#F5F5FF; --brand-50:#E8E9FF; --brand-100:#D6D9FC; --brand-200:#B9B9F9;
  --brand:#635BFF; --brand-600:#533AFD; --brand-700:#4032C8;

  /* neutrals (hds core-neutral, anchored on the classic #0A2540 / #425466)
     --slate-400 and --slate-300 were #7D8BA4 / #95A4BA: 3.44:1 and 2.53:1 on
     white. Between them they carried 21 pieces of small text — field labels,
     table headers, plan names, the copyright — every one of which failed WCAG
     AA. Now 5.39:1 and 5.00:1 on white, and both still clear 4.5:1 on
     --bg-subdued, which is where half of them actually sit. */
  --ink:#0A2540; --ink-deep:#061B31;
  --slate:#425466; --slate-500:#52617A; --slate-400:#5C6B85; --slate-300:#637087;
  --line:#E5EDF5; --line-soft:#EFF4F9; --bg-subdued:#F2F6FB;

  /* accents — every one of these is used; none is decorative-only */
  --cyan:#00A3E0; --teal:#0BB4A6;
  --green:#00B261; --green-deep:#006F3A;
  --orange:#FF6118; --lemon:#F9B900; --magenta:#F44BCC;
  /* the two ink-surface text colours (code strings, inverse links) */
  --mint:#6FE3C4; --lilac:#A8BFFF;

  /* ── TYPE SCALE — ten steps, nothing between them ─────────────────────
     px equivalents at a 16px root: 11 12 13 14 15 17 19, then three fluid
     display steps. There is no 10px step and no 16px step: 10px failed the
     small-text floor, and 16px was a redundant neighbour of both 15 and 17. */
  --fs-3xs:.6875rem;   /* 11 — uppercase micro-labels only */
  --fs-2xs:.75rem;     /* 12 — meta, mono captions */
  --fs-xs:.8125rem;    /* 13 — small UI text */
  --fs-sm:.875rem;     /* 14 — secondary body, small controls */
  --fs-md:.9375rem;    /* 15 — body + UI default */
  --fs-lg:1.0625rem;   /* 17 — lead prose, disclosure summaries */
  --fs-xl:1.1875rem;   /* 19 — card / step / utility headings */
  --fs-2xl:clamp(1.6rem,1.1rem + 1.5vw,2.25rem);      /* 26 → 36 */
  --fs-3xl:clamp(1.9rem,1.15rem + 2.1vw,2.875rem);    /* 30 → 46 */
  --fs-4xl:clamp(2.5rem,1.35rem + 3.5vw,3.75rem);     /* 40 → 60 */

  /* ── TRACKING LADDER — keyed to rendered size, loosening as size drops ──
     The ladder was previously inverted at the small end: an 18px wordmark and
     a 17px stat were tracked TIGHTER than a 60px headline. Optical tracking is
     a function of size, so it must be monotonic. It crosses zero between 13px
     and 14px, which is where Inter's own metric curve crosses it.
     Running prose carries NO tracking at all — it is set at 0 by inheritance.
     Tracking is for headings, numerals and UI labels. */
  --tr-display:-.040em; /* 47px+   */
  --tr-xl:-.032em;      /* 26–46px */
  --tr-lg:-.022em;      /* 18–25px */
  --tr-md:-.014em;      /* 16–17px */
  --tr-sm:-.008em;      /* 14–15px */
  --tr-xs:.004em;       /* 11–13px */
  /* uppercase needs positive tracking, on the same loosening curve */
  --tr-caps-lg:.045em;  /* uppercase 13–15px */
  --tr-caps:.07em;      /* uppercase 11–12px */

  /* ── elevation — stripe's two-layer recipe, verbatim ratios ─────────── */
  --sh-xs:0 1px 2px rgba(0,55,112,.06),0 1px 1px rgba(0,59,137,.04);
  --sh-sm:0 5px 14px rgba(0,55,112,.08),0 2px 8px rgba(0,59,137,.05);
  --sh-md:0 6px 22px rgba(0,55,112,.10),0 4px 8px rgba(0,59,137,.02);
  --sh-lg:0 15px 40px rgba(0,55,112,.10),0 5px 20px rgba(0,59,137,.04);
  --sh-xl:0 30px 70px rgba(0,55,112,.13),0 10px 30px rgba(0,59,137,.06);
  --sh-btn:0 2px 5px rgba(10,37,64,.10),0 1px 1px rgba(10,37,64,.06);

  /* ── ONE CARD MATERIAL ───────────────────────────────────────────────
     Three surface systems used to coexist within one scroll: shadow-only,
     flat-inset-border, and shadow-plus-hairline-ring. Every resting card now
     uses --sh-card and lifts to --sh-card-hover. --sh-xl is reserved for the
     two hero artefacts (.sbar, .rescard) and appears nowhere else, which is
     what makes them read as the front-most objects on the page.
     --ring-inset is the ONE nested material: panels inside a card. */
  --ring:0 0 0 1px rgba(10,37,64,.05);
  --sh-card:var(--sh-sm),var(--ring);
  --sh-card-hover:var(--sh-lg),var(--ring);
  --ring-inset:inset 0 0 0 1px var(--line);

  /* radii */
  --r-sm:4px; --r:6px; --r-md:10px; --r-lg:16px; --r-pill:999px;

  /* ── FOCUS — two rings, and only two ─────────────────────────────────
     Both are built on an INSET box-shadow, because an outline at a positive
     offset is drawn outside the element and any overflow:hidden ancestor
     clips it away. The outer halo is a second, non-inset layer: it is a
     bonus where there is room for it and simply invisible where there is
     not, which means the ring never depends on it to be seen.
     --ring-focus is for controls on white and near-white. --ring-focus-inv
     is for controls whose own background is --brand or --ink, where a
     brand-coloured ring is the same colour as the thing it is ringing. */
  --ring-focus:inset 0 0 0 2px var(--brand),0 0 0 3px rgba(99,91,255,.25);
  --ring-focus-inv:inset 0 0 0 2px #fff,0 0 0 3px rgba(255,255,255,.35);

  /* type faces */
  --ff:"Inter","SF Pro Text",-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  --ff-d:"Inter Tight","Inter","SF Pro Display",-apple-system,sans-serif;
  --ff-m:"Source Code Pro","SFMono-Regular",ui-monospace,Menlo,monospace;

  /* motion — two durations. .15s for controls and colour, .2s for card lift. */
  --e:cubic-bezier(.165,.84,.44,1);
  --e-io:cubic-bezier(.4,0,.2,1);
  --t:.15s var(--e-io);
  --t-card:.2s var(--e);
  /* The scroll reveal and the card hover both wanted `transform`, and the
     reveal's `.js .reveal.is-in{transform:none}` (0,3,0) outranked
     `.card:hover` (0,2,0) — so no card on this page has ever actually lifted.
     The reveal now rides the independent `translate` property, and every card
     concatenates both transitions into one declaration so neither clobbers the
     other. */
  --t-reveal:opacity .5s var(--e) var(--d,0ms),translate .5s var(--e) var(--d,0ms);
  --lift:-2px;      /* cards */
  --lift-btn:-1px;  /* buttons */

  /* ── SECTION RHYTHM — three steps, and only three ─────────────────────
     Measured gaps used to run 136/160/208/208/208/208/176/176/208: six of the
     eight boundaries were identical, so nothing in the vertical spacing told
     you whether the next section continued the argument or started a new one.
     Now: 72 = continuation, 104 = default, 144 = new chapter. Sections pay
     half a gap each, so a boundary is the sum of the two edges that meet. */
  --gap-sm:72px; --gap-md:104px; --gap-lg:144px;

  --shell:1160px;
  --gut:24px;
}

/* ── reset ──────────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:hidden}
/* No body-level letter-spacing. It was -.003em — roughly 0.05px at body size,
   below any perceptual threshold, and it silently offset every element that
   did not declare its own tracking, including all the prose. */
body{
  margin:0;background:#fff;color:var(--slate);
  font:400 var(--fs-md)/1.6 var(--ff);
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  font-variant-numeric:tabular-nums lining-nums;
}
img,svg,canvas{display:block;max-width:100%}
h1,h2,h3,h4{margin:0;color:var(--ink);font-family:var(--ff-d);font-weight:600;line-height:1.1}
p{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
button{background:none;border:0;padding:0;cursor:pointer}
table{border-collapse:collapse;width:100%}
code,pre{font-family:var(--ff-m)}

::selection{background:var(--brand-100);color:var(--ink)}

/* An outline at a positive offset is drawn OUTSIDE the element, so any
   overflow:hidden ancestor clips it away. The FAQ summaries sit flush against
   .faq{overflow:hidden}, which erased their focus ring entirely — six keyboard
   stops with no visible indicator. An inset ring cannot be clipped.
   The transparent outline is deliberate: it survives Windows High Contrast,
   where box-shadow is discarded. */
:focus-visible{
  outline:2px solid transparent;
  box-shadow:var(--ring-focus);
}
.qa summary:focus-visible{box-shadow:inset 0 0 0 2px var(--brand)}
.sbar__f:focus-within{outline:none}

.sr{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}
.skip-link{
  position:fixed;top:-120px;left:16px;z-index:999;
  background:var(--brand);color:#fff;padding:12px 20px;border-radius:var(--r);
  font-weight:600;font-size:var(--fs-sm);letter-spacing:var(--tr-sm);
  box-shadow:var(--sh-md);transition:top .2s var(--e);
}
.skip-link:focus{top:16px}

/* ── layout + section rhythm ────────────────────────────────────────────── */
.shell{width:100%;max-width:var(--shell);margin-inline:auto;padding-inline:var(--gut)}

.section{padding-block:calc(var(--gap-md) / 2)}
/* --follow / --lead knit a section to its neighbour: the two halves sum to 72
   and the pair reads as one thought. --open / --close declare a new chapter. */
.section--follow{padding-top:calc(var(--gap-sm) / 2)}
.section--lead{padding-bottom:calc(var(--gap-sm) / 2)}
.section--open{padding-top:calc(var(--gap-lg) / 2)}
.section--close{padding-bottom:calc(var(--gap-lg) / 2)}
/* retained for pages that already use it — same value as a knit pair */
.section--tight{padding-block:calc(var(--gap-sm) / 2)}
.section--subdued{background:var(--bg-subdued);border-block:1px solid var(--line-soft)}
/* two knitted subdued sections are one band, not two — otherwise their facing
   borders stack into a 2px rule at the seam */
.section--subdued + .section--subdued{border-top:0}

/* ── icons ──────────────────────────────────────────────────────────────────
   The sprite is drawn once on a 24 grid, then rendered at three sizes. A single
   stroke-width across all three does NOT give a single stroke weight, because
   the stroke scales with the box: 1.7 on a 24 grid is 1.42px at 20px, 1.13px at
   16px and 0.92px at 13px. The set therefore got visibly thinner every time it
   got smaller, and the 13px marks — which is most of them, the chevrons and
   ticks — were painting under a physical pixel and turning grey.
   Each size now carries the stroke-width that renders 1.5px of ink:
       20px × 1.80/24 = 1.50   16px × 2.25/24 = 1.50   13px × 2.70/24 = 1.46
   One weight, one grid, one set. */
.ico{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.ico--sm{width:16px;height:16px;stroke-width:2.25}
.ico--xs{width:13px;height:13px;stroke-width:2.7}

/* ── reveal ─────────────────────────────────────────────────────────────── */
/* Scoped to .js so the page is fully visible when JavaScript never runs. */
.js .reveal{opacity:0;translate:0 14px}
.js .reveal.is-in{opacity:1;translate:0 0}
.js :where(.reveal){transition:var(--t-reveal)}

/* ── eyebrow + section head ─────────────────────────────────────────────── */
.eyebrow{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--ff);font-size:var(--fs-xs);font-weight:600;
  letter-spacing:var(--tr-caps-lg);text-transform:uppercase;
  color:var(--brand-600);
}
.eyebrow::before{
  content:"";width:16px;height:2px;border-radius:2px;
  background:currentColor;opacity:.55;
}
.eyebrow--cyan{color:#00699E}   /* was #0086C9 — 3.78:1 on subdued, failed at 13px */
.eyebrow--teal{color:#0A7A72}   /* was #0A8F86 — 3.76:1 */
.eyebrow--orange{color:#C24000}
.eyebrow--lemon{color:#9B6829}
.eyebrow--inv{color:var(--brand-200)}

.shead{max-width:760px;margin-bottom:56px}
.shead h2{
  margin-top:18px;
  font-size:var(--fs-3xl);
  letter-spacing:var(--tr-xl);line-height:1.08;text-wrap:balance;
}
/* 63ch rendered as ~79 characters, because ch is the width of a zero and Inter's
   zero is wider than its average lowercase glyph. 52ch measures ~65. */
.shead p{
  margin-top:20px;max-width:52ch;
  font-size:var(--fs-lg);line-height:1.62;color:var(--slate);text-wrap:pretty;
}
.shead--sm{margin-bottom:40px}
.shead--sm h2{font-size:var(--fs-2xl)}

.grad{
  background:linear-gradient(94deg,var(--brand) 0%,#5A6BFF 34%,var(--cyan) 68%,var(--teal) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* ── --ff-d IS A DISPLAY FACE ────────────────────────────────────────────────
   Inter Tight is Inter with tighter sidebearings and slightly narrower
   counters. That difference is worth having at 40px, where the extra tracking
   in Inter opens a headline up and softens it. It is worth nothing at 19px: set
   the same string in both at 19px and the widths differ by about 2%, which is
   under a pixel per word. The token comment has always said "≥24px only"; the
   stylesheet did not honour it, and eleven selectors were calling a second
   family for text between 14 and 19px.
   Every sub-24px user moved to --ff. Two consequences: Inter Tight 700 lost its
   last two users and left the font request entirely, and the type on this page
   is now one family below 24px and one above it, which is a rule you can hold
   in your head. The one thing that did NOT move is any font-size, weight or
   tracking — this is a family swap and nothing else.
   Six of them had a dead `font-family:var(--ff-d)` deleted at source and now
   simply inherit --ff: .brand__word, .tick__who, .statline b, .filters__count,
   .quote__av, .qa summary. The three below inherit --ff-d from an ancestor
   rather than declaring it, so they need a real override. */
.card h3,.step h3,.plan__cur{font-family:var(--ff)}

/* Faux bold. Both of these asked for a weight that is not in the font request,
   so the browser synthesised one by smearing the 600 — .feed b resolved to
   Source Code Pro 700, and the sheet's "#" header resolved to 900, because the
   UA sheet gives <b> `bolder` and bolder-than-600 is 900. Two elements were
   rendering in a weight that does not exist. */
.feed b,.sample__sheet th b{font-weight:600}

/* ═══════════════════════════ BUTTONS ═══════════════════════════════════════
   ONE state matrix, applied to every variant. Before this pass, rest and hover
   were the only states any variant reliably had: --outline, --ghost, --dark and
   --glass had no :active at all, nothing on the page had a disabled or a
   loading state, and the primary CTA's focus ring was a brand-coloured inset
   ring drawn on a brand-coloured button — i.e. invisible, on the single most
   important control on the site.

       rest → hover → active → focus-visible → disabled → loading

   HOVER DARKENS, ALWAYS. --brand → --brand-600 → --brand-700. Lightening to
   #7A73FF once dropped white-on-brand from 4.70:1 to 3.67:1: hovering the
   button made its own label harder to read. Do not reintroduce it.

   THE PRESS. translateY(-1px) up, translateY(0) down is not a press — it is the
   absence of a hover. A real button press is the object moving toward the
   surface: it gets fractionally smaller, its shadow collapses under it, and it
   does it FAST. Hover lifts 1px over 150ms; the press scales to .98 and drops
   the shadow to --sh-xs over 80ms, then eases back out over the normal 150ms
   because releasing is not as sharp as pressing. Total travel is well under the
   150ms ceiling, and both properties are compositor-only.

   THE HEIGHT LADDER. 36 / 40 / 48, from 34 / 40 / 48 — 34 was two steps below
   its neighbour where 48 is one above, and it sat under the 36px minimum for a
   pointer target of any kind. Under (pointer:coarse) every control on this page
   is floored at 44px; see the block at the end of this file. */
.btn{
  --btn-fg:#fff;                 /* spinner + loading colour, per variant */
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  position:relative;
  min-height:40px;padding:9px 18px;border-radius:var(--r-pill);
  font-size:var(--fs-md);font-weight:600;letter-spacing:var(--tr-sm);line-height:1.2;
  white-space:nowrap;border:1px solid transparent;
  transition:background-color var(--t),color var(--t),transform var(--t),
             box-shadow var(--t),border-color var(--t),opacity var(--t);
}
.btn--sm{min-height:36px;padding:7px 15px;font-size:var(--fs-sm)}
/* A large button is larger by mass, not by type size — same step, more padding. */
.btn--lg{min-height:48px;padding:13px 26px}
.btn--block{width:100%}

/* ── icon behaviour inside a button ───────────────────────────────────────
   Every icon in every button used to slide right on hover, including the
   LEADING download icon on "Download the sample file", which drifted into its
   own label. Only a trailing mark can lead the eye out of the button, so only a
   trailing mark moves.
   The negative margin is optical, not structural. A 24-unit icon box is never
   full: the chevron's ink runs 8 → 16.5, so at .ico--xs the box carries 3.6px
   of invisible air before the mark starts and 3.3px after it ends. Measured on
   the nav CTA before the trim, "Start free trial ›" had 16.0px from the button
   edge to the label but 19.3px from the chevron to the other edge, and a 9.6px
   hole between label and mark against a nominal gap of 6. Pulling 2px off both
   flanks of every non-solo icon lands it at 16.0 / 16.3 with a 7.6px gap —
   symmetric to a third of a pixel, and glyph-agnostic, so it stays true when
   the icon is a download tray or a search lens instead.
   The half-pixel lift is the standard cap-height correction: centring an icon
   box against a line box centres it against the descender too, which reads
   about half a pixel low.

   :only-child is NOT the guard for "icon-only button", and reaching for it is
   the easy mistake here: the label is a text node, so in `Start free trial
   <svg>` the svg IS the only ELEMENT child and the rule silently does nothing.
   The reliable marker is aria-label, which quality-bar rule 9 already requires
   on every icon-only control and forbids nowhere else. */
.btn .ico{translate:0 -.5px;margin-inline:-2px;transition:transform var(--t)}
.btn[aria-label] .ico{margin-inline:0}
.btn:not([aria-label]):hover .ico:last-child{transform:translateX(2px)}

/* ── the enabled guard ────────────────────────────────────────────────────
   :where() carries no specificity, so wrapping the guard in it lets every
   interactive rule below stay at the same weight as its variant's base rule
   while still refusing to fire on a disabled or busy control. <a> elements
   cannot be :disabled, which is why aria-disabled is in the list. */
.btn:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):hover{
  transform:translateY(var(--lift-btn));
}
.btn:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):active{
  transform:translateY(0) scale(.98);
  box-shadow:var(--sh-xs);
  transition-duration:.08s;
}

/* ── variants: rest / hover / active ──────────────────────────────────── */
.btn--primary{background:var(--brand);color:#fff;box-shadow:var(--sh-btn)}
.btn--primary:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):hover{
  background:var(--brand-600);
  box-shadow:0 4px 12px rgba(99,91,255,.35),0 1px 2px rgba(10,37,64,.08);
}
.btn--primary:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):active{
  background:var(--brand-700);
}

.btn--outline{--btn-fg:var(--brand-600);background:var(--brand-25);color:var(--brand-600);border-color:var(--brand-100)}
.btn--outline:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):hover{
  background:var(--brand-50);border-color:var(--brand-200);color:var(--brand-700);
}
.btn--outline:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):active{
  background:var(--brand-100);border-color:var(--brand-200);color:var(--brand-700);
}

.btn--ghost{--btn-fg:var(--brand-600);color:var(--ink);background:transparent}
.btn--ghost:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):hover{
  color:var(--brand-600);background:rgba(99,91,255,.07);
}
.btn--ghost:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):active{
  color:var(--brand-700);background:rgba(99,91,255,.14);
}

.btn--dark{background:var(--ink);color:#fff;box-shadow:var(--sh-btn)}
/* The one variant whose hover goes UP the ramp rather than down, and
   deliberately: --ink is already 15.5:1 against its own white label, there is
   almost no headroom below it, and #143A5E still holds 11.7:1. Read the pair as
   physics rather than as a colour rule — hover raises the surface toward the
   light, the press pushes it into shadow at --ink-deep. Same story the shadow
   is telling. This is not the --primary bug; do not "fix" it. */
.btn--dark:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):hover{
  background:#143A5E;box-shadow:var(--sh-md);
}
.btn--dark:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):active{
  background:var(--ink-deep);
}

.btn--glass{background:rgba(255,255,255,.14);color:#fff;border-color:rgba(255,255,255,.28)}
.btn--glass:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):hover{
  background:rgba(255,255,255,.24);border-color:rgba(255,255,255,.45);
}
.btn--glass:where(:not(:disabled):not([aria-disabled="true"]):not(.is-loading)):active{
  background:rgba(255,255,255,.34);border-color:rgba(255,255,255,.55);
}

/* ── focus ───────────────────────────────────────────────────────────────
   The global :focus-visible draws a brand-coloured inset ring. On a white or
   near-white button that is exactly right. On --primary, --dark and --glass the
   ring is brand-on-brand or brand-on-ink and cannot be seen, so those three
   invert to a white inset ring with a translucent halo outside it. Both rings
   are inset-based and therefore survive an overflow:hidden ancestor. */
.btn--primary:focus-visible,
.btn--dark:focus-visible,
.btn--glass:focus-visible{box-shadow:var(--ring-focus-inv)}

/* ── disabled ────────────────────────────────────────────────────────────
   Not opacity. Fading a --primary button to .5 takes white-on-brand from 4.70:1
   to about 2.4:1, which is unreadable rather than merely inactive. A disabled
   button gets its own flat, legible, obviously-inert material instead:
   --slate-500 on --line is 5.4:1, so the label is still readable, and the total
   absence of shadow, border and lift is what says "not now". */
.btn:disabled,.btn[aria-disabled="true"],.btn.is-disabled{
  background:var(--line);color:var(--slate-500);border-color:transparent;
  box-shadow:none;transform:none;cursor:not-allowed;
}
a.btn[aria-disabled="true"],a.btn.is-disabled{pointer-events:none}
.card--dark .btn:disabled,.card--dark .btn[aria-disabled="true"],
.cta .btn:disabled,.cta .btn[aria-disabled="true"]{
  background:rgba(255,255,255,.10);color:rgba(255,255,255,.62);
}

/* ── loading ─────────────────────────────────────────────────────────────
   The label is hidden with `color:transparent` rather than removed, so the
   button keeps its exact width and the row it sits in does not reflow the
   instant you click it. --btn-fg is declared by each variant so the spinner is
   always the colour the label was. */
.btn.is-loading{cursor:progress;color:transparent!important}
.btn.is-loading .ico{visibility:hidden}
.btn.is-loading::after{
  content:"";position:absolute;top:50%;left:50%;width:16px;height:16px;margin:-8px 0 0 -8px;
  border:2px solid var(--btn-fg);border-top-color:transparent;border-radius:50%;
  animation:btnspin .6s linear infinite;
}
.btn--sm.is-loading::after{width:14px;height:14px;margin:-7px 0 0 -7px}
@keyframes btnspin{to{transform:rotate(1turn)}}

/* ── arrow-suffixed text link ────────────────────────────────────────────
   The padding and the matching negative margin cancel exactly, so not one
   glyph moves — but the hit area goes from 132 × 24 to 146 × 34, and there is
   now somewhere for an inset focus ring to be drawn. Before this, .link was a
   24px-tall keyboard stop whose focus ring was a 2px rectangle struck straight
   through its own text. */
.link{
  display:inline-flex;align-items:center;gap:5px;
  padding:5px 7px;margin:-5px -7px;border-radius:var(--r);
  color:var(--brand-600);font-weight:600;font-size:var(--fs-md);letter-spacing:var(--tr-sm);
  transition:color var(--t),background-color var(--t);
}
.link .ico{translate:0 -.5px;margin-inline:-2px;transition:transform var(--t)}
.link:hover{color:var(--brand-700);background:rgba(99,91,255,.07)}
.link:hover .ico{transform:translateX(3px)}
.link:active{color:var(--brand-700);background:rgba(99,91,255,.14)}
.link--inv{color:var(--lilac)}
.link--inv:hover,.link--inv:active{color:#fff;background:rgba(255,255,255,.12)}
.link--inv:focus-visible{box-shadow:var(--ring-focus-inv)}

/* ── chips ──────────────────────────────────────────────────────────────── */
.chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px 10px;border-radius:var(--r-pill);
  font-size:var(--fs-2xs);font-weight:600;letter-spacing:var(--tr-xs);
  background:var(--line-soft);color:var(--slate-500);
}
.chip--live{background:rgba(0,178,97,.10);color:var(--green-deep)}
.chip--live i{
  width:6px;height:6px;border-radius:50%;background:var(--green);
  box-shadow:0 0 0 3px rgba(0,178,97,.18);
  animation:pulse 2.4s var(--e-io) infinite;
}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ═══════════════════════════ NAV ═══════════════════════════════════════ */
.nav{
  position:fixed;inset:0 0 auto;z-index:100;
  transition:background-color .25s var(--e-io),box-shadow .25s var(--e-io),border-color .25s var(--e-io);
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  background:rgba(255,255,255,.86);
  backdrop-filter:saturate(180%) blur(14px);
  -webkit-backdrop-filter:saturate(180%) blur(14px);
  border-bottom-color:var(--line-soft);
  box-shadow:0 1px 3px rgba(0,55,112,.05);
}
.nav__inner{display:flex;align-items:center;gap:28px;height:68px}
.nav__progress{
  position:absolute;left:0;bottom:-1px;height:2px;width:100%;
  background:linear-gradient(90deg,var(--brand),var(--cyan) 60%,var(--teal));
  transform:scaleX(0);transform-origin:0 50%;will-change:transform;
}

.brand{display:inline-flex;align-items:center;gap:9px}
.brand__mark{width:28px;height:28px;flex:none;filter:drop-shadow(0 2px 4px rgba(99,91,255,.28))}
.brand__mark svg{width:100%;height:100%}
.brand__word{
  font-weight:700;font-size:var(--fs-xl);
  letter-spacing:var(--tr-lg);color:var(--ink);
}
.brand__word span{color:var(--brand)}

.nav__links{display:flex;gap:4px;margin-right:auto}
.nav__links a{
  padding:7px 12px;border-radius:var(--r);
  font-size:var(--fs-md);font-weight:500;letter-spacing:var(--tr-sm);color:var(--ink);
  transition:color var(--t),background-color var(--t);
}
.nav__links a:hover{color:var(--brand-600);background:rgba(99,91,255,.07)}
.nav__links a:active{color:var(--brand-700);background:rgba(99,91,255,.14)}
.nav__actions{display:flex;align-items:center;gap:8px}
.nav__burger{
  display:none;width:44px;height:44px;align-items:center;justify-content:center;
  border-radius:var(--r);color:var(--ink);
  transition:background-color var(--t),transform var(--t);
}
.nav__burger:hover{background:rgba(10,37,64,.06)}
.nav__burger:active{background:rgba(10,37,64,.12);transform:scale(.94);transition-duration:.08s}

.mobilemenu{
  position:fixed;inset:68px 0 0;z-index:99;
  background:rgba(255,255,255,.98);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  padding:20px var(--gut) 48px;overflow-y:auto;
  animation:menuIn .22s var(--e);
}
@keyframes menuIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.mobilemenu nav{display:flex;flex-direction:column;gap:2px;max-width:var(--shell);margin-inline:auto}
/* :not(.btn) matters. `.mobilemenu a` (0,2,0) out-ranked `.btn--primary` (0,1,0),
   so the mobile "Start free trial" button rendered --ink on --brand: 3.31:1, a
   failing CTA on every phone, at rest, silently — the only rule that restored
   white was the :hover, which a touch device never fires. Excluding .btn here
   is the fix; the button now keeps its own colour, size and weight. */
.mobilemenu a:not(.btn){
  padding:14px 4px;font-size:var(--fs-xl);font-weight:600;
  letter-spacing:var(--tr-lg);color:var(--ink);border-bottom:1px solid var(--line-soft);
}
.mobilemenu a:not(.btn):hover{color:var(--brand-600)}
.mobilemenu hr{border:0;height:16px}
.mobilemenu .btn{margin-top:14px;justify-content:center;min-height:48px}

/* ═══════════════════════════ HERO ══════════════════════════════════════ */
.hero{position:relative;isolation:isolate;overflow:hidden;padding:132px 0 88px}

.hero__band{
  position:absolute;z-index:-2;
  left:-12vw;right:-12vw;top:-420px;bottom:210px;
  transform:skewY(-7deg);transform-origin:0 0;
  background:
    linear-gradient(180deg,#FFFFFF 0%,#FAFBFE 26%,#F4F7FE 52%,#EDF0FE 78%,#E7EAFD 100%);
  overflow:hidden;
}
/* the signature multi-stop colour edge */
.hero__band::after{
  content:"";position:absolute;inset:auto 0 0 0;height:340px;
  background:linear-gradient(97deg,#7C5CFF 0%,var(--brand) 20%,#5169FF 42%,#1E9FE5 70%,var(--teal) 100%);
  -webkit-mask-image:linear-gradient(180deg,transparent 0,rgba(0,0,0,.55) 46%,#000 76%);
  mask-image:linear-gradient(180deg,transparent 0,rgba(0,0,0,.55) 46%,#000 76%);
}
/* Stripe never puts type on the colour — the band is a stage that sits behind
   and BELOW the content, so the headline always lands on a clean white field. */
.blob{
  position:absolute;border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,var(--c),rgba(255,255,255,0) 100%);
}
.blob--1,.blob--2,.blob--4{will-change:transform}
.blob--1{--c:rgba(99,91,255,.30);width:62%;height:70%;left:-14%;top:38%;animation:drift1 28s var(--e-io) infinite}
.blob--2{--c:rgba(0,163,224,.22);width:52%;height:62%;right:-10%;top:30%;animation:drift2 34s var(--e-io) infinite}
.blob--4{--c:rgba(11,180,166,.18);width:48%;height:56%;left:8%;top:56%;animation:drift2 38s var(--e-io) infinite reverse}
@keyframes drift1{0%,100%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(9%,-6%,0) scale(1.12)}}
@keyframes drift2{0%,100%{transform:translate3d(0,0,0) scale(1.05)}50%{transform:translate3d(-8%,7%,0) scale(.92)}}

/* mix-blend-mode:multiply on a full-viewport animated layer is the single most
   expensive declaration in this file. Plain opacity with a pre-darkened stroke
   colour is visually equivalent here and costs nothing. */
.hero__net{
  position:absolute;z-index:-1;inset:0 0 auto 0;height:74%;
  width:100%;opacity:.55;
  -webkit-mask-image:linear-gradient(180deg,#000 52%,transparent 92%);
  mask-image:linear-gradient(180deg,#000 52%,transparent 92%);
}

.hero__inner{position:relative;display:flex;flex-direction:column;align-items:center;text-align:center}

.hero__eyebrow{
  display:inline-flex;align-items:center;gap:8px;
  padding:6px 14px 6px 10px;border-radius:var(--r-pill);
  background:rgba(255,255,255,.72);border:1px solid rgba(99,91,255,.18);
  box-shadow:var(--sh-xs);backdrop-filter:blur(6px);
  font-size:var(--fs-xs);font-weight:600;letter-spacing:var(--tr-caps-lg);text-transform:uppercase;
  color:var(--brand-600);
}
.pip{
  width:8px;height:8px;border-radius:50%;
  background:linear-gradient(135deg,var(--brand),var(--cyan));
  box-shadow:0 0 0 3px rgba(99,91,255,.16);
}

.hero__title{
  margin-top:26px;
  font-size:var(--fs-4xl);
  font-weight:600;line-height:1.03;letter-spacing:var(--tr-display);
  color:var(--ink);text-wrap:balance;
}
.hero__title em{
  font-style:normal;
  background:linear-gradient(96deg,var(--brand) 0%,#5A6BFF 30%,#1E9FE5 66%,var(--teal) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
/* 60ch rendered as ~76 characters. 48ch measures ~60 — a full line for a
   centred hero subhead, which wants to be shorter than body measure anyway. */
.hero__sub{
  margin-top:18px;max-width:48ch;
  font-size:var(--fs-xl);line-height:1.55;
  color:var(--slate);text-wrap:pretty;
}

/* ── search bar — hero artefact #1, one of only two users of --sh-xl ───── */
.sbar{
  display:flex;gap:6px;align-items:stretch;
  width:100%;max-width:880px;margin-top:28px;padding:8px;
  background:#fff;border-radius:var(--r-lg);
  box-shadow:var(--sh-xl),var(--ring);
  text-align:left;
  /* The bar has to outrank .rescard: the combobox panel drops out of this
     subtree and would otherwise be painted under the results card below. */
  position:relative;z-index:2;
}
.sbar__f{
  position:relative;flex:1 1 0;min-width:0;
  padding:8px 12px;border-radius:var(--r-md);
  transition:background-color var(--t),box-shadow var(--t);
}
.sbar__f:hover{background:var(--bg-subdued)}
.sbar__f:focus-within{background:var(--brand-25);box-shadow:inset 0 0 0 1px var(--brand-200)}
.sbar__lab{
  display:block;font-size:var(--fs-3xs);font-weight:600;letter-spacing:var(--tr-caps);
  text-transform:uppercase;color:var(--slate-400);margin-bottom:2px;
}
.sbar__f input,.sbar__f select{
  width:100%;border:0;background:transparent;padding:0;
  font-size:var(--fs-md);font-weight:500;letter-spacing:var(--tr-sm);color:var(--ink);
  appearance:none;-webkit-appearance:none;
}
.sbar__f input::placeholder{color:var(--slate-300);font-weight:400}
.sbar__f input:focus,.sbar__f select:focus{outline:none}
.sbar__f input::-webkit-calendar-picker-indicator{display:none!important}

.sbar__f--c{display:grid;grid-template-columns:auto 1fr auto;grid-template-rows:auto auto;
  column-gap:7px;align-items:center}
.sbar__f--c .sbar__lab{grid-column:1/-1}
/* A source we have researched and not yet built. Deliberately quiet — no live
   pulse, no green — so it cannot be mistaken for the Connected state next to it. */
.chip--soon{
  background:var(--sunk);color:var(--slate-400);
  border:1px solid var(--line);
}
.chip--soon i{display:none}

.sbar__flag{font-size:var(--fs-md);line-height:1}
.sbar__f--c select{grid-column:2;padding-right:2px;text-overflow:ellipsis}
.sbar__caret{grid-column:3;color:var(--slate-400);pointer-events:none;transform:rotate(90deg)}

/* 22 × 22 was under the 24px absolute floor for a pointer target, and the
   button is the only way to empty a field. The visible disc stays 24px so the
   search bar does not gain visual weight; the ::before extends the hit area to
   32px square (44 under a coarse pointer) without changing a single pixel of
   what is drawn. */
.sbar__x{
  position:absolute;right:7px;top:50%;transform:translateY(-2px);
  width:24px;height:24px;display:flex;align-items:center;justify-content:center;
  border-radius:50%;color:var(--slate-300);opacity:0;
  transition:opacity var(--t),color var(--t),background-color var(--t);
}
.sbar__x::before{content:"";position:absolute;inset:-4px}
.sbar__f:hover .sbar__x,.sbar__f:focus-within .sbar__x{opacity:1}
.sbar__x:hover{background:rgba(10,37,64,.07);color:var(--ink)}
.sbar__x:active{background:rgba(10,37,64,.14);color:var(--ink)}
.sbar__x:focus-visible{opacity:1;box-shadow:inset 0 0 0 2px var(--brand)}

.sbar__go{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  flex:none;min-height:44px;padding:0 24px;border-radius:var(--r-md);
  background:var(--brand);color:#fff;font-weight:600;font-size:var(--fs-md);letter-spacing:var(--tr-sm);
  box-shadow:0 2px 6px rgba(99,91,255,.32);
  transition:background-color var(--t),box-shadow var(--t),transform var(--t);
}
.sbar__go .ico{translate:0 -.5px;margin-inline:-2px}
.sbar__go:hover{background:var(--brand-600);box-shadow:0 5px 14px rgba(99,91,255,.42)}
/* Same press physics as .btn: toward the surface, shadow collapsing under it. */
.sbar__go:active{background:var(--brand-700);transform:scale(.98);box-shadow:var(--sh-xs);transition-duration:.08s}
/* white ring — a brand ring on a brand button is not a ring */
.sbar__go:focus-visible{box-shadow:var(--ring-focus-inv)}
.sbar__go:disabled{background:var(--line);color:var(--slate-500);box-shadow:none;cursor:not-allowed;transform:none}

/* ── live results card — hero artefact #2 ───────────────────────────────── */
.rescard{
  position:relative;z-index:1;width:100%;max-width:880px;margin-top:20px;
  background:#fff;border-radius:var(--r-lg);overflow:hidden;text-align:left;
  box-shadow:var(--sh-xl),var(--ring);
}
.rescard__top{
  display:flex;align-items:center;gap:10px;
  padding:16px 20px;border-bottom:1px solid var(--line-soft);
  background:linear-gradient(180deg,#fff,#FCFDFF);
}
.rescard__dot{
  width:8px;height:8px;border-radius:50%;flex:none;
  background:linear-gradient(135deg,var(--brand),var(--cyan));
}
.rescard__h{
  flex:1 1 auto;min-width:0;margin:0;
  font-family:var(--ff);font-size:var(--fs-sm);font-weight:600;letter-spacing:var(--tr-sm);
  color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.rescard__scroll{overflow-x:auto;overscroll-behavior-x:contain}

.restab{min-width:560px;font-size:var(--fs-sm)}
.restab th{
  padding:12px 20px;text-align:left;
  font-size:var(--fs-3xs);font-weight:600;letter-spacing:var(--tr-caps);text-transform:uppercase;
  color:var(--slate-400);background:var(--bg-subdued);
  border-bottom:1px solid var(--line-soft);
}
.restab th:last-child{text-align:right}
.restab td{
  padding:12px 20px;border-bottom:1px solid var(--line-soft);
  color:var(--slate);vertical-align:middle;
}
.restab tr:last-child td{border-bottom:0}
.restab tbody tr{transition:background-color var(--t)}
.restab tbody tr:hover{background:var(--brand-25)}
.rt-name{font-weight:600;color:var(--ink);white-space:nowrap}
.rt-tel,.rt-mail{font-family:var(--ff-m);font-size:var(--fs-xs);letter-spacing:var(--tr-xs);color:var(--slate-500);white-space:nowrap}
.rt-mail{max-width:200px;overflow:hidden;text-overflow:ellipsis}
.rt-soc{text-align:right;white-space:nowrap}
.rt-soc span{
  display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;border-radius:5px;margin-left:4px;
  transition:transform var(--t);
}
.rt-soc span:hover{transform:translateY(var(--lift))}
.rt-soc svg{width:12px;height:12px;fill:#fff}
.s-mail{background:#8792A2}.s-fb{background:#1877F2}
.s-ig{background:linear-gradient(45deg,#F9CE34,#EE2A7B 55%,#6228D7)}
.s-tt{background:var(--ink)}.s-x{background:var(--ink)}
.s-in{background:#0A66C2}.s-yt{background:#FF0000}

.rescard__veil{
  position:absolute;left:0;right:0;bottom:74px;height:190px;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.72) 46%,#fff 100%);
  backdrop-filter:blur(2.5px);-webkit-backdrop-filter:blur(2.5px);
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 55%);
  mask-image:linear-gradient(180deg,transparent 0,#000 55%);
}
.rescard__cta{
  position:relative;z-index:1;
  display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding:16px 20px;border-top:1px solid var(--line-soft);
  background:linear-gradient(180deg,#FCFDFF,#F6F9FC);
}
.rescard__cta p{font-size:var(--fs-sm);color:var(--slate-500)}
.rescard__cta b{color:var(--ink);font-family:var(--ff-m);font-weight:600}

.hero__note{
  display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap;
  margin-top:26px;font-size:var(--fs-sm);font-weight:500;color:var(--slate-500);
}
.hero__note .ico{color:var(--green);stroke-width:2.8}
.hero__note span{color:var(--slate-300)}

/* ═══════════════════════════ TRUST STRIP ═══════════════════════════════ */
.trust{padding:8px 0 calc(var(--gap-md) / 2);background:#fff}
.trust__label{
  text-align:center;font-size:var(--fs-xs);font-weight:600;
  letter-spacing:var(--tr-caps-lg);text-transform:uppercase;color:var(--slate-400);
}
.trust__label b{color:var(--ink);font-weight:700}
.marquee{
  margin-top:28px;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
}
/* 46s over an 11k-px track is ~240px/s — about 3x faster than anyone can read
   a line. Slowed to a readable pace. */
.marquee__track{display:flex;width:max-content;animation:marq 110s linear infinite}
.marquee:hover .marquee__track{animation-play-state:paused}

/* Each item is one export by one customer. The child combinator matters: the
   old `.marquee__track span` was a descendant selector, so it also hit every
   nested span inside an item. */
.marquee__track > .tick{
  flex:none;display:inline-flex;align-items:baseline;gap:8px;
  padding:0 28px;white-space:nowrap;
  font-family:var(--ff);font-size:var(--fs-sm);font-weight:400;
  color:var(--slate-500);
}
.tick__who{
  font-weight:600;color:var(--ink);letter-spacing:var(--tr-sm);
}
.tick__what{color:var(--slate-400)}
.tick__where{font-style:normal;font-weight:500;color:var(--slate)}
.tick__flag{margin:0 1px}
.tick__when{
  padding-left:9px;border-left:1px solid var(--line);
  font-size:var(--fs-2xs);color:var(--slate-400);
}
@keyframes marq{to{transform:translateX(-50%)}}

/* ═══════════════════════════ SOURCES ═══════════════════════════════════ */
.sources__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.source{
  position:relative;padding:24px;
  background:#fff;border-radius:var(--r-lg);
  box-shadow:var(--sh-card);
  transition:var(--t-reveal),transform var(--t-card),box-shadow var(--t-card);
}
.source:hover{transform:translateY(var(--lift));box-shadow:var(--sh-card-hover)}
.source header{display:flex;align-items:center;gap:10px;margin-bottom:20px}
.source__logo{
  width:30px;height:30px;flex:none;display:grid;place-items:center;
  border-radius:8px;background:var(--bg-subdued);color:var(--ink);
  box-shadow:var(--ring-inset);
}
.source__logo svg{width:18px;height:18px}
.source h3{
  flex:1 1 auto;font-size:var(--fs-md);font-weight:600;letter-spacing:var(--tr-sm);
  font-family:var(--ff);
}
.source__n{
  font-family:var(--ff-d);font-size:var(--fs-2xl);
  font-weight:600;letter-spacing:var(--tr-xl);line-height:1;color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.source__cap{margin-top:8px;font-size:var(--fs-sm);color:var(--slate-500);text-wrap:pretty}
.source__meter{margin-top:18px;height:4px;border-radius:2px;background:var(--line-soft);overflow:hidden}
.source__meter span{
  display:block;height:100%;width:var(--w);border-radius:2px;
  background:linear-gradient(90deg,var(--brand),var(--cyan));
}

/* ═══════════════════════════ HOW IT WORKS ══════════════════════════════ */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;counter-reset:s}
.step{
  position:relative;padding:24px;
  border-radius:var(--r-lg);background:#fff;
  box-shadow:var(--sh-card);
  transition:var(--t-reveal),box-shadow var(--t-card),transform var(--t-card);
}
.step:hover{box-shadow:var(--sh-card-hover);transform:translateY(var(--lift))}
.step__n{
  position:absolute;top:24px;right:24px;
  font-family:var(--ff-m);font-size:var(--fs-2xs);font-weight:600;letter-spacing:var(--tr-caps);
  color:var(--slate-300);
}
.step__ico{
  display:grid;place-items:center;width:40px;height:40px;border-radius:10px;
  background:linear-gradient(140deg,var(--brand-25),var(--brand-50));
  color:var(--brand-600);box-shadow:inset 0 0 0 1px var(--brand-100);
}
.step h3{margin-top:20px;font-size:var(--fs-xl);letter-spacing:var(--tr-lg);text-wrap:balance}
.step p{margin-top:10px;font-size:var(--fs-md);line-height:1.6;color:var(--slate);max-width:46ch;text-wrap:pretty}

/* ═══════════════════════════ SAMPLE EXPORT ═════════════════════════════ */
.sample{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:56px;align-items:center}
.sample__copy h2{
  margin-top:16px;font-size:var(--fs-2xl);letter-spacing:var(--tr-xl);text-wrap:balance;
}
.sample__copy>p{margin-top:18px;font-size:var(--fs-lg);line-height:1.62;max-width:46ch;text-wrap:pretty}
.sample__copy .btn{margin-top:26px}
.sample__meta{
  display:flex;align-items:center;gap:7px;margin-top:16px;
  font-family:var(--ff-m);font-size:var(--fs-2xs);color:var(--slate-400);
}

.sample__sheet{
  background:#fff;border-radius:var(--r-lg);overflow:hidden;
  box-shadow:var(--sh-card);
}
.sheet__bar{
  display:flex;align-items:center;gap:6px;padding:12px 16px;
  background:var(--bg-subdued);border-bottom:1px solid var(--line);
}
.sheet__bar i{width:9px;height:9px;border-radius:50%;background:#D4DEE9}
.sheet__bar i:first-child{background:var(--orange)}
.sheet__bar i:nth-child(2){background:var(--lemon)}
.sheet__bar i:nth-child(3){background:var(--green)}
.sheet__name{
  margin-left:8px;font-family:var(--ff-m);font-size:var(--fs-2xs);color:var(--slate-500);
}
.sheet__scroll{overflow-x:auto}
.sample__sheet table{min-width:800px;font-size:var(--fs-xs)}
.sample__sheet th{
  padding:8px 16px;text-align:left;white-space:nowrap;
  font-family:var(--ff-m);font-size:var(--fs-3xs);font-weight:600;letter-spacing:var(--tr-xs);
  color:var(--slate-400);background:#FBFCFE;
  border-bottom:1px solid var(--line);border-right:1px solid var(--line-soft);
}
.sample__sheet td{
  padding:8px 16px;white-space:nowrap;color:var(--slate);
  border-bottom:1px solid var(--line-soft);border-right:1px solid var(--line-soft);
}
.sample__sheet th:last-child,.sample__sheet td:last-child{border-right:0}
.sample__sheet tbody tr:last-child td{border-bottom:0}
.sample__sheet tbody tr:hover td{background:var(--brand-25)}
.sheet__i{
  width:34px;text-align:center;color:var(--slate-300);
  font-family:var(--ff-m);font-size:var(--fs-3xs);background:#FBFCFE;
}
/* column treatments — columns are: # name email_1 phone phone_type rating review_count
   instagram scraped_at. Machine-readable fields get the mono face so the sheet reads as
   data rather than prose. */
.sample__sheet td:nth-child(2){font-weight:600;color:var(--ink)}
.sample__sheet td:nth-child(3),
.sample__sheet td:nth-child(4),
.sample__sheet td:nth-child(8),
.sample__sheet td:nth-child(9){font-family:var(--ff-m);font-size:var(--fs-2xs)}
.sample__sheet td:nth-child(3),
.sample__sheet td:nth-child(8){color:var(--brand-600)}
.sample__sheet td:nth-child(5){color:var(--slate-400);font-size:var(--fs-2xs)}
.sample__sheet td:nth-child(6),
.sample__sheet td:nth-child(7){text-align:right;font-variant-numeric:tabular-nums}
.sample__sheet td:nth-child(9){color:var(--slate-400)}
/* an empty cell is information too — Koie Ramen genuinely has no listed phone */
.sheet__nil{color:var(--slate-300);text-align:center}

/* ═══════════════════════════ BENTO ═════════════════════════════════════ */
.bento{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.card{
  display:flex;flex-direction:column;overflow:hidden;
  background:#fff;border-radius:var(--r-lg);
  box-shadow:var(--sh-card);
  transition:var(--t-reveal),transform var(--t-card),box-shadow var(--t-card);
}
.card:hover{transform:translateY(var(--lift));box-shadow:var(--sh-card-hover)}
.card--wide{grid-column:span 2}
.card--tall{grid-row:span 2}

/* A wide card is 733px, but prose is capped near 46ch to stay readable — which
   left ~298px of dead space to the right of every wide card's paragraph while
   the demo art sat stacked underneath. Side-by-side uses the width the card
   actually has: copy reads at its proper measure on the left, the artefact gets
   real estate on the right, and each card sheds well over 100px of height.
   Only above 1080px — below that the bento drops to two columns and nothing
   spans, so there is no extra width to reclaim. */
@media (min-width:1081px){
  .card--wide{
    display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
    align-items:center;column-gap:4px;
  }
  .card--wide .card__body{padding:28px 4px 28px 28px}
  .card--wide .card__art{margin-top:0;padding:24px 28px 24px 0}
  /* the map wants to bleed to the card edge rather than sit in a gutter */
  .card--wide.card--map .card__art{padding:0;align-self:stretch;display:flex}
  .card--wide.card--map .map{width:100%}
}
.card__body{padding:24px}
.card__ico{
  display:grid;place-items:center;width:38px;height:38px;border-radius:10px;
  background:linear-gradient(140deg,var(--brand-25),var(--brand-50));
  color:var(--brand-600);box-shadow:inset 0 0 0 1px var(--brand-100);margin-bottom:18px;
}
.card__ico--ok{
  background:linear-gradient(140deg,rgba(0,178,97,.08),rgba(0,178,97,.16));
  color:var(--green-deep);box-shadow:inset 0 0 0 1px rgba(0,178,97,.22);
}
.card__ico--inv{
  background:rgba(255,255,255,.10);color:var(--lilac);box-shadow:inset 0 0 0 1px rgba(255,255,255,.16);
}
.card h3{font-size:var(--fs-xl);letter-spacing:var(--tr-lg);line-height:1.24;text-wrap:balance}
/* 56ch rendered as ~70 characters — well past the 45–75 comfort band for a
   card sitting in a two-column bento. */
.card p{margin-top:11px;font-size:var(--fs-md);line-height:1.62;color:var(--slate);max-width:46ch;text-wrap:pretty}
/* 11 + the link's own 5px of new padding = the 16px gap that was here before. */
.card .link{margin-top:11px}
.card__art{margin-top:auto;padding:0 24px 24px}

.card--soft{background:linear-gradient(170deg,#FBFDFF,#F4F9FC)}
.card--dark{
  background:linear-gradient(155deg,var(--ink) 0%,#0D2C4C 55%,#122054 100%);
}
.card--dark h3{color:#fff}
.card--dark p{color:#B7C6D8}

/* tree */
.card__art--tree{display:flex;flex-direction:column;gap:20px}
.tree{
  display:flex;flex-direction:column;gap:2px;padding:16px;
  border-radius:var(--r-md);background:var(--bg-subdued);
  box-shadow:var(--ring-inset);
}
.tree li{
  display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:var(--r-sm);
  font-size:var(--fs-xs);transition:background-color var(--t);
}
.tree li+li{margin-left:14px}
.tree li.is-on{background:#fff;box-shadow:var(--sh-xs)}
.tree__k{
  width:68px;flex:none;font-size:var(--fs-3xs);font-weight:700;letter-spacing:var(--tr-caps);
  text-transform:uppercase;color:var(--slate-300);
}
.tree__v{font-weight:600;color:var(--slate)}
.tree li.is-on .tree__v{color:var(--brand-600)}
.statline{display:flex;gap:8px}
.statline div{
  flex:1;padding:12px 8px;border-radius:var(--r-md);text-align:center;
  background:#fff;box-shadow:var(--ring-inset);
}
.statline b{
  display:block;font-size:var(--fs-lg);font-weight:600;
  letter-spacing:var(--tr-md);color:var(--ink);
}
.statline span{display:block;margin-top:3px;font-size:var(--fs-3xs);color:var(--slate-400)}

/* filters */
.filters{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
/* The filter chips are toggles, so they need the same six states a button does
   — they previously had three. Note the two focus rings: an unset chip is white
   and takes the brand ring, a set chip is brand and takes the white one. */
.tog{
  display:inline-flex;align-items:center;min-height:32px;
  padding:7px 14px;border-radius:var(--r-pill);
  font-size:var(--fs-xs);font-weight:600;letter-spacing:var(--tr-xs);
  color:var(--slate-500);background:#fff;
  box-shadow:var(--ring-inset);
  transition:color var(--t),background-color var(--t),box-shadow var(--t),transform var(--t);
}
.tog:hover{color:var(--ink);box-shadow:inset 0 0 0 1px var(--slate-300)}
.tog:active{transform:scale(.97);transition-duration:.08s}
.tog.is-on{
  color:#fff;background:var(--brand);
  box-shadow:inset 0 0 0 1px var(--brand),0 2px 6px rgba(99,91,255,.28);
}
.tog.is-on:hover{background:var(--brand-600);box-shadow:inset 0 0 0 1px var(--brand-600),0 3px 9px rgba(99,91,255,.36)}
.tog.is-on:active{background:var(--brand-700);box-shadow:inset 0 0 0 1px var(--brand-700)}
.tog.is-on:focus-visible{box-shadow:var(--ring-focus-inv)}
.tog:disabled{color:var(--slate-300);background:var(--line-soft);box-shadow:none;cursor:not-allowed;transform:none}
.slider{flex:1 1 240px;min-width:200px;margin-top:6px}
.slider label{
  display:flex;align-items:center;gap:5px;margin-bottom:8px;
  font-size:var(--fs-2xs);font-weight:600;letter-spacing:var(--tr-caps);color:var(--slate-400);
  text-transform:uppercase;
}
.slider output{
  font-family:var(--ff-m);color:var(--brand-600);font-weight:600;
}
#rating{
  --p:75%;
  -webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:3px;
  background:linear-gradient(90deg,var(--brand) 0 var(--p),var(--line) var(--p) 100%);
  cursor:pointer;
}
#rating::-webkit-slider-thumb{
  -webkit-appearance:none;width:18px;height:18px;border-radius:50%;
  background:#fff;box-shadow:0 0 0 1px rgba(10,37,64,.10),var(--sh-sm);
  border:4px solid var(--brand);cursor:grab;transition:transform var(--t);
}
#rating::-webkit-slider-thumb:hover{transform:scale(1.12)}
#rating::-moz-range-thumb{
  width:18px;height:18px;border-radius:50%;background:#fff;
  border:4px solid var(--brand);box-shadow:var(--sh-sm);cursor:grab;
}
#rating::-moz-range-track{height:6px;border-radius:3px;background:transparent}
.filters .filters__count{
  width:100%;max-width:none;margin-top:16px!important;padding-top:16px;
  border-top:1px solid var(--line-soft);
  font-size:var(--fs-xl);font-weight:600;letter-spacing:var(--tr-lg);
  color:var(--ink);
}
.filters .filters__count em{
  font-style:normal;font-family:var(--ff);font-size:var(--fs-xs);font-weight:500;
  letter-spacing:var(--tr-xs);color:var(--slate-400);margin-left:6px;
}

/* feed */
.feed{display:flex;flex-direction:column;gap:2px}
.feed li{
  display:flex;align-items:center;gap:10px;padding:8px 12px;
  border-radius:var(--r-md);font-size:var(--fs-xs);color:var(--slate);
  background:var(--bg-subdued);
}
.feed b{margin-left:auto;font-family:var(--ff-m);font-size:var(--fs-2xs);color:var(--green-deep)}
.feed__d{
  width:6px;height:6px;border-radius:50%;flex:none;background:var(--green);
  box-shadow:0 0 0 3px rgba(0,178,97,.16);
  animation:blink 2.4s var(--e-io) infinite;
}
.feed li:nth-child(2) .feed__d{animation-delay:.4s}
.feed li:nth-child(3) .feed__d{animation-delay:.8s}
.feed li:nth-child(4) .feed__d{animation-delay:1.2s}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.25}}

/* map */
.card--map .card__art--map{padding:0}
.map{position:relative;overflow:hidden;background:#F3F7FB;border-top:1px solid var(--line-soft)}
.map__canvas{width:100%;height:280px;display:block}
.map__roads path{stroke:#DCE6F0;stroke-width:7;fill:none;stroke-linecap:round}
.map__blocks rect{fill:#E6EDF5}
.map__poly,.map__circle{
  fill:rgba(99,91,255,.12);stroke:var(--brand);stroke-width:2;
  stroke-linejoin:round;transition:opacity .35s var(--e);
}
.map__poly{stroke-dasharray:1400;stroke-dashoffset:1400}
.map.is-seen .map__poly{animation:draw 1.8s var(--e) forwards}
@keyframes draw{from{stroke-dashoffset:1400}to{stroke-dashoffset:0}}
.map__circle{opacity:0;stroke-dasharray:6 7}
.map.is-radius .map__poly{opacity:0}
.map.is-radius .map__circle{opacity:1}
#pins circle{
  fill:var(--brand-600);stroke:#fff;stroke-width:1.6;
  animation:pop .4s var(--e) backwards;
}
@keyframes pop{from{transform:scale(0);opacity:0}to{transform:scale(1);opacity:1}}
.map__badge{
  position:absolute;left:16px;bottom:16px;
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 13px;border-radius:var(--r-pill);
  background:rgba(255,255,255,.94);backdrop-filter:blur(8px);
  box-shadow:var(--sh-md),var(--ring);
  font-size:var(--fs-xs);font-weight:500;color:var(--slate);
}
.map__badge .ico{color:var(--brand)}
.map__badge b{font-family:var(--ff-m);font-weight:600;color:var(--ink)}

.seg{
  display:inline-flex;gap:3px;margin-top:18px;padding:3px;
  border-radius:var(--r-pill);background:var(--bg-subdued);
  box-shadow:var(--ring-inset);
}
.seg__b{
  display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:7px 15px;
  border-radius:var(--r-pill);font-size:var(--fs-xs);font-weight:600;
  letter-spacing:var(--tr-xs);
  color:var(--slate-500);
  transition:color var(--t),background-color var(--t),box-shadow var(--t),transform var(--t);
}
.seg__b .ico{translate:0 -.5px;margin-left:-1px}
.seg__b:hover{color:var(--ink);background:rgba(10,37,64,.04)}
.seg__b:active{transform:scale(.97);transition-duration:.08s}
.seg__b.is-on{background:#fff;color:var(--brand-600);box-shadow:var(--sh-xs)}
.seg__b.is-on:hover{background:#fff;color:var(--brand-700);box-shadow:var(--sh-sm)}
.seg__b.is-on:active{box-shadow:none}
.seg__b:focus-visible,
.seg__b.is-on:focus-visible{outline:2px solid transparent;box-shadow:var(--ring-focus)}
.seg__b:disabled{color:var(--slate-300);cursor:not-allowed;transform:none;background:none}

/* chatlog */
.chatlog{display:flex;flex-direction:column;gap:8px}
.chatlog p{
  margin:0!important;padding:12px 16px;border-radius:14px;
  font-size:var(--fs-xs);line-height:1.55;max-width:94%;
}
.chatlog__u{
  align-self:flex-end;background:var(--brand);color:#fff!important;
  border-bottom-right-radius:5px;box-shadow:0 2px 8px rgba(99,91,255,.24);
}
.chatlog__a{
  align-self:flex-start;background:var(--bg-subdued);color:var(--slate)!important;
  border-bottom-left-radius:5px;box-shadow:var(--ring-inset);
  display:flex;gap:7px;align-items:flex-start;
}
.chatlog__a .ico{color:var(--brand);fill:currentColor;stroke:none;margin-top:2px;flex:none}
/* The message body is one flex item, not four anonymous ones. Loose text runs
   in a flex row each become their own unshrinkable item, so the assistant reply
   used to spill past the right edge of its own bubble. */
.chatlog__a > span{min-width:0}
.chatlog__a code{
  font-size:var(--fs-2xs);padding:1px 5px;border-radius:var(--r-sm);
  background:var(--brand-25);color:var(--brand-600);
  box-shadow:inset 0 0 0 1px var(--brand-100);
}
.chatlog__a b{color:var(--green-deep)}

/* terminal — first-class product artefact */
.term{
  border-radius:var(--r-md);overflow:hidden;
  background:var(--ink-deep);box-shadow:inset 0 0 0 1px rgba(255,255,255,.08),0 12px 30px rgba(0,0,0,.30);
}
.term__bar{
  display:flex;align-items:center;gap:6px;padding:9px 13px;
  background:rgba(255,255,255,.045);border-bottom:1px solid rgba(255,255,255,.08);
}
.term__bar i{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.18)}
.term__bar i:first-child{background:var(--orange)}
.term__bar i:nth-child(2){background:var(--lemon)}
.term__bar i:nth-child(3){background:var(--green)}
.term__tab{
  padding:3px 11px;border-radius:var(--r-sm);margin-left:4px;
  font-family:var(--ff-m);font-size:var(--fs-3xs);color:#7C93AD;
}
.term__tab:first-of-type{margin-left:12px}
.term__tab.is-on{background:rgba(255,255,255,.10);color:#E6EEF8}
.term__code{
  margin:0;padding:16px;overflow-x:auto;
  font-size:var(--fs-2xs);line-height:1.75;color:#D6E2F0;
  white-space:pre;-webkit-overflow-scrolling:touch;
}
.c-c{color:#5E7B99}
.c-m{color:var(--lemon)}
.c-s{color:var(--mint)}
.c-k{color:#7FD3FF}
.c-n{color:var(--magenta)}

/* ticks */
.ticks{display:flex;flex-direction:column;gap:11px}
.ticks li{
  display:flex;align-items:center;gap:10px;
  font-size:var(--fs-sm);font-weight:500;color:var(--slate);
}
.ticks .ico{
  width:18px;height:18px;padding:3.5px;border-radius:50%;flex:none;
  color:#fff;background:var(--green);stroke-width:3.4;
}
.ticks--sm li{font-size:var(--fs-xs);gap:9px}
.ticks--sm .ico{width:16px;height:16px;padding:3px;background:var(--brand)}

/* ═══════════════════════════ PRICING ═══════════════════════════════════ */
/* Four columns rather than three, and stretched rather than start-aligned: the
   teaser now carries the same four tiers as the pricing page, and cards of equal
   height are what let the CTA sit on one line across the row. */
.plans{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:20px;align-items:stretch}
.plan{
  position:relative;display:flex;flex-direction:column;
  padding:28px 24px 24px;border-radius:var(--r-lg);background:#fff;
  box-shadow:var(--sh-card);
  transition:var(--t-reveal),transform var(--t-card),box-shadow var(--t-card);
}
.plan:hover{transform:translateY(var(--lift));box-shadow:var(--sh-card-hover)}
.plan--hero{
  box-shadow:var(--sh-sm),0 0 0 2px var(--brand);
  background:linear-gradient(180deg,#FDFDFF,#fff 40%);
}
.plan--hero:hover{box-shadow:var(--sh-lg),0 0 0 2px var(--brand)}
.plan__badge{
  position:absolute;top:-13px;left:24px;
  padding:5px 12px;border-radius:var(--r-pill);
  background:var(--brand);color:#fff;
  font-size:var(--fs-3xs);font-weight:700;letter-spacing:var(--tr-caps);text-transform:uppercase;
  box-shadow:0 3px 10px rgba(99,91,255,.35);
}
.plan h3{font-family:var(--ff);font-size:var(--fs-md);font-weight:600;letter-spacing:var(--tr-caps-lg);text-transform:uppercase;color:var(--slate-400)}
.plan__p{
  margin-top:14px;font-family:var(--ff-d);font-size:var(--fs-3xl);font-weight:600;
  letter-spacing:var(--tr-xl);line-height:1;color:var(--ink);
}
.plan__cur{font-size:var(--fs-xl);font-weight:500;letter-spacing:var(--tr-lg);vertical-align:.35em;margin-right:2px;color:var(--slate-400)}
.plan__per{font-family:var(--ff);font-size:var(--fs-sm);font-weight:500;letter-spacing:var(--tr-sm);color:var(--slate-400);margin-left:4px}
.plan__for{margin-top:12px;font-size:var(--fs-sm);line-height:1.55;color:var(--slate-500);min-height:2.7em;text-wrap:pretty}
.plan .ticks{margin:24px 0;padding-top:24px;border-top:1px solid var(--line-soft)}
.plan .btn{margin-top:auto}
/* This was display:flex, which is right for a one-line badge and wrong for a
   paragraph. It now holds four sentences and a link, and under flex layout each
   run of text became an anonymous flex item: the trailing link was squeezed to
   115px and wrapped inside itself, 58px tall in a 22px line. A paragraph is a
   block. */
.plans__note{
  max-width:66ch;margin:32px auto 0;text-align:center;
  font-size:var(--fs-sm);line-height:1.6;color:var(--slate-500);text-wrap:pretty;
}
.plans__note .ico{
  display:inline-block;vertical-align:-2px;margin-right:5px;color:var(--slate-400);
}
/* The aggregate score used to be a 405px-tall grid of five near-identical
   numbers wedged between pricing and the FAQ. It is one line of evidence, so
   it gets one line, directly under the thing it is evidence for. */
.plans__rating{
  display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;
  margin-top:16px;font-size:var(--fs-xs);color:var(--slate-500);
}
.plans__rating b{color:var(--ink);font-weight:600}

.stars{display:flex;gap:2px;color:var(--lemon)}
.stars svg{width:15px;height:15px}
.stars--sm svg{width:13px;height:13px}

/* ═══════════════════════════ TESTIMONIAL ═══════════════════════════════ */
/* One customer, one number, one sentence. Nine thousand vertical pixels used
   to pass without a single quoted human being on them. */
.quote{
  max-width:820px;margin-inline:auto;padding:32px;
  background:#fff;border-radius:var(--r-lg);
  box-shadow:var(--sh-card);
  transition:var(--t-reveal),transform var(--t-card),box-shadow var(--t-card);
}
.quote:hover{transform:translateY(var(--lift));box-shadow:var(--sh-card-hover)}
.quote blockquote{
  margin:0;font-family:var(--ff-d);font-size:var(--fs-2xl);font-weight:500;
  letter-spacing:var(--tr-xl);line-height:1.28;color:var(--ink);text-wrap:pretty;
}
.quote blockquote b{font-weight:600;color:var(--brand-600)}
.quote__by{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-top:24px;padding-top:24px;border-top:1px solid var(--line-soft);
}
.quote__av{
  width:40px;height:40px;flex:none;display:grid;place-items:center;border-radius:50%;
  background:linear-gradient(140deg,var(--brand-100),var(--brand-50));
  color:var(--brand-700);
  font-size:var(--fs-sm);font-weight:700;letter-spacing:var(--tr-sm);
}
.quote__who{font-size:var(--fs-sm);color:var(--slate-500)}
.quote__who b{display:block;color:var(--ink);font-weight:600}
.quote__src{margin-left:auto;display:flex;align-items:center;gap:8px;font-size:var(--fs-2xs);color:var(--slate-400)}

/* ═══════════════════════════ FAQ ═══════════════════════════════════════ */
.faq{
  max-width:780px;background:#fff;border-radius:var(--r-lg);overflow:hidden;
  box-shadow:var(--sh-card);
}
.qa+.qa{border-top:1px solid var(--line-soft)}
.qa summary{
  display:flex;align-items:center;gap:16px;cursor:pointer;list-style:none;
  padding:20px 24px;
  font-size:var(--fs-lg);font-weight:600;letter-spacing:var(--tr-md);
  color:var(--ink);transition:color var(--t),background-color var(--t);
}
.qa summary::-webkit-details-marker{display:none}
.qa summary:hover{color:var(--brand-600);background:var(--brand-25)}
.qa summary .ico{margin-left:auto;flex:none;color:var(--slate-300);transform:rotate(90deg);transition:transform .25s var(--e),color var(--t)}
.qa[open] summary{color:var(--brand-600)}
.qa[open] summary .ico{transform:rotate(-90deg);color:var(--brand)}
/* 70ch rendered as ~88 characters — a third over the comfort ceiling. */
.qa p{
  padding:0 24px 24px;max-width:58ch;
  font-size:var(--fs-md);line-height:1.68;color:var(--slate);text-wrap:pretty;
  animation:qaIn .3s var(--e);
}
.qa code{
  font-size:var(--fs-xs);padding:1px 5px;border-radius:var(--r-sm);
  background:var(--bg-subdued);color:var(--brand-600);
  box-shadow:var(--ring-inset);
}
@keyframes qaIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}

/* ═══════════════════════════ FINAL CTA ═════════════════════════════════ */
.cta{
  position:relative;isolation:isolate;overflow:hidden;
  padding-block:var(--gap-md);text-align:center;
  background:linear-gradient(165deg,var(--ink) 0%,#0D2748 48%,#122054 100%);
}
.cta__band{position:absolute;inset:0;z-index:-1;overflow:hidden;opacity:.85}
/* These never animate, so they must not be GPU-promoted — two static
   full-bleed layers were being held in video memory for the life of the page. */
.cta__band .blob{will-change:auto;animation:none}
.cta__band .blob--1{--c:rgba(99,91,255,.6);width:70%;height:120%;left:-16%;top:-24%}
.cta::after{
  content:"";position:absolute;inset:auto 0 0 0;height:6px;z-index:-1;
  background:linear-gradient(90deg,var(--brand),#5169FF 34%,#1E9FE5 68%,var(--teal));
}
.cta__inner{display:flex;flex-direction:column;align-items:center}
.cta h2{
  margin-top:20px;color:#fff;
  font-size:var(--fs-4xl);
  letter-spacing:var(--tr-display);line-height:1.05;text-wrap:balance;
}
.cta p{margin-top:20px;max-width:52ch;font-size:var(--fs-lg);line-height:1.6;color:#B7C6D8;text-wrap:pretty}
.cta__btns{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-top:34px}
.cta__ticks{display:flex;gap:22px;flex-wrap:wrap;justify-content:center;margin-top:32px}
.cta__ticks li{display:flex;align-items:center;gap:8px;font-size:var(--fs-sm);font-weight:500;color:#9FB3C8}
.cta__ticks .ico{
  width:17px;height:17px;padding:3px;border-radius:50%;
  background:rgba(255,255,255,.12);color:var(--mint);stroke-width:3.4;
}

/* ═══════════════════════════ FOOTER ════════════════════════════════════ */
.foot{background:#fff;padding-top:var(--gap-sm)}
.foot__inner{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1.85fr);
  gap:56px;padding-bottom:56px;
}
.foot__brand .brand{margin-bottom:18px}
.foot__brand p{font-size:var(--fs-md);line-height:1.62;color:var(--slate-500);max-width:38ch;text-wrap:pretty}
.foot__stars{display:flex;align-items:center;gap:10px;margin-top:18px}
.foot__stars span{font-size:var(--fs-xs);color:var(--slate-400)}
.foot__cols{display:grid;grid-template-columns:repeat(3,1fr);gap:32px}
/* These were <h4>s under an <h2>-less footer — a heading level used purely to
   style a nav group label. They are labels, so they are paragraphs now. */
.foot__ttl{
  font-family:var(--ff);font-size:var(--fs-2xs);font-weight:700;letter-spacing:var(--tr-caps);
  text-transform:uppercase;color:var(--slate-400);margin-bottom:16px;
}
.foot__cols div{display:flex;flex-direction:column;gap:11px;align-items:flex-start}
.foot__cols a{font-size:var(--fs-md);color:var(--slate);transition:color var(--t)}
.foot__cols a:hover{color:var(--brand-600)}
.foot__bar{
  display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding-block:24px;border-top:1px solid var(--line-soft);
}
.foot__bar p{font-size:var(--fs-xs);color:var(--slate-400)}
/* Terms and Privacy measured 38x16 and 86x16 — under the 24px floor in WCAG 2.2
   SC 2.5.8. They sit in a footer bar rather than inline in a sentence, so the
   inline exemption does not apply. inline-block plus vertical padding lifts the
   hit area past 24px without moving a single pixel of rendered text. */
.foot__bar a{
  display:inline-block;margin-left:22px;padding-block:5px;
  transition:color var(--t)
}
.foot__bar a:first-child{margin-left:0}
.foot__bar a:hover{color:var(--brand-600)}

/* ═══════════════════════════ RESPONSIVE ════════════════════════════════ */
@media (max-width:1080px){
  .bento{grid-template-columns:repeat(2,1fr)}
  /* .card--wide used to keep span 2 here, so four of seven cards went
     full-width and the remaining three each sat alone beside an empty cell —
     four half-empty rows on every iPad landscape and small laptop.
     At two columns nothing spans, and the seven cards pack 3 x 2 with a single
     card trailing — one gap instead of four. */
  .card--wide,.card--map,.card--dark{grid-column:auto}
  .card--tall{grid-row:auto}
  .sample{grid-template-columns:1fr;gap:36px}
  .sample__copy>p{max-width:56ch}
  .plans{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}
}
@media (max-width:900px){
  :root{--gut:20px}
  .nav__links,.nav__actions{display:none}
  .nav__burger{display:flex}
  .nav__inner{justify-content:space-between}
  .brand{margin-right:auto}
  .hero{padding:132px 0 96px}
  .hero__band{bottom:170px;top:-340px}
  .sbar{flex-wrap:wrap;gap:4px;border-radius:var(--r-lg)}
  .sbar__f{flex:1 1 44%}
  .sbar__go{flex:1 1 100%;padding:13px 20px;margin-top:4px}
  .sources__grid,.steps{grid-template-columns:1fr}
  .foot__inner{grid-template-columns:1fr;gap:40px}
}
@media (max-width:680px){
  /* The rhythm scale shrinks as one system; every section edge follows. */
  :root{--gap-sm:48px; --gap-md:72px; --gap-lg:96px}
  .hero{padding:112px 0 76px}
  .hero__band{transform:skewY(-5deg);bottom:150px}
  .hero__band::after{height:260px}
  .bento{grid-template-columns:1fr}
  .card--wide{grid-column:auto}
  .card__body{padding:20px}
  .card__art{padding:0 20px 20px}
  .card--map .card__art--map{padding:0}
  .source,.step{padding:20px}
  .plans{grid-template-columns:1fr}
  .plan{padding:24px 20px 20px}
  .quote{padding:24px}
  .foot__cols{grid-template-columns:repeat(2,1fr)}
  .shead{margin-bottom:40px}
  .rescard__cta{flex-direction:column;align-items:stretch;text-align:center}
  .rescard__cta .btn{justify-content:center}
  .cta__btns .btn{flex:1 1 100%}
  .map__canvas{height:230px}
  .qa summary{padding:20px;font-size:var(--fs-md)}
  .qa p{padding:0 20px 20px}
}
@media (max-width:420px){
  .sbar__f{flex:1 1 100%}
  .foot__cols{grid-template-columns:1fr}
  .hero__note{gap:6px;font-size:var(--fs-xs)}
  .quote__src{margin-left:0;width:100%}
}

/* ═══════════════════════════ COARSE POINTER ════════════════════════════════
   The quality bar says ≥44px under (pointer:coarse) and ≥24px always. Neither
   was enforced anywhere in this file: measured on a phone the clear-field
   button was 22px, the filter chips and the draw-mode segments 34.8px, the
   small buttons 34px, the burger 40px and the arrow links 24px. Six control
   types, none of them reachable with a thumb.

   The floor is applied by growing padding, never by growing the drawn shape:
   a chip that renders 32px tall keeps rendering 32px tall, it just occupies
   44px of hit area. That is why the block is here at the end rather than in
   each component — it is one rule about hands, not twelve about looks. */
@media (pointer:coarse){
  .btn{min-height:44px}
  .btn--sm{min-height:44px;padding-block:10px}
  /* .btn--lg is declared before .btn is re-declared above, so without this it
     LOSES its 48px to the 44px floor and the large CTA shrinks on touch — the
     one place it should be biggest. */
  .btn--lg{min-height:48px}
  .tog,.seg__b{min-height:44px;padding-block:12px}
  .nav__links a{padding-block:11px}
  .link{padding-block:10px;margin-block:-10px}
  .sbar__go{min-height:48px}
  /* the drawn disc stays 24px; only the invisible hit box grows, 24 → 44 */
  .sbar__x::before{inset:-10px}
  .nav__burger{width:48px;height:48px}
  /* contiguous 44px rows is the right shape for a footer under a thumb */
  .foot__cols div{gap:0}
  .foot__cols a{padding-block:10px}
  .foot__bar a{padding-block:10px}
  #rating::-webkit-slider-thumb{width:24px;height:24px}
  #rating::-moz-range-thumb{width:24px;height:24px}
}

/* ═══════════════════════════ REDUCED MOTION ════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important;
  }
  .reveal{opacity:1;translate:none}
  .marquee__track{animation:none}
  .blob{animation:none}
  /* A spinner frozen mid-rotation by the blanket rule above is a broken arc,
     not a loading indicator. Close the ring and hold it at half strength: the
     button still reads as busy, without anything moving. */
  .btn.is-loading::after{border-color:var(--btn-fg);opacity:.55}
  .map__poly{stroke-dasharray:none;stroke-dashoffset:0}
}

/* ═══════════════════════════ OFF-SCREEN PARKING ════════════════════════
   Set by the IntersectionObserver in app.js. Freezing rather than stopping
   means the animation resumes mid-cycle, so nothing snaps when it scrolls
   back into view. */
.is-parked,
.is-parked *{animation-play-state:paused!important}

/* ── plan card: badged tier + quoted tier ───────────────────────────────────
   Growth is the recommended plan and says why on the card. Enterprise carries
   a phrase where the others carry a number, so it needs to occupy the same
   optical space as a price or the card row loses its baseline. */
.plan--best{
  position:relative;
  box-shadow:var(--sh-card-hover);
  outline:1.5px solid var(--brand-200);outline-offset:-1.5px;
}
.plan__quote{
  font-family:var(--ff-d);font-size:var(--fs-3xl);font-weight:600;
  letter-spacing:var(--tr-lg);color:var(--ink);
}
