/* =========================================================================
   Assertify marketing — v2 "paper & signal"
   Light paper canvas with full-bleed near-black signal bands, a floating
   pill nav, grotesque two-tone headlines, mono-uppercase labels, and white
   cards carrying live product mockups. Rebuilt for Assertify's QA story,
   heavily inspired by modern security-platform marketing design.
   Light-first; html.dark flips the token set (toggle in nav + footer).
   ========================================================================= */

/* Typefaces — kept in lockstep with the app (web/src/app/layout.tsx). Geist sans
   was retired from BOTH surfaces: it's Vercel's font, the one create-next-app
   ships, so it read as a template rather than as a brand. Switzer carries body
   text; Bricolage Grotesque (already the heading face on the legal + 404 pages)
   carries the headlines; Geist MONO stays as the label/code voice, which is the
   connective tissue of this whole design. */
@font-face {
  font-family: "Switzer";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/switzer-variable.woff2") format("woff2");
}
@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/fonts/bricolage-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/geist-mono-latin.woff2") format("woff2");
}

/* ------------------------------------------------------------ tokens */
:root {
  --paper: #f4f4f2;
  --paper-2: #eeeeeb;
  --card: #ffffff;
  --ink: #0e1013;
  --ink-soft: #40444c;
  --muted: #7c808a;
  --line: #e4e4e0;
  --line-2: #d6d6d1;

  --band: #1d2230;          /* full-bleed dark sections — a lifted slate in LIGHT
                               mode (dark mode drops to near-black below) so the
                               theme toggle visibly changes the dark bands too */
  --band-2: #272d3d;        /* raised chrome on the band */
  --band-line: #363d50;
  --on-band: #f4f5f7;
  --on-band-soft: rgb(244 245 247 / 0.64);

  --accent: #7c3aed;        /* Assertify violet — elegant amethyst */
  --accent-strong: #6d28d9;
  --accent-lite: #a78bfa;   /* headline tint on dark */
  --accent-100: #ede9fe;
  --accent-50: #f5f3ff;

  --ok: #16a34a; --ok-100: #dcfce7;
  --warn: #d97706; --warn-100: #fef3c7;
  --err: #dc2626; --err-100: #fee2e2;

  --r: 10px;
  --r-sm: 8px;
  --shadow: 0 16px 44px -26px rgb(14 16 19 / 0.25);
  --shadow-lg: 0 40px 90px -44px rgb(14 16 19 / 0.35);
  --nav-h: 64px;
  --wrap: 1180px;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

html.dark {
  --paper: #0b0c10;
  --paper-2: #101116;
  --card: #14161b;
  --ink: #f2f3f5;
  --ink-soft: #b9bcc4;
  --muted: #82868f;
  --line: #22242b;
  --line-2: #2d3038;
  --band: #060709;
  --band-2: #101116;
  --band-line: #202229;
  --accent-100: #2e2352;
  --accent-50: #1d1638;
  --ok-100: #10331d; --warn-100: #38290b; --err-100: #3a1414;
  --shadow: 0 16px 44px -26px rgb(0 0 0 / 0.6);
  --shadow-lg: 0 40px 90px -44px rgb(0 0 0 / 0.7);
}

* { box-sizing: border-box; }
html, body { margin: 0; }
/* The page is framed by the dark --band at BOTH ends — the hero at the top and
   the footer at the bottom — in BOTH themes, and the html backdrop is that same
   --band. So fast scroll / rubber-band overscroll at either end only ever reveals
   that dark, never the beige paper mid-page (which the opaque body covers). */
html { scroll-behavior: smooth; background-color: var(--band); overflow-x: clip; scrollbar-width: none; -ms-overflow-style: none; }
/* hide the page scrollbar chrome (scroll still works via wheel/trackpad/keys) */
html::-webkit-scrollbar, body::-webkit-scrollbar { width: 0; height: 0; display: none; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
/* Anchor targets clear the always-visible floating nav on hash navigation, so a
   jumped-to section lands below the bar rather than behind it. site.js refines
   this on link clicks; this is the no-JS / direct-#hash-load fallback. */
/* Anchor jumps land the target section flush to the top of the viewport, so its
   own background fills the whole top — behind and around the floating glass pill —
   and the PREVIOUS section never peeks above/beside the bar. (Any positive offset
   here would drop the section below the pill and reveal a strip of the prior
   section around it.) The section's own top padding (6.5rem) clears the bar and
   frames the heading. */
section[id] { scroll-margin-top: 0; }

body {
  font-family: "Switzer", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--paper);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

/* Headlines take the display face. The tracking stays at -0.035em: Bricolage is
   already tighter-fitting than Geist was, but the two-tone hero headline is set
   large enough that it still wants the pull. */
h1, h2, h3, h4 {
  margin: 0;
  font-family: "Bricolage Grotesque", "Switzer", sans-serif;
  font-weight: 620;
  letter-spacing: -0.035em;
  line-height: 1.02;
}

.wrap { width: min(var(--wrap), calc(100% - 44px)); margin-inline: auto; }
.section { padding: 6.5rem 0; }
.section.tight { padding: 3.5rem 0; }

/* Perf: skip layout/paint for below-fold sections until they near the viewport.
   Speeds first paint and, crucially, stops the many infinite animations in these
   sections (reactor spin/breathe, calc glow, CTA aurora, logo marquee) from
   repainting while off-screen — that's most of the scroll-jank. `contain-intrinsic-size:
   auto <px>` lets the browser remember each section's real height so the scrollbar
   doesn't jump. Hero (above fold) and #how are intentionally excluded;
   all .band sections already clip overflow, so the implied paint-containment is a no-op. */
/* content-visibility is kept OFF the nav-target sections (#why/#local/#download/
   #chat/#pricing): its size-estimate defers layout, which throws off smooth-scroll
   anchor landings (the section lands under the sticky bar). Non-target sections
   keep it for the paint-skipping perf win. */
.trust,
#platform, #suite, #faq, #export,
.band--cta, footer {
  content-visibility: auto;
  contain-intrinsic-size: auto 700px;
}

/* mono utility — the connective tissue of the whole design */
.mono, .eyebrow, .btn, .chip, .mock__bar, .mock__badge, .tbl th, .tag {
  font-family: var(--mono);
}

/* eyebrow chip — bordered mono uppercase label */
.eyebrow {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: 0.7rem; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 7px; padding: 0.32rem 0.65rem; background: color-mix(in srgb, var(--card) 55%, transparent);
}
.eyebrow .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); animation: pulse 2s ease-out infinite; }
.band .eyebrow { color: var(--accent-lite); border-color: rgb(167 139 250 / 0.35); background: transparent; }
.band .eyebrow .dot { background: var(--accent-lite); }
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  70%, 100% { box-shadow: 0 0 0 8px transparent; }
}
@media (prefers-reduced-motion: reduce) { .eyebrow .dot { animation: none; } }

/* section heads — big two-tone grotesque */
.sec-head { max-width: 46rem; }
.sec-head.center { margin-inline: auto; text-align: center; }
.sec-head h2 { font-size: clamp(2.2rem, 4.6vw, 3.6rem); margin-top: 1.1rem; }
.sec-head h2 .hl { color: var(--accent); }
.band .sec-head h2 .hl { color: var(--accent-lite); }
.sec-head p { margin: 1.15rem 0 0; color: var(--ink-soft); font-size: 1.08rem; max-width: 38rem; }
.sec-head.center p { margin-inline: auto; }

/* ------------------------------------------------------------ buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  border-radius: 8px; padding: 0.78rem 1.5rem; border: 1px solid transparent;
  cursor: pointer; transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn-primary { background: var(--ink); color: var(--paper); }
.btn-primary:hover { background: var(--ink-soft); }
html.dark .btn-primary { background: #f2f3f5; color: #0b0c10; }
html.dark .btn-primary:hover { background: #d8dade; }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-strong); }
.btn-ghost { background: var(--card); color: var(--ink); border-color: var(--line-2); }
.btn-ghost:hover { border-color: var(--muted); }
.btn-lg { padding: 0.95rem 1.9rem; font-size: 0.76rem; }
.band .btn-ghost { background: transparent; color: var(--on-band); border-color: rgb(244 245 247 / 0.28); }
.band .btn-ghost:hover { border-color: rgb(244 245 247 / 0.6); }
.band .btn-primary { background: #f2f3f5; color: #0b0c10; }
.band .btn-primary:hover { background: #ffffff; }

/* razor-whoosh sheen — a soft blade of LIGHT glides across the BLACK button.
   The blade only ever lands on a dark-filled button, so it's always a light
   streak (no color-flip). Which button is black depends on theme + context, so
   we toggle it with --wh: ON ("") lights the ::after, OFF (none) removes it.
     · light mode → the SOLID primary is black         → whoosh on .btn-primary
     · dark  mode → primary goes white, the ghost
       ("Book a demo") goes black                       → whoosh flips to .btn-ghost
   Auto-sweeps every ~5s, plus an instant faster pass on hover/focus. */
.btn { position: relative; overflow: hidden; }
.btn { --wh: none; }                                  /* default: no whoosh */
html.light .btn-primary { --wh: ""; }                 /* light: solid primary is black */
html.dark  .btn-ghost   { --wh: ""; }                 /* dark: solid ghost is black */
html.dark .band .btn-ghost { --wh: ""; }              /* on a dark band the ghost reads black */
/* corrections for band context (higher specificity / later source order wins) */
html.light .band--cta .btn-ghost { --wh: none; }      /* translucent ghost on the purple CTA */
html.light .band--cta .btn-primary { --wh: none; }    /* the CTA primary is WHITE on purple — no light streak */
.btn::after {
  content: var(--wh, none); position: absolute; top: -60%; left: 0; width: 100%; height: 220%;
  z-index: 2; pointer-events: none;
  background: linear-gradient(90deg, transparent 16%,
    rgb(255 255 255 / 0.10) 34%, rgb(255 255 255 / 0.55) 50%, rgb(255 255 255 / 0.10) 66%, transparent 84%);
  filter: blur(6px);
  transform: translateX(-115%) skewX(-26deg);
  animation: bladeAuto 5s cubic-bezier(0.3, 0.55, 0.35, 1) 2s infinite;
}
.btn:hover::after, .btn:focus-visible::after {
  animation: bladeSweep 0.9s cubic-bezier(0.3, 0.55, 0.35, 1);
}
/* one clean pass across for hover */
@keyframes bladeSweep {
  from { transform: translateX(-115%) skewX(-26deg); }
  to   { transform: translateX(115%) skewX(-26deg); }
}
/* auto: sweep in the first ~18% (~0.9s) of the 5s cycle, then rest off-screen */
@keyframes bladeAuto {
  0%   { transform: translateX(-115%) skewX(-26deg); }
  18%  { transform: translateX(115%) skewX(-26deg); }
  100% { transform: translateX(115%) skewX(-26deg); }
}
@media (prefers-reduced-motion: reduce) {
  .btn::after,
  .btn:hover::after, .btn:focus-visible::after { animation: none; opacity: 0; }
}
/* Pricing CTAs never sheen. On the plan cards the blade reads as noise, not
   polish — it lit up in dark mode via `html.dark .btn-ghost`. The #pricing id
   outranks that rule so the whoosh is off in EVERY theme (ghost + accent). */
#pricing .btn { --wh: none; }

/* ------------------------------------------------------------ floating pill nav
   Always on (no hide-on-scroll) and glassy: a mostly-transparent pill with a
   heavy blur+saturate backdrop, so it refracts whatever band sits behind it. */
