/* Self-hosted, latin subset only.
   Space Grotesk is a VARIABLE font: Google serves one identical file for every
   weight. The first cut of this file downloaded it four times under four names
   — 66KB shipped for 22KB of data. One @font-face with a weight RANGE lets the
   browser synthesise all four weights from the single file. */
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url('assets/fonts/space-grotesk.woff2') format('woff2-variations'),
      url('assets/fonts/space-grotesk.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url('assets/fonts/ibm-plex-mono-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url('assets/fonts/ibm-plex-mono-500.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* KyndGuard marketing site
   ---------------------------------------------------------------------------
   No build step: one HTML file, one stylesheet, no dependencies.

   Design notes, so future edits keep the intent:

   • The shield logo is NOT transparent — it carries its own dark navy fill.
     On a white page it reads as a pasted rectangle. So the page is built dark,
     around #070B14, which is that same navy. The logo stops looking stuck on
     and starts looking part of the page.
   • Deliberately not a three-up card grid. Sections are numbered, features
     alternate against real product screenshots, and the type is editorial
     rather than the usual centred-hero-plus-cards SaaS template.
   • Monospace is used only for labels and status — it reads as an operations
     console, which is the business these customers are in.                    */

:root{
  --ink:#070B14;        /* the shield's own navy */
  --ink-2:#0C1322;
  --ink-3:#131C2E;
  --line:rgba(255,255,255,.09);
  --text:#E9EEF6;
  --muted:#94A2B8;
  --dim:#6B7A91;
  --blue:#2563EB;
  --blue-hi:#4B84FF;
  --green:#10B981;
  --paper:#FFFFFF;
  --paper-ink:#0B1220;
  --paper-muted:#5A677A;
  --cyan:#22D3EE;
  --violet:#7C5CFF;
  /* Space Grotesk: geometric with slightly odd terminals — reads technical
     without tipping into costume-military. Deliberately NOT the default
     system stack, which is what makes most pages look templated. */
  --sans:'Space Grotesk',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  background:var(--ink);
  color:var(--text);
  font-family:var(--sans);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}

.wrap{max-width:1180px;margin:0 auto;padding:0 28px}
.narrow{max-width:60ch}

/* ─── Type ──────────────────────────────────────────────────────────────── */
h1{
  font-size:clamp(2.6rem,7vw,5rem);
  line-height:.98;letter-spacing:-.04em;font-weight:800;margin:0 0 22px;
}
h1 em{font-style:normal;color:var(--blue-hi)}
h2{font-size:clamp(1.7rem,3.6vw,2.9rem);line-height:1.08;letter-spacing:-.03em;font-weight:750;margin:0 0 20px}
h3{font-size:clamp(1.25rem,2vw,1.6rem);line-height:1.15;letter-spacing:-.02em;font-weight:700;margin:0 0 12px}
p{margin:0 0 14px}
.lede{font-size:1.12rem;color:var(--muted);max-width:36em;margin-bottom:30px}
.body{color:var(--muted)}

.sec-label{
  font-family:var(--mono);font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--dim);margin:0 0 14px;
}
.tag{
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);border:1px solid var(--line);border-radius:999px;
  padding:6px 13px;margin:0 0 26px;
}
.fineprint{font-size:.84rem;color:var(--dim);margin:0}

/* ─── Buttons ───────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--blue);color:#fff;font-weight:650;font-size:.94rem;
  padding:12px 20px;border-radius:9px;border:1px solid var(--blue);
  transition:background .15s,transform .06s;white-space:nowrap;
}
.btn:hover{background:var(--blue-hi);border-color:var(--blue-hi)}
.btn:active{transform:translateY(1px)}
.btn-lg{padding:15px 28px;font-size:1rem}
.ghost{
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--text);font-weight:600;font-size:.94rem;padding:12px 18px;
  border:1px solid var(--line);border-radius:9px;transition:border-color .15s,background .15s;
}
.ghost:hover{border-color:rgba(255,255,255,.24);background:rgba(255,255,255,.04)}
.ghost-lg{padding:15px 24px;font-size:1rem}

/* ─── Nav ───────────────────────────────────────────────────────────────── */
.nav{position:sticky;top:0;z-index:60;background:rgba(7,11,20,.82);backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}
.nav-inner{display:flex;align-items:center;gap:30px;height:70px}
.brand{display:flex;align-items:center;gap:10px;font-size:1.06rem;letter-spacing:-.02em;font-weight:500}
.brand b{font-weight:800}
.nav-links{display:flex;gap:26px;margin-left:auto}
.nav-links a{color:var(--muted);font-size:.92rem;font-weight:550}
.nav-links a:hover{color:var(--text)}
.nav-cta{display:flex;gap:10px}

/* ─── Hero ──────────────────────────────────────────────────────────────── */
.hero{position:relative;padding-top:84px;overflow:hidden}
.hero::before{
  /* a single soft light source behind the headline — enough depth that the
     page doesn't read as a flat black rectangle */
  content:"";position:absolute;top:-280px;left:-160px;width:900px;height:760px;
  background:radial-gradient(closest-side,rgba(37,99,235,.30),transparent 70%);
  filter:blur(20px);pointer-events:none;
}
.hero-grid{
  position:relative;max-width:1180px;margin:0 auto;padding:0 28px;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.08fr);
  gap:56px;align-items:center;
}
.actions{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:16px}

/* The screenshot bleeds off the right edge — it reads as a window into a
   running system rather than a framed picture sitting in a box. */
.hero-shot{position:relative;margin-right:-16vw}
.hero-shot img{
  /* height:auto is load-bearing. The <img> carries width/height attributes so
     the browser can reserve space and avoid layout shift — but without
     height:auto it honours that fixed height against a 100% width and the
     screenshot renders squashed. */
  width:100%;height:auto;border-radius:14px;border:1px solid var(--line);
  box-shadow:0 40px 90px rgba(0,0,0,.62), 0 0 0 1px rgba(255,255,255,.04);
}

/* Capability strip under the hero.
   Was monospace, and on a phone it wrapped into five ragged lines that read as
   terminal output — the loudest 'AI template' tell on the page. Now sans, with
   a real label/descriptor hierarchy and an actual grid: five across on desktop
   with hairline dividers, two tidy columns on a phone. */
.ticker{margin-top:70px;border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:rgba(255,255,255,.02)}
.ticker-inner{display:grid;grid-template-columns:repeat(5,1fr);gap:0;padding:0 28px}
.ticker-inner > div{padding:22px 22px 22px 0;border-left:1px solid var(--line);padding-left:22px}
.ticker-inner > div:first-child{border-left:0;padding-left:0}
.ticker b{display:block;color:var(--text);font-weight:650;font-size:.95rem;letter-spacing:-.015em;margin-bottom:4px}
.ticker span{display:block;color:var(--dim);font-size:.84rem;line-height:1.45}
@media (max-width:900px){
  .ticker-inner{grid-template-columns:1fr 1fr;padding:0 24px}
  .ticker-inner > div{padding:18px 16px;border-left:1px solid var(--line);border-top:1px solid var(--line)}
  .ticker-inner > div:nth-child(odd){border-left:0;padding-left:0}
  .ticker-inner > div:nth-child(-n+2){border-top:0}
  .ticker-inner > div:last-child{grid-column:1 / -1;border-left:0;padding-left:0}
}
@media (max-width:420px){
  .ticker b{font-size:.9rem}
  .ticker span{font-size:.8rem}
}

/* ─── Sections ──────────────────────────────────────────────────────────── */
.section{padding:110px 0}
.section.tight{padding:80px 0}
.band{padding:110px 0;background:var(--ink-2);border-block:1px solid var(--line)}