.nav { position: sticky; top: 12px; z-index: 50; pointer-events: none; }
.nav.nav--hidden { transform: none; } /* neutralize site.js's hide-on-scroll */
.nav__in {
  pointer-events: auto; position: relative;
  display: flex; align-items: center; gap: 1.4rem;
  width: min(1180px, calc(100% - 32px)); margin-inline: auto;
  background: color-mix(in srgb, var(--card) 42%, transparent);
  /* fallback frost; glass.js upgrades this to the liquid-glass lens:
     blur(2px) saturate(1.15) url(#lens-nav) — light blur + SVG refraction,
     exactly the recipe the reference site uses. */
  -webkit-backdrop-filter: blur(3px) saturate(1.3);
  backdrop-filter: blur(3px) saturate(1.3);
  border: 1px solid color-mix(in srgb, var(--line) 60%, transparent); border-radius: 14px;
  box-shadow: var(--shadow), inset 0 1px 0 rgb(255 255 255 / 0.22), inset 0 -1px 0 rgb(0 0 0 / 0.05);
  padding: 0.55rem 0.65rem 0.55rem 1.4rem;
  min-height: var(--nav-h);
}
html.dark .nav__in { background: rgb(244 245 247 / 0.10); border-color: rgb(255 255 255 / 0.14); box-shadow: var(--shadow), inset 0 1px 0 rgb(255 255 255 / 0.12); }
.brand { display: inline-flex; align-items: center; gap: 0.6rem; font-weight: 760; letter-spacing: -0.03em; font-size: 1.28rem; }
.brand .mark { width: 30px; height: 30px; }
/* the wordmark leads the bar as a gradient — clearly heavier + larger than the nav links */
.nav .brand span {
  background: linear-gradient(96deg, var(--accent) 8%, #b393ff 92%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
}
.nav__links a { transition: color .28s ease; }
.nav.nav--over-dark .brand span {
  background: linear-gradient(96deg, #ffffff 22%, #c7b0ff 96%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
}
.nav.nav--over-dark .nav__links a { color: rgb(255 255 255 / .9); }
.nav.nav--over-dark .nav__links a.is-active,
.nav.nav--over-dark .nav__links a.is-current { color: #fff; }
.nav.nav--over-dark .nav__links a:hover { color: var(--accent); }
.nav.nav--over-dark .btn-ghost { color: #fff; border-color: rgb(255 255 255 / .28); background: rgb(255 255 255 / .08); }
.nav.nav--over-dark .btn-ghost:hover { border-color: rgb(255 255 255 / .55); background: rgb(255 255 255 / .18); }
.nav.nav--over-dark .btn-primary { color: #111318; background: #fff; border-color: rgb(255 255 255 / .55); }
.nav.nav--over-dark .btn-primary:hover { background: #e7e9ee; box-shadow: 0 8px 22px rgb(0 0 0 / .28); }
.nav__links { display: flex; align-items: center; gap: 1.7rem; margin-inline: auto; }
.nav__links a { font-size: 0.94rem; font-weight: 600; letter-spacing: -0.012em; white-space: nowrap; color: var(--ink-soft); transition: color 0.15s ease; }
.nav__links a.is-active { color: var(--ink); }
.nav__links a:hover { color: var(--accent); }

/* Hover "roll": the label slides up and out of a one-line clip window while an
   identical copy rolls up into its place — the tester.army app-bar trick.
   .navroll is a STATIC overflow-hidden mask sized to a single line, so the
   incoming copy (.navroll__t::after, parked one line below) is clipped away at
   rest — nothing rasterizes into view until you hover. The inner .navroll__t is
   the mover. Disabled in the mobile drawer (links are full-width buttons). */
.navroll {
  display: inline-block;
  position: relative;
  overflow: hidden;
  vertical-align: bottom;
  line-height: 1.3;
}
.navroll__t {
  display: block;
  position: relative;
  transition: transform 0.42s cubic-bezier(0.3, 0.86, 0.28, 1);
  will-change: transform;
}
.navroll__t::after {
  content: attr(data-label);
  position: absolute;
  left: 0;
  top: 100%;
  width: 100%;
  white-space: nowrap;
}
.nav__links a:hover .navroll__t { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) {
  .navroll__t { transition: none; }
  .nav__links a:hover .navroll__t { transform: none; }
}
.nav__spacer { display: none; }
.nav__actions { display: flex; align-items: center; gap: 0.5rem; }
.nav__drawer-only { display: none; }
.nav__toggle-cb { display: none; }
.nav__toggle { display: none; }

/* utils FIXED to the viewport's top-right — independent of the app bar */
.nav__utils { position: fixed; right: 18px; top: 25px; display: flex; gap: 0.4rem; pointer-events: auto; z-index: 60; }
.theme-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--card) 42%, transparent);
  -webkit-backdrop-filter: blur(12px) saturate(1.5); backdrop-filter: blur(12px) saturate(1.5);
  border: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  box-shadow: var(--shadow), inset 0 1px 0 rgb(255 255 255 / 0.2);
  color: var(--ink-soft); cursor: pointer;
  transition: transform 0.2s ease, border-color 0.2s ease;
}
.theme-btn:hover { transform: scale(1.08); border-color: var(--muted); }
.theme-btn:active { transform: scale(0.94); }
.theme-btn svg { width: 16px; height: 16px; transition: transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1.3); }
.theme-btn:hover svg { transform: rotate(-24deg); }
html.dark .theme-btn { background: rgb(18 20 28 / 0.45); color: #e6e8ee; }
html.light .theme-btn .i-sun { display: none; }
html.dark .theme-btn .i-moon { display: none; }

/* circular theme reveal (View Transitions API; site.js sets --vt-x/--vt-y) */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
::view-transition-new(root) {
  clip-path: circle(0px at var(--vt-x, 92%) var(--vt-y, 4%));
  animation: vtSweep 0.55s ease-in-out forwards;
}
@keyframes vtSweep { to { clip-path: circle(150vmax at var(--vt-x, 92%) var(--vt-y, 4%)); } }

/* Nav collapses to a hamburger at 1140px, NOT 900px: six links + two CTA
   buttons don't fit on one line below ~1120px (they wrapped/clipped before),
   so the drawer takes over while there's still room for a clean bar above it. */
/* The floating theme toggle sits OUTSIDE the bar to its right; the wider bar
   leaves it too little margin until ~1260px, where it would overlap START FREE.
   Hide it below that (the footer keeps a theme toggle) — the bar itself still
   shows its full links down to the 1140px collapse point below. */
@media (max-width: 1260px) { .nav__utils { display: none; } }
@media (max-width: 1140px) {
  .nav__in { gap: 0.8rem; padding-left: 1rem; }
  /* `.nav__in > .nav__links` (2 classes) so it beats `.nav__in > *`, the later
     glass-refinement rule that forces every nav child to position:relative — that
     tie, decided by source order, was collapsing the drawer back into the flex row
     (shifted right, cut off). */
  .nav__in > .nav__links {
    position: absolute; left: 50%; transform: translateX(-50%); top: calc(100% + 10px);
    flex-direction: column; align-items: stretch; gap: 0;
    width: min(420px, calc(100vw - 32px));
    background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
    box-shadow: var(--shadow-lg); padding: 0.6rem; z-index: 5;
    display: none;
  }
  .nav__toggle-cb:checked ~ .nav__links { display: flex; }
  .nav__links a { padding: 0.85rem 1rem; border-radius: 10px; font-size: 1rem; }
  /* drawer links are full-width buttons — kill the roll so the label sits flat */
  .navroll { overflow: visible; }
  .navroll__t { transform: none !important; }
  .navroll__t::after { display: none; }
  /* the drawer is a solid light sheet, so links stay dark even while the bar itself
     is in over-dark mode (white-on-white had made them vanish). */
  .nav.nav--over-dark .nav__links a { color: var(--ink-soft); }
  .nav.nav--over-dark .nav__links a.is-active { color: var(--ink); }
  .nav__links a:hover { background: var(--paper-2); color: var(--accent); }
  .nav.nav--over-dark .nav__cta-primary,
  .nav__cta-primary { color: #fff; }
  .nav__drawer-only { display: block; }
  .nav__cta-primary { background: var(--accent); color: #fff !important; text-align: center; margin-top: 0.4rem; }
  .nav__actions { display: none; }
  .nav__toggle { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; cursor: pointer; color: var(--ink); margin-left: auto; }
  .nav__toggle .i-close { display: none; }
  .nav__toggle-cb:checked ~ .nav__toggle .i-menu { display: none; }
  .nav__toggle-cb:checked ~ .nav__toggle .i-close { display: block; }
}

/* ------------------------------------------------------------ dark band */
.band { background: var(--band); color: var(--on-band); position: relative; overflow: hidden; }
.band--hero { margin-top: calc(-1 * var(--nav-h) - 24px); padding-top: calc(var(--nav-h) + 24px); }
/* signal texture: faint horizontal data streaks + violet glow, pure CSS */
.band::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.55;
  background-image:
    radial-gradient(70% 55% at 50% 0%, rgb(124 58 237 / 0.24), transparent 70%);
}
.band > .wrap { position: relative; z-index: 1; }

/* ------------------------------------------------------------ hero — copy centered, 3D constellation as an offset background layer */
.hero { position: relative; text-align: center; padding: 7rem 0 7.5rem; min-height: min(74vh, 660px); display: flex; flex-direction: column; align-items: center; justify-content: center; }
.hero__copy { position: relative; z-index: 2; width: 100%; max-width: 44rem; margin-inline: auto; display: flex; flex-direction: column; align-items: center; }
.hero__chip {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--on-band-soft); border: 1px solid var(--band-line); border-radius: 999px;
  padding: 0.4rem 0.9rem; background: rgb(255 255 255 / 0.03);
  transition: border-color 0.2s ease, background 0.2s ease;
}
.hero__chip:hover { border-color: rgb(244 245 247 / 0.35); background: rgb(255 255 255 / 0.06); }
.hero__chip .live { width: 7px; height: 7px; border-radius: 50%; background: #34d399; animation: pulse 2s ease-out infinite; flex: none; }
.hero__chip .tag { font-size: 0.58rem; letter-spacing: 0.14em; border: 1px solid rgb(167 139 250 / 0.4); color: var(--accent-lite); border-radius: 6px; padding: 0.1rem 0.4rem; }
.hero__chip .topbar__msg { display: inline-flex; align-items: center; gap: 0.4rem; }
.hero__chip .topbar__msg b { color: var(--on-band); font-weight: 600; }
.hero__chip .topbar__cta { display: inline-flex; align-items: center; gap: 0.5rem; color: rgb(244 245 247 / 0.45); border-left: 1px solid var(--band-line); padding-left: 0.9rem; margin-left: 0.2rem; }
.hero__chip .cd { display: inline-flex; gap: 0.45rem; }
.hero__chip .cd__seg b { color: var(--on-band); font-weight: 600; }
.hero__chip .arr { color: var(--accent-lite); }
@media (max-width: 640px) { .hero__chip .topbar__cta { display: none; } }

/* ---- Product Hunt launch badge — the old dark chip was barely visible on the
   signal-black hero, so this is the recognizable coral PH badge, sized to get
   noticed: PH coral gradient, a white-disc cat, a live d/h/m countdown, a soft
   pulse ring + hover lift. Reuses the .topbar__* hooks the countdown JS drives
   (and its go-live flip), so only the skin changed. */
.ph-badge {
  display: inline-flex; align-items: center; gap: 0.6rem;
  padding: 0.42rem 0.7rem 0.42rem 0.5rem; border-radius: 8px;
  text-decoration: none; color: #fff; font-size: 0.9rem;
  background: linear-gradient(135deg, #ff7a55 0%, #da552f 100%);
  border: 1px solid rgb(255 255 255 / 0.22);
  box-shadow: 0 10px 30px -10px rgb(218 85 47 / 0.7), inset 0 1px 0 rgb(255 255 255 / 0.32);
  position: relative; isolation: isolate;
  transition: transform 0.2s cubic-bezier(0.3, 0.6, 0.4, 1), box-shadow 0.2s ease, border-color 0.2s ease;
}

/* Compact launch badge: supporting signal, not a competing hero headline. */
.hero .ph-badge { gap: .46rem; padding: .32rem .56rem .32rem .4rem; border-radius: 8px; font-size: .78rem; }
.hero .ph-badge .topbar__msg { gap: .4rem; }
.hero .ph-badge .topbar__ph { width: 23px; height: 23px; }
.hero .ph-badge .topbar__ph svg { width: 15px; height: 15px; }
.hero .ph-badge .ph-badge__kicker,
.hero .ph-badge .topbar__msg [data-i18n] { font-size: .56rem; letter-spacing: .1em; }
.hero .ph-badge .topbar__msg b { font-size: .86rem; }
.hero .ph-badge .topbar__cta { gap: .3rem; padding-left: .5rem; margin-left: .04rem; }
.hero .ph-badge .cd { gap: .28rem; }
.hero .ph-badge .cd__seg { font-size: .62rem; }
.hero .ph-badge .cd__seg b { font-size: .76rem; }

/* Product Hunt as the SECONDARY hero CTA (sits next to "Start testing free"),
   sized up from the compact inline badge to match the primary button's height. */
.hero .ph-badge--cta { gap: .55rem; padding: .6rem 1rem; border-radius: 8px; font-size: .82rem; }
.hero .ph-badge--cta .topbar__msg { gap: .5rem; }
.hero .ph-badge--cta .topbar__ph { width: 26px; height: 26px; }
.hero .ph-badge--cta .topbar__ph svg { width: 17px; height: 17px; }
.hero .ph-badge--cta .ph-badge__kicker { font-size: .6rem; letter-spacing: .1em; }
.hero .ph-badge--cta .topbar__msg b { font-size: .96rem; }
.hero .ph-badge--cta .topbar__cta { padding-left: .6rem; margin-left: .1rem; gap: .35rem; }
.hero .ph-badge--cta .cd { gap: .32rem; }
.hero .ph-badge--cta .cd__seg { font-size: .68rem; }
.hero .ph-badge--cta .cd__seg b { font-size: .82rem; }
.ph-badge:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 40px -10px rgb(218 85 47 / 0.82), inset 0 1px 0 rgb(255 255 255 / 0.32);
  border-color: rgb(255 255 255 / 0.4);
}
.ph-badge .topbar__msg { display: inline-flex; align-items: center; gap: 0.5rem; }
.ph-badge .topbar__ph {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 27px; height: 27px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.18);
}
.ph-badge .topbar__ph svg { display: block; width: 18px; height: 18px; }
/* the small "coming soon on / we're live on" kicker sits above the wordmark weight */
.ph-badge .ph-badge__kicker,
.ph-badge .topbar__msg [data-i18n] {
  font-size: 0.64rem; letter-spacing: 0.11em; text-transform: uppercase; font-weight: 600; opacity: 0.92;
}
.ph-badge .topbar__msg b { color: #fff; font-weight: 700; font-size: 0.98rem; letter-spacing: -0.01em; }
.ph-badge .topbar__cta {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding-left: 0.65rem; margin-left: 0.1rem; border-left: 1px solid rgb(255 255 255 / 0.32);
}
.ph-badge .cd { display: inline-flex; gap: 0.35rem; font-variant-numeric: tabular-nums; }
.ph-badge .cd__seg { font-size: 0.7rem; opacity: 0.9; }
.ph-badge .cd__seg b { font-weight: 700; font-size: 0.86rem; opacity: 1; }
.ph-badge .arr { font-weight: 700; }
/* attention pulse — a coral ring that breathes outward behind the badge */
.ph-badge::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -1;
  box-shadow: 0 0 0 0 rgb(255 122 85 / 0.55);
  animation: phPulse 3s ease-out infinite;
}
@keyframes phPulse {
  0% { box-shadow: 0 0 0 0 rgb(255 122 85 / 0.5); }
  70% { box-shadow: 0 0 0 14px rgb(255 122 85 / 0); }
  100% { box-shadow: 0 0 0 0 rgb(255 122 85 / 0); }
}
@media (prefers-reduced-motion: reduce) { .ph-badge::after { animation: none; } }
@media (max-width: 640px) { .ph-badge .topbar__cta { display: none; } }

/* ---- pre-launch state: no PH post yet, so the badge is a static "SOON" chip
   instead of a countdown. It isn't a link, so drop the hover lift/pointer — and
   keep the short label visible on mobile, where the countdown used to be hidden. */
.ph-badge--soon { cursor: default; }
.ph-badge--soon:hover { transform: none; box-shadow: 0 10px 30px -10px rgb(218 85 47 / 0.7), inset 0 1px 0 rgb(255 255 255 / 0.32); border-color: rgb(255 255 255 / 0.22); }
.ph-badge .ph-soon { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; }
@media (max-width: 640px) { .ph-badge--soon .topbar__cta { display: inline-flex; } }

.hero h1 {
  font-size: clamp(2.6rem, 5.4vw, 4.6rem); font-weight: 620; letter-spacing: -0.045em; line-height: 1.0;
  margin: 1.5rem auto 0; max-width: 15ch; color: #fff; text-align: center;
}
.hero h1 .hl { color: var(--accent-lite); }
.hero .lead { max-width: 37rem; margin: 1.5rem auto 0; color: var(--on-band-soft); font-size: 1.08rem; line-height: 1.55; text-align: center; }
.hero .lead b { color: var(--on-band); font-weight: 600; }
.hero .cta { display: flex; gap: 0.7rem; margin-top: 2rem; flex-wrap: wrap; justify-content: center; align-items: center; }
.hero .micro { margin-top: 1.1rem; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: rgb(244 245 247 / 0.4); }

/* the 3D constellation — a perfect symmetric pentagon of tool logos around the
   Assertify core, CENTRED behind the copy and spanning wide so the satellites frame
   the headline near the hero's edges. Anchored to the full-width band. */
/* animated blueprint canvas — bottom layer of the hero stack */
.hero__bg { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
.hero__visual { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.orbit { position: absolute; top: 50%; left: 80%; transform: translate(-50%, -50%); width: min(500px, 38vw); aspect-ratio: 1 / 1; }
.orbit__links { position: absolute; inset: 0; width: 100%; height: 100%; }
.orbit__links line { stroke: rgb(167 139 250 / 0.28); stroke-width: 0.4; stroke-dasharray: 1.6 2.2; }
/* --px/--py/--rot/--sc are a per-logo mouse-proximity offset set by
   initOrbParallax (site.js): only the orb the cursor is near leans toward it,
   grows a touch and tilts — each logo reacts on its own, not as a group.
   Composed AFTER the centring translate so the icon's bob (on the <img>) is
   untouched; the transition makes each orb drift/settle rather than snap.
   Rest state is 0/1, so no-JS / touch / reduced-motion leaves it static. */
.orb {
  position: absolute; left: var(--x, 50%); top: var(--y, 48%); z-index: 1;
  transform: translate(-50%, -50%) translate3d(var(--px, 0px), var(--py, 0px), 0) rotate(var(--rot, 0deg)) scale(var(--sc, 1));
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) { .orb { transition: none; } }
/* max-width:none defeats the global `img{max-width:100%}` reset, which otherwise
   collapses a <picture>-wrapped orb whose source has a large natural size (Claude's
   webp is 1193px) down to a fraction of its --s — the Claude orb was rendering at
   ~38px instead of 112px. */
.orb img { width: var(--s, 96px); height: auto; max-width: none; animation: bob 7s ease-in-out infinite; filter: drop-shadow(0 18px 32px rgb(0 0 0 / 0.55)); will-change: transform; }
.orb--core { z-index: 2; }
.orb--core img { width: 172px; filter: drop-shadow(0 28px 55px rgb(124 58 237 / 0.5)); animation-duration: 8.5s; }
.orb--chatgpt img { animation-delay: -0.7s; }
.orb--jira img { animation-delay: -1.4s; }
.orb--claude img { animation-delay: -2.8s; }
.orb--slack img { animation-delay: -4.2s; }
.orb--github img { animation-delay: -5.6s; }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
@media (prefers-reduced-motion: reduce) { .orb img, .caps-visual img, .cta-final__logo img { animation: none; } }
/* Touch devices: freeze the six hero orbs (they're a faint 0.5-opacity backdrop
   here anyway). Six forever-bobbing, drop-shadowed layers under the sticky glass
   nav were a needless per-frame repaint that fed the mobile scroll stutter. */
@media (hover: none) { .orb img { animation: none; will-change: auto; } }
/* Wide / zoomed-out viewports: `.wrap` is pinned at 1180px, so between ~1400 and
   ~2200px the whole hero floats as a centred block with the constellation stuck
   around 62% across and a wedge of dead space to its right — which reads as the
   logos being "off-centre" when you zoom out. Let ONLY the hero span wider and
   grow the orbit so the headline (left) and constellation (right) fill the
   viewport as one intentional composition instead of a marooned centred block.
   Every other section keeps the 1180 rhythm, and nothing below 1400px changes. */
@media (min-width: 1400px) {
  .band--hero > .wrap { width: min(1500px, calc(100% - 120px)); }
  .orbit { width: min(560px, 36vw); left: 80%; }
}
/* On smaller screens the pentagon tightens and softens so the copy stays readable. */
@media (max-width: 1180px) {
  .hero { padding: 5rem 0 4.5rem; min-height: 0; }
  .orbit { width: min(560px, 92vw); left: 50%; opacity: 0.5; }
  .orb--core img { width: 132px; }
  .orb img { width: calc(var(--s, 96px) * 0.7); }
}

/* ------------------------------------------------------------ marquees
   Two grayscale rows: the QA stack Assertify REPLACES (frameworks, languages,
   runners) and the stack it PLUGS INTO (Claude, Jira, Slack, GitHub, CI…). */
.trust { padding: 3.4rem 0 4.4rem; }
.trust__label { text-align: center; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); margin: 0 0 2rem; }
.trust__label b { color: var(--ink-soft); font-weight: 600; }
/* Vertical padding gives the clip box headroom so a hovered icon's scale(1.22)
   isn't sliced off top & bottom by `overflow: hidden` (needed for the horizontal
   loop). The mask is horizontal-only, so the padded band stays fully visible. */
.marquee { overflow: hidden; padding: 14px 0; -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); }
.marquee + .marquee { margin-top: 0.6rem; }
/* The loop is 3 identical copies moved by -33.333%. Spacing lives on each item's
   margin-right (NOT flex gap): gap yields 3N-1 gaps so one third of the track ≠
   one copy, and the ~1.4rem shortfall showed as a jump/seam every cycle. With a
   trailing margin on every item, one copy = exactly one third → seamless. */
.marquee__track { display: flex; align-items: center; width: max-content; animation: marquee 40s linear infinite; }
.marquee--rev .marquee__track { animation-direction: reverse; }
.marquee__track img { height: 26px; width: auto; margin-right: 4.2rem; opacity: 0.75; filter: grayscale(1) brightness(0.45) contrast(1.15); transition: opacity 0.2s ease, filter 0.2s ease, transform 0.2s ease; }
/* Hover reveals the real brand colour AND lifts/scales — so even the intrinsically
   monochrome marks (GitHub, the OpenAI knot) give a clear response, not just the
   colourful ones. */
.marquee__track img:hover { opacity: 1; filter: none; transform: scale(1.22); }
html.dark .marquee__track img { filter: grayscale(1) invert(0.8) brightness(1.1); }
@keyframes marquee { to { transform: translateX(-33.333%); } }
/* initVizPause toggles .viz-off 200px before/after the viewport — actually pause
   the strip there (this rule was missing, so the marquee animated 24/7). */
.marquee.viz-off .marquee__track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .marquee__track { animation: none; flex-wrap: wrap; justify-content: center; width: 100%; } }

/* ------------------------------------------------------------ cards & mockups */
.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); padding: 1.4rem;
}
.card h3 { font-size: 1.25rem; letter-spacing: -0.02em; margin: 1.1rem 0 0.4rem; font-weight: 600; }
.card > p { margin: 0; color: var(--ink-soft); font-size: 0.95rem; }

/* mock window: browser chrome — macOS traffic lights + a centered URL pill */
.mock { border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; background: var(--card); }
.mock__bar {
  display: flex; align-items: center; gap: 0.65rem; padding: 0.55rem 0.8rem;
  font-size: 0.68rem; letter-spacing: 0.08em; color: var(--muted);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, color-mix(in srgb, var(--card) 60%, var(--paper-2)), var(--paper-2));
}
.mock__dots { display: inline-flex; gap: 5px; flex: none; }
.mock__dots i { width: 9px; height: 9px; border-radius: 50%; background: var(--line-2); box-shadow: inset 0 0 0 0.5px rgb(0 0 0 / 0.12); }
.mock__dots i:nth-child(1) { background: #ff5f57; }
.mock__dots i:nth-child(2) { background: #febc2e; }
.mock__dots i:nth-child(3) { background: #28c840; }
.mock__url {
  flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 0.4rem;
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.04em; color: var(--muted);
  background: var(--card); border: 1px solid var(--line); border-radius: 999px;
  padding: 0.24rem 0.9rem; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.mock__url .lock { width: 9px; height: 9px; flex: none; color: var(--muted); }
.mock__url b { color: var(--ink-soft); font-weight: 500; }
.mock__badge { margin-left: auto; display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.mock__badge .live { width: 6px; height: 6px; border-radius: 50%; background: #22c55e; }

/* results table inside the runs-inbox mock */
.tbl { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.tbl th { text-align: left; font-weight: 500; font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); padding: 0.55rem 0.9rem; border-bottom: 1px solid var(--line); }
.tbl td { padding: 0.62rem 0.9rem; border-bottom: 1px solid var(--line); }
.tbl tr:last-child td { border-bottom: 0; }
.tbl .src { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 0.14rem 0.4rem; white-space: nowrap; }
.tag {
  display: inline-block; font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase;
  border-radius: 6px; padding: 0.18rem 0.5rem; font-weight: 500;
}
.tag--pass { background: var(--ok-100); color: var(--ok); }
.tag--fail { background: var(--err-100); color: var(--err); }
.tag--heal { background: var(--accent-100); color: var(--accent); }
html.dark .tag--heal { color: var(--accent-lite); }
.tag--warn { background: var(--warn-100); color: var(--warn); }
.tbl .age { color: var(--muted); font-family: var(--mono); font-size: 0.72rem; white-space: nowrap; }
/* interactive fail row → evidence drawer */
.tbl__row--fail { cursor: pointer; }
.tbl__row--fail:hover td { background: color-mix(in srgb, var(--err) 4%, transparent); }
.tbl__row--fail.is-open td { border-bottom-color: transparent; }
.tbl__detail td { background: color-mix(in srgb, var(--err) 4%, transparent); padding-top: 0; }
.tbl__detail .evi { display: inline-block; font-family: var(--mono); font-size: 0.68rem; color: var(--muted); border: 1px solid var(--line); background: var(--card); border-radius: 6px; padding: 0.2rem 0.5rem; margin: 0 0.4rem 0.2rem 0; }
.tbl__detail .evi b { color: var(--ink); }

/* platform bento */
.bento { display: grid; grid-template-columns: 5fr 7fr; gap: 1.4rem; margin-top: 3rem; }
.bento + .bento { margin-top: 1.4rem; }
.bento--flip { grid-template-columns: 7fr 5fr; }
@media (max-width: 900px) { .bento, .bento--flip { grid-template-columns: 1fr; } }

/* chat mock (ask across your app) */
.chat { display: flex; flex-direction: column; gap: 0.7rem; padding: 1rem; }
.chat__msg { border-radius: 12px; padding: 0.7rem 0.9rem; font-size: 0.88rem; max-width: 94%; }
.chat__msg--user { align-self: flex-end; background: var(--ink); color: var(--paper); }
html.dark .chat__msg--user { background: #f2f3f5; color: #0b0c10; }
.chat__msg--ai { align-self: flex-start; background: var(--paper-2); border: 1px solid var(--line); width: 94%; }
.chat__rows { display: flex; flex-direction: column; gap: 0.45rem; margin-top: 0.55rem; font-size: 0.82rem; }
.chat__row { display: flex; align-items: center; gap: 0.5rem; }
.chat__row .ck { color: var(--ok); font-weight: 700; }
.chat__row .tag { margin-left: auto; }
.chat__row.dim { color: var(--muted); }
.caret { display: inline-block; width: 7px; height: 1em; background: var(--accent); vertical-align: text-bottom; animation: blink 1.1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* self-heal path card */
.pathcard { padding: 1.1rem; }
.pathcard__sev { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
.pathcard__sev .sev { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--err); border: 1px solid color-mix(in srgb, var(--err) 40%, transparent); border-radius: 6px; padding: 0.2rem 0.55rem; }
.pathcard__sev .meta { font-family: var(--mono); font-size: 0.68rem; color: var(--muted); letter-spacing: 0.06em; }
.pathcard h4 { font-size: 1.05rem; margin: 0.8rem 0 0.3rem; font-weight: 600; }
.pathcard > p { margin: 0; color: var(--ink-soft); font-size: 0.88rem; }
.pathcard__path {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem;
  font-family: var(--mono); font-size: 0.72rem; margin-top: 0.95rem;
  color: var(--ink-soft);
}
.pathcard__path .seg { border: 1px solid var(--line); background: var(--paper-2); border-radius: 6px; padding: 0.25rem 0.55rem; }
.pathcard__path .seg.bad { border-color: color-mix(in srgb, var(--err) 45%, transparent); color: var(--err); }
.pathcard__path .seg.fix { border-color: color-mix(in srgb, var(--ok) 45%, transparent); color: var(--ok); }
.pathcard__path .sep { color: var(--muted); }
.pathcard__foot {
  display: flex; flex-wrap: wrap; gap: 0.6rem 1.2rem; margin-top: 1rem; padding-top: 0.9rem;
  border-top: 1px solid var(--line); font-size: 0.82rem; color: var(--muted); align-items: center;
}
.pathcard__foot b { color: var(--ink); font-weight: 600; }
.pathcard__foot .cta-mini { margin-left: auto; font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }

/* canvas graph mock — chrome spans edge-to-edge; only the drawing is inset */
.graph { padding: 0; }
.graph svg { width: calc(100% - 1.6rem); height: auto; display: block; margin: 0.8rem auto; }
.graph .node rect { fill: var(--card); stroke: var(--line-2); }
.graph .node.ok rect { stroke: color-mix(in srgb, var(--ok) 55%, transparent); }
.graph .node.err rect { stroke: color-mix(in srgb, var(--err) 55%, transparent); }
.graph .node .t { font: 500 11px var(--mono); fill: var(--ink-soft); }
.graph .sdot { fill: var(--accent); }
.graph .port { fill: var(--line-2); }
.graph .edge-base { fill: none; stroke: var(--line-2); stroke-width: 1.4; }
.graph .edge-base.ok { stroke: color-mix(in srgb, var(--ok) 45%, transparent); }
.graph .edge-base.err { stroke: color-mix(in srgb, var(--err) 35%, transparent); stroke-dasharray: 3 4; }
.graph .edge-flow { fill: none; stroke: var(--accent); stroke-width: 1.4; stroke-dasharray: 5 22; animation: flow 1.6s linear infinite; }
.graph .edge-flow.ok { stroke: var(--ok); }
@keyframes flow { to { stroke-dashoffset: -27; } }

/* ------------------------------------------------------------ why — economics + 3D calc
   Compact 2-column so the whole section fits one viewport: tight copy on the left,
   an interactive card on the right that tilts to the cursor and counts up on reveal. */
.why { display: grid; grid-template-columns: 5fr 6fr; gap: 3.5rem; align-items: center; }
@media (max-width: 980px) { .why { grid-template-columns: 1fr; align-items: start; gap: 2.4rem; } }
.why__copy h2 { font-size: clamp(2.2rem, 4.6vw, 3.6rem); line-height: 1.05; margin: 1.05rem 0 0; letter-spacing: -0.02em; }
.why__copy h2 .hl { color: var(--accent); }
.why__copy > p { margin: 1.1rem 0 0; color: var(--ink-soft); font-size: 1.05rem; max-width: 34rem; }
.why__points { list-style: none; margin: 1.5rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.72rem; }
.why__points li { position: relative; padding-left: 1.4rem; font-size: 0.95rem; color: var(--ink-soft); }
.why__points li::before {
  content: ""; position: absolute; left: 0; top: 0.42em; width: 7px; height: 7px;
  background: var(--accent); border-radius: 2px; transform: rotate(45deg);
  box-shadow: 0 0 10px rgb(124 58 237 / 0.5);
}
.why__points b { color: var(--ink); font-weight: 600; }

/* ---- the 3D tilting calculator ---- */
.calc {
  position: relative; background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; padding: 1.7rem 1.7rem 1.5rem; overflow: hidden;
  box-shadow: 0 34px 70px -30px rgb(66 28 155 / 0.4), var(--shadow);
  transform: perspective(1100px) rotateX(0) rotateY(0);
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1);
  transform-style: preserve-3d; will-change: transform;
}
.calc > *:not(.calc__grid):not(.calc__glow) { position: relative; z-index: 2; }
/* faint animated blueprint grid — ties the card to the hero background.
   The grid pattern lives on a ::before that pans via a compositor transform
   instead of animating background-position on the main thread (which repainted
   the full card area every frame while #why is on screen). The pseudo is offset
   −26px (one full 26px cell) top/left and translates +26px, so the visible phase
   at every instant is identical to the old background-position pan; overflow:hidden
   clips the 26px overhang and the parent's mask/opacity shape it exactly as before. */
.calc__grid {
  position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0.7;
  overflow: hidden;
  -webkit-mask-image: radial-gradient(130% 110% at 88% 4%, #000, transparent 72%);
  mask-image: radial-gradient(130% 110% at 88% 4%, #000, transparent 72%);
}
.calc__grid::before {
  content: ""; position: absolute; top: -26px; left: -26px; right: 0; bottom: 0;
  background-image:
    linear-gradient(rgb(124 58 237 / 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgb(124 58 237 / 0.07) 1px, transparent 1px);
  background-size: 26px 26px;
  animation: calcGrid 26s linear infinite;
}
@keyframes calcGrid { to { transform: translate3d(26px, 26px, 0); } }
/* violet glow that follows nobody — just breathes in the top-right */
.calc__glow {
  position: absolute; top: -30%; right: -12%; width: 60%; height: 80%; z-index: 1; pointer-events: none;
  background: radial-gradient(circle, rgb(124 58 237 / 0.22), transparent 66%); filter: blur(8px);
  animation: calcGlow 6s ease-in-out infinite;
}
@keyframes calcGlow { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .calc__grid::before, .calc__glow { animation: none; } }

.calc__head { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; }
.calc__head h3 { font-size: 1.22rem; font-weight: 640; margin: 0; letter-spacing: -0.01em; }
.calc__tag { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
/* local / cloud switcher — leads with the $0 (local) option; a sliding thumb
   (positioned by site.js initCalc) tracks the active option, like the app toggles */
.calc__mode { position: relative; display: inline-flex; margin-top: 1rem; padding: 0.22rem; border-radius: 10px; background: rgb(124 58 237 / 0.09); }
.calc__mode-btn { position: relative; z-index: 1; font-family: var(--mono); font-size: 0.62rem; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); background: none; border: 0; border-radius: 7px; padding: 0.4rem 0.8rem; cursor: pointer; transition: color 0.2s ease; }
.calc__mode-btn:hover { color: var(--ink); }
.calc__mode-btn.is-active { color: #fff; }
/* geometry (width/height/transform) is set inline by JS — CSS only paints + slides */
.calc__mode__thumb { position: absolute; z-index: 0; top: 0; left: 0; border-radius: 7px; background: var(--accent); box-shadow: 0 4px 14px rgb(124 58 237 / 0.35);
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1), width 0.28s cubic-bezier(0.2, 0.7, 0.2, 1); }
@media (prefers-reduced-motion: reduce) { .calc__mode__thumb { transition: none; } }
.calc__slider { margin: 1.3rem 0 1.5rem; }
.calc__slider input[type="range"] {
  width: 100%; appearance: none; -webkit-appearance: none; height: 6px; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent) var(--p, 30%), var(--line) var(--p, 30%));
  outline: none;
}
.calc__slider input::-webkit-slider-thumb {
  -webkit-appearance: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--card); border: 2px solid var(--accent); cursor: grab;
  box-shadow: 0 4px 14px rgb(124 58 237 / 0.45), 0 0 0 6px rgb(124 58 237 / 0.1);
  transition: box-shadow 0.2s ease;
}
.calc__slider input:active::-webkit-slider-thumb { cursor: grabbing; box-shadow: 0 4px 14px rgb(124 58 237 / 0.55), 0 0 0 10px rgb(124 58 237 / 0.14); }
.calc__slider input::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; background: var(--card); border: 2px solid var(--accent); cursor: grab; }
.calc__slider output { display: block; margin-top: 0.75rem; font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.calc__slider output b { color: var(--ink); font-size: 1rem; }

.calc__bars { display: flex; flex-direction: column; gap: 0.95rem; }
.calc-bar { display: grid; grid-template-columns: 8rem 1fr auto; align-items: center; gap: 0.9rem; font-size: 0.86rem; }
.calc-bar__name { color: var(--ink-soft); }
/* 3D extruded track: inset well + a raised, glossy fill */
.calc-bar__track { height: 15px; border-radius: 5px; background: var(--paper-2); overflow: hidden; box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.14), inset 0 -1px 0 rgb(255 255 255 / 0.5); }
.calc-bar__track i {
  display: block; height: 100%; width: var(--w, 10%); border-radius: inherit;
  background: linear-gradient(180deg, rgb(178 178 188 / 0.95), rgb(126 126 138 / 0.95));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.35);
  transition: width 0.75s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.calc-bar.is-us .calc-bar__name { color: var(--ink); font-weight: 600; display: flex; flex-direction: column; gap: 0.1rem; }
/* run-allowance sublabel: "unlimited runs" (local) vs "up to 5,000/mo" (cloud) */
.calc-us-note { font-family: var(--mono); font-size: 0.58rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--accent); }
.calc-bar.is-us .calc-bar__track { background: rgb(124 58 237 / 0.1); }
.calc-bar.is-us .calc-bar__track i {
  background: linear-gradient(180deg, #a882ff, var(--accent));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.5), 0 0 18px rgb(124 58 237 / 0.65);
}
.calc-bar b { font-family: var(--mono); font-size: 0.82rem; font-weight: 600; white-space: nowrap; }
.calc-bar.is-us b { color: var(--accent); }
.calc-bar b span { color: var(--muted); font-weight: 400; }

.calc__save { margin: 1.3rem 0 0; padding-top: 1.15rem; border-top: 1px solid var(--line-2); font-size: 1rem; color: var(--ink-soft); }
.calc__save b { color: var(--accent); font-family: var(--mono); font-weight: 700; }
.calc__fine { margin: 0.7rem 0 0; font-size: 0.7rem; color: var(--muted); line-height: 1.5; }
@media (max-width: 560px) { .calc-bar { grid-template-columns: 6rem 1fr auto; gap: 0.6rem; } }

/* ------------------------------------------------------------ capabilities band
   Interactive layer stack: tapered isometric plates, one glowing = active. */
.stackwrap { display: grid; grid-template-columns: 1fr 400px 1fr; gap: 2.5rem; align-items: center; margin-top: 3.5rem; }
.stack__col { display: flex; flex-direction: column; gap: 1.1rem; }
.stack__col--left { text-align: right; align-items: flex-end; }
/* each capability is a blueprint/cyberpunk glass container that lights up when active */
.stack__label {
  position: relative; display: block; width: 100%; max-width: 21rem;
  padding: 0.85rem 1rem; border-radius: 10px; cursor: pointer; overflow: hidden;
  text-align: inherit; color: inherit; font: inherit;
  background: linear-gradient(150deg, rgb(255 255 255 / 0.05), rgb(255 255 255 / 0.012));
  border: 1px solid rgb(167 139 250 / 0.16);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06), 0 16px 34px -22px rgb(0 0 0 / 0.75);
  opacity: 0.66;
  transition: opacity 0.3s ease, border-color 0.3s ease, transform 0.35s cubic-bezier(.2,.7,.2,1.2), box-shadow 0.35s ease, background 0.3s ease;
}
/* faint blueprint grid inside each container, fading from the outer corner */
.stack__label::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0.6;
  background-image:
    linear-gradient(rgb(167 139 250 / 0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgb(167 139 250 / 0.08) 1px, transparent 1px);
  background-size: 16px 16px;
  -webkit-mask-image: radial-gradient(130% 110% at 100% 0%, #000, transparent 68%);
  mask-image: radial-gradient(130% 110% at 100% 0%, #000, transparent 68%);
}
.stack__col--right .stack__label::before { -webkit-mask-image: radial-gradient(130% 110% at 0% 0%, #000, transparent 68%); mask-image: radial-gradient(130% 110% at 0% 0%, #000, transparent 68%); }
.stack__label b, .stack__label p { position: relative; z-index: 1; }
.stack__label b { display: flex; align-items: center; gap: 0.55rem; font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; color: var(--on-band); }
.stack__col--left .stack__label b { flex-direction: row-reverse; }
.stack__dot { width: 7px; height: 7px; border-radius: 50%; background: rgb(244 245 247 / 0.28); transition: background 0.25s ease, box-shadow 0.25s ease; flex: none; }
.stack__label p { margin: 0.4rem 0 0; font-size: 0.83rem; color: var(--on-band-soft); line-height: 1.45; }
.stack__label:hover { opacity: 1; transform: translateY(-3px); border-color: rgb(167 139 250 / 0.34); }
.stack__label.is-on {
  opacity: 1; border-color: rgb(167 139 250 / 0.5);
  background: linear-gradient(150deg, rgb(124 58 237 / 0.2), rgb(124 58 237 / 0.03));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.1), 0 0 0 1px rgb(167 139 250 / 0.22), 0 20px 44px -20px rgb(124 58 237 / 0.7), 0 0 30px rgb(124 58 237 / 0.22);
}
.stack__label.is-on .stack__dot { background: var(--accent-lite); box-shadow: 0 0 0 4px rgb(167 139 250 / 0.22); }
/* cyberpunk corner bracket on the active container */
.stack__label.is-on::after {
  content: ""; position: absolute; top: 7px; width: 11px; height: 11px; z-index: 1; border-top: 1.5px solid var(--accent-lite);
}
.stack__col--left .stack__label.is-on::after { left: 7px; border-left: 1.5px solid var(--accent-lite); }
.stack__col--right .stack__label.is-on::after { right: 7px; border-right: 1.5px solid var(--accent-lite); }
.stack3d { position: relative; height: 460px; perspective: 1400px; }
.plate {
  position: absolute; left: 50%; top: 56%;
  width: calc(330px - var(--i) * 14px); height: calc(330px - var(--i) * 14px); border-radius: 40px;
  transform: translate(-50%, -50%) rotateX(62deg) rotateZ(45deg) translateZ(calc(var(--i) * 30px));
  background: linear-gradient(145deg, #262b3c, #151827);
  border: 1px solid rgb(255 255 255 / 0.12);
  box-shadow: 0 30px 60px -30px rgb(0 0 0 / 0.8), inset 0 1px 0 rgb(255 255 255 / 0.07);
  cursor: pointer; transition: background 0.35s ease, box-shadow 0.35s ease, border-color 0.35s ease, transform 0.35s ease;
}
.plate:hover { border-color: rgb(255 255 255 / 0.16); transform: translate(-50%, -50%) rotateX(62deg) rotateZ(45deg) translateZ(calc(var(--i) * 30px + 8px)); }
.plate.is-on {
  background: linear-gradient(145deg, #5b21b6, #7c3aed 55%, #9333ea);
  border-color: rgb(167 139 250 / 0.8);
  transform: translate(-50%, -50%) rotateX(62deg) rotateZ(45deg) translateZ(calc(var(--i) * 30px + 12px));
  animation: platePulse 2.6s ease-in-out infinite;
}
@keyframes platePulse {
  0%, 100% { box-shadow: 0 0 70px 2px rgb(124 58 237 / 0.4), 0 30px 60px -30px rgb(0 0 0 / 0.8); }
  50% { box-shadow: 0 0 120px 12px rgb(124 58 237 / 0.6), 0 30px 60px -30px rgb(0 0 0 / 0.8); }
}
@media (prefers-reduced-motion: reduce) { .plate.is-on { animation: none; } }
@media (max-width: 1080px) { .stackwrap { grid-template-columns: 1fr 320px 1fr; gap: 1.6rem; } .plate { width: calc(260px - var(--i) * 11px); height: calc(260px - var(--i) * 11px); } }
@media (max-width: 900px) { .stackwrap { display: none; } }

/* Original quality-reactor visual: eight capabilities feed one shared context
   core, which turns intent into verifiable proof. Unlike a generic layer stack,
   the radial system makes the closed-loop orchestration explicit. */
.quality-reactor {
  position: relative; width: 390px; aspect-ratio: 1; margin-inline: auto;
  display: grid; place-items: center; isolation: isolate; perspective: 900px;
}
.reactor__field {
  position: absolute; inset: 12%; border-radius: 50%; z-index: -2;
  background: radial-gradient(circle, rgb(124 58 237 / .3), rgb(124 58 237 / .08) 42%, transparent 70%);
  filter: blur(10px); animation: reactorBreathe 4s ease-in-out infinite;
}
.reactor__ring { position: absolute; border-radius: 50%; pointer-events: none; }
/* radius 48% == the node radius (nodes sit at --x/--y 2%–98%), so the ring runs
   right through the icon centres and the icons sit on the line */
.reactor__ring--outer {
  inset: 2%; border: 1px solid rgb(167 139 250 / .28);
  box-shadow: inset 0 0 55px rgb(124 58 237 / .1), 0 0 55px rgb(124 58 237 / .1);
}
.reactor__ring--outer::before {
  content: ""; position: absolute; inset: -2px; border-radius: inherit;
  background: conic-gradient(from 20deg, transparent 0 9%, #9f73ff 11%, transparent 14% 35%, #6f43d8 38%, transparent 41% 68%, #c4a7ff 71%, transparent 74%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1px));
  animation: reactorSpin 12s linear infinite;
}
.reactor__ring--inner {
  inset: 25%; border: 1px dashed rgb(255 255 255 / .14);
  animation: reactorSpin 18s linear infinite reverse;
}
.reactor__node {
  position: absolute; left: var(--x); top: var(--y); transform: translate(-50%,-50%);
  width: 48px; height: 48px; border-radius: 8px; display: grid; place-items: center;
  color: rgb(255 255 255 / .34);
  /* glass sheen over an OPAQUE dark base so the ring line stays hidden behind the
     node (inactive nodes were translucent, letting the line show through) */
  background: linear-gradient(145deg, rgb(255 255 255 / .07), rgb(255 255 255 / .015)), linear-gradient(150deg, #1b1f2e, #11141d);
  border: 1px solid rgb(255 255 255 / .12); box-shadow: inset 0 1px 0 rgb(255 255 255 / .1), 0 15px 28px rgb(0 0 0 / .25);
  transition: color .35s ease, border-color .35s ease, background .35s ease, box-shadow .35s ease, transform .35s cubic-bezier(.2,.7,.2,1.25);
}
.reactor__node b { font-family: var(--mono); font-size: .65rem; letter-spacing: -.04em; display: grid; place-items: center; }
.reactor__node svg { width: 22px; height: 22px; display: block; }
.reactor__node.is-on {
  color: #fff; border-color: rgb(190 158 255 / .8); background: linear-gradient(145deg,#9c6cff,#6330d7);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .45), 0 0 0 7px rgb(124 58 237 / .12), 0 0 34px rgb(139 92 246 / .65);
  transform: translate(-50%,-50%) translateZ(24px) scale(1.14);
}
.reactor__core {
  position: relative; width: 185px; height: 185px; border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle at 36% 28%, rgb(255 255 255 / .16), transparent 25%), linear-gradient(145deg,rgb(48 31 76 / .86),rgb(12 10 20 / .96));
  border: 1px solid rgb(205 181 255 / .32); box-shadow: inset 0 1px 0 rgb(255 255 255 / .22), inset 0 -20px 35px rgb(0 0 0 / .28), 0 30px 70px rgb(0 0 0 / .5), 0 0 55px rgb(124 58 237 / .25);
  transform: rotateX(7deg); transform-style: preserve-3d;
}
.reactor__core img { width: 112px; height: auto; display: block; filter: drop-shadow(0 20px 24px rgb(66 28 155 / .5)); animation: reactorFloat 4.5s ease-in-out infinite; }
.reactor__core > span,.reactor__core > strong,.reactor__core > em { position: absolute; font-family: var(--mono); font-style: normal; letter-spacing: .15em; text-transform: uppercase; }
.reactor__core > span { top: -35px; color: rgb(255 255 255 / .35); font-size: .5rem; }
.reactor__core > strong { bottom: 17px; color: #fff; font-size: .5rem; font-weight: 600; }
.reactor__core > em { bottom: -35px; color: #b794ff; font-size: .5rem; }
@keyframes reactorSpin { to { rotate: 1turn; } }
@keyframes reactorBreathe { 50% { transform: scale(1.1); opacity: .72; } }
@keyframes reactorFloat { 50% { transform: translateY(-8px) rotate(2deg); } }
@media (prefers-reduced-motion: reduce) { .reactor__field,.reactor__ring::before,.reactor__ring--inner,.reactor__core img { animation: none; } }
@media (max-width:1080px) { .quality-reactor { width: 315px; } .reactor__node { width: 42px; height: 42px; border-radius: 8px; } .reactor__core { width: 155px; height: 155px; } .reactor__core img { width: 92px; } }
.caps.caps--fallback { display: none; }
@media (max-width: 900px) { .caps.caps--fallback { display: grid; margin-top: 3rem; } }

.caps { display: grid; grid-template-columns: repeat(3, 1fr); margin-top: 3.4rem; border: 1px solid var(--band-line); border-radius: var(--r); overflow: hidden; }
.cap { padding: 1.7rem 1.6rem; border-right: 1px solid var(--band-line); border-bottom: 1px solid var(--band-line); background: rgb(255 255 255 / 0.015); }
.cap:nth-child(3n) { border-right: 0; }
.cap:nth-child(n+7) { border-bottom: 0; }
.cap b { display: block; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent-lite); margin-bottom: 0.55rem; }
.cap p { margin: 0; color: var(--on-band-soft); font-size: 0.92rem; }
@media (max-width: 860px) {
  .caps { grid-template-columns: 1fr; }
  .cap { border-right: 0 !important; border-bottom: 1px solid var(--band-line) !important; }
  .cap:last-child { border-bottom: 0 !important; }
}

/* ------------------------------------------------------------ how it works */
.how { display: grid; grid-template-columns: 6fr 5fr; gap: 3.5rem; align-items: center; }
@media (max-width: 980px) { .how { grid-template-columns: 1fr; } }
.steps { margin-top: 2.6rem; border-top: 1px solid var(--line-2); }
.step { display: grid; grid-template-columns: 3.2rem 1fr; gap: 1rem; padding: 1.5rem 0; border-bottom: 1px solid var(--line-2); }
.step__num { font-family: var(--mono); font-size: 0.8rem; color: var(--accent); padding-top: 0.3rem; }
.step h3 { font-size: 1.25rem; font-weight: 600; margin: 0 0 0.4rem; }
.step p { margin: 0; color: var(--ink-soft); font-size: 0.95rem; max-width: 34rem; }

/* coverage / integrations side card */
.sidecard { align-self: center; }
.sidecard .card { padding: 0; overflow: hidden; }
.sidecard__head { padding: 1.4rem 1.4rem 1.1rem; border-bottom: 1px solid var(--line); }
.sidecard__head .k { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.sidecard__head h3 { font-size: 1.2rem; font-weight: 600; margin: 0.5rem 0 0.35rem; }
.sidecard__head p { margin: 0; color: var(--ink-soft); font-size: 0.88rem; }
.sidecard__logos { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0.55rem; padding: 1.2rem 1.4rem 1.4rem; }
.sidecard__logos span, .sidecard__logos button { display: grid; place-items: center; aspect-ratio: 1; border: 1px solid var(--line); border-radius: 10px; background: var(--paper-2); }
.sidecard__logos button { cursor: pointer; padding: 0; transition: border-color 0.15s ease, transform 0.15s ease; }
.sidecard__logos button:hover { transform: translateY(-2px); }
.sidecard__logos button.is-on { border-color: var(--accent); background: var(--card); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent); }
.sidecard__logos img { width: 52%; height: auto; }

/* ---- ASCII logo carousel (Trident-style morphing glyph art) */
.ascii { padding: 0.6rem 1.4rem 0; }
.ascii__art {
  /* The art is a fixed 46-col grid; at 10px mono that's ~276px wide. On a narrow
     phone that overflows the card and gets clipped by overflow:hidden — cutting
     the ChatGPT knot's edges (the "warped" look). Scale font-size DOWN to fit,
     capped at 10px. line-height MUST track font-size (ratio 1 → 0.6 cell aspect)
     or the glyph grid stretches vertically and the logo distorts. 46 cols ×
     0.6 glyph-advance = 27.6em of width; keep it inside the card's content box. */
  margin: 0; font-family: var(--mono);
  font-size: min(10px, calc((100vw - 6rem) / 27.6)); line-height: 1; letter-spacing: 0;
  color: #a7adbd; text-align: center; user-select: none;
  min-height: 20em; overflow: hidden;
  background:
    repeating-linear-gradient(0deg, transparent 0 3px, rgb(255 255 255 / 0.02) 3px 4px),
    radial-gradient(80% 90% at 50% 0%, #12141d, #0b0d13);
  border: 1px solid #1d2029; border-radius: 10px; padding: 1rem 0;
  text-shadow: 0 0 6px rgb(167 139 250 / 0.12);
}
.ascii__caption { display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin-top: 0.8rem; font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.ascii__caption .live { width: 7px; height: 7px; border-radius: 50%; background: #22c55e; }
.ascii__caption b { color: var(--ink); font-weight: 600; }
.ascii__desc { margin: 0.45rem auto 0; text-align: center; font-size: 0.84rem; color: var(--ink-soft); max-width: 24rem; min-height: 2.6em; }
.ascii__nav { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 0.7rem; }
.ascii__arrow { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--line-2); background: var(--card); color: var(--ink-soft); cursor: pointer; font-size: 1rem; line-height: 1; display: grid; place-items: center; padding-bottom: 2px; }
.ascii__arrow:hover { border-color: var(--muted); }
.ascii__dashes { display: flex; gap: 6px; }
.ascii__dashes i { display: block; width: 18px; height: 2.5px; border-radius: 2px; background: var(--line-2); transition: width 0.25s ease, background 0.25s ease; }
.ascii__dashes i.on { width: 30px; background: var(--ink); }
.sidecard__status { display: flex; align-items: center; gap: 0.5rem; padding: 0.8rem 1.4rem; border-top: 1px solid var(--line); font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.sidecard__status .live { width: 7px; height: 7px; border-radius: 50%; background: #22c55e; }
@media (max-width: 640px) { .sidecard__logos { grid-template-columns: repeat(4, 1fr); } }

/* ------------------------------------------------------------ integrations */
/* Slack conversation mock */
.slackmock { padding: 0.9rem; display: flex; flex-direction: column; gap: 0.8rem; }
.slackmock__head { display: flex; align-items: center; gap: 0.5rem; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.08em; color: var(--muted); }
.slackmock__head img { width: 15px; height: 15px; }
.slackmsg { display: grid; grid-template-columns: 34px 1fr; gap: 0.65rem; }
.slackmsg__av { width: 34px; height: 34px; border-radius: 8px; display: grid; place-items: center; background: var(--accent-50); border: 1px solid var(--line); font-weight: 700; font-size: 0.75rem; color: var(--accent); overflow: hidden; }
.slackmsg__av img { width: 20px; height: 20px; }
.slackmsg__who { font-size: 0.82rem; font-weight: 650; }
.slackmsg__who span { font-weight: 400; color: var(--muted); font-size: 0.72rem; margin-left: 0.4rem; font-family: var(--mono); }
.slackmsg__body { font-size: 0.86rem; color: var(--ink-soft); margin-top: 0.15rem; }
.slackmsg__body b { color: var(--ink); }
.slackmsg__body code { font-family: var(--mono); font-size: 0.78rem; background: var(--paper-2); border: 1px solid var(--line); border-radius: 5px; padding: 0.05rem 0.3rem; }
.slackmsg__files { display: flex; gap: 0.45rem; margin-top: 0.45rem; flex-wrap: wrap; }
.slackmsg__files span { font-family: var(--mono); font-size: 0.66rem; border: 1px solid var(--line); border-radius: 6px; padding: 0.2rem 0.5rem; color: var(--muted); background: var(--paper-2); }

/* ------------------------------------------------------------ economics formula + facts */
/* ---- the loop: text left, live stage right (half & half) */
.loopwrap { display: grid; grid-template-columns: 1fr 1fr; gap: 3.5rem; align-items: center; }
@media (max-width: 980px) { .loopwrap { grid-template-columns: 1fr; } }
.loopsteps { margin-top: 2.2rem; border-top: 1px solid var(--line-2); }
.loopstep {
  display: block; width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  font: inherit; color: inherit; padding: 0.95rem 0.4rem; border-bottom: 1px solid var(--line-2);
  opacity: 0.5; transition: opacity 0.25s ease, background 0.25s ease;
}
.loopstep:hover { opacity: 0.85; }
.loopstep.is-on { opacity: 1; background: color-mix(in srgb, var(--accent) 4%, transparent); }
.loopstep b { display: flex; align-items: center; gap: 0.6rem; font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; color: var(--ink); }
.loopstep__ic { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; background: var(--card); border: 1px solid var(--line); font-style: normal; font-size: 0.75rem; font-weight: 700; flex: none; transition: box-shadow 0.25s ease, border-color 0.25s ease; }
.loopstep__ic img { width: 14px; height: 14px; }
.loopstep__ic--fail { color: var(--err); }
.loopstep__ic--ok { color: var(--ok); }
.loopstep.is-on .loopstep__ic { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent); }
.loopstep p { margin: 0.4rem 0 0 2.2rem; font-size: 0.88rem; color: var(--ink-soft); }
.loopstep p b { display: inline; font-family: inherit; font-size: inherit; letter-spacing: 0; text-transform: none; color: var(--ink); font-weight: 600; }
.loopcard { padding: 1.6rem; }
.loop__stagewrap { min-height: 300px; display: grid; align-items: center; }
.loop__stage { display: none; grid-area: 1 / 1; }
.loop__stage.is-on { display: block; animation: stageIn 0.35s ease; }
@keyframes stageIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.loop__foot { display: flex; align-items: center; gap: 0.5rem; margin-top: 1.3rem; padding-top: 1rem; border-top: 1px solid var(--line); font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.loop__foot .live { width: 7px; height: 7px; border-radius: 50%; background: #22c55e; }

/* stage panes */
.failrow { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 1rem; border: 1px solid var(--line); border-radius: var(--r-sm); padding: 1rem 1.1rem; background: color-mix(in srgb, var(--err) 3%, var(--card)); max-width: 44rem; margin-inline: auto; }
.failrow .src { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 0.14rem 0.4rem; }
.failrow__t > b { display: block; font-size: 0.95rem; }
.failrow__t small b { display: inline; font-size: inherit; color: var(--ink); font-weight: 600; }
.failrow__t small { color: var(--ink-soft); font-size: 0.8rem; }
.evir { display: flex; flex-wrap: wrap; gap: 0.45rem; justify-content: center; margin-top: 0.9rem; }
.evir .evi { font-family: var(--mono); font-size: 0.68rem; border: 1px solid var(--line); border-radius: 6px; padding: 0.22rem 0.55rem; color: var(--muted); background: var(--card); }
.evir .evi b { color: var(--ink); }
.loop__stage .slackmock { max-width: 34rem; margin-inline: auto; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--card); }

/* jira ticket pane */
.tkt { max-width: 34rem; margin-inline: auto; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--card); padding: 1.1rem 1.2rem; }
.tkt__head { display: flex; align-items: center; gap: 0.6rem; }
.tkt__head img { width: 18px; height: 18px; }
.tkt__head b { font-size: 0.78rem; letter-spacing: 0.08em; color: var(--muted); }
.tkt__title { margin: 0.7rem 0 0.9rem; font-size: 1.02rem; font-weight: 620; line-height: 1.35; }
.tkt .evir { justify-content: flex-start; margin-top: 0; }

/* github PR pane */
.ghpr { max-width: 34rem; margin-inline: auto; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--card); overflow: hidden; }
.ghpr__row { display: flex; justify-content: space-between; gap: 1rem; padding: 0.85rem 1.1rem; border-bottom: 1px solid var(--line); font-size: 0.92rem; }
.ghpr__row .mono { color: var(--muted); font-size: 0.78rem; }
.ghpr__check { display: flex; align-items: center; gap: 0.7rem; padding: 0.75rem 1.1rem; font-size: 0.86rem; color: var(--ink-soft); }
.ghpr__check + .ghpr__check { border-top: 1px solid var(--line); }
.ghpr__check i { font-style: normal; font-weight: 700; }
.ghpr__check.is-bad i { color: var(--err); }
.ghpr__check.is-ok i { color: var(--ok); }
.ghpr__check em { margin-left: auto; font-style: normal; font-family: var(--mono); font-size: 0.66rem; color: var(--muted); }

/* green pane */
.loop__done { text-align: center; max-width: 30rem; margin-inline: auto; }
.loop__doneck { display: grid; place-items: center; width: 54px; height: 54px; margin: 0 auto 0.9rem; border-radius: 50%; background: var(--ok-100); color: var(--ok); font-size: 1.4rem; font-weight: 700; }
.loop__done b { font-size: 1.05rem; }
.loop__done p { margin: 0.5rem 0 0; color: var(--ink-soft); font-size: 0.92rem; }

/* ---- the economics: itemized receipt */
.econ { display: grid; grid-template-columns: 6fr 5fr; gap: 3.5rem; align-items: start; margin-top: 3rem; }
@media (max-width: 980px) { .econ { grid-template-columns: 1fr; } }
.econ__points { margin-top: 0; }
.receipt {
  position: relative; font-family: var(--mono); background: var(--card); border: 1px solid var(--line);
  box-shadow: var(--shadow-lg); border-radius: 4px 4px 0 0; max-width: 26rem; justify-self: center; width: 100%;
  transform: rotate(1.4deg);
  padding-bottom: 14px;
  -webkit-mask: linear-gradient(#000 0 0) padding-box, conic-gradient(from -45deg at bottom, transparent 0 25%, #000 0 75%, transparent 0) bottom / 18px 14px repeat-x border-box;
          mask: linear-gradient(#000 0 0) padding-box, conic-gradient(from -45deg at bottom, transparent 0 25%, #000 0 75%, transparent 0) bottom / 18px 14px repeat-x border-box;
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
html.dark .receipt { background: #f4f2ec; border-color: transparent; }
.receipt__head { text-align: center; font-size: 0.68rem; letter-spacing: 0.22em; color: #6b6f7a; padding: 1.3rem 1.4rem 0.9rem; border-bottom: 2px dashed #d9d7cf; margin: 0 1.2rem; }
.receipt__body { padding: 1.1rem 2.4rem 1.4rem; }
.receipt__row { display: flex; align-items: baseline; gap: 0.5rem; padding: 0.34rem 0; font-size: 0.8rem; color: #3a3e47; }
.receipt__row i { flex: 1; border-bottom: 2px dotted #cfcdc5; transform: translateY(-3px); }
.receipt__row b { font-weight: 600; color: #171a20; }
.receipt__row sup { color: #8a8e98; }
.receipt__total { display: flex; align-items: baseline; gap: 0.5rem; margin-top: 0.8rem; padding-top: 0.9rem; border-top: 2px dashed #d9d7cf; font-size: 1rem; font-weight: 600; color: #171a20; }
.receipt__total i { flex: 1; }
.receipt__total b { font-size: 1.5rem; letter-spacing: -0.02em; }
.receipt__total small { font-size: 0.75rem; color: #6b6f7a; font-weight: 400; }
.receipt__cmp { margin-top: 0.8rem; font-size: 0.68rem; color: #8a8e98; text-align: center; letter-spacing: 0.02em; }
.receipt__fine { margin-top: 0.5rem; font-size: 0.64rem; color: #a3a7b0; text-align: center; }
.receipt__stamp {
  position: absolute; right: 0.9rem; top: 41%; transform: rotate(-9deg);
  border: 2.5px solid #16a34a; color: #16a34a; border-radius: 8px;
  font-size: 0.62rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  padding: 0.45rem 0.7rem; max-width: 11rem; text-align: center; opacity: 0.85;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence baseFrequency='0.6'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.9'/></svg>"), linear-gradient(#000 0 0);
  -webkit-mask-composite: source-in;
}

/* ------------------------------------------------------------ local runner ($0)
   A dark band (matches the hero/CTA surfaces, and separates cleanly from the
   paper #how above and paper-2 #pricing below) carrying a real terminal with
   per-line click-to-copy. */
.local__grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 2.4rem; align-items: center; margin-top: 2.6rem; }
@media (max-width: 900px) { .local__grid { grid-template-columns: 1fr; gap: 1.8rem; } }
.local__col { display: flex; flex-direction: column; gap: 1.1rem; }

/* terminal — title bar + mono body; each row is a copy button */
.local__term { border-radius: 12px; overflow: hidden; background: #0b0e15; border: 1px solid rgb(255 255 255 / 0.09); box-shadow: 0 24px 60px -30px rgb(0 0 0 / 0.75); }
.local__bar { display: flex; align-items: center; gap: 0.7rem; padding: 0.7rem 0.95rem; background: rgb(255 255 255 / 0.03); border-bottom: 1px solid rgb(255 255 255 / 0.07); }
.local__dots { display: flex; gap: 0.45rem; }
.local__dots i { width: 11px; height: 11px; border-radius: 50%; }
.local__dots i:nth-child(1) { background: #ff5f57; }
.local__dots i:nth-child(2) { background: #febc2e; }
.local__dots i:nth-child(3) { background: #28c840; }
.local__title { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.02em; color: rgb(255 255 255 / 0.4); }
.local__body { padding: 0.45rem 0; }
.local__body[hidden] { display: none; }

/* platform tabs — they live in the terminal title bar and replace the static
   "bash — ~/project" caption, so the chrome does double duty as the switcher.
   site.js preselects the visitor's OS; without JS macOS stays active and every
   command is still readable (the panels are plain markup, not fetched). */
.local__tabs { display: flex; gap: 0.15rem; margin-left: 0.35rem; }
.local__tab { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.02em; color: rgb(255 255 255 / 0.4); background: transparent; border: 0; border-radius: 6px; padding: 0.3rem 0.6rem; cursor: pointer; transition: color 0.14s ease, background 0.14s ease; }
.local__tab:hover { color: rgb(255 255 255 / 0.72); background: rgb(255 255 255 / 0.05); }
.local__tab:focus-visible { outline: 2px solid var(--accent-lite); outline-offset: -2px; }
.local__tab.is-active { color: #fff; background: rgb(255 255 255 / 0.09); }

/* Linux panel — no command to copy yet, so it reads as prose at the same
   optical weight as a command row rather than a disabled-looking button. */
.local__soon { font-family: var(--mono); font-size: 0.78rem; line-height: 1.65; color: rgb(255 255 255 / 0.45); margin: 0; padding: 0.6rem 1rem; }
.local__soon b { color: rgb(255 255 255 / 0.82); font-weight: 600; }
.local__soon a { color: var(--accent-lite); }

.local__cmd { display: flex; align-items: center; gap: 0.55rem; width: 100%; text-align: left; background: transparent; border: 0; cursor: pointer; font-family: var(--mono); font-size: 0.86rem; line-height: 1.5; color: #e6e8ef; padding: 0.5rem 1rem; transition: background 0.14s ease; }
.local__cmd:hover { background: rgb(255 255 255 / 0.045); }
.local__cmd:focus-visible { outline: 2px solid var(--accent-lite); outline-offset: -2px; }
.local__prompt { color: #4ade80; user-select: none; flex-shrink: 0; }
.local__text { white-space: nowrap; }
.local__text b { color: #fff; font-weight: 600; }
.local__hint { color: rgb(255 255 255 / 0.3); white-space: nowrap; }
@media (max-width: 520px) { .local__hint { display: none; } }
.local__cursor { color: var(--accent-lite); margin-left: -0.15rem; animation: local-blink 1.1s steps(1) infinite; }
@keyframes local-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .local__cursor { animation: none; } }

/* copy affordance — brightens on row hover, swaps to a green check when copied */
.local__copy { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; color: rgb(255 255 255 / 0.3); transition: color 0.14s ease; }
.local__cmd:hover .local__copy { color: rgb(255 255 255 / 0.62); }
.local__copy svg { width: 15px; height: 15px; }
.local__copy .i-check { display: none; color: #4ade80; }
.local__cmd.is-copied .local__copy { color: #4ade80; }
.local__cmd.is-copied .local__copy .i-copy { display: none; }
.local__cmd.is-copied .local__copy .i-check { display: inline-flex; }

.local__note { color: var(--on-band-soft); font-size: 0.86rem; line-height: 1.55; margin: 0; padding-left: 0.15rem; }

/* feature list — tuned for the dark band */
.local__feats { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1.05rem; }
.local__feats li { display: flex; gap: 0.75rem; font-size: 0.95rem; line-height: 1.55; color: var(--on-band-soft); }
.local__feats .ck { color: #4ade80; font-weight: 700; flex-shrink: 0; }
.local__feats b { color: var(--on-band); font-weight: 600; }

/* section head + footnote read light on the band */
#local .sec-head p { color: var(--on-band-soft); }
#local .plans__note { color: var(--on-band-soft); }
#local .plans__note a { color: var(--accent-lite); }

/* ------------------------------------------------------------ agent chat (#chat)
   The demo card is a faithful mini-replica of the in-app Agent Chat: indigo→violet
   user bubble, indigo "Thought process" box, "Used <tool>" rows with mono pills,
   suggestion chips, the real composer toolbar, and the Live-browser PiP. Palette
   mirrors the app's Tailwind indigo scale on purpose — don't re-token it. */
.chatsec { display: grid; grid-template-columns: 0.94fr 1.06fr; gap: 3rem; align-items: center; }
/* let the columns shrink below their content's min-width (the composer's nowrap
   placeholder otherwise blows the 1fr track past the viewport on phones) */
.chatsec > * { min-width: 0; }
@media (max-width: 900px) { .chatsec { grid-template-columns: 1fr; gap: 2.2rem; } }
.chatsec__term { margin-top: 1.7rem; }
.chatsec__note { color: var(--muted); font-size: 0.86rem; line-height: 1.55; margin: 0.8rem 0 0; padding-left: 0.15rem; }
.chatsec__note b { color: var(--ink); font-weight: 600; }
/* the longest command row on the page — drop the hint earlier than the #local rows */
@media (max-width: 620px) { .chatsec__term .local__hint { display: none; } }
#chat .sec-head p { max-width: 33rem; }

.chatui { position: relative; background: var(--card); border: 1px solid var(--line); border-radius: 18px; box-shadow: var(--shadow); padding: 1.1rem 1.1rem 0.9rem; display: flex; flex-direction: column; gap: 0.7rem; }
.chatui svg { width: 1em; height: 1em; }
/* user bubble — the app's indigo→violet gradient, small bottom-right corner */
.chatui__user { align-self: flex-end; max-width: 85%; background: linear-gradient(135deg, #6366f1, #7c3aed); color: #fff; font-size: 0.86rem; font-weight: 500; line-height: 1.5; padding: 0.6rem 1rem; border-radius: 16px 16px 6px 16px; box-shadow: 0 1px 2px rgb(0 0 0 / 0.08); }
/* collapsed "Thought process" box */
.chatui__think { display: flex; align-items: center; gap: 0.6rem; border: 1px solid rgb(199 210 254 / 0.7); background: rgb(238 242 255 / 0.6); border-radius: 12px; padding: 0.55rem 0.85rem; font-size: 0.84rem; font-weight: 500; color: #312e81; }
.chatui__think > svg { color: #6366f1; font-size: 1rem; flex: none; }
.chatui__think span { flex: 1; }
.chatui__chev { color: #818cf8; opacity: 0.7; flex: none; font-size: 0.85rem; }
/* "Used <tool>" rows */
.chatui__tools { display: flex; flex-direction: column; gap: 0.5rem; padding-left: 0.15rem; }
.chatui__tool { display: flex; align-items: center; gap: 0.5rem; font-size: 0.84rem; font-weight: 500; color: var(--muted); }
.chatui__ticon { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 6px; background: #eef2ff; color: #4f46e5; flex: none; font-size: 0.72rem; }
.chatui__tool code { font-family: var(--mono); font-size: 0.78rem; font-weight: 600; color: #4338ca; background: #eef2ff; border-radius: 6px; padding: 0.1rem 0.42rem; }
.chatui__reply { margin: 0.1rem 0 0; font-size: 0.86rem; line-height: 1.55; color: var(--ink-soft); max-width: 62%; }
.chatui__reply b { color: var(--ink); font-weight: 600; }
/* model-proposed next-step chips */
.chatui__chips { display: flex; flex-wrap: wrap; gap: 0.5rem; max-width: 62%; }
.chatui__chips span { border: 1px solid #c7d2fe; background: #eef2ff; color: #4338ca; font-size: 0.78rem; font-weight: 500; border-radius: 999px; padding: 0.32rem 0.8rem; }
/* composer — rounded card w/ toolbar: paperclip, ⌘, model, effort, live pill, send */
.chatui__composer { border: 1px solid var(--line); background: var(--card); border-radius: 14px; padding: 0.55rem; box-shadow: 0 1px 2px rgb(0 0 0 / 0.04); margin-top: 0.2rem; }
.chatui__input { font-size: 0.84rem; color: var(--muted); padding: 0.25rem 0.4rem 0.55rem; overflow: hidden; white-space: nowrap; }
.chatui__input .caret { margin-left: 1px; }
.chatui__bar { display: flex; align-items: center; gap: 0.4rem; }
.chatui__ibtn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 1px solid var(--line); border-radius: 8px; color: var(--muted); font-size: 0.82rem; flex: none; }
/* model + effort pickers — plain text buttons with an icon and a chevron */
.chatui__chip { display: inline-flex; align-items: center; gap: 0.32rem; height: 28px; padding: 0 0.35rem; border-radius: 8px; color: var(--ink-soft); font-size: 0.76rem; font-weight: 600; white-space: nowrap; flex: none; }
.chatui__chip > svg:first-child { font-size: 0.85rem; }
.chatui__chev { font-size: 0.7rem; opacity: 0.55; }
.chatui__spacer { flex: 1; }
.chatui__livebtn { display: inline-flex; align-items: center; gap: 0.35rem; height: 28px; padding: 0 0.6rem; border-radius: 8px; background: #eef2ff; color: #4f46e5; font-size: 0.72rem; font-weight: 600; flex: none; }
.chatui__send { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 10px; background: #6366f1; color: #fff; font-size: 0.82rem; flex: none; box-shadow: 0 1px 2px rgb(99 102 241 / 0.4); }
@media (max-width: 520px) { .chatui__chip--effort { display: none; } .chatui__chip { font-size: 0.72rem; } }
/* the in-app Live-browser popout, floating over the transcript above the composer */
.chatui__live { position: absolute; right: 14px; bottom: 108px; width: 176px; border-radius: 10px; overflow: hidden; background: #0b0e15; border: 1px solid rgb(255 255 255 / 0.12); box-shadow: 0 16px 40px -14px rgb(0 0 0 / 0.5); }
.chatui__livebar { display: flex; align-items: center; gap: 0.42rem; font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.04em; color: rgb(255 255 255 / 0.68); padding: 0.38rem 0.55rem; background: rgb(255 255 255 / 0.04); border-bottom: 1px solid rgb(255 255 255 / 0.08); white-space: nowrap; }
.chatui__livebar i { width: 6px; height: 6px; border-radius: 50%; background: #4ade80; animation: pulse 2s ease-out infinite; flex: none; }
.chatui__livebody { height: 84px; position: relative; background: #10141d; }
/* a tiny fake webpage being driven: paper, header bar, two text lines, accent button */
.chatui__livebody::before { content: ""; position: absolute; inset: 8px; border-radius: 5px; background: #f4f4f2; }
.chatui__livebody::after {
  content: ""; position: absolute; inset: 8px; border-radius: 5px;
  background:
    linear-gradient(#d8d8d3 0 0) 9px 7px / 46px 6px,
    linear-gradient(#e4e4df 0 0) 9px 21px / 110px 5px,
    linear-gradient(#e4e4df 0 0) 9px 32px / 88px 5px,
    linear-gradient(#6366f1 0 0) 9px 46px / 50px 14px;
  background-repeat: no-repeat;
}
@media (max-width: 640px) { .chatui__live { position: static; width: 100%; margin-top: 0.1rem; order: 10; } .chatui__reply, .chatui__chips { max-width: 100%; } }
/* dark theme — mirror the app's dark indigo tints */
html.dark .chatui__think { border-color: rgb(99 102 241 / 0.2); background: rgb(99 102 241 / 0.07); color: #c7d2fe; }
html.dark .chatui__think > svg { color: #818cf8; }
html.dark .chatui__ticon, html.dark .chatui__tool code, html.dark .chatui__livebtn { background: rgb(99 102 241 / 0.15); }
html.dark .chatui__ticon { color: #a5b4fc; }
html.dark .chatui__tool code { color: #a5b4fc; }
html.dark .chatui__chips span { border-color: rgb(99 102 241 / 0.3); background: rgb(99 102 241 / 0.1); color: #a5b4fc; }
html.dark .chatui__livebtn { color: #a5b4fc; }
html.dark .chatui__send { background: #818cf8; color: #0b0c10; }

/* ------------------------------------------------------------ pricing */
.bill-toggle-wrap { display: flex; justify-content: center; margin: 2.4rem 0 2rem; }
.bill-toggle { position: relative; display: inline-flex; border: 1px solid var(--line-2); border-radius: 10px; padding: 4px; background: var(--card); }
.bill-toggle__btn { position: relative; z-index: 1; border: 0; background: transparent; cursor: pointer; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); padding: 0.55rem 1.1rem; border-radius: 6px; display: inline-flex; align-items: center; gap: 0.5rem; }
.bill-toggle__btn.is-active { color: var(--ink); }
/* The thumb is measured + moved by site.js (initBillToggle) via inline
   width/height/transform — CSS only paints it. No static geometry here or
   the two collide and the pill lands offset. */
.bill-toggle__thumb { position: absolute; z-index: 0; top: 0; left: 0; border-radius: 6px; background: var(--paper-2); border: 1px solid var(--line);
  transition: transform 0.25s cubic-bezier(0.2, 0.7, 0.2, 1), width 0.25s cubic-bezier(0.2, 0.7, 0.2, 1); }
.bill-toggle__save { font-size: 0.58rem; background: var(--ok-100); color: var(--ok); border-radius: 5px; padding: 0.12rem 0.4rem; }

/* Gap below the section head. This USED to come from the monthly/yearly billing
   toggle that sat between them; the free-tier rewrite removed the toggle and took
   the spacing with it, leaving margin-bottom:0 / margin-top:0 — so the cards
   butted straight against the subhead and `.plan > .tag` (which hangs 0.75rem
   ABOVE the card edge) printed the "COMING SOON" badge on top of the paragraph. */
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; align-items: stretch; margin-top: 3.25rem; }
@media (max-width: 900px) { .plans { grid-template-columns: 1fr; } }
/* Free + the "coming soon" Pro teaser. Capped narrower than the 3-up default so
   two cards read as a pair instead of stretching into slabs. */
.plans--2 { grid-template-columns: repeat(2, 1fr); max-width: 46rem; margin-inline: auto; }
@media (max-width: 900px) { .plans--2 { grid-template-columns: 1fr; max-width: 26rem; } }
.plan { display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 1.7rem; box-shadow: var(--shadow); position: relative; }
.plan.featured { border-color: color-mix(in srgb, var(--accent) 55%, transparent); box-shadow: 0 24px 70px -30px color-mix(in srgb, var(--accent) 45%, transparent); }
.plan > .tag { position: absolute; top: -0.75rem; left: 1.6rem; background: var(--accent); color: #fff; letter-spacing: 0.12em; }
.plan__head h3 { font-size: 1.15rem; font-weight: 640; }
.plan__desc { margin: 0.35rem 0 0; color: var(--muted); font-size: 0.85rem; }
.plan__price { margin: 1.3rem 0; }
.price { margin: 0; display: flex; align-items: baseline; gap: 0.5rem; }
.price__was { display: none; color: var(--muted); text-decoration: line-through; font-size: 1rem; }
.plans.is-yearly .price__was { display: inline; }
.price__amt { font-size: 2.4rem; font-weight: 640; letter-spacing: -0.03em; }
.price .per { color: var(--muted); font-size: 0.9rem; }
.price.custom { font-size: 2rem; font-weight: 640; }
.price__badge { display: none; font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase; background: var(--ok-100); color: var(--ok); border-radius: 6px; padding: 0.2rem 0.5rem; margin-top: 0.4rem; }
.plans.is-yearly .price__badge { display: inline-block; }
.price__sub { display: none; margin: 0.4rem 0 0; color: var(--muted); font-size: 0.78rem; }
.plans.is-yearly .price__sub { display: block; }
.price__note { margin: 0.4rem 0 0; color: var(--muted); font-size: 0.82rem; }
.plan__feats { list-style: none; margin: 0 0 1.6rem; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; flex: 1; }
.plan__feats li { display: flex; gap: 0.6rem; font-size: 0.9rem; color: var(--ink-soft); }
.plan__feats .ck { color: var(--ok); font-weight: 700; }
.plans__note { text-align: center; color: var(--muted); font-size: 0.88rem; margin-top: 2rem; }
.plans__note a { color: var(--accent); font-weight: 600; }

/* ------------------------------------------------------------ faq */
.faq { display: grid; grid-template-columns: 4fr 7fr; gap: 3rem; align-items: start; }
@media (max-width: 900px) { .faq { grid-template-columns: 1fr; } }
.faq__list { border-top: 1px solid var(--line-2); }
.faq__list details { border-bottom: 1px solid var(--line-2); position: relative; }
.faq__list summary { cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 1.15rem 0; font-weight: 600; font-size: 1rem; color: var(--ink); transition: color 0.25s ease; }
.faq__list summary::-webkit-details-marker { display: none; }
.faq__list summary:hover { color: var(--accent); }
.faq__list summary::after { content: "+"; font-family: var(--mono); color: var(--muted); font-size: 1.1rem; transition: transform 0.2s ease; flex-shrink: 0; }
.faq__list details[open] summary::after { transform: rotate(45deg); color: var(--accent); }
.faq__list p { margin: 0 0 1.2rem; color: var(--ink-soft); font-size: 0.95rem; max-width: 56ch; }
.faq__list p a { color: var(--accent); }

/* No height animation on the panel — the interpolate-size + content-visibility
   trick painted the item at its stale (often zero) content-visibility height
   first, then reflowed to the real height a beat later, reading as an empty
   row popping in after open. Native instant toggle avoids that flicker
   entirely; the icon/color transitions above still make the open feel soft. */
@media (prefers-reduced-motion: reduce) {
  .faq__list summary, .faq__list summary::after { transition: none; }
}

/* ------------------------------------------------------------ founder */
.cred { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); padding: 2.2rem; }
.cred__in { display: grid; grid-template-columns: 110px 1fr; gap: 1.8rem; align-items: center; }
@media (max-width: 640px) { .cred__in { grid-template-columns: 1fr; } }
.cred__photo img { width: 110px; height: 110px; border-radius: 50%; object-fit: cover; border: 3px solid var(--paper-2); }
.cred blockquote { margin: 0; font-size: 1.15rem; line-height: 1.5; letter-spacing: -0.01em; }
.cred blockquote b { color: var(--accent); }
.cred .who { margin-top: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.9rem; font-size: 0.85rem; color: var(--muted); }
.cred .who b { color: var(--ink); }
.cred .who a { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--accent); font-weight: 600; }
.cred .who a svg { width: 14px; height: 14px; fill: currentColor; }

/* ------------------------------------------------------------ final CTA band */
.cta-final { text-align: center; padding: 6rem 0; }
.cta-final__logo { display: grid; place-items: center; margin-bottom: 1.2rem; }
.cta-final__logo img { width: 190px; filter: drop-shadow(0 26px 50px rgb(124 58 237 / 0.5)); animation: bob 8s ease-in-out infinite; }
.cta-final h2 { font-size: clamp(2.4rem, 5.5vw, 4rem); color: #fff; letter-spacing: -0.04em; }
.cta-final h2 .hl { color: var(--accent-lite); }
.cta-final p { color: var(--on-band-soft); margin: 1.1rem auto 0; max-width: 32rem; }
.cta-final .cta { display: flex; gap: 0.7rem; justify-content: center; margin-top: 2rem; flex-wrap: wrap; }

/* ------------------------------------------------------------ footer */
footer { background: var(--band); color: var(--on-band); border-top: 1px solid var(--band-line); }
/* footer sits on the same dark band as the CTA — give the wordmark the same
   gradient treatment as the nav's dark-background variant. */
footer .brand span {
  background: linear-gradient(96deg, #ffffff 22%, #c7b0ff 96%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
}
.foot { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 2.5rem; padding: 4rem 0 3rem; position: relative; }
@media (max-width: 900px) { .foot { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .foot { grid-template-columns: 1fr; } }
.foot__brand p { color: var(--on-band-soft); font-size: 0.9rem; max-width: 26ch; }
.foot .copy { display: block; color: rgb(244 245 247 / 0.38); font-size: 0.72rem; margin-top: 0.3rem; font-family: var(--mono); }
.foot__col h4 { font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; color: rgb(244 245 247 / 0.45); margin: 0 0 1rem; font-weight: 500; }
.foot__col a { display: block; color: var(--on-band-soft); font-size: 0.9rem; padding: 0.28rem 0; }
.foot__col a:hover { color: var(--on-band); }
.foot__controls { margin-top: 1.4rem; display: flex; align-items: center; gap: 0.8rem; }
.theme-toggle { display: inline-flex; align-items: center; gap: 0.6rem; background: transparent; border: 1px solid var(--band-line); border-radius: var(--r-sm); padding: 0.4rem 0.75rem; cursor: pointer; color: var(--on-band-soft); font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; }
.theme-toggle__track { position: relative; width: 34px; height: 18px; border-radius: 999px; background: var(--band-2); border: 1px solid var(--band-line); }
.theme-toggle__knob { position: absolute; top: 1px; left: 1px; width: 14px; height: 14px; border-radius: 50%; background: var(--accent-lite); display: grid; place-items: center; transition: transform 0.2s ease; }
html.light .theme-toggle__knob { transform: translateX(16px); background: #f4c94f; }
.theme-toggle__knob svg { width: 9px; height: 9px; color: #0b0c10; }
html.dark .theme-toggle__knob .i-sun { display: none; }
html.light .theme-toggle__knob .i-moon { display: none; }
.foot__top { position: absolute; right: 0; top: 4rem; display: grid; place-items: center; width: 40px; height: 40px; border: 1px solid var(--band-line); border-radius: var(--r-sm); color: var(--on-band-soft); }
.foot__top:hover { color: var(--on-band); border-color: rgb(244 245 247 / 0.4); }
.foot__top svg { width: 16px; height: 16px; }
.foot__social { position: absolute; right: 52px; top: 4rem; display: grid; place-items: center; width: 40px; height: 40px; border: 1px solid var(--band-line); border-radius: var(--r-sm); color: var(--on-band-soft); }
.foot__social:hover { color: var(--on-band); border-color: rgb(244 245 247 / 0.4); }
.foot__social svg { width: 18px; height: 18px; }
.lang { display: none; } /* language picker parked for the redesign (English-only) */

/* ------------------------------------------------------------ demo modal */
.modal { position: fixed; inset: 0; z-index: 100; display: none; }
.modal.is-open, .modal:target { display: block; }
.modal__backdrop { position: absolute; inset: 0; background: rgb(10 11 14 / 0.6); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.modal__panel {
  position: relative; z-index: 1; width: min(560px, calc(100% - 32px));
  margin: 6vh auto 0; max-height: 88dvh; overflow: auto;
  /* keep momentum scroll inside the panel — never chain to the page behind it */
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow-lg); padding: 2rem;
}
/* The JS toggles body.modal-open on open; without this rule the page behind the
   modal still scrolled (made the sheet feel like it "wouldn't slide"). */
body.modal-open { overflow: hidden; }
.modal__close { position: absolute; top: 1rem; right: 1rem; width: 36px; height: 36px; display: grid; place-items: center; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--card); cursor: pointer; color: var(--muted); transition: transform 0.2s ease, border-color 0.2s ease, color 0.2s ease; }
.modal__close svg { width: 15px; height: 15px; transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1.3); }
.modal__close:hover { transform: scale(1.08); border-color: var(--muted); color: var(--ink); }
.modal__close:hover svg { transform: rotate(90deg); }
.modal__close:active { transform: scale(0.92); }
@media (prefers-reduced-motion: reduce) { .modal__close, .modal__close svg { transition: none; } .modal__close:hover, .modal__close:active, .modal__close:hover svg { transform: none; } }
.modal__head h2 { font-size: 1.6rem; margin: 0.8rem 0 0.4rem; }
.modal__head p { margin: 0 0 1.1rem; color: var(--ink-soft); font-size: 0.92rem; }
.wl { display: flex; flex-direction: column; gap: 0.85rem; }
.wl__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 560px) { .wl__row { grid-template-columns: 1fr; } }
.wl__field { display: flex; flex-direction: column; gap: 0.35rem; }
.wl__label { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.wl__opt { color: var(--muted); text-transform: none; letter-spacing: 0; }
.wl__input {
  font-family: inherit; font-size: 0.92rem; color: var(--ink);
  background: var(--paper-2); border: 1px solid var(--line); border-radius: 10px;
  padding: 0.7rem 0.85rem; outline: none; width: 100%;
}
.wl__input:focus { border-color: var(--accent); background: var(--card); }
/* the "what to test" textarea drags vertically only — a horizontal drag shrank
   it into a narrow scrolling column that looked broken. */
textarea.wl__input { resize: vertical; min-height: 3.25rem; }
.wl__err { color: var(--err); font-size: 0.74rem; min-height: 1em; }
.wl__submit { margin-top: 0.4rem; }
.wl__note { margin: 0; font-size: 0.85rem; color: var(--ok); }

/* ---- book-a-demo modal on phones ----
   Turn the centered card into a full-height scrollable sheet so the on-screen
   keyboard can never trap a field beneath it — the whole form is reachable by
   scrolling. Inputs go to 16px: below that, iOS Safari auto-zooms the page on
   focus, which was the layout "breaking" as the keyboard opened. */
@media (max-width: 560px) {
  .modal { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
  .modal__panel {
    width: 100%; margin: 0; min-height: 100dvh; max-height: none;
    border: 0; border-radius: 0;
    padding: 4.25rem 1.25rem calc(1.75rem + env(safe-area-inset-bottom));
  }
  /* close stays put while the sheet scrolls */
  .modal__close { position: fixed; top: 0.85rem; right: 0.85rem; z-index: 2; }
  .wl__input { font-size: 16px; }
}
.wl__note.err { color: var(--err); }

/* custom select (site.js initSelect enhances select.wl__input) */
.csel { position: relative; }
.csel__native { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; margin: 0; }
.csel__btn { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; text-align: left; cursor: pointer; }
.csel__label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.csel__label.is-placeholder { color: var(--muted); }
.csel__arrow { flex: none; display: grid; place-items: center; color: var(--muted); transition: transform 0.22s cubic-bezier(0.2, 0.7, 0.2, 1); }
.csel__arrow svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.3; stroke-linecap: round; stroke-linejoin: round; }
.csel.is-open .csel__arrow { transform: rotate(180deg); color: var(--accent); }
.csel__btn.is-invalid { border-color: var(--err); box-shadow: 0 0 0 4px rgb(225 29 72 / 0.1); }
/* fixed (viewport-relative) so the open menu never contributes to the modal
   panel's scroll height — an absolute menu grew a second scrollbar on the panel
   and reflowed its content narrower (the "shift left"). JS place() sets left/
   width/top or bottom from the button's rect and clamps max-height to the room. */
.csel__list { position: fixed; z-index: 120; padding: 0.35rem;
  border-radius: 12px; border: 1px solid var(--line-2); background: var(--card); box-shadow: var(--shadow-lg);
  overflow-y: auto; transform-origin: top center; animation: cselIn 0.16s cubic-bezier(0.2, 0.7, 0.2, 1);
  /* keep it scrollable for a genuinely-taller-than-viewport window, but never
     show the scrollbar chrome — a phantom track on a 6-item list looks broken. */
  scrollbar-width: none; -ms-overflow-style: none; }
.csel__list::-webkit-scrollbar { width: 0; height: 0; display: none; }
.csel.is-up .csel__list { transform-origin: bottom center; animation-name: cselInUp; }
@keyframes cselIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes cselInUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.csel__opt { padding: 0.58rem 0.7rem; border-radius: 8px; font-size: 0.92rem; font-weight: 500; color: var(--ink); cursor: pointer; }
.csel__opt.is-placeholder { color: var(--muted); }
.csel__opt:hover, .csel__opt.kb { background: var(--accent-50); color: var(--accent); }
.csel__opt.on { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
html.dark .csel__opt:hover, html.dark .csel__opt.kb, html.dark .csel__opt.on { color: var(--accent-lite); }
@media (prefers-reduced-motion: reduce) { .csel__list { animation: none; } .csel__arrow { transition: none; } }

/* ------------------------------------------------------------ split-flap heading reveal
   site.js's initBoard wraps each h2 letter in a fixed-width cell: a hidden
   ghost reserves the width, an absolute overlay spins the glyphs. */
.flap-w { display: inline-block; white-space: nowrap; }
.flap-c { position: relative; display: inline-block; overflow-x: clip; overflow-y: visible; vertical-align: bottom; }
.flap-c__g { visibility: hidden; }                          /* final glyph — reserves exact width */
.flap-c__r { position: absolute; left: 0; right: 0; top: 0; text-align: center; white-space: nowrap; }
.flap-c.is-flipping .flap-c__r { color: var(--accent); }    /* spinning letters glow accent, settle to ink */
.band .flap-c.is-flipping .flap-c__r { color: var(--accent-lite); }
@media (prefers-reduced-motion: reduce) { .flap-c.is-flipping .flap-c__r { color: inherit; } }

/* split-flap button hover — the label rolls up to an identical copy */
.flip { display: inline-block; overflow: hidden; height: 1.2em; line-height: 1.2; vertical-align: middle; }
.flip__in { display: flex; flex-direction: column; transition: transform 0.42s cubic-bezier(0.2, 0.7, 0.2, 1); }
.flip__in > span { display: block; height: 1.2em; line-height: 1.2; white-space: nowrap; }
.btn:hover .flip__in { transform: translateY(-50%); }
@media (prefers-reduced-motion: reduce) { .flip__in { transition: none; } .btn:hover .flip__in { transform: none; } }

/* typewriter founder quote */
.cred blockquote.tw .tw-c { visibility: hidden; }
.cred blockquote.tw .tw-c.on { visibility: visible; }
.cred blockquote.tw .tw-c.caret { border-right: 2px solid currentColor; margin-right: -2px; }
.cred blockquote.tw.is-typing .tw-c.caret { animation: twBlink 1.05s step-end infinite; }
@keyframes twBlink { 0%, 100% { border-color: currentColor; } 50% { border-color: transparent; } }
@media (prefers-reduced-motion: reduce) {
  .cred blockquote.tw .tw-c { visibility: visible; }
  .cred blockquote.tw .tw-c.caret { border-right: 0; margin-right: 0; }
}

/* dark theme: logo tiles go light so dark marks (GitHub, TS, …) stay visible */
html.dark .sidecard__logos button, html.dark .sidecard__logos span,
html.dark .route__logos span, html.dark .conn__ic,
html.dark .val-term__ic, html.dark .slackmsg__av { background: #e9e8e3; border-color: transparent; }
html.dark .sidecard__logos button.is-on { background: #ffffff; }
html.dark .val-term__ic--win { background: #e9e8e3; }

/* ------------------------------------------------------------ reveal on scroll */
html.js-reveal [data-reveal],
html.js-reveal [data-reveal-children] > * { opacity: 0; transform: translateY(18px); }
html.js-reveal.reveal-ready [data-reveal],
html.js-reveal.reveal-ready [data-reveal-children] > * { transition: opacity 0.6s ease, transform 0.6s ease; }
html.js-reveal [data-reveal].is-in,
html.js-reveal [data-reveal-children] > .is-in { opacity: 1; transform: none; }

/* ------------------------------------------------------------ light theme: less black.
   The hero + capabilities keep the dark signature; the final CTA band and the
   footer go light so a light-mode page doesn't end in a wall of night. */
/* NOTE: the old light-mode CTA overrides (light paper band + dark button + a
   dark :hover) used to live here. They're fully superseded by the full-bleed
   purple CTA block further down. The leftover :hover was the bug — it flipped the
   WHITE button to dark charcoal on hover. Hover states now live with that block. */

/* The footer stays the dark --band in light mode too (matching the hero), so the
   page ends on the same dark the overscroll reveals — no beige seam. It keeps its
   default dark-band text/toggle styling (light-on-dark). */

/* footer: subtle notebook squares, fading out all around (eraser-edge mask) */
footer { position: relative; }
footer::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgb(255 255 255 / 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgb(255 255 255 / 0.045) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(75% 85% at 50% 50%, #000 25%, transparent 98%);
          mask-image: radial-gradient(75% 85% at 50% 50%, #000 25%, transparent 98%);
}
.foot { position: relative; z-index: 1; }

/* ============================================================ mobile hardening
   Phones were scrolling sideways: the decorative "product screenshot" mocks
   (the runs data-table, the canvas SVG, the browser-chrome URL rows) each carry
   a large min-content that locked their card to a fixed ~485px — so the whole
   page became ~505px wide on a 360-390px screen. That horizontal overflow also
   dragged the sticky app bar off to the left as you scrolled (why it "didn't
   stay on top"). Fix = let those cards shrink (min-width:0 defeats the default
   min-width:auto of grid/flex items), fit the table + SVG inside the card, and
   scale the big display headings down so a nowrap split-flap <h2> can't poke out.
   overflow-x:clip is the safety net — unlike overflow:hidden it does NOT spawn a
   scroll container, so position:sticky on the nav keeps working. */
html, body { overflow-x: clip; }
@media (max-width: 980px) {
  .bento, .bento--flip, .card, .mock, .sidecard, .loopwrap, .econ, .how, .why, .plans, .faq, .stack, .caps { min-width: 0; }
  .bento > *, .bento--flip > *, .stack > *, .caps > *, .loopwrap > *, .econ > * { min-width: 0; }
  .mock, .mock * { min-width: 0; }
  .graph svg { max-width: 100%; }
  /* the runs mock table: share the width by column instead of forcing min-content */
  .tbl { table-layout: fixed; font-size: 0.8rem; }
  .tbl th, .tbl td { padding-left: 0.55rem; padding-right: 0.55rem; }
  .tbl th:nth-child(1), .tbl td:nth-child(1) { width: 16%; }
  .tbl th:nth-child(2), .tbl td:nth-child(2) { width: 44%; }
  .tbl th:nth-child(3), .tbl td:nth-child(3) { width: 24%; }
  .tbl th:nth-child(4), .tbl td:nth-child(4) { width: 16%; }
  .tbl td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* the expandable evidence row spans all 4 cols — keep it free to wrap */
  .tbl__detail td { width: auto; white-space: normal; overflow: visible; text-overflow: clip; }
  /* carousel chevrons: 30px is under the comfortable touch minimum. flex:none
     stops the neighbouring progress dashes from squeezing the buttons narrower
     than 44px; the (decorative) dashes absorb and clip the shrink instead. */
  .ascii__arrow { width: 44px; height: 44px; flex: none; }
  .ascii__dashes { min-width: 0; overflow: hidden; }
}
@media (max-width: 560px) {
  .hero h1 { font-size: clamp(2.05rem, 8.5vw, 3rem); }
  .sec-head h2 { font-size: clamp(1.7rem, 7vw, 2.6rem); }
  /* keep the whole constellation inside the viewport with symmetric margins —
     at 92vw the right-hand orb was bleeding into (and getting clipped at) the edge */
  .orbit { width: min(288px, 80vw); }
}

/* ------------------------------------------------------------ how-it-works STEP grid */
.stepgrid { display: grid; grid-template-columns: 1fr 1fr; margin-top: 2.4rem; border: 1px solid var(--line-2); border-radius: var(--r); overflow: hidden; background: var(--card); }
.stepcell { padding: 1.5rem 1.5rem 1.6rem; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.stepcell:nth-child(2n) { border-right: 0; }
.stepcell:nth-child(n+3) { border-bottom: 0; }
.stepcell__k { display: block; font-family: var(--mono); font-size: 0.66rem; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); margin-bottom: 0.6rem; }
.stepcell h3 { font-size: 1.1rem; font-weight: 620; margin: 0 0 0.45rem; }
.stepcell p { margin: 0; font-size: 0.88rem; color: var(--ink-soft); }
.stepcode { display: inline-block; margin-top: 0.8rem; font-family: var(--mono); font-size: 0.72rem; color: var(--accent); background: var(--accent-50); border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent); border-radius: 7px; padding: 0.3rem 0.6rem; }
@media (max-width: 640px) { .stepgrid { grid-template-columns: 1fr; } .stepcell { border-right: 0 !important; border-bottom: 1px solid var(--line) !important; } .stepcell:last-child { border-bottom: 0 !important; } }

/* ------------------------------------------------------------ agents brick wall */
.agents { display: grid; grid-template-columns: 5fr 6fr; gap: 3.5rem; align-items: center; }
@media (max-width: 980px) { .agents { grid-template-columns: 1fr; } }
.brickwall {
  display: flex; flex-direction: column; gap: 0.7rem; overflow: hidden;
  -webkit-mask-image: radial-gradient(85% 90% at 50% 50%, #000 45%, transparent 100%);
          mask-image: radial-gradient(85% 90% at 50% 50%, #000 45%, transparent 100%);
}
.brickrow { display: flex; gap: 0.7rem; justify-content: center; }
.brickrow--shift { transform: translateX(-2rem); }
.brick {
  flex: 1 0 auto; min-width: 7rem; height: 4.2rem; border: 1px solid var(--line-2); border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6rem;
  font-weight: 600; font-size: 1rem; color: var(--ink); letter-spacing: -0.01em;
  background: transparent;
}
.brick--filled { background: var(--card); box-shadow: var(--shadow); flex-grow: 0; padding: 0 1.6rem; }
.brick--filled img { width: 22px; height: 22px; }
html.dark .brick--filled img[src*="openai"] { filter: invert(0.9); }
@media (max-width: 640px) { .brick { min-width: 5rem; height: 3.4rem; font-size: 0.85rem; } .brick--filled { padding: 0 1rem; } }

/* ------------------------------------------------------------ brick wall v2: logos + life */
.brick { background: color-mix(in srgb, var(--card) 45%, transparent); }
.brick--filled {
  background: var(--card); cursor: default;
  transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1.2), box-shadow 0.35s ease, border-color 0.35s ease;
}
.brick--filled:hover {
  transform: translateY(-4px);
  box-shadow: 0 14px 30px color-mix(in srgb, var(--ink) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line-2));
}
.brick--filled img { transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1.2); }
.brick--filled:hover img { transform: scale(1.18) rotate(-5deg); }
.brick__glyph { font-family: var(--mono); font-weight: 700; font-size: 0.92rem; color: var(--accent); letter-spacing: -0.05em; }
html.dark .brick--filled img.inv { filter: invert(0.92); }

/* ------------------------------------------------------------ nav pill: dimensional glass */
/* Depth that doesn't depend on what's behind the lens: lift shadows below,
   a rim catch on the top edge, glass thickness shading at the bottom, and a
   curved specular sheen painted above the frost but under the content. */
.nav__in {
  box-shadow:
    0 1px 1.5px rgb(10 12 16 / 0.10),
    0 4px 10px -6px rgb(10 12 16 / 0.16),
    0 14px 34px -14px rgb(10 12 16 / 0.38),
    inset 0 1.5px 0.5px rgb(255 255 255 / 0.45),
    inset 0 -2px 4px rgb(0 0 0 / 0.10),
    inset 2px 0 6px -4px rgb(255 255 255 / 0.20),
    inset -2px 0 6px -4px rgb(0 0 0 / 0.07);
}
.nav__in::after {
  content: ""; position: absolute; inset: 1px; border-radius: 13px;
  pointer-events: none; z-index: -1; /* above the frost, below the links */
  background:
    radial-gradient(130% 95% at 50% -35%, rgb(255 255 255 / 0.32), rgb(255 255 255 / 0.05) 55%, transparent 62%),
    radial-gradient(130% 120% at 50% 135%, rgb(255 255 255 / 0.12), transparent 55%),
    linear-gradient(90deg, rgb(16 18 22 / 0.05), transparent 7%, transparent 93%, rgb(16 18 22 / 0.05));
}
html.dark .nav__in {
  box-shadow:
    0 1px 1.5px rgb(0 0 0 / 0.45),
    0 4px 12px -6px rgb(0 0 0 / 0.40),
    0 16px 38px -14px rgb(0 0 0 / 0.60),
    inset 0 1.5px 0.5px rgb(255 255 255 / 0.22),
    inset 0 -2px 5px rgb(0 0 0 / 0.42),
    inset 2px 0 6px -4px rgb(255 255 255 / 0.10),
    inset -2px 0 6px -4px rgb(0 0 0 / 0.30);
}
html.dark .nav__in::after {
  background:
    radial-gradient(130% 95% at 50% -35%, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0.03) 55%, transparent 62%),
    radial-gradient(130% 120% at 50% 135%, rgb(255 255 255 / 0.07), transparent 55%),
    linear-gradient(90deg, rgb(0 0 0 / 0.16), transparent 8%, transparent 92%, rgb(0 0 0 / 0.16));
}

/* One identical glass theme control in both modes. The two glyphs occupy the
   same centre and cross-fade/rotate, so the moon becomes the sun rather than
   abruptly swapping icons. */
.theme-btn,
html.dark .theme-btn {
  position: relative; overflow: hidden;
  background: rgb(255 255 255 / .12);
  border-color: rgb(255 255 255 / .28);
  box-shadow: 0 10px 28px -14px rgb(16 12 28 / .4), inset 0 1px 0 rgb(255 255 255 / .42);
  color: #242733;
  transition: transform .25s ease, border-color .25s ease, background .25s ease;
}
.nav-over-dark .theme-btn { color: #fff; background: rgb(255 255 255 / .1); border-color: rgb(255 255 255 / .3); }
/* Dark mode: keep the icon light. The refinement block above set one dark
   #242733 for BOTH themes, so in dark mode the icon blended into the dark
   button/page and all but disappeared. */
html.dark .theme-btn { color: #e9ebf2; }
.theme-btn svg,
html.light .theme-btn .i-sun,
html.dark .theme-btn .i-moon { display: block; position: absolute; inset: 50% auto auto 50%; margin: 0; transition: opacity .32s ease, transform .48s cubic-bezier(.2,.75,.2,1.25); }
html.light .theme-btn .i-moon { opacity: 1; transform: translate(-50%,-50%) rotate(0) scale(1); }
html.light .theme-btn .i-sun { opacity: 0; transform: translate(-50%,-50%) rotate(-100deg) scale(.45); }
html.dark .theme-btn .i-moon { opacity: 0; transform: translate(-50%,-50%) rotate(100deg) scale(.45); }
html.dark .theme-btn .i-sun { opacity: 1; transform: translate(-50%,-50%) rotate(0) scale(1); }
.theme-btn:hover svg { transform-origin: center; }
html.light .theme-btn:hover .i-moon,
html.dark .theme-btn:hover .i-sun { transform: translate(-50%,-50%) rotate(-18deg) scale(1.06); }

/* ------------------------------------------------------------ refinement pass
   Preserve the original airy page and its visible product UI. The polish lives
   in optical depth: a clearer nav lens, raised translucent feature cards, and a
   purple closing environment that contains (rather than recolours) the page. */
.nav__in {
  background: color-mix(in srgb, var(--card) 20%, transparent);
  -webkit-backdrop-filter: blur(9px) saturate(1.45);
  backdrop-filter: blur(9px) saturate(1.45);
  /* NO drawn outline — a uniform 1px white border read as a flat sticker edge.
     The pill's silhouette comes from the ::before bevel ring below (lit top
     edge, shaded bottom = glass thickness) plus the lift shadows. */
  border-color: transparent;
  box-shadow:
    0 2px 2px rgb(15 10 30 / 0.08),
    0 12px 28px -12px rgb(24 14 55 / 0.28),
    0 30px 70px -34px rgb(85 49 170 / 0.35),
    inset 0 1.5px 0 rgb(255 255 255 / 0.5),
    inset 0 -1px 0 rgb(20 12 46 / 0.10),
    inset 0 -7px 16px -15px rgb(69 35 140 / 0.5);
}
/* bevel ring: light falls from above — the top arc catches it, the sides fall
   off to nothing, the bottom edge shades dark. Reads as thickness, not border. */
.nav__in::before {
  content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: 15px;
  pointer-events: none; padding: 1px;
  background:
    linear-gradient(180deg,
      rgb(255 255 255 / .62), rgb(255 255 255 / .14) 22%,
      rgb(255 255 255 / .02) 45%, transparent 60%,
      rgb(20 12 46 / .08) 82%, rgb(20 12 46 / .20)),
    linear-gradient(115deg, transparent 55%, rgb(145 105 255 / .22) 76%, transparent 94%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.nav__in::after {
  z-index: 0; opacity: .8;
  background:
    linear-gradient(105deg, transparent 13%, rgb(255 255 255 / .24) 28%, transparent 43%),
    radial-gradient(100% 80% at 50% -25%, rgb(255 255 255 / .4), transparent 60%);
  mix-blend-mode: soft-light;
}
.nav__in > * { position: relative; z-index: 1; }
html.dark .nav__in {
  background: rgb(18 13 31 / .22);
  border-color: transparent;
  box-shadow:
    0 2px 2px rgb(0 0 0 / 0.30),
    0 12px 28px -12px rgb(0 0 0 / 0.45),
    0 30px 70px -34px rgb(85 49 170 / 0.40),
    inset 0 1.5px 0 rgb(255 255 255 / 0.20),
    inset 0 -1px 0 rgb(0 0 0 / 0.35),
    inset 0 -7px 16px -15px rgb(0 0 0 / 0.55);
}
html.dark .nav__in::before {
  background:
    linear-gradient(180deg,
      rgb(255 255 255 / .34), rgb(255 255 255 / .08) 22%,
      rgb(255 255 255 / .015) 45%, transparent 60%,
      rgb(0 0 0 / .18) 82%, rgb(0 0 0 / .42)),
    linear-gradient(115deg, transparent 55%, rgb(145 105 255 / .16) 76%, transparent 94%);
}

#platform .card {
  --mx: 50%; --my: 30%;
  position: relative; isolation: isolate; overflow: hidden;
  background: color-mix(in srgb, var(--card) 78%, transparent);
  border-color: color-mix(in srgb, var(--accent) 10%, var(--line));
  box-shadow:
    0 2px 4px rgb(34 24 55 / .04),
    0 18px 45px -28px rgb(67 39 125 / .3),
    inset 0 1px 0 rgb(255 255 255 / .75),
    inset 0 -1px 0 rgb(92 55 170 / .06);
  transition: transform .35s cubic-bezier(.2,.7,.2,1), box-shadow .35s ease, border-color .35s ease;
  transform-style: preserve-3d;
}
#platform .card::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(380px circle at var(--mx) var(--my), rgb(255 255 255 / .8), rgb(174 135 255 / .13) 24%, transparent 55%);
  opacity: 0; transition: opacity .35s ease;
}
#platform .card::after {
  content: ""; position: absolute; inset: 1px; z-index: -1; pointer-events: none; border-radius: calc(var(--r) - 1px);
  background: linear-gradient(135deg, rgb(255 255 255 / .26), transparent 35%, rgb(126 80 236 / .045));
}
#platform .card:hover { border-color: color-mix(in srgb, var(--accent) 28%, var(--line)); box-shadow: 0 28px 65px -35px rgb(91 48 180 / .48), inset 0 1px 0 #fff; }
#platform .card:hover::before { opacity: .65; }
#platform .card .mock { transform: translateZ(16px); box-shadow: 0 18px 35px -26px rgb(50 29 94 / .35); }
html.dark #platform .card { background: rgb(26 22 37 / .72); box-shadow: 0 22px 55px -32px #000, inset 0 1px 0 rgb(255 255 255 / .12); }
html.dark #platform .card::before { background: radial-gradient(380px circle at var(--mx) var(--my), rgb(168 126 255 / .2), transparent 58%); }

.band--cta {
  /* Full-bleed band — spans the viewport edge to edge (no inset, no rounded
     corners). The content inside still uses .wrap, so text/buttons stay
     centred; only the purple background goes wall to wall. */
  width: 100%; margin: 0;
  border-radius: 0; overflow: hidden;
  isolation: isolate; /* aurora children use z:-1; keep them inside this band */
  background: linear-gradient(125deg, #4b20c1 0%, #7c3aed 48%, #b56ae9 100%);
}
/* The two oversized aurora gradients are real children (see index.html) that
   pan via compositor-only transforms. They REPLACE the old background-position
   keyframes, which re-painted the whole viewport-wide band every frame it was
   on screen — the biggest per-frame paint area on the page. z:-1 paints them
   above the base gradient and below ::before + .wrap: the exact paint order of
   the old background stack. Translate endpoints reproduce the old
   background-position offsets exactly: position p% ⇒ offset p·(band − layer),
   converted to the layer's own box (135%: 12,16 ⇒ −3.111,−4.148 · 130%:
   −10,12 ⇒ +2.308,−2.769). Same 14s ease-in-out alternate timing → identical
   pixels at every point of the cycle. */
.cta-aurora { position: absolute; left: 0; top: 0; z-index: -1; pointer-events: none; will-change: transform; }
.cta-aurora--a {
  width: 135%; height: 135%;
  background: radial-gradient(75% 120% at 83% 15%, rgb(206 139 255 / .78), transparent 56%);
  animation: ctaAuroraA 14s ease-in-out infinite alternate;
}
.cta-aurora--b {
  width: 130%; height: 130%;
  background: radial-gradient(80% 120% at 8% 82%, rgb(62 32 190 / .82), transparent 60%);
  animation: ctaAuroraB 14s ease-in-out infinite alternate;
}
.band--cta::before {
  display: block !important; opacity: 1;
  /* top hairline moved here from the band's box-shadow: ::before paints above
     the aurora children, keeping the line visible exactly as before (white
     over white — compositing order can't change the result) */
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .28);
  background:
    radial-gradient(55% 75% at 24% 48%, rgb(63 38 195 / .45), transparent 70%),
    linear-gradient(112deg, transparent 26%, rgb(255 255 255 / .1) 47%, transparent 66%);
}
html.light .band--cta { color: #fff; background: linear-gradient(125deg,#4b20c1,#7c3aed 48%,#b56ae9); }
html.light .band--cta h2 { color: #fff; }
html.light .band--cta h2 .hl { color: rgb(230 207 255 / .78); }
html.light .band--cta p { color: rgb(255 255 255 / .78); }
html.light .band--cta .btn-primary { background: #fff; color: #20172c; border-color: rgb(255 255 255 / .55); box-shadow: 0 18px 40px rgb(43 15 104 / .2), inset 0 1px 0 #fff; }
html.light .band--cta .btn-ghost { background: rgb(255 255 255 / .12); color: #fff; border-color: rgb(255 255 255 / .3); backdrop-filter: blur(12px); }
/* Dark mode: a deeper, moodier violet so the CTA reads as part of the dark
   theme instead of a glaring bright band. Same aurora, darker base. */
html.dark .band--cta { color: #fff; background: linear-gradient(125deg,#1c0e4a 0%,#3a1a8f 52%,#5e2fb5 100%); }
html.dark .cta-aurora--a { background: radial-gradient(75% 120% at 83% 15%, rgb(150 96 240 / .5), transparent 56%); }
html.dark .cta-aurora--b { background: radial-gradient(80% 120% at 8% 82%, rgb(40 20 130 / .9), transparent 60%); }
html.dark .band--cta h2 { color: #fff; }
html.dark .band--cta h2 .hl { color: rgb(200 175 255 / .85); }
html.dark .band--cta p { color: rgb(255 255 255 / .72); }
html.dark .band--cta .btn-primary { background: #fff; color: #1a1030; border-color: rgb(255 255 255 / .5); box-shadow: 0 18px 40px rgb(15 8 45 / .35), inset 0 1px 0 #fff; }
html.dark .band--cta .btn-ghost { background: rgb(255 255 255 / .1); color: #fff; border-color: rgb(255 255 255 / .28); backdrop-filter: blur(12px); }
/* Hover: the white pill STAYS white and just lifts (deeper glow) — never flips to
   charcoal. Ghost brightens its fill + border. Applies to both themes. */
html.light .band--cta .btn-primary:hover,
html.dark  .band--cta .btn-primary:hover {
  background: #fff; color: #1a1030;
  transform: translateY(-1px);
  box-shadow: 0 24px 52px rgb(15 8 45 / .42), inset 0 1px 0 #fff;
}
html.light .band--cta .btn-ghost:hover,
html.dark  .band--cta .btn-ghost:hover {
  background: rgb(255 255 255 / .22); border-color: rgb(255 255 255 / .6);
}
.cta-final__logo img { width: 230px; height: auto; aspect-ratio: 820 / 753; object-fit: contain; filter: drop-shadow(0 30px 48px rgb(49 17 126 / .48)); }
.cta-final { position: relative; isolation: isolate; }
/* Old warped 3D orbit + floating glass tiles removed — they read as random and
   the tilted ring stretched into an oval on the full-bleed band. */
.cta-final::before, .cta-final::after { content: none; }
.cta-final__logo { position: relative; z-index: 1; }
/* Behind the logo: a soft glow with faint concentric "coverage" rings. Fixed
   square dimensions → always a true circle, never warps however wide the band
   gets. Symmetric and on-brand (coverage radiating from the core). */
.cta-final__logo::before {
  content: ""; position: absolute; z-index: -1; left: 50%; top: 46%;
  width: 460px; height: 460px; transform: translate(-50%,-50%); border-radius: 50%;
  pointer-events: none;
  background:
    radial-gradient(circle, transparent 30%, rgb(255 255 255 / .07) 31%, transparent 33%),
    radial-gradient(circle, transparent 47%, rgb(255 255 255 / .05) 48%, transparent 50%),
    radial-gradient(circle, rgb(255 255 255 / .14) 0%, rgb(190 150 255 / .08) 38%, transparent 64%);
}
/* One "signal" ring pulsing outward from the core. */
.cta-final__logo::after {
  content: ""; position: absolute; z-index: -1; left: 50%; top: 46%;
  width: 240px; height: 240px; transform: translate(-50%,-50%); border-radius: 50%;
  border: 1px solid rgb(255 255 255 / .18); pointer-events: none;
  animation: ctaPulse 4.5s ease-out infinite;
}
@keyframes ctaPulse {
  0%   { transform: translate(-50%,-50%) scale(.62); opacity: .5; }
  70%  { opacity: 0; }
  100% { transform: translate(-50%,-50%) scale(1.9); opacity: 0; }
}
@keyframes ctaAuroraA { to { transform: translate3d(-3.111%, -4.148%, 0); } }
@keyframes ctaAuroraB { to { transform: translate3d(2.308%, -2.769%, 0); } }
@keyframes ctaOrbit { to { transform: translate(-50%,-50%) rotateX(68deg) rotateZ(352deg); } }
@keyframes ctaShard { 50% { transform: translateY(-12px) rotate(27deg) scale(1.05); } }
@media (prefers-reduced-motion: reduce) { .band--cta,.cta-aurora,.cta-final::before,.cta-final::after,.cta-final__logo::before,.cta-final__logo::after { animation: none; } }
@media (max-width: 720px) { .band--cta { width: 100%; margin-block: 0; } .cta-final { padding-inline: 1.2rem; } }

/* Final optical balance: keep the lens genuinely transparent. The refraction
   and rim provide its shape; the fill should not become an opaque grey bar. */
.nav__in { background: rgb(255 255 255 / .09); }
.nav__in::after { opacity: .36; }
html.dark .nav__in { background: rgb(255 255 255 / .065); }

/* ------------------------------------------------------------ PH launch button
   The Product Hunt CTA should read as the SAME button as "Start testing free"
   (full pill, matched height) — only Product-Hunt orange. Its icon disc is taller
   than a text cap, so it takes less vertical padding to land at the same ~btn-lg
   height. Appended last so it overrides the compact-badge sizing above. */
.hero .ph-badge.ph-btn {
  gap: .6rem; padding: .8rem 1.6rem; border-radius: 8px; font-size: .76rem;
}
.hero .ph-badge.ph-btn .topbar__msg { gap: .5rem; }
.hero .ph-badge.ph-btn .topbar__msg b { font-size: .95rem; }
.hero .ph-badge.ph-btn .topbar__cta { padding-left: .7rem; margin-left: .1rem; gap: .35rem; }
.hero .ph-badge.ph-btn .cd { gap: .34rem; }
.hero .ph-badge.ph-btn .cd__seg { font-size: .72rem; }
.hero .ph-badge.ph-btn .cd__seg b { font-size: .84rem; }
/* no attention-pulse — the primary button is static, so this one is too */
.ph-badge.ph-btn::after { content: none; }

/* reactor nodes are hover-interactive (switch the active plate) — show it */
.reactor__node { cursor: pointer; }

/* Closing scene layout. NOTE: this block used to carry a dark "dissolve into the
   footer" gradient with `html.light .band--cta` in its selector list — in LIGHT
   mode that outranked (later source, equal specificity) the vivid purple CTA
   above, so light mode ended in a muddy dark-purple wash bleeding into the
   footer while dark mode (whose `html.dark` rule wins on specificity) kept the
   clean purple→footer edge. Both themes now use their vivid purple blocks above;
   only layout lives here. */
.band--cta {
  width: 100%; margin: 2rem 0 0; border-radius: clamp(30px,4vw,58px) clamp(30px,4vw,58px) 0 0;
}
.band--cta::before {
  background:
    radial-gradient(circle at 18% 24%,rgb(255 255 255 / .12) 0 1px,transparent 1.5px),
    radial-gradient(circle at 78% 31%,rgb(185 150 255 / .16) 0 1px,transparent 1.5px),
    linear-gradient(112deg,transparent 22%,rgb(255 255 255 / .055) 45%,transparent 66%);
  background-size: 74px 74px,96px 96px,100% 100%; opacity: .78;
}
.band--cta::after {
  content: ""; position: absolute; z-index: 0; left: 0; right: 0; bottom: 0; height: 230px; pointer-events: none;
  background-image: linear-gradient(rgb(255 255 255 / .04) 1px,transparent 1px),linear-gradient(90deg,rgb(255 255 255 / .04) 1px,transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: linear-gradient(transparent,#000 92%); mask-image: linear-gradient(transparent,#000 92%);
}
footer { border-top: 0; }
@media (max-width:720px) { .band--cta,html.light .band--cta { width:100%; margin-top:1rem; } }

/* Seamless top edge: no card silhouette and no circular halo. The preceding
   page color washes into the dark-purple scene before the aurora takes over. */
.band--cta,
html.light .band--cta,
html.dark .band--cta { margin-top: 0; border-radius: 0; box-shadow: none; }
.band--cta::before {
  opacity: 1;
  background:
    radial-gradient(circle at 18% 24%,rgb(255 255 255 / .12) 0 1px,transparent 1.5px),
    radial-gradient(circle at 78% 31%,rgb(185 150 255 / .16) 0 1px,transparent 1.5px);
  background-size: 74px 74px,96px 96px;
}
.cta-final__logo::before,
.cta-final__logo::after { content: none; }
.band--cta .cta-final { padding-top: 4rem; }
@media (max-width:720px) { .band--cta,html.light .band--cta,html.dark .band--cta { margin-top:0; border-radius:0; } }

/* Full first-screen hero. The trust/marquee section begins only after the fold,
   while the copy stays optically centered and the orbit clears the glass nav. */
.band--hero { height: calc(100svh + 24px); min-height: 704px; box-sizing: border-box; }
/* the CAD crosshair in hero-bg.js substitutes for the native pointer, so hide the
   real one — but only where the JS actually draws it (mirrors its `fine && !reduce`
   gate exactly, else reduced-motion/coarse-pointer visitors lose their cursor
   entirely). Buttons/links are hidden too: over them the reticle morphs into a
   lock-on bracket (see hero-bg.js), which IS the affordance — a native pointer on
   top would just double up with it. */
@media (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .band--hero, .band--hero a, .band--hero button { cursor: none; }
}
.band--hero > .hero {
  height: calc(100svh - var(--nav-h) - 24px); min-height: calc(680px - var(--nav-h) - 24px);
  padding: clamp(3.5rem,8vh,6rem) 0 clamp(2.5rem,6vh,4.5rem);
  justify-content: center;
}
@media (min-width:981px) {
  .band--hero .orbit { top: 54%; }
}
@media (max-width:980px) {
  .band--hero { height:auto; min-height:calc(100svh + 24px); }
  .band--hero > .hero { height:auto; min-height:calc(100svh - var(--nav-h) - 24px); }
}
/* ---- mobile hero: stack it. Copy + CTAs read first at the top; the Assertify
   logo ringed by its five tool icons drops to a clean constellation BELOW — it used
   to be a faint 0.5-opacity wash sitting on top of the copy, which read as clutter.
   The band becomes a flex column and `order` puts the visual after the copy without
   touching the DOM (source order is visual-then-copy). ---- */
@media (max-width: 900px) {
  .band--hero { display: flex; flex-direction: column; height: auto; min-height: 0; }
  .band--hero > .hero {
    order: 1; height: auto; min-height: 0;
    padding: 2.25rem 0 0.5rem; justify-content: flex-start;
  }
  .hero__visual {
    order: 2; position: relative; inset: auto; z-index: 1;
    display: flex; justify-content: center; align-items: center;
    width: 100%; overflow: visible; padding: 0 0 clamp(2.5rem, 8vh, 4.5rem);
  }
  .orbit {
    position: relative; top: auto; left: auto; transform: none;
    width: min(80vw, 340px); opacity: 1; margin: 0 auto;
  }
  .orbit__links { display: none; }            /* the SVG lines use desktop coords — hide vs misalign */
  /* five icons on an even ring, 72° apart, around the centered core */
  .orbit .orb--core    { left: 50%; top: 50%; }
  .orbit .orb--chatgpt { left: 50%; top: 13%; }
  .orbit .orb--claude  { left: 85%; top: 38%; }
  .orbit .orb--jira    { left: 72%; top: 80%; }
  .orbit .orb--github  { left: 28%; top: 80%; }
  .orbit .orb--slack   { left: 15%; top: 38%; }
  .hero__visual .orb img       { width: 54px; }   /* uniform ring; core stays larger */
  .hero__visual .orb--core img { width: 96px; }
}

/* ================================================== download (desktop app) —
   OS badges in the store-button idiom: platform logo left, two-line label.
   site.js (initDownloadOS) detects the visitor's OS and reorders so their
   platform leads. macOS and Windows both ship, so both carry the same filled
   CTA treatment and stream real byte-progress on click (initDownloadFeedback). */
.dl { margin-top: 2.75rem; text-align: center; }
.dl__row { display: flex; justify-content: center; align-items: stretch; gap: 0.95rem; flex-wrap: wrap; }
.dl__btn {
  display: inline-flex; align-items: center; gap: 0.9rem; text-align: left;
  border-radius: 14px; padding: 0.9rem 1.65rem; border: 1px solid transparent;
  transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.dl__btn--mac, .dl__btn--win { background: var(--ink); color: var(--paper); box-shadow: 0 22px 44px -22px rgb(14 16 19 / 0.55); }
.dl__btn--mac:hover, .dl__btn--win:hover { background: var(--ink-soft); transform: translateY(-2px); }
html.dark .dl__btn--mac, html.dark .dl__btn--win { background: #f2f3f5; color: #0b0c10; box-shadow: 0 22px 44px -26px rgb(0 0 0 / 0.9); }
html.dark .dl__btn--mac:hover, html.dark .dl__btn--win:hover { background: #d8dade; }
.dl__logo { width: 26px; height: 26px; flex: none; }
.dl__txt small { display: block; font-size: 0.66rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.62; }
.dl__txt b { display: block; font-size: 1.06rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25; }
.dl__meta { margin-top: 1.2rem; color: var(--muted); font-size: 0.86rem; }
.dl__meta a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.dl__note { margin-top: 0.35rem; color: var(--muted); font-size: 0.8rem; }
.dl__note a { color: var(--accent); }
/* Click-to-copy command chip (light-section variant of .local__cmd). */
.copy-chip { display: inline-flex; align-items: center; gap: 0.6rem; margin: 0.5rem 0 0.6rem; padding: 0.45rem 0.75rem; max-width: 100%; border: 1px solid var(--line-2); border-radius: 9px; background: var(--card); cursor: pointer; font-family: var(--mono); font-size: 0.82rem; color: var(--ink); transition: background 0.14s ease, border-color 0.14s ease; }
.copy-chip:hover { border-color: var(--accent-lite); background: var(--accent-50); }
.copy-chip:focus-visible { outline: 2px solid var(--accent-lite); outline-offset: 2px; }
.copy-chip code { font-family: var(--mono); background: none; color: inherit; white-space: nowrap; overflow-x: auto; }
.copy-chip__ico { display: inline-flex; flex: none; color: var(--muted); }
.copy-chip__ico svg { width: 14px; height: 14px; }
.copy-chip__ico .i-check { display: none; }
.copy-chip.is-copied { border-color: #22c55e; }
.copy-chip.is-copied .copy-chip__ico { color: #16a34a; }
.copy-chip.is-copied .copy-chip__ico .i-copy { display: none; }
.copy-chip.is-copied .copy-chip__ico .i-check { display: inline-flex; }
/* Windows visitors see their platform first (site.js adds .dl--win) */
.dl--win .dl__btn--win { order: -1; }
/* Show only the visitor's-OS meta + first-run caveats. macOS by default (and with
   no JS); .dl--win swaps to the Windows block. Both download buttons stay live. */
.dl__plat--win { display: none; }
.dl--win .dl__plat--mac { display: none; }
.dl--win .dl__plat--win { display: block; }

/* ---- download feedback (site.js initDownloadFeedback): the .dmg is ~220 MB, so
   the browser's own download shelf lags; we show an in-page spinner + real byte
   progress from click until the file lands. ---- */
.dl__spinner {
  display: none; width: 20px; height: 20px; flex: none; border-radius: 50%;
  border: 2.5px solid currentColor; border-top-color: transparent; opacity: 0.85;
  animation: dlSpin 0.7s linear infinite;
}
/* Hidden until the button is clicked. Scoped under .dl__btn:not(.is-loading) so
   it outranks `.dl__txt b { display:block }` (0,1,1) — a bare `.dl__txt-busy`
   (0,1,0) lost that cascade and left "Preparing your download…" showing at rest. */
.dl__btn:not(.is-loading) .dl__txt-busy { display: none; }
.dl__btn.is-loading { pointer-events: none; }
.dl__btn.is-loading .dl__logo { display: none; }
.dl__btn.is-loading .dl__spinner { display: inline-block; }
.dl__btn.is-loading .dl__txt-idle { display: none; }
.dl__btn.is-loading .dl__txt-busy {
  display: block; font-size: 1.02rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25;
}
@keyframes dlSpin { to { transform: rotate(360deg); } }

.dl__progress { max-width: 420px; margin: 1.15rem auto 0; }
.dl__track { height: 8px; border-radius: 999px; background: var(--line-2); overflow: hidden; }
.dl__fill {
  display: block; height: 100%; width: 0%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), #a855f7);
  transition: width 0.2s ease;
}
.dl__status { margin-top: 0.55rem; color: var(--muted); font-size: 0.84rem; font-variant-numeric: tabular-nums; }
/* No Content-Length (or streaming unavailable) → an indeterminate sweep. */
.dl--indeterminate .dl__fill { width: 40% !important; transition: none; animation: dlIndet 1.1s ease-in-out infinite; }
/* translateX (compositor) instead of margin-left (per-frame layout). The fill is
   pinned to width:40%, so translateX %s (resolved against the fill's own 0.4·track
   width) reproduce the old margin-left %s (resolved against the full track) exactly:
   −42%→−105%, 102%→255%. If that 40% ever changes, recompute as old-margin% ÷ 0.40. */
@keyframes dlIndet { 0% { transform: translateX(-105%); } 100% { transform: translateX(255%); } }
@media (prefers-reduced-motion: reduce) {
  .dl__spinner { animation: none; }
  .dl--indeterminate .dl__fill { animation: none; margin-left: 0; width: 100% !important; }
}

@media (max-width: 560px) {
  .dl__btn { width: 100%; justify-content: center; }
}

/* ---- mobile "open on your computer" popup (site.js initDownloadFeedback):
   shown when a phone/tablet taps the mac button — the runner is desktop-only. */
.dl-modal .modal__panel { max-width: min(440px, calc(100% - 32px)); text-align: center; }
.dl-modal__ico {
  width: 60px; height: 60px; margin: 0.25rem auto 0; display: grid; place-items: center;
  border-radius: 16px; background: var(--accent-50); color: var(--accent);
}
.dl-modal__ico svg { width: 30px; height: 30px; }
.dl-modal .modal__head h2 { font-size: 1.35rem; }
.dl-modal .modal__head p { margin-bottom: 1.5rem; }
.dl-modal__copy { width: 100%; justify-content: center; }
.dl-modal__copy-done { display: none; }
.dl-modal__copy.is-copied .dl-modal__copy-idle { display: none; }
.dl-modal__copy.is-copied .dl-modal__copy-done { display: inline; }
/* the popup is a centered card even on phones (unlike the tall demo sheet) */
@media (max-width: 560px) {
  .dl-modal .modal__panel {
    width: calc(100% - 32px); min-height: 0; margin: 16vh auto 0;
    border: 1px solid var(--line); border-radius: var(--r);
    padding: 2.25rem 1.4rem 1.6rem;
  }
  .dl-modal .modal__close { position: absolute; }
}

/* ============================================================ light theme: LIGHT bands
   In light mode the page used to keep FOUR full dark sections (hero, capabilities,
   run-local, plus CTA+footer) — toggling the theme barely changed the page. Now
   only the purple CTA and the dark footer keep the night signature; the hero and
   the two mid-page bands flip to lavender-tinted paper. The section-scoped token
   flip below carries most of the restyle: everything inside these bands that was
   written against --band/--on-band/--accent-lite re-resolves to the light set.
   The dark set pieces (isometric plates, quality reactor, terminal mock) stay
   dark on purpose — they read as rendered objects on paper. */
html.light { background-color: var(--paper); } /* top overscroll matches the light hero */

html.light .band--hero,
html.light #suite,
html.light #local {
  --band: color-mix(in srgb, var(--accent) 4%, var(--paper));
  --band-2: var(--card);
  --band-line: var(--line-2);
  --on-band: var(--ink);
  --on-band-soft: var(--ink-soft);
  --accent-lite: var(--accent);
  background: var(--band);
  color: var(--ink);
}
/* the violet crown glow overpowers paper — keep a whisper of it */
html.light .band--hero::before,
html.light #suite::before { opacity: 0.3; }

/* #local reads as a plain beige section (matching Download/Pricing), NOT a
   violet-tinted band — drop the accent tint and kill the crown glow in light. */
html.light #local {
  --band: var(--paper-2);
  background: var(--paper-2);
}
html.light #local::before { display: none; }

/* --- hero on paper --- */
html.light .hero h1 { color: var(--ink); }
html.light .hero h1 .hl { color: var(--accent); }
html.light .hero .micro { color: var(--muted); }
html.light .hero__chip { background: color-mix(in srgb, var(--card) 60%, transparent); }
html.light .band--hero .btn-primary { background: var(--ink); color: var(--paper); }
html.light .band--hero .btn-primary:hover { background: var(--ink-soft); }
html.light .band--hero .btn-ghost,
html.light #suite .btn-ghost,
html.light #local .btn-ghost { background: var(--card); color: var(--ink); border-color: var(--line-2); }
html.light .band--hero .btn-ghost:hover,
html.light #suite .btn-ghost:hover,
html.light #local .btn-ghost:hover { border-color: var(--muted); }
html.light .orbit__links line { stroke: rgb(109 40 217 / 0.3); }
html.light .orb img { filter: drop-shadow(0 18px 32px rgb(14 16 19 / 0.28)); }
html.light .orb--core img { filter: drop-shadow(0 28px 55px rgb(124 58 237 / 0.35)); }

/* --- capabilities on paper: labels become white cards --- */
html.light #suite .stack__label {
  background: var(--card);
  border-color: var(--line-2);
  box-shadow: inset 0 1px 0 #fff, 0 14px 30px -24px rgb(14 16 19 / 0.35);
  opacity: 0.82;
}
html.light #suite .stack__label:hover { border-color: color-mix(in srgb, var(--accent) 35%, var(--line-2)); }
html.light #suite .stack__label.is-on {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: linear-gradient(150deg, rgb(124 58 237 / 0.09), rgb(124 58 237 / 0.015)), var(--card);
  box-shadow: inset 0 1px 0 #fff, 0 0 0 1px rgb(124 58 237 / 0.14), 0 20px 44px -20px rgb(124 58 237 / 0.45);
}
html.light #suite .stack__dot { background: rgb(14 16 19 / 0.18); }
html.light #suite .stack__label.is-on .stack__dot { background: var(--accent); box-shadow: 0 0 0 4px rgb(124 58 237 / 0.16); }
html.light #suite .plate { box-shadow: 0 30px 60px -30px rgb(14 16 19 / 0.45), inset 0 1px 0 rgb(255 255 255 / 0.07); }
html.light #suite .reactor__ring--inner { border-color: rgb(109 40 217 / 0.22); }
html.light #suite .reactor__core > span { color: var(--muted); }
html.light #suite .reactor__core > em { color: var(--accent); }
html.light #suite .cap { background: color-mix(in srgb, var(--card) 55%, transparent); }
/* reactor satellite nodes: on paper the dark #1b1f2e tiles read as heavy black
   squares — flip them to white cards with a dark glyph (like the capability
   cards). The active node keeps its violet glow, and the "Quality Core"
   medallion stays a dark rendered object. */
html.light #suite .reactor__node {
  color: var(--ink-soft);
  background: linear-gradient(150deg, #ffffff, #f2f2f5);
  border-color: var(--line-2);
  box-shadow: inset 0 1px 0 #fff, 0 12px 24px -14px rgb(14 16 19 / 0.3);
}
html.light #suite .reactor__node.is-on {
  color: #fff; border-color: rgb(139 92 246 / 0.7);
  background: linear-gradient(145deg,#9c6cff,#6330d7);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .45), 0 0 0 6px rgb(124 58 237 / .12), 0 12px 30px -8px rgb(124 58 237 / .5);
}

/* --- run-local on paper (the terminal card itself stays a dark terminal) --- */
html.light #local .local__feats .ck { color: var(--ok); }
/* the cursor blinks INSIDE the dark terminal — keep it lavender there, the
   section-scoped --accent-lite flip would turn it near-invisible dark violet */
html.light #local .local__cursor { color: #a78bfa; }

/* ------------------------------------------------------------ #export chip wall
   Staggered "brick" rows of framework/language chips — the same brand marks the
   app's Code tab switcher renders — with empty ghost tiles bleeding off both
   edges under a horizontal fade, so the wall reads as a slice of an endless
   keyboard of stacks rather than a bounded grid. */
.stackwall {
  margin-top: 3.2rem; display: flex; flex-direction: column; gap: 0.95rem;
  overflow: hidden; padding-block: 4px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 16%, #000 84%, transparent);
}
.stackwall__row {
  display: flex; justify-content: center; gap: 0.95rem; flex-wrap: nowrap;
  transform: translateX(var(--shift, 0px));
}
.swchip {
  display: inline-flex; align-items: center; gap: 0.7rem; flex: none;
  padding: 1.02rem 1.55rem; border-radius: 15px; white-space: nowrap;
  background: var(--card); border: 1px solid var(--line); color: var(--ink);
  font-weight: 620; font-size: 1.04rem; letter-spacing: -0.02em;
  box-shadow: 0 1px 2px rgb(14 16 19 / 0.05), 0 16px 34px -22px rgb(14 16 19 / 0.28);
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1.2), border-color 0.28s ease, box-shadow 0.28s ease;
}
.swchip svg { width: 25px; height: 25px; flex: none; }
/* only REAL framework chips react — the decorative ghost fillers stay inert */
.swchip:not(.swchip--ghost):hover {
  transform: translateY(-4px) rotate(-1deg);
  border-color: color-mix(in srgb, var(--accent) 38%, var(--line));
  box-shadow: 0 2px 3px rgb(14 16 19 / 0.05), 0 24px 48px -22px rgb(124 58 237 / 0.4);
}
.swchip--ghost {
  width: clamp(6.5rem, 11vw, 10.5rem); height: 3.6rem; padding: 0;
  background: color-mix(in srgb, var(--card) 42%, transparent);
  box-shadow: none; opacity: 0.6;
}
html.dark .swchip { box-shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 16px 34px -22px rgb(0 0 0 / 0.6); }
html.dark .swchip:not(.swchip--ghost):hover { box-shadow: 0 2px 3px rgb(0 0 0 / 0.3), 0 24px 48px -22px rgb(124 58 237 / 0.45); }
html.dark .swchip--ghost { background: rgb(255 255 255 / 0.025); box-shadow: none; }
.stackwall__meta {
  margin: 2.4rem 0 0; text-align: center;
  font-family: var(--mono); font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
@media (max-width: 760px) {
  .stackwall { gap: 0.7rem; }
  .stackwall__row { gap: 0.7rem; }
  .swchip { padding: 0.78rem 1.1rem; font-size: 0.92rem; border-radius: 12px; gap: 0.55rem; }
  .swchip svg { width: 21px; height: 21px; }
  .swchip--ghost { height: 2.95rem; }
}

/* ------------------------------------------------------------ light theme: bright footer
   The footer joins the light flip: in light mode it sits on the same paper as
   the rest of the page (the purple CTA above ends on a crisp edge, and bottom
   overscroll already reveals paper). Same section-scoped token remap as the
   hero/#suite/#local bands; dark mode keeps the night footer untouched. */
html.light footer {
  --band: var(--paper);
  --band-2: var(--card);
  --band-line: var(--line-2);
  --on-band: var(--ink);
  --on-band-soft: var(--ink-soft);
  --accent-lite: var(--accent);
  background: var(--paper);
  color: var(--ink);
  border-top: 1px solid var(--line);
}
/* wordmark: same accent gradient the light nav uses, not white-on-dark */
html.light footer .brand span {
  background: linear-gradient(96deg, var(--accent) 8%, #b393ff 92%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
/* notebook-squares texture: ink lines on paper instead of white on night */
html.light footer::before {
  background-image:
    linear-gradient(rgb(14 16 19 / 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgb(14 16 19 / 0.05) 1px, transparent 1px);
}
html.light .foot .copy { color: var(--muted); }
html.light .foot__col h4 { color: var(--muted); }

/* ------------------------------------------------------------ chatui: faithful to the app
   Corrections against the REAL agent-chat page (web/src/app/(app)/[project]/
   agent-chat/view.tsx + globals.css) — the mock had drifted:
   · the chat sits on the app's dotted --canvas (= --paper) not on a white card
   · consecutive tool steps live inside the indigo ToolGroup box ("4 actions")
   · assistant replies carry the sparkles avatar (indigo-50 rounded-xl)
   · model chip is BORDERED (border-border, text-foreground); effort chip isn't
   · the send button is the brand --primary #5b4de6 (dark #6f5aee), not indigo-500 */
.chatui {
  background-color: var(--paper);
  background-image: radial-gradient(circle, rgb(16 18 22 / 0.05) 1px, transparent 1.5px);
  background-size: 16px 16px;
  background-position: center top;
}
html.dark .chatui {
  background-image: radial-gradient(circle, rgb(148 163 184 / 0.055) 1px, transparent 1.5px);
}
.chatui__user { box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.1), 0 1px 2px rgb(0 0 0 / 0.08); }
/* ToolGroup — same skin as the ThinkingRow (indigo-200/70 on indigo-50/60) */
.chatui__group { overflow: hidden; border-radius: 12px; border: 1px solid rgb(199 210 254 / 0.7); background: rgb(238 242 255 / 0.6); }
.chatui__ghead { display: flex; align-items: center; gap: 0.6rem; padding: 0.5rem 0.8rem; font-size: 0.84rem; }
.chatui__gicons { display: inline-flex; align-items: center; gap: 0.25rem; color: #6366f1; font-size: 0.8rem; flex: none; }
.chatui__gcount { flex: 1; font-weight: 600; color: #312e81; }
.chatui__group .chatui__tools { border-top: 1px solid rgb(199 210 254 / 0.7); padding: 0.55rem 0.8rem; }
html.dark .chatui__group { border-color: rgb(99 102 241 / 0.2); background: rgb(99 102 241 / 0.07); }
html.dark .chatui__gicons { color: #818cf8; }
html.dark .chatui__gcount { color: #c7d2fe; }
html.dark .chatui__group .chatui__tools { border-top-color: rgb(99 102 241 / 0.2); }
/* assistant row: sparkles avatar beside the reply, chips indent to match */
.chatui__row { display: flex; align-items: flex-start; gap: 0.6rem; }
.chatui__avatar { flex: none; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 9px; background: #eef2ff; color: #4f46e5; font-size: 0.8rem; }
html.dark .chatui__avatar { background: rgb(99 102 241 / 0.15); color: #a5b4fc; }
.chatui__row .chatui__reply { margin: 0.15rem 0 0; }
.chatui__chips { margin-left: calc(26px + 0.6rem); }
/* composer chrome */
.chatui__chip { border: 1px solid var(--line); color: var(--ink); font-weight: 500; padding: 0 0.55rem; }
.chatui__chip--effort { border: 0; color: var(--muted); font-weight: 600; padding: 0 0.35rem; }
.chatui__send { background: #5b4de6; box-shadow: 0 1px 2px rgb(91 77 230 / 0.4); }
html.dark .chatui__send { background: #6f5aee; box-shadow: 0 1px 2px rgb(0 0 0 / 0.4); }

/* ------------------------------------------------------------ mobile polish */
/* The nav drawer was a flat opaque card — visually unrelated to the glass pill
   it drops from. Same glass recipe as .nav__in: translucent frost + blur, no
   drawn border, bevel ring (lit top edge, shaded bottom) via inset shadows. */
@media (max-width: 1140px) {
  /* NOTE: no backdrop-filter here — the drawer is a descendant of .nav__in,
     whose own backdrop-filter makes it a backdrop root, so a child's blur can
     never sample the page behind (it renders fully transparent instead).
     Near-opaque frost + the pill's bevel shadows read as the same glass. */
  .nav__in > .nav__links {
    border: 0; border-radius: 16px;
    background: linear-gradient(180deg,
      color-mix(in srgb, var(--card) 97%, var(--accent)),
      color-mix(in srgb, var(--card) 93%, var(--accent)));
    box-shadow:
      0 2px 2px rgb(15 10 30 / 0.08),
      0 12px 28px -12px rgb(24 14 55 / 0.30),
      0 30px 70px -34px rgb(85 49 170 / 0.38),
      inset 0 1.5px 0 rgb(255 255 255 / 0.55),
      inset 0 -1px 0 rgb(20 12 46 / 0.10);
  }
  html.dark .nav__in > .nav__links {
    background: linear-gradient(180deg, #1a1526, #151020);
    box-shadow:
      0 2px 2px rgb(0 0 0 / 0.35),
      0 12px 28px -12px rgb(0 0 0 / 0.5),
      0 30px 70px -34px rgb(85 49 170 / 0.4),
      inset 0 1.5px 0 rgb(255 255 255 / 0.16),
      inset 0 -1px 0 rgb(0 0 0 / 0.4);
  }
  .nav__links a { font-weight: 520; }
  .nav__links a:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }
  .nav__cta-primary { border-radius: 10px; }
}
/* The #local terminal overflowed the phone viewport: the nowrap command rows set
   a large min-content width, and the grid column's default min-width:auto let
   that push the card past the screen edge. Let the column shrink, and wrap the
   long command on narrow screens instead of clipping it. */
.local__col { min-width: 0; }
.local__term { max-width: 100%; }
.local__cmd { min-width: 0; }
@media (max-width: 640px) {
  .local__cmd { align-items: flex-start; font-size: 0.8rem; }
  .local__text { white-space: normal; overflow-wrap: anywhere; }
  .local__copy { margin-top: 0.15rem; }
}