.probs{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;margin-top:44px;background:var(--line);border:1px solid var(--line);border-radius:14px;overflow:hidden}
.probs > div{background:var(--ink-2);padding:30px 26px}
.probs span{display:block;font-family:var(--mono);font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;color:var(--blue-hi);margin-bottom:12px}
.probs p{color:var(--muted);margin:0;font-size:.96rem}

/* ─── Feature rows ──────────────────────────────────────────────────────── */
.feature-shot img{
  width:100%;height:auto;border-radius:12px;border:1px solid var(--line);
  box-shadow:0 26px 60px rgba(0,0,0,.5);
}

/* ─── Coverage ──────────────────────────────────────────────────────────── */
.split-inner{display:grid;grid-template-columns:1.05fr .95fr;gap:64px;align-items:center}
.chips{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.chip{border:1px solid var(--line);border-radius:12px;padding:18px;background:rgba(255,255,255,.02)}
.chip b{display:block;font-size:1rem;letter-spacing:-.01em}
.chip span{font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}


/* ─── Pricing ───────────────────────────────────────────────────────────── */

/* ─── FAQ ───────────────────────────────────────────────────────────────── */
.faq-wrap{max-width:820px}
details{border-bottom:1px solid var(--line);padding:20px 0}
details:first-of-type{border-top:1px solid var(--line);margin-top:34px}
summary{cursor:pointer;font-weight:620;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:18px;font-size:1.02rem}
summary::-webkit-details-marker{display:none}
summary::after{content:"+";color:var(--blue-hi);font-weight:700;font-size:1.3rem;line-height:1;flex-shrink:0}
details[open] summary::after{content:"–"}
details p{color:var(--muted);margin:12px 0 0;font-size:.96rem;max-width:70ch}

/* ─── CTA + footer ──────────────────────────────────────────────────────── */
.cta{padding:120px 0;text-align:center;background:
  radial-gradient(60% 120% at 50% 0%,rgba(37,99,235,.20),transparent 70%),var(--ink-2);
  border-top:1px solid var(--line)}
.cta h2{margin-bottom:28px}

.footer{background:var(--ink);padding:70px 0 34px;border-top:1px solid var(--line);font-size:.92rem}
.foot-inner{display:grid;grid-template-columns:2fr 1fr 1fr;gap:44px}
.foot-brand p{color:var(--dim);margin:14px 0 0;max-width:32ch;font-size:.88rem}
.foot-col h4{font-family:var(--mono);font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:var(--dim);margin:0 0 14px;font-weight:600}
.foot-col a{display:block;color:var(--muted);margin-bottom:9px}
.foot-col a:hover{color:var(--text)}
.foot-legal{margin-top:52px;padding-top:22px;border-top:1px solid var(--line);color:var(--dim);font-size:.8rem}
.foot-legal p{margin:0 0 6px}
.tiny{font-size:.74rem;color:#4E5C71;max-width:80ch}

/* ─── Responsive ────────────────────────────────────────────────────────── */
@media (max-width:1040px){
  .hero-grid{grid-template-columns:1fr;gap:44px}
  .hero-shot{margin-right:0}
  .feature,.split-inner{grid-template-columns:1fr;gap:32px}
  .probs{grid-template-columns:1fr}
  .foot-inner{grid-template-columns:1fr 1fr;gap:32px}
  .nav-links{display:none}
  .section,.band{padding:72px 0}
  .hero{padding-top:56px}
}
@media (max-width:620px){
  .wrap,.hero-grid{padding:0 20px}
  .actions .btn,.actions .ghost{width:100%}
  .chips{grid-template-columns:1fr}
  .foot-inner{grid-template-columns:1fr}
  .nav-cta .ghost{display:none}
  .cta{padding:80px 0}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .btn,.ghost{transition:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOTION + additions
   ---------------------------------------------------------------------------
   Reveal classes are applied BY app.js, never by default, so a visitor with
   JS disabled (or a crawler that does not execute it) gets the fully rendered
   page rather than an empty one.
   ═══════════════════════════════════════════════════════════════════════════ */

.pre-reveal{opacity:0;transform:translateY(18px)}
.pre-reveal.is-revealed{
  opacity:1;transform:none;
  transition:opacity .68s cubic-bezier(.22,.61,.36,1), transform .68s cubic-bezier(.22,.61,.36,1);
}

.skip{position:absolute;left:-9999px;top:0;background:var(--blue);color:#fff;padding:10px 16px;z-index:200;border-radius:0 0 8px 0}
.skip:focus{left:0}

.nav{transition:background .25s,border-color .25s}
.nav.is-stuck{background:rgba(7,11,20,.94);border-bottom-color:rgba(255,255,255,.14)}

.hero-shot{will-change:transform}
.hero-shot img{transition:transform .5s cubic-bezier(.22,.61,.36,1)}

/* Feature screenshots lift very slightly on hover — enough to feel alive,
   not enough to be a distraction while reading. */

.chip{transition:border-color .22s,background .22s,transform .22s}
.chip:hover{border-color:rgba(75,132,255,.5);background:rgba(37,99,235,.09);transform:translateY(-2px)}

.probs > div{transition:background .22s}
.probs > div:hover{background:var(--ink-3)}

details{transition:border-color .2s}
details[open]{border-color:rgba(75,132,255,.34)}
summary::after{transition:transform .22s}
details[open] summary::after{transform:rotate(180deg)}
details[open] p{animation:fade .34s ease both}
@keyframes fade{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:none}}

/* ─── Trust grid ────────────────────────────────────────────────────────── */
.trust-grid{display:grid;grid-template-columns:.85fr 1.15fr;gap:60px;align-items:start}
.trust-list{display:grid;grid-template-columns:1fr 1fr;gap:34px}
.trust-list h3{font-size:1.02rem;margin-bottom:8px}
.trust-list p{color:var(--muted);font-size:.94rem;margin:0}

/* ─── Mobile nav ────────────────────────────────────────────────────────── */
.burger{display:none;flex-direction:column;gap:5px;background:none;border:0;cursor:pointer;padding:8px;margin-left:auto}
.burger span{display:block;width:22px;height:2px;background:var(--text);transition:transform .25s,opacity .25s}
.burger[aria-expanded="true"] span:first-child{transform:translateY(3.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:last-child{transform:translateY(-3.5px) rotate(-45deg)}
.mobile-menu{display:none;flex-direction:column;gap:4px;padding:16px 28px 26px;border-bottom:1px solid var(--line);background:var(--ink)}
.mobile-menu.is-open{display:flex}
.mobile-menu a{padding:11px 0;color:var(--muted);font-size:1rem;border-bottom:1px solid var(--line)}
.mobile-menu a:last-child{border-bottom:0;margin-top:12px;justify-content:center}

@media (max-width:1040px){
  .trust-grid{grid-template-columns:1fr;gap:30px}
}
@media (max-width:820px){
  .burger{display:flex}
  .nav-cta{display:none}
  .trust-list{grid-template-columns:1fr;gap:26px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   ANIMATED GRADIENT + AURORA
   ---------------------------------------------------------------------------
   The headline carries a slow colour sweep rather than a flat fill, and the
   hero sits over two drifting light sources. Both are pure CSS — no canvas, no
   library, no JS — so they cost nothing on load and stop entirely under
   prefers-reduced-motion.
   ═══════════════════════════════════════════════════════════════════════════ */

h1{
  background:linear-gradient(100deg,
    #FFFFFF 0%, #FFFFFF 22%,
    var(--cyan) 38%, var(--blue-hi) 50%, var(--violet) 62%,
    #FFFFFF 80%, #FFFFFF 100%);
  background-size:260% 100%;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  animation:sweep 9s ease-in-out infinite;
}
h1 em{
  /* The emphasised line keeps its own stronger tint so the sweep reads as
     movement across a headline, not as a colour wash over everything. */
  background:linear-gradient(100deg,var(--blue-hi),var(--cyan),var(--violet),var(--blue-hi));
  background-size:260% 100%;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  animation:sweep 7s ease-in-out infinite reverse;
}
@keyframes sweep{
  0%,100%{background-position:0% 50%}
  50%{background-position:100% 50%}
}

/* Two slow-drifting light sources. Large, heavily blurred and low opacity —
   the goal is depth, not a light show. */
.hero::before{
  content:"";position:absolute;top:-320px;left:-200px;width:980px;height:820px;
  background:radial-gradient(closest-side,rgba(37,99,235,.34),transparent 70%);
  filter:blur(26px);pointer-events:none;
  animation:drift-a 22s ease-in-out infinite;
}
.hero::after{
  content:"";position:absolute;top:-140px;right:-260px;width:820px;height:720px;
  background:radial-gradient(closest-side,rgba(124,92,255,.24),transparent 70%);
  filter:blur(30px);pointer-events:none;z-index:0;
  animation:drift-b 27s ease-in-out infinite;
}
.hero-grid{z-index:1}
@keyframes drift-a{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  50%{transform:translate3d(90px,50px,0) scale(1.10)}
}
@keyframes drift-b{
  0%,100%{transform:translate3d(0,0,0) scale(1.04)}
  50%{transform:translate3d(-80px,60px,0) scale(.94)}
}

/* A hairline of colour under the sticky nav — ties the header to the hero. */
.nav::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:linear-gradient(90deg,transparent,var(--blue-hi),var(--cyan),var(--violet),transparent);
  background-size:220% 100%;opacity:.55;
  animation:sweep 11s linear infinite;
}
.nav{position:sticky;overflow:visible}

/* The live dot actually pulses — it is the one element claiming to be live. */
@keyframes pulse{
  0%,100%{box-shadow:0 0 0 3px rgba(16,185,129,.18)}
  50%{box-shadow:0 0 0 6px rgba(16,185,129,.05)}
}

/* Type refinements for Space Grotesk, which sets tighter than a system font. */
body{letter-spacing:-.005em}
h1{letter-spacing:-.045em;font-weight:700}
h2{letter-spacing:-.032em;font-weight:700}
h3{letter-spacing:-.022em;font-weight:600}
.btn,.ghost{font-weight:600;letter-spacing:-.01em}
.brand{font-weight:400}
.brand b{font-weight:700}

@media (prefers-reduced-motion:reduce){
  h1,h1 em,.nav::after,.live,.hero::before,.hero::after{animation:none}
  h1{-webkit-text-fill-color:#fff;color:#fff;background:none}
  h1 em{-webkit-text-fill-color:var(--blue-hi);background:none}
}

/* Kicker replaces the pill badge that used to sit above the headline.
   Pill-shaped eyebrow badges are the single most recognisable tell of a
   templated landing page — a plain typographic kicker with a rule reads as
   editorial instead. */
.kicker{
  font-family:var(--mono);font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);margin:0 0 22px;padding-left:46px;position:relative;
}
.kicker::before{
  content:"";position:absolute;left:0;top:.62em;width:34px;height:1px;
  background:linear-gradient(90deg,var(--blue-hi),transparent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   AUDIT FIXES — verified against the live files, not assumed
   ═══════════════════════════════════════════════════════════════════════════ */

/* Nav dead zone. .nav-links hid at 1040px but .burger only appeared at 820px,
   so between 821 and 1040 there was NO navigation at all — exactly the width
   of iPad landscape and a half-screen laptop window, which is how a small
   business owner actually evaluates software. */
@media (max-width:1040px){
  .burger{display:flex}
  .nav-cta{display:none}
}

/* The mobile menu had no upper-width guard while app.js locks body scroll.
   Open it on a phone, rotate to landscape (844px on an iPhone 14) and the
   burger vanishes, the menu stays open, and the page cannot be scrolled or
   closed — recoverable only by reloading. */
@media (min-width:1041px){
  .mobile-menu, .mobile-menu.is-open{display:none}
}

/* Contrast. --dim failed 4.5:1 on every surface except --ink. */
:root{ --dim:#8593A8; }

/* .mobile-menu a beat .btn on specificity, so the ONLY call-to-action a phone
   user can reach rendered grey-on-blue at 2.0:1 and lost its padding. */
.mobile-menu a:not(.btn){color:var(--muted)}
.mobile-menu .btn{color:#fff;padding:14px 20px;border-bottom:0}

/* Was #4E5C71 — 2.9:1, the worst on the page, and it carries the disclaimer
   saying the screenshot figures are illustrative. That line has to be legible. */
.tiny{color:var(--dim);font-size:.8rem}

/* .btn:hover went from 5.17:1 to 3.47:1 — hover made it harder to read. */
.btn:hover{background:#1D4FD8;border-color:#1D4FD8}

/* Ticker padding collapsed on phones: .wrap's shorthand at a later line won
   and took the block padding with it. */
@media (max-width:620px){
  .ticker-inner{padding:16px 20px}
}

/* Nothing should ever distort again. The screenshots set height:auto
   explicitly, so this is safe as a global backstop. */
img{height:auto}

/* The animated headline gradient relies on background-clip:text. Under Windows
   High Contrast the background is replaced and the text becomes INVISIBLE, and
   it prints blank. Keep the effect — restore a solid fill where it cannot work. */
@media (forced-colors:active){
  h1,h1 em{
    -webkit-text-fill-color:CanvasText;color:CanvasText;
    background:none;animation:none;
  }
}
@media print{
  h1,h1 em{-webkit-text-fill-color:#000;color:#000;background:none;animation:none}
}

/* ── Pricing tiers ─────────────────────────────────────────────────────────
   Three cards, per-guard pricing, with a USD/CAD switch. Amounts carry both
   currencies as data-attributes so switching never refetches or reflows the
   page — see app.js. The numbers themselves are recorded in DECISIONS.md
   together with the market rates they were set against. */
.cur-switch{display:inline-flex;gap:4px;margin-top:28px;padding:4px;
  border:1px solid var(--line);border-radius:999px;background:rgba(255,255,255,.03)}
.cur-btn{appearance:none;border:0;cursor:pointer;border-radius:999px;
  padding:8px 18px;font:inherit;font-size:.85rem;font-weight:600;letter-spacing:-.01em;
  color:var(--muted);background:transparent;transition:background .18s,color .18s}
.cur-btn:hover{color:var(--text)}
.cur-btn.is-on{background:var(--blue);color:#fff}
.cur-btn:focus-visible{outline:2px solid var(--blue-hi);outline-offset:2px}

.tiers{display:grid;gap:20px;margin-top:34px;
  grid-template-columns:repeat(auto-fit,minmax(280px,1fr));align-items:start}
.tier{position:relative;border:1px solid var(--line);border-radius:16px;
  padding:30px 26px;background:var(--ink-3);display:flex;flex-direction:column;height:100%}
.tier.is-featured{border-color:rgba(75,132,255,.45);
  background:linear-gradient(180deg,rgba(37,99,235,.14),var(--ink-3) 62%)}
.tier-flag{position:absolute;top:-11px;left:26px;font-family:var(--mono);
  font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;
  background:var(--blue);color:#fff;padding:4px 10px;border-radius:999px}
.tier h3{font-size:1.15rem;font-weight:700;letter-spacing:-.02em;margin:0 0 4px}
/* Reserve exactly two lines. The line box is 1.6em, so 2.4em only fits one and
   a half and the two-line subtitle pushed its whole card out of alignment with
   the other two. */
.tier-for{color:var(--dim);font-size:.86rem;margin:0 0 18px;min-height:3.2em}
.tier-price{display:flex;align-items:baseline;gap:6px;margin:0 0 6px}
.tier-price .amt{font-size:2.6rem;font-weight:750;letter-spacing:-.04em;line-height:1}
.tier-price .amt::before{content:"$";font-size:1.3rem;font-weight:600;
  vertical-align:super;margin-right:1px}
.tier-price .per{color:var(--muted);font-size:.84rem}
.tier-min{color:var(--dim);font-size:.8rem;margin:0 0 20px;
  padding-bottom:20px;border-bottom:1px solid var(--line)}
.tier ul{list-style:none;margin:0 0 26px;padding:0;display:grid;gap:10px;flex:1}
.tier li{position:relative;padding-left:22px;font-size:.9rem;color:var(--muted);line-height:1.5}
.tier li::before{content:"";position:absolute;left:0;top:.5em;width:10px;height:2px;
  border-radius:2px;background:var(--green)}
.tier .btn,.tier .ghost{width:100%;justify-content:center;text-align:center}
.fineprint.centred{text-align:center;max-width:56ch;margin:30px auto 0}

/* One column on narrow screens; the featured card keeps its emphasis but
   loses the lift so it does not look detached from the stack. */
@media (max-width:720px){
  .tier-for{min-height:0}
  .tier-price .amt{font-size:2.2rem}
}

/* ===========================================================================
   2026-08-01 (rev 2) — design pass.
   Rev 1 feedback: cursor too big and laggy, the enlarge-on-click was unwanted,
   and the capability list "just sitting there in bulk" was not attractive.
   This replaces all of that. Palette, fonts and section numbering still
   untouched — the design Hassan approved stays underneath.
   ========================================================================= */

/* ── Ambient backdrop ────────────────────────────────────────────────────── */
#bg{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;opacity:.45}
@media (prefers-reduced-motion:reduce){#bg{display:none}}
/* NOTE: .nav is deliberately NOT in this list. It is position:sticky, and
   including it here silently overrode that (later rule, equal specificity) —
   the header stopped sticking and nobody noticed for two deploys. Only main
   and the footer need lifting above the canvas backdrop. */
main,.footer{position:relative;z-index:1}

.progress{position:fixed;top:0;left:0;height:2px;width:100%;z-index:80;
  transform-origin:0 50%;transform:scaleX(0);
  background:linear-gradient(90deg,var(--blue),var(--cyan));pointer-events:none}
@media (prefers-reduced-motion:reduce){.progress{display:none}}

/* ── Cursor ──────────────────────────────────────────────────────────────────
   Sleeker than rev 1: 18px instead of 34, a hairline instead of a 1px ring at
   full opacity, no crosshair ticks, and it tracks much closer to the pointer
   (0.42 easing, was 0.18 — the lag was the main complaint). */
@media (hover:hover) and (pointer:fine){
  html.has-cursor,html.has-cursor *{cursor:none !important}
  .cur,.cur-dot{position:fixed;top:0;left:0;z-index:90;pointer-events:none;
    border-radius:50%;will-change:transform}
  .cur{width:18px;height:18px;margin:-9px 0 0 -9px;
    border:1px solid rgba(150,180,255,.42);
    transition:width .18s ease,height .18s ease,margin .18s ease,
               border-color .18s,background-color .18s,opacity .16s}
  .cur-dot{width:3px;height:3px;margin:-1.5px 0 0 -1.5px;background:var(--blue-hi)}
  html.cur-hot .cur{width:34px;height:34px;margin:-17px 0 0 -17px;
    border-color:rgba(75,132,255,.85);background:rgba(75,132,255,.09)}
  html.cur-hot .cur-dot{opacity:0}
  html.cur-down .cur{width:14px;height:14px;margin:-7px 0 0 -7px}
  html.cur-out .cur,html.cur-out .cur-dot{opacity:0}
}
@media (prefers-reduced-motion:reduce){
  html.has-cursor,html.has-cursor *{cursor:auto !important}
  .cur,.cur-dot{display:none}
}

/* ── Product showcases ───────────────────────────────────────────────────────
   The screenshot runs the full wrap width. These are 2x-DPR captures, so a
   2090px crop at 1180px is a 0.565 downscale — 16px UI text lands at ~18px on
   screen and reads without any click-to-enlarge. Eight narrow alternating rows
   were both unreadable and monotonous. */
.shows{display:grid;gap:clamp(64px,8vw,116px);margin-top:clamp(44px,5vw,72px)}
.show{margin:0}
.show-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(20px,4vw,60px);align-items:end;margin-bottom:26px}
.show-eyebrow{font-family:var(--mono);font-size:.7rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--blue-hi);margin:0 0 10px}
.show-head h3{margin:0;font-size:clamp(1.5rem,2.7vw,2.15rem);line-height:1.1;
  letter-spacing:-.028em}
.show-body{color:var(--muted);margin:0;font-size:1rem;line-height:1.65;max-width:46ch}

.show-shot{margin:0;border-radius:14px;overflow:hidden;
  border:1px solid var(--line);background:var(--ink-2);
  box-shadow:0 34px 80px -28px rgba(0,0,0,.9),0 0 0 1px rgba(255,255,255,.03)}
.show-shot img{width:100%;height:auto;display:block}

.show-points{list-style:none;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  gap:14px clamp(20px,3vw,44px);margin:22px 0 0;padding:0}
.show-points li{position:relative;padding-left:22px;color:var(--muted);
  font-size:.92rem;line-height:1.5}
.show-points li::before{content:"";position:absolute;left:0;top:.6em;width:10px;
  height:1px;background:var(--blue-hi)}

/* ── Capability clusters ─────────────────────────────────────────────────────
   Six themed groups with a lead line each, rather than 26 identical cells in
   one flat table. The eye gets somewhere to rest and a reader can skip to the
   part they care about. */
.clusters{display:grid;gap:clamp(38px,4.5vw,64px);margin-top:clamp(40px,5vw,64px)}
.cluster{margin:0}
.cluster-head{display:flex;flex-wrap:wrap;align-items:baseline;
  gap:6px clamp(14px,2vw,26px);padding-bottom:18px;
  border-bottom:1px solid var(--line);margin-bottom:24px}
.cluster-head h3{margin:0;font-size:clamp(1.15rem,1.7vw,1.45rem);letter-spacing:-.022em}
.cluster-head p{margin:0;color:var(--dim);font-size:.92rem}
/* Exactly three columns at desktop. Groups are sized 6 or 3 so the last
   row is always full — a single orphaned card read as dead space. */
.cluster-items{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(18px,2.4vw,32px)}
.ci h4{margin:0 0 6px;font-size:.97rem;font-weight:700;letter-spacing:-.015em}
.ci p{margin:0;color:var(--muted);font-size:.88rem;line-height:1.55}

@media (max-width:980px){.cluster-items{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:620px){.cluster-items{grid-template-columns:1fr}}
@media (max-width:820px){
  .show-head{grid-template-columns:1fr;align-items:start}
  .cluster-head{align-items:start}
  .show-head{gap:14px}
  .cluster-head{gap:8px}
}
@media print{#bg,.cur,.cur-dot,.progress{display:none !important}}

.chips-note{margin-top:18px;max-width:52ch;line-height:1.55}

/* ── The argument (section 02) ───────────────────────────────────────────────
   Deliberately NOT another card grid: prose on the left carrying the rate
   argument, three short beats on the right marking the moments it pays off.
   Breaking the rhythm here is the point — every other section on the page is
   a grid, and uniformity is what made it read as generated. */
.why-wrap{max-width:1080px}
.why-body{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:clamp(30px,5vw,72px);margin-top:clamp(28px,3.5vw,44px);align-items:start}
.why-body .body{font-size:1.05rem;line-height:1.7;margin-bottom:18px}
.why-body .body:last-child{margin-bottom:0}
.why-body em{font-style:normal;color:var(--text);font-weight:600}
.why-beats{display:grid;gap:26px;padding-left:clamp(0px,2vw,26px);
  border-left:1px solid var(--line)}
.why-beats > div{padding-left:clamp(14px,1.6vw,22px)}
.why-beats h3{font-size:1rem;margin:0 0 7px;letter-spacing:-.015em}
.why-beats p{margin:0;color:var(--muted);font-size:.92rem;line-height:1.55}
@media (max-width:860px){
  .why-body{grid-template-columns:1fr;gap:32px}
  .why-beats{border-left:0;padding-left:0;border-top:1px solid var(--line);padding-top:26px}
  .why-beats > div{padding-left:0}
}

/* ═══ Review fixes ═════════════════════════════════════════════════════════
   Measured, not guessed. Each number below came from instrumenting the
   rendered page rather than eyeballing a screenshot. */

/* 1. HERO — the headline was rendering as FIVE ragged lines at 1440px
   (measured 392px tall ÷ 78px line-height, in a 513px column at 80px type),
   leaving two single-word lines with dead space beside them. Widen the copy
   column and cap the size so the two authored <br>s produce three lines. */
@media (min-width:981px){
  .hero-grid{grid-template-columns:minmax(0,1.12fr) minmax(0,1fr)}
  h1{font-size:clamp(2.6rem,4.5vw,4rem)}
}

/* 2. MOBILE SCREENSHOTS — the real regression. At 375px a 2090px capture was
   rendering 333px wide: a 0.159 downscale, putting 16px UI text at ~5px. The
   enlarge-on-click that used to cover this was removed by request, so instead
   the shot keeps a readable scale and the reader pans it sideways. 0.45 scale
   puts that same text back at ~14px. */
@media (max-width:820px){
  .show-shot{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
    scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.22) transparent}
  .show-shot img{width:auto;height:auto;min-width:940px;max-width:none}
  .show-shot::-webkit-scrollbar{height:6px}
  .show-shot::-webkit-scrollbar-thumb{background:rgba(255,255,255,.22);border-radius:3px}
  .show-shot + .show-points{margin-top:10px}
  .show-shot{position:relative}
  /* Tell the reader it moves — an image that silently clips looks broken. */
  .show::after{content:"Scroll the screenshot sideways to read it";
    display:block;font-size:.76rem;color:var(--dim);margin-top:9px}
}

/* 3. Three bullets were sitting in a 4-column auto-fit grid, so every one of
   the eight showcases carried a trailing empty column. */
.show-points{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:820px){.show-points{grid-template-columns:1fr}}

/* 4. The featured pricing badge was a rounded uppercase mono pill — the exact
   element this page's own CSS notes call "the single most recognisable tell of
   a templated landing page", reintroduced on the most prominent card. Replaced
   with a flat label set on the card's top edge. */
.tier-flag{position:static;display:block;border-radius:0;background:none;
  padding:0 0 12px;margin:0 0 14px;border-bottom:1px solid rgba(75,132,255,.35);
  color:var(--blue-hi);font-family:var(--sans);font-size:.8rem;font-weight:600;
  letter-spacing:-.01em;text-transform:none}
.cur-switch,.cur-btn{border-radius:8px}

/* 5. CURSOR — at rest it is now 18px, but hover grew it back to 34px, which is
   the size that drew the complaint, and hover is the state you are in most of
   the time on a page this dense. Cap it lower and animate transform rather
   than width/height/margin, which forced layout on every hover. */
@media (hover:hover) and (pointer:fine){
  .cur{transition:transform .16s cubic-bezier(.22,.61,.36,1),
                  border-color .16s,background-color .16s,opacity .16s}
  html.cur-hot .cur{width:18px;height:18px;margin:-9px 0 0 -9px;
    border-color:rgba(75,132,255,.9);background:rgba(75,132,255,.10)}
  html.cur-down .cur{width:18px;height:18px;margin:-9px 0 0 -9px}
}

/* Hardcoded <br>s forced a 22-character line ("without the guesswork.") that
   could not fit the copy column at any hero-sized type, so the headline kept
   wrapping to four or five ragged lines. Let the browser balance it instead
   and give the column enough room to land on three. */
h1{text-wrap:balance}
@media (min-width:981px){
  .hero-grid{grid-template-columns:minmax(0,1.22fr) minmax(0,1fr)}
  h1{font-size:clamp(2.6rem,4.2vw,3.65rem)}
}

/* The pannable mobile screenshot escaped its container: a grid item will not
   shrink below its content's intrinsic width unless min-width is reset, so the
   940px image widened the whole page instead of scrolling inside its figure. */
@media (max-width:820px){
  .shows,.show,.show-shot{min-width:0}
  .show-shot{max-width:100%}
}

/* These four were the only animations left without a reduced-motion escape:
   the FAQ answer fade-in, the FAQ chevron rotation, the coverage-chip hover
   lift, and the burger's rotate-to-X. Everything else was already covered. */
@media (prefers-reduced-motion:reduce){
  .faq-wrap details[open] p{animation:none}
  .faq-wrap summary::after{transition:none}
  .chip{transition:none}
  .chip:hover{transform:none}
  .burger span{transition:none}
}

/* ═══ Showcase rhythm ══════════════════════════════════════════════════════
   Audited: all eight images measured 1124x646 at left:158 — identical size,
   identical axis, eight times, and the section was 7,873px of a 16,431px page.
   Same size + same centre line = nothing for the eye to catch on.

   Three treatments now alternate:
     .show--wide    full wrap width, full height. The two flagships.
     .show--bleed-* copy in a narrow column, image running off the viewport
                    edge at a LARGER pixel scale — more dynamic AND more
                    readable, because it is clipped rather than shrunk.
     .show--band    full width, cropped to a short band. Varies vertical
                    weight without touching horizontal scale, so legibility
                    is unaffected.
   Legibility is never traded for layout: no treatment renders the capture
   below ~0.53 scale (≈17px effective UI text). */

/* Distance from the wrap edge out to the viewport edge. */
:root{--gutter:calc((100vw - min(calc(100vw - 56px), 1180px)) / 2)}

@media (min-width:981px){
  .show--bleed-r,.show--bleed-l{
    display:grid;column-gap:clamp(28px,3.4vw,56px);
    grid-template-columns:minmax(0,.44fr) minmax(0,.56fr);
    align-items:center}
  .show--bleed-r{grid-template-areas:"head shot" "points shot"}
  .show--bleed-l{grid-template-areas:"shot head" "shot points";
    grid-template-columns:minmax(0,.56fr) minmax(0,.44fr)}
  .show--bleed-r .show-head,.show--bleed-l .show-head{grid-area:head;
    display:block;margin-bottom:20px;align-self:end}
  .show--bleed-r .show-points,.show--bleed-l .show-points{grid-area:points;
    grid-template-columns:1fr;gap:11px;margin-top:0;align-self:start}
  .show--bleed-r .show-shot,.show--bleed-l .show-shot{grid-area:shot;align-self:center}
  .show--bleed-r .show-body,.show--bleed-l .show-body{max-width:100%}

  /* Run past the viewport edge, and show the capture BIGGER while doing it.
     body already has overflow-x:hidden, so the excess is clipped cleanly. */
  .show--bleed-r .show-shot{margin-right:calc(-1 * var(--gutter) - 70px);
    border-radius:14px 0 0 14px;border-right:0}
  .show--bleed-l .show-shot{margin-left:calc(-1 * var(--gutter) - 70px);
    border-radius:0 14px 14px 0;border-left:0}
  .show--bleed-r .show-shot img,.show--bleed-l .show-shot img{
    width:1340px;max-width:none}
  .show--bleed-l .show-shot img{margin-left:auto;display:block}

  /* A short band: same horizontal scale, a third of the height. */
  .show--band .show-shot{aspect-ratio:1180/300;overflow:hidden}
  .show--band .show-shot img{height:100%;object-fit:cover;object-position:50% 0}
}

/* Below 981px every treatment collapses to the single-column stack, which
   already pans horizontally on phones. */
@media (max-width:980px){
  .show--bleed-r,.show--bleed-l{display:block}
  .show--bleed-r .show-shot,.show--bleed-l .show-shot{
    margin:0;border-radius:14px;border-width:1px}
  .show--bleed-r .show-shot img,.show--bleed-l .show-shot img{width:100%}
}

/* The bleed image is ~770px tall while its copy is ~330px, and the two grid
   rows were distributing the slack — leaving the headline stranded low with a
   200px hole above it. Pack the rows to their content and centre the pair as a
   single block against the image. */
@media (min-width:981px){
  .show--bleed-r,.show--bleed-l{
    grid-template-rows:min-content min-content;align-content:center}
  .show--bleed-r .show-head,.show--bleed-l .show-head{align-self:end;margin-bottom:18px}
  .show--bleed-r .show-points,.show--bleed-l .show-points{align-self:start}
}

/* The bleed deliberately overhangs the viewport, so the overhang must be
   clipped somewhere. NOT on <html> or <body>: I tried that and it killed the
   sticky nav outright (measured nav top at -3000px after a 3000px scroll).
   Clipping on <main> works because the nav lives outside it — the overhang is
   contained and the header still sticks. */
main{overflow-x:clip}

/* ═══ Product rows, rebuilt (rev 5) ════════════════════════════════════════
   The bleed/band experiment shipped misaligned slabs and sliver crops — the
   page read as unfinished. This is the deliberately boring, correct version:
   ONE treatment executed consistently. Copy beside a window-framed screenshot,
   alternating sides, identical frame size on every row, everything on the
   wrap grid. All .show / .shows rules above are inert (markup renamed).      */

.feats{display:grid;gap:clamp(56px,7vw,96px);margin-top:clamp(40px,5vw,64px)}
.feat{display:grid;align-items:center;gap:clamp(28px,4vw,64px)}
@media (min-width:901px){
  .feat{grid-template-columns:minmax(0,.40fr) minmax(0,.60fr)}
  /* Flipping ONLY the order put the frame into the narrow .42fr column on
     alternate rows (measured 619px vs 448px). The column widths must swap
     with it so the frame is the same size on every row. */
  .feat.flip{grid-template-columns:minmax(0,.60fr) minmax(0,.40fr)}
  .feat.flip .feat-copy{order:2}
  .feat.flip .feat-frame{order:1}
}
.feat-kicker{font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--blue-hi);margin:0 0 10px}
.feat-copy h3{margin:0 0 12px;font-size:clamp(1.35rem,2vw,1.75rem);
  line-height:1.15;letter-spacing:-.025em}
.feat-body{color:var(--muted);margin:0 0 18px;font-size:.97rem;line-height:1.65}
.feat-points{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.feat-points li{position:relative;padding-left:22px;color:var(--muted);
  font-size:.9rem;line-height:1.5}
.feat-points li::before{content:"";position:absolute;left:0;top:.6em;
  width:10px;height:1px;background:var(--blue-hi)}

/* The frame is what makes a light screenshot sit comfortably on a dark page:
   a browser-chrome bar in the page's own palette mediates the jump instead of
   a white rectangle hard-cutting against near-black. */
.feat-frame{margin:0;border-radius:12px;overflow:hidden;
  border:1px solid var(--line-2,rgba(255,255,255,.16));background:var(--ink-3);
  box-shadow:0 24px 60px -24px rgba(0,0,0,.85)}
.frame-bar{display:flex;align-items:center;gap:6px;padding:10px 14px;
  background:var(--ink-3);border-bottom:1px solid var(--line)}
.frame-bar i{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.14)}
.frame-bar em{font-family:var(--mono);font-style:normal;font-size:.66rem;
  letter-spacing:.04em;color:var(--dim);margin-left:10px}
.feat-frame img{width:100%;height:auto;display:block}

/* Phones: plain full-width framed image. The pan experiment shipped broken —
   width:auto resolved to the image's INTRINSIC 2090px inside a 350px frame,
   so phones showed a giant zoomed slab with the chrome bar scrolling away.
   Small text at 350px is normal for a mobile product page; the frame and the
   copy do the work. */
@media (max-width:900px){
  .feat-frame img{width:100%;height:auto;min-width:0;max-width:100%}
}

/* ═══ Capability cells, redesigned (rev 5b) ════════════════════════════════
   Hassan: "too plain". The cells were bare h4+p paragraphs floating in space.
   Each is now an object: a hairline left rule that lights up on hover, a
   running two-digit index (01–24, continuing ACROSS clusters — one system),
   and a staggered cascade on reveal. Still no pills, no boxes-in-boxes. */
.cluster-items{gap:0 clamp(18px,2.4vw,32px)}
.ci{position:relative;padding:18px 16px 20px 20px;margin:0 0 6px;
  border-left:1px solid var(--line);border-radius:0 10px 10px 0;
  transition:border-color .25s,background-color .25s,transform .25s}
.ci:hover{border-left-color:var(--blue-hi);background:rgba(75,132,255,.05);
  transform:translateX(3px)}
.ci-i{position:absolute;top:20px;right:14px;font-family:var(--mono);
  font-size:.62rem;letter-spacing:.08em;color:var(--dim);opacity:.55;
  transition:color .25s,opacity .25s}
.ci:hover .ci-i{color:var(--blue-hi);opacity:1}
.ci h4{margin:0 0 7px;padding-right:30px}
.cluster-head{position:relative}
.cluster-head::after{content:"";position:absolute;left:0;bottom:-1px;
  width:44px;height:1px;background:var(--blue-hi)}
@media (prefers-reduced-motion:reduce){
  .ci,.ci-i{transition:none}
  .ci:hover{transform:none}
}

/* ── Topical icons ──────────────────────────────────────────────────────────
   Line icons drawn to each section's subject, at 1.5px stroke in currentColor
   so they inherit the kicker's accent. aria-hidden: every one sits beside a
   label that already says the same thing, so a screen reader gains nothing
   from announcing it. */
.feat-kicker{display:flex;align-items:center;gap:9px}
.ic{width:17px;height:17px;flex:none;stroke:var(--blue-hi);opacity:.95}
.feat-kicker span{display:inline-block}

/* Icons in the capability clusters get the same treatment but quieter. */
.ci .ic{width:15px;height:15px;stroke:var(--blue-hi);opacity:.8;margin-bottom:8px}

/* ── Two-tier pricing ───────────────────────────────────────────────────────
   Was a three-rung ladder that charged MORE per guard as the team grew, which
   is backwards — a sixty-guard agency runs the same software as a twelve-guard
   one. Now one flat per-guard rate, and a flat monthly retainer for the custom
   work, so the grid is two wider cards rather than three narrow ones. */
.tiers-2{grid-template-columns:repeat(auto-fit,minmax(340px,1fr));max-width:880px;margin-inline:auto}
.tiers-2 .tier-price .per{font-size:.8rem;max-width:14ch;line-height:1.3}
.tiers-2 .tier-min{line-height:1.5}

/* ═══════════════════════════════════════════════════════════════════════════
   DESIGN SYSTEM REVISION — 2026-08-02
   Driven by a survey of production CSS from 24 current product sites (Linear,
   Vercel, Stripe, Clerk, Warp, Retool, Raycast, Attio, Railway, Liveblocks,
   PlanetScale et al), not by taste. Every value below has a measured source.

   The brief's finding was blunt: the ambient effects layer — animated gradient
   headline, drifting orbs, canvas field, custom cursor, scroll progress bar —
   is the "machine-made" signature. Not one of the 24 sites ships that stack.
   ⚠️ Hassan asked for the gradient headline and the custom cursor by name.
   They are removed here on the evidence; restoring either is a one-line revert
   and this block is the only place to do it.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* Parameterised neutral ramp (Warp ships exactly this shape). Chroma was
     ~0.025 — roughly 3.5x Warp's 0.007. The navy identity stays; there is
     just far less of it. One variable re-tints the whole page, which matters
     for a white-label product. */
  --gray-hue: 250;
  --gray-chroma: .009;

  --ink:   oklch(9%  var(--gray-chroma) var(--gray-hue));
  --ink-2: oklch(13% var(--gray-chroma) var(--gray-hue));
  --ink-3: oklch(17% var(--gray-chroma) var(--gray-hue));
  --dim:   oklch(59.5% var(--gray-chroma) var(--gray-hue));
  --muted: oklch(72% var(--gray-chroma) var(--gray-hue));
  --text:  oklch(96% var(--gray-chroma) var(--gray-hue));

  /* Surface-tinted alphas (Retool). Black at low alpha over a tinted surface
     goes muddy; the surface colour at partial alpha does not. */
  --alpha-6:  oklch(17% var(--gray-chroma) var(--gray-hue) / .40);
  --alpha-12: oklch(20% var(--gray-chroma) var(--gray-hue) / .60);
  --line:     oklch(100% 0 0 / .085);
  --line-2:   oklch(100% 0 0 / .14);

  /* Radii collapsed. The survey's mass sits at 4–12px; 999px pills and 14px
     cards both read as template defaults. */
  --r-sm: 4px;
  --r:    6px;
  --r-lg: 12px;

  /* Elevation: hairline RING as a shadow, plus a BLUE-BLACK tinted drop.
     Clerk and Stripe both tint; neutral black shadows are the tell. */
  --elev-1: inset 0 0 0 .5px oklch(100% 0 0 / .06), 0 1px 2px oklch(0% 0 0 / .30);
  --elev-2: inset 0 0 0 .5px oklch(100% 0 0 / .07),
            0 2px 4px oklch(0% 0 0 / .22), 0 8px 16px -6px oklch(22% .03 265 / .40);
}

/* ── P0: delete the effects layer ──────────────────────────────────────── */
/* The effects JS is deleted, so nothing to hide and no has-cursor class.
   The old blanket `cursor:auto !important` here removed the pointer from every
   link, button and FAQ row on the page. */
.hero::before,.hero::after,.nav::after{display:none}
/* Flat headline. The 9s colour sweep was the single loudest tell. */
h1,h1 em{
  background:none !important;-webkit-background-clip:initial !important;
  background-clip:initial !important;-webkit-text-fill-color:currentColor !important;
  animation:none !important;
}
h1{color:var(--text)}
h1 em{color:var(--blue-hi)}

/* ── Type: lighter display, tracking baked per step, in em not px ───────── */
h1{font-weight:500;letter-spacing:-.038em;line-height:1.02;text-wrap:balance}
h2{font-weight:500;letter-spacing:-.024em;text-wrap:balance}
h3{font-weight:600;letter-spacing:-.018em;text-wrap:balance}
.feat-copy h3,.cluster-head h3,.tier h3{font-weight:600}
body{letter-spacing:0}
p,li,.feat-body,.body,.lede{text-wrap:pretty}
.lede{letter-spacing:-.004em}

/* ── Radii + elevation applied ─────────────────────────────────────────── */
.btn,.ghost,.cur-btn,.cur-switch{border-radius:var(--r)}
.feat-frame,.tier,.hero-shot img,.split-media,.grid-shots figure{border-radius:var(--r-lg)}
.frame-bar{border-radius:var(--r-lg) var(--r-lg) 0 0}
.feat-frame{box-shadow:var(--elev-2)}
.tier{box-shadow:var(--elev-1)}
.hero-shot img{box-shadow:var(--elev-2)}
.ticker{background:var(--alpha-6)}

/* ── Accent rationing ───────────────────────────────────────────────────────
   Measured accent coverage on the surveyed sites: 0–0.29% of page area. This
   page was using blue on the headline em, every kicker, all 24 cluster
   indices, every bullet, every FAQ chevron, both hover states and the nav
   hairline — an order of magnitude over. Blue now means "this is an action or
   the one thing that matters here". */
.ci-i{color:var(--dim);opacity:.8}
.ci:hover .ci-i{color:var(--muted);opacity:.9}
.ci:hover{border-left-color:var(--line-2);background:var(--alpha-6)}
.cluster-head::after{background:var(--line-2)}
.feat-points li::before,.ticker b::before{background:var(--dim)}
.faq-wrap summary::after{color:var(--muted)}
.faq-wrap summary:hover::after{color:var(--text)}
.ic,.ci .ic{stroke:var(--muted);opacity:.85}
.feat-kicker{color:var(--dim)}

@media (prefers-reduced-motion:reduce){
  details[open] p{animation:none}
}

/* The per-unit suffix was wrapping to three ragged lines beside a 150. Give it
   its own line under the figure — the amount is the thing being scanned. */
.tiers-2 .tier-price{display:block;margin-bottom:4px}
.tiers-2 .tier-price .amt{display:inline-block}
.tiers-2 .tier-price .per{display:block;max-width:none;margin-top:2px;
  font-size:.82rem;color:var(--dim);line-height:1.4}
.tiers-2 .tier-flag{margin-bottom:16px}

/* Footer had four columns in a three-column grid (Legal wrapped alone with
   ~1000px of void beside it) and styled an h4 that the markup renders as h3,
   so the column titles came out at 25px bold instead of a small eyebrow. */
.foot-inner{grid-template-columns:2fr 1fr 1fr 1fr}
.foot-col h3{font-family:var(--mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);font-weight:500;margin:0 0 12px}
@media (max-width:820px){.foot-inner{grid-template-columns:1fr 1fr}}
@media (max-width:520px){.foot-inner{grid-template-columns:1fr}}

/* ── One label treatment, not nine ──────────────────────────────────────────
   The page had 12 monospace declarations across 9 distinct size/spacing
   combinations (.66–.74rem, .04–.18em) for what is functionally the same
   thing: a small uppercase label. Nine near-identical-but-not treatments is a
   machine-generated fingerprint — a person picks one and reuses it.

   SUBTRACTIVE ONLY. No new elements, no new copy, nothing added to the page.
   Same labels, one consistent treatment. Oxide ships exactly this discipline:
   one mono label style, used 22 times on a single page.                      */
.sec-label,
.probs span,
.chip span,
.foot-col h3,
.foot-col h4,
.show-eyebrow,
.feat-kicker,
.frame-bar em,
.ci-i,
.tier-flag{
  font-family:var(--mono);
  font-size:.7rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  font-weight:500;
  font-style:normal;
}
/* The frame-bar URL is a literal address, not a label — it keeps its case. */
.frame-bar em{text-transform:none;letter-spacing:.04em;font-size:.66rem}
/* The cluster index is a numeral; uppercase is meaningless and tracking at
   .14em pushes two digits apart. */
.ci-i{letter-spacing:.06em;text-transform:none}

/* ═══════════════════════════════════════════════════════════════════════════
   ARCHITECTURE REBUILD — 2026-08-02
   The six near-identical alternating copy/screenshot rows were the templated
   pattern. Replaced with four DIFFERENT geometries so the page has a shape
   instead of a rhythm:
     .moment   full-bleed product surface, wider than the text column
     .proof    display-size numerals beside the report they came from
     .bento    mixed-size cells, no alternation
     clusters  unchanged
   Oxide's discipline applies throughout: standard grids, no rotation, no
   grain, no blend modes. Specific, not decorated.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── A · the full-bleed moment ──────────────────────────────────────────── */
.moment{padding:clamp(80px,12vh,140px) 0}
.moment-head{max-width:760px;margin-bottom:clamp(38px,5vw,60px)}
.bleed{margin:0;width:100%;padding-inline:clamp(12px,2vw,28px)}
.bleed-inner{
  max-width:1520px;margin-inline:auto;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line-2);background:var(--ink-2);
  box-shadow:0 40px 90px -40px oklch(0% 0 0 / .9), var(--elev-1);
}
.bleed-inner img{width:100%;height:auto;display:block}
.moment-points{margin-top:clamp(28px,4vw,44px)}
/* A rail, not bullets — the list reads as a caption strip under the surface. */
.rail{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:0;
  border-top:1px solid var(--line)}
.rail li{padding:18px 22px 0 0;color:var(--muted);font-size:.92rem;line-height:1.5;
  border-left:1px solid var(--line);padding-left:22px}
.rail li:first-child{border-left:0;padding-left:0}

/* ── B · the proof band ─────────────────────────────────────────────────── */
.proof{padding:clamp(80px,12vh,140px) 0;border-block:1px solid var(--line);
  background:var(--alpha-6)}
.proof-grid{display:grid;grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr);
  gap:clamp(30px,5vw,66px);align-items:center;margin-top:clamp(34px,4vw,52px)}
.proof-stats{display:grid;gap:clamp(20px,2.6vw,30px)}
.stat b{
  display:block;font-size:clamp(2.4rem,4.4vw,3.4rem);font-weight:500;
  letter-spacing:-.035em;line-height:1;color:var(--text);
  /* Tabular figures so the column of numerals aligns on the digit, not the
     glyph — the one typographic detail this audience reads every day. */
  font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1;
}
.stat span{display:block;margin-top:8px;color:var(--muted);font-size:.9rem;
  line-height:1.5;max-width:34ch}
.proof-shot{margin:0;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line-2);background:var(--ink-2);box-shadow:var(--elev-2)}
.proof-shot img{width:100%;height:auto;display:block}
.proof-shot figcaption{padding:12px 16px;font-size:.8rem;color:var(--dim);
  border-top:1px solid var(--line)}
.proof-note{margin-top:clamp(30px,4vw,46px)}

/* ── C · bento ──────────────────────────────────────────────────────────── */
.bento-sec{padding:clamp(80px,12vh,140px) 0}
.bento{display:grid;gap:clamp(14px,1.6vw,20px);margin-top:clamp(34px,4vw,52px);
  grid-template-columns:repeat(3,minmax(0,1fr));
  grid-auto-rows:minmax(0,auto)}
.cell{display:flex;flex-direction:column;margin:0;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r-lg);background:var(--ink-2);
  transition:border-color .25s}
.cell:hover{border-color:var(--line-2)}
.cell-copy{padding:26px 26px 20px}
.cell-copy h3{margin:0 0 9px;font-size:1.12rem;letter-spacing:-.02em;font-weight:600}
.cell-copy p{margin:0;color:var(--muted);font-size:.9rem;line-height:1.55}
/* The screenshot is cropped by the cell rather than scaled into it — the UI
   keeps its real pixel size and the cell decides how much you see. */
.cell-shot{flex:1;min-height:0;overflow:hidden;border-top:1px solid var(--line);
  margin-top:auto}
.cell-shot img{width:100%;height:auto;display:block}
.cell-wide{grid-column:span 2}
.cell-tall{grid-row:span 2}
.cell-tall .cell-shot img{width:auto;height:100%;max-width:none;object-fit:cover;
  object-position:left top}

@media (max-width:1000px){
  .proof-grid{grid-template-columns:1fr;gap:34px}
  .proof-stats{grid-template-columns:1fr 1fr;gap:24px}
  .bento{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cell-wide{grid-column:span 2}
  .cell-tall{grid-row:span 1}
  .cell-tall .cell-shot img{width:100%;height:auto;object-fit:fill}
}
@media (max-width:640px){
  .proof-stats{grid-template-columns:1fr}
  .bento{grid-template-columns:1fr}
  .cell-wide,.cell-tall{grid-column:span 1;grid-row:span 1}
  .rail li{border-left:0;padding-left:0;border-top:1px solid var(--line);
    padding-top:16px;margin-top:2px}
  .rail{border-top:0}
  .rail li:first-child{border-top:0}
}

/* ── Bento image handling, corrected ────────────────────────────────────────
   First cut set `.cell-tall img{width:auto;height:100%}` — a 2090px capture in
   a 1389px-tall cell resolved to ~2400px wide, so the UI text rendered at
   double size and burst the cell. And `flex:1` on .cell-shot left a black void
   in the wide cell when the image was shorter than the space.

   Correct approach: every cell crops to a fixed aspect with object-fit, so the
   capture always renders at its natural horizontal scale and the CELL decides
   how much of it you see. No cell scales the pixels. */
.cell-shot{flex:none;aspect-ratio:16/10;overflow:hidden;
  border-top:1px solid var(--line);margin-top:auto}
.cell-shot img{width:100%;height:100%;object-fit:cover;object-position:left top}
.cell-wide .cell-shot{aspect-ratio:2/1}
.cell-tall .cell-shot{aspect-ratio:4/5}
.cell-tall .cell-shot img{width:100%;height:100%;object-fit:cover;
  object-position:right top;max-width:100%}

/* ── Proof screenshot: crop at a card boundary, not mid-row ─────────────── */
.proof-shot{position:relative}
.proof-shot picture{display:block;max-height:520px;overflow:hidden}
.proof-shot img{object-fit:cover;object-position:top left}
@media (max-width:1000px){.proof-shot picture{max-height:none}}

/* The tall cell spans two grid rows (~926px) but copy + a 4:5 shot only fills
   ~590px, and `margin-top:auto` pushed the shot down leaving a ~330px void.
   Drop the fixed aspect on that cell and let the shot absorb whatever height
   the span gives it. */
.cell-tall .cell-shot{flex:1 1 auto;aspect-ratio:auto;min-height:0}
@media (max-width:1000px){
  .cell-tall .cell-shot{flex:none;aspect-ratio:16/10}
}

/* The tall cell now uses a purpose-cut PORTRAIT asset (960x1600) rather than a
   landscape one cropped to fit, so lines are no longer sliced mid-word. */
.cell-tall .cell-shot img{object-position:left top}

/* ── QA fixes on the rebuild ────────────────────────────────────────────────
   1. .moment-head carried BOTH .wrap and its own max-width, so .wrap's
      margin:0 auto re-centred a 760px box in the viewport — the headline sat
      +210px right of every other heading on the page, giving that section
      three different left edges. Keep the 760px measure, restore the column. */
/* max-width:none removed the wrap constraint too, swinging the heading the
   other way to the viewport edge. Match .wrap exactly, and put the 760px
   reading measure on the CHILDREN. */
.moment-head{max-width:1180px}
.moment-head > *{max-width:760px}

/* 2. .rail auto-fit produced a 2-column shape between 500–740px while the
      divider rules assumed 3-col or 1-col — a half-width rule above item 2,
      and item 3 orphaning a left hairline with nothing beside it. Pin the
      columns and move the stacking breakpoint to match. */
.rail{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:749px){
  .rail{grid-template-columns:1fr;border-top:0}
  .rail li{border-left:0;padding-left:0;border-top:1px solid var(--line);
    padding-top:16px;margin-top:2px}
  .rail li:first-child{border-top:0}
}

/* 3. The inert max-height:520px on .proof-shot could never engage (the image
      renders ~388px in a ≤680px column). The crop is baked into the asset now. */
.proof-shot picture{max-height:none}

/* 4. Four cells in two columns left the last one orphaned beside an empty
      half-row. Let the wide cell drop to one column so the grid closes 2x2. */
@media (max-width:1000px){
  .cell-wide{grid-column:span 1}
}
