@charset "UTF-8";
/* ==========================================================================
   AZMILE.AI — Design System v2
   Zero-build. Plain CSS custom properties. No framework, no CDN.
   Layers: tokens → reset → primitives → components → sections → utilities
   ========================================================================== */

/* ---------------------------------------------------------------- TOKENS - */
:root {
  /* — Canvas: layered near-black. Never flat #000; depth comes from steps. — */
  --bg-0: #04060c;
  /* deepest — page canvas */
  --bg-1: #070a12;
  /* alt band */
  --bg-2: #0a0e18;
  /* raised band */
  --surface: rgba(255, 255, 255, 0.035);
  --surface-2: rgba(255, 255, 255, 0.055);
  --line: rgba(255, 255, 255, 0.085);
  --line-soft: rgba(255, 255, 255, 0.05);
  --line-hard: rgba(255, 255, 255, 0.14);

  /* — Brand: lime is the signature. Cyan + violet appear ONLY in AI moments. — */
  --lime: #a8e04a;
  --lime-2: #c9f77e;
  /* brighter — accent text on dark, raises contrast */
  --lime-deep: #6f9a1f;
  --cyan: #4fd6e8;
  --violet: #8b7cf6;
  --glow: rgba(168, 224, 74, 0.18);

  /* AI signature gradient — reserved for AI surfaces, never decoration */
  --grad-ai: linear-gradient(115deg, #4fd6e8 0%, #a8e04a 52%, #c9f77e 100%);
  --grad-ai-soft: linear-gradient(115deg, rgba(79, 214, 232, .16), rgba(168, 224, 74, .16));

  /* — Ink — */
  --ink: #f0f4fa;
  --ink-2: #b9c3d3;
  --ink-3: #7c8798;

  /* — Status — */
  --ok: #3ecf7c;
  --warn: #f5c144;
  --info: #5ab5f7;
  --danger: #ff6b6b;

  /* — Type — */
  --ff-display: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ff-body: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ff-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --fs-display: clamp(44px, 7vw, 88px);
  --fs-h1: clamp(38px, 5.6vw, 72px);
  --fs-h2: clamp(29px, 3.9vw, 50px);
  --fs-h3: clamp(19px, 1.5vw, 22px);
  --fs-lede: clamp(16px, 1.25vw, 19px);
  --fs-body: 16px;
  --fs-sm: 14px;
  --fs-xs: 12.5px;
  --fs-mono: 12.5px;

  /* — Space (8px base) — */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --sp-9: 96px;
  --sp-10: 128px;
  --section-y: clamp(76px, 9vw, 132px);

  /* — Radius — */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 9999px;

  /* — Elevation — */
  --sh-1: 0 1px 2px rgba(0, 0, 0, .4);
  --sh-2: 0 12px 32px -12px rgba(0, 0, 0, .7);
  --sh-3: 0 32px 80px -28px rgba(0, 0, 0, .85);
  --sh-glow: 0 0 0 1px rgba(168, 224, 74, .28), 0 18px 50px -18px rgba(168, 224, 74, .35);

  /* — Motion — */
  --ease: cubic-bezier(.22, 1, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-io: cubic-bezier(.65, 0, .35, 1);
  --dur-1: .18s;
  --dur-2: .32s;
  --dur-3: .6s;
  --dur-4: .9s;

  --maxw: 1220px;
  --nav-h: 68px;
}

/* ----------------------------------------------------------------- RESET - */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 24px);
}

body {
  font-family: var(--ff-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--ink-2);
  background: var(--bg-0);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'ss01';
  overflow-x: hidden;
  min-height: 100vh;
}

/* Author `display` rules beat the UA sheet, so [hidden] needs to win explicitly
   or every .thinking/.msg/.console-foot with `hidden` would still render. */
[hidden] {
  display: none !important;
}

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

img {
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

ul,
ol {
  list-style: none;
}

table {
  border-collapse: collapse;
}

::selection {
  background: rgba(168, 224, 74, .28);
  color: #fff;
}

:focus-visible {
  outline: 2px solid var(--lime-2);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

/* Ambient page backdrop — fixed so it never reflows on scroll */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(60% 45% at 78% -5%, rgba(79, 214, 232, .10), transparent 62%),
    radial-gradient(55% 42% at 12% 8%, rgba(168, 224, 74, .10), transparent 60%),
    radial-gradient(70% 50% at 50% 108%, rgba(139, 124, 246, .08), transparent 62%);
  pointer-events: none;
}

/* Fine grain — kills banding in the big gradients */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------------ TYPOGRAPHY - */
.h1,
.h2,
.h3,
.h4,
h1,
h2,
h3,
h4 {
  font-family: var(--ff-display);
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -.032em;
  line-height: 1.06;
  text-wrap: balance;
}

.h1,
h1 {
  font-size: var(--fs-h1);
}

.h2,
h2 {
  font-size: var(--fs-h2);
  letter-spacing: -.028em;
}

.h3,
h3 {
  font-size: var(--fs-h3);
  line-height: 1.3;
  letter-spacing: -.018em;
}

.h4,
h4 {
  font-size: 15px;
  line-height: 1.4;
  letter-spacing: -.01em;
}

.display {
  font-size: var(--fs-display);
  line-height: 1.0;
  letter-spacing: -.04em;
}

.lede {
  font-size: var(--fs-lede);
  line-height: 1.65;
  color: var(--ink-2);
  text-wrap: pretty;
  max-width: 62ch;
}

.muted {
  color: var(--ink-3);
}

.mono {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono);
  letter-spacing: -.01em;
}

.center {
  text-align: center;
}

.center .lede {
  margin-inline: auto;
}

/* Gradient accent word — the one place raw AI-gradient touches type */
.accent {
  background: var(--grad-ai);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.accent-plain {
  color: var(--lime-2);
}

b,
strong {
  color: var(--ink);
  font-weight: 600;
}

/* ------------------------------------------------------------- PRIMITIVES */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 32px);
}

.section {
  padding-block: var(--section-y);
  position: relative;
}

.section--tight {
  padding-block: clamp(48px, 6vw, 76px);
}

/* Alternating band with hairline gradient rules top & bottom */
.band {
  background: linear-gradient(180deg, rgba(255, 255, 255, .018), rgba(255, 255, 255, 0));
  border-block: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--line), transparent) 1;
}

.section-head {
  max-width: 760px;
  margin-bottom: var(--sp-8);
}

.section-head.center {
  margin-inline: auto;
}

/* Eyebrow pill — glass chip, gradient hairline, live dot */
.eyebrow {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-2);
  background: linear-gradient(180deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, .02));
  padding: 8px 16px;
  border-radius: var(--r-pill);
  margin-bottom: var(--sp-5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .09), 0 10px 26px -18px #000;
}

/* Hairline drawn as a masked ring so the pill radius stays exact */
.eyebrow::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(115deg, rgba(168, 224, 74, .7), rgba(79, 214, 232, .42) 44%, rgba(255, 255, 255, .07) 80%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.eyebrow::before {
  content: '';
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lime);
  animation: eyebrowPulse 2.6s var(--ease-io) infinite;
}

@keyframes eyebrowPulse {

  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(168, 224, 74, .5), 0 0 10px 1px rgba(168, 224, 74, .75);
  }

  60% {
    box-shadow: 0 0 0 6px rgba(168, 224, 74, 0), 0 0 10px 1px rgba(168, 224, 74, .75);
  }
}

/* --------------------------------------------------------------- BUTTONS - */
.btn {
  --btn-py: 11px;
  --btn-px: 20px;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: var(--btn-py) var(--btn-px);
  font-family: var(--ff-body);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -.008em;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  white-space: nowrap;
  cursor: pointer;
  isolation: isolate;
  transition: transform var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    background var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease),
    color var(--dur-2) var(--ease);
}

.btn-lg {
  --btn-py: 14px;
  --btn-px: 26px;
  font-size: 15px;
}

.btn-primary {
  color: #08120a;
  background: var(--grad-ai);
  background-size: 180% 100%;
  background-position: 0% 50%;
  box-shadow: 0 10px 30px -10px rgba(168, 224, 74, .5), inset 0 1px 0 rgba(255, 255, 255, .35);
  overflow: hidden;
}

.btn-primary:hover {
  background-position: 100% 50%;
  transform: translateY(-2px);
  box-shadow: 0 18px 44px -12px rgba(168, 224, 74, .6), inset 0 1px 0 rgba(255, 255, 255, .4);
}

.btn-primary:active {
  transform: translateY(0);
}

/* Gloss that wipes across the pill on hover. Sits above the fill but is
   transparent enough to read straight through to the label. */
.btn-primary::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 60%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .5), transparent);
  transform: translateX(-180%) skewX(-14deg);
  pointer-events: none;
  z-index: 1;
}

.btn-primary:hover::after {
  transform: translateX(320%) skewX(-14deg);
  transition: transform .8s var(--ease-out);
}

.btn-ghost {
  color: var(--ink);
  background: var(--surface);
  border-color: var(--line);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.btn-ghost:hover {
  background: var(--surface-2);
  border-color: rgba(168, 224, 74, .4);
  color: #fff;
  transform: translateY(-2px);
}

.btn-quiet {
  color: var(--ink-2);
  padding-inline: 12px;
}

.btn-quiet:hover {
  color: var(--ink);
  background: var(--surface);
}

/* Arrow nudge on hover */
.btn .arw {
  transition: transform var(--dur-2) var(--ease);
}

.btn:hover .arw {
  transform: translateX(4px);
}

/* Inline text link with sliding underline */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: var(--fs-sm);
  color: var(--lime-2);
  padding-bottom: 2px;
  background-image: linear-gradient(var(--lime-2), var(--lime-2));
  background-size: 0% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size var(--dur-2) var(--ease);
}

.link-arrow:hover {
  background-size: 100% 1px;
}

.link-arrow .arw {
  transition: transform var(--dur-2) var(--ease);
}

.link-arrow:hover .arw {
  transform: translateX(4px);
}

/* Tool / capability tag */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--ff-mono);
  font-size: 11.5px;
  color: var(--lime-2);
  background: rgba(168, 224, 74, .07);
  border: 1px solid rgba(168, 224, 74, .18);
  padding: 4px 10px;
  border-radius: var(--r-xs);
  white-space: nowrap;
}

.tag::before {
  content: '▮';
  opacity: .55;
  font-size: 9px;
}

.tag--neutral {
  color: var(--ink-3);
  background: var(--surface);
  border-color: var(--line);
}

.tag--neutral::before {
  content: none;
}

/* Tool-name grids in the Azzy action tabs. Was three inline
   grid-template-columns declarations, which a media query can't override
   without !important — hence the class. */
.tag-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
}

.tag-grid.is-wide {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* Skip link */
.skip {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 200;
  background: var(--lime);
  color: #08120a;
  padding: 10px 18px;
  border-radius: var(--r-sm);
  font-weight: 700;
  transition: top var(--dur-2) var(--ease);
}

.skip:focus {
  top: 12px;
}

/* ------------------------------------------------------------------ CARD - */
.card {
  position: relative;
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .012));
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: var(--sh-2), inset 0 1px 0 rgba(255, 255, 255, .06);
  overflow: hidden;
  transition: transform var(--dur-3) var(--ease),
    border-color var(--dur-3) var(--ease),
    box-shadow var(--dur-3) var(--ease);
}

/* Cursor spotlight — driven by --mx/--my set in JS */
.card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%),
      rgba(168, 224, 74, .13), transparent 62%);
  transition: opacity var(--dur-3) var(--ease);
}

.card:hover {
  transform: translateY(-4px);
  border-color: rgba(168, 224, 74, .3);
  box-shadow: var(--sh-3), inset 0 1px 0 rgba(255, 255, 255, .09);
}

.card:hover::before {
  opacity: 1;
}

.card>* {
  position: relative;
  z-index: 1;
}

.card .h3 {
  margin-bottom: 10px;
}

.card p {
  font-size: var(--fs-sm);
  line-height: 1.68;
  color: var(--ink-2);
}

.card .tag {
  margin-top: var(--sp-4);
}

/* Icon chip */
.icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: var(--sp-5);
  border-radius: 13px;
  color: var(--lime-2);
  background: linear-gradient(150deg, rgba(168, 224, 74, .16), rgba(79, 214, 232, .07));
  border: 1px solid rgba(168, 224, 74, .22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
  transition: transform var(--dur-3) var(--ease), box-shadow var(--dur-3) var(--ease);
}

.card:hover .icon {
  transform: translateY(-2px) scale(1.06) rotate(-3deg);
  box-shadow: 0 8px 22px -8px rgba(168, 224, 74, .5);
}

.icon svg {
  width: 21px;
  height: 21px;
}

/* Numbered step chip */
.step-n {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  margin-bottom: var(--sp-5);
  border-radius: 13px;
  font-family: var(--ff-mono);
  font-weight: 600;
  font-size: 15px;
  color: var(--lime-2);
  background: linear-gradient(150deg, rgba(168, 224, 74, .16), rgba(79, 214, 232, .06));
  border: 1px solid rgba(168, 224, 74, .24);
}

/* --------------------------------------------------------------- GRIDS --- */
.grid {
  display: grid;
  gap: var(--sp-5);
}

.grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.grid-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.grid-auto {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

/* Bento — modern asymmetric feature layout */
.bento {
  display: grid;
  gap: var(--sp-5);
  grid-template-columns: repeat(6, 1fr);
}

.bento>.card {
  grid-column: span 2;
}

.bento>.card.is-wide {
  grid-column: span 3;
}

.bento>.card.is-hero {
  grid-column: span 4;
}

.bento>.card.is-full {
  grid-column: span 6;
}

/* --------------------------------------------------------------- NAV ----- */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  padding-inline: clamp(18px, 4vw, 32px);
  transition: background var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), backdrop-filter var(--dur-2);
  border-bottom: 1px solid transparent;
}

.nav.is-stuck {
  background: rgba(4, 6, 12, .78);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-bottom-color: var(--line);
}

/* No flex `gap` here: bare text nodes become anonymous flex items, which
   would insert a gap between "Azmile" and ".Ai". Space the mark instead. */
.brand {
  display: inline-flex;
  align-items: center;
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: 18.5px;
  letter-spacing: -.03em;
  color: var(--ink);
  margin-right: auto;
}

.brand .ai {
  color: var(--lime-2);
}

.brand-mark {
  position: relative;
  width: 26px;
  height: 26px;
  flex: none;
  margin-right: 10px;
  border-radius: 8px;
  background: var(--grad-ai);
  box-shadow: 0 4px 14px -4px rgba(168, 224, 74, .6);
}

.brand-mark::after {
  content: '';
  position: absolute;
  inset: 6px;
  border-radius: 3px;
  background: var(--bg-0);
  clip-path: polygon(0 100%, 100% 0, 100% 38%, 42% 100%);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 2px;
}

.nav-links a {
  position: relative;
  padding: 8px 14px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink-2);
  border-radius: var(--r-pill);
  transition: color var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}

.nav-links a:hover {
  color: var(--ink);
  background: var(--surface);
}

.nav-links a.active {
  color: var(--ink);
}

.nav-links a.active::after {
  content: '';
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 2px;
  height: 2px;
  border-radius: 2px;
  background: var(--grad-ai);
}

.nav-cta {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* "Ask Azzy" — the AI affordance, always one tap away */
.nav-ask {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--lime-2);
  border-radius: var(--r-pill);
  border: 1px solid rgba(168, 224, 74, .26);
  background: rgba(168, 224, 74, .06);
  transition: background var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}

.nav-ask:hover {
  background: rgba(168, 224, 74, .13);
  border-color: rgba(168, 224, 74, .5);
}

.nav-ask .spark {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: 0 0 8px 1px rgba(168, 224, 74, .9);
  animation: pulse 2.4s var(--ease-io) infinite;
}

@keyframes pulse {

  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }

  50% {
    opacity: .45;
    transform: scale(.7);
  }
}

.burger {
  display: none;
  padding: 8px;
  border-radius: var(--r-sm);
  color: var(--ink);
}

.burger:hover {
  background: var(--surface);
}

/* Mobile drawer */
.drawer {
  position: fixed;
  inset: var(--nav-h) 0 auto 0;
  z-index: 99;
  display: grid;
  gap: 6px;
  padding: var(--sp-5) clamp(18px, 4vw, 32px) var(--sp-6);
  background: rgba(4, 6, 12, .96);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--line);
  transform: translateY(-12px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease), visibility var(--dur-2);
}

.drawer.open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.drawer a:not(.btn) {
  padding: 12px 4px;
  font-size: 17px;
  font-weight: 500;
  color: var(--ink);
  font-family: var(--ff-display);
  letter-spacing: -.02em;
  border-bottom: 1px solid var(--line-soft);
}

.drawer .btn {
  margin-top: 8px;
}

/* Scroll progress bar */
.progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 101;
  height: 2px;
  width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: var(--grad-ai);
  box-shadow: 0 0 12px rgba(168, 224, 74, .6);
}

/* --------------------------------------------------------------- HERO ---- */
.hero {
  position: relative;
  padding-block: clamp(64px, 8vw, 112px) var(--section-y);
  overflow: hidden;
  isolation: isolate;
}

/* Dissolve into the page instead of ending on a hard edge */
.hero::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 200px;
  background: linear-gradient(180deg, transparent, var(--bg-0));
  pointer-events: none;
  z-index: -1;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

/* Platform hero: the wired flow is the star, so give it the wider column */
.hero-grid--wire {
  grid-template-columns: minmax(0, .86fr) minmax(0, 1.14fr);
}

/* Above-the-fold hero: one screen, no scrolling to see the whole story.
   Type in here is capped by BOTH vw and vh, so a short laptop screen shrinks
   the headline instead of pushing the visual off the bottom. */
.hero--fit {
  min-height: calc(100vh - var(--nav-h));
  min-height: calc(100svh - var(--nav-h));
  display: grid;
  align-content: center;
  padding-block: clamp(16px, 2.6vh, 44px);
}

.hero--fit .h1 {
  font-size: clamp(32px, min(5.4vw, 7vh), 68px);
  margin-block: clamp(8px, 1.4vh, 20px) clamp(10px, 1.8vh, 24px);
}

.hero--fit .lede {
  font-size: clamp(14.5px, min(1.2vw, 1.85vh), 18px);
  margin-bottom: clamp(14px, 2.2vh, 30px);
}

.hero--fit .eyebrow {
  margin-bottom: clamp(10px, 1.6vh, 22px);
}

.hero--fit .hero-meta {
  margin-top: clamp(12px, 1.9vh, 24px);
}

/* Narrower copy column here — tighten the pills so the strip stays a single
   row instead of wrapping into a half-empty box. */
.hero--fit .hero-meta span {
  padding: clamp(7px, 1.15vh, 11px) 13px;
  font-size: 11px;
}

/* The console is the tallest thing in the hero, so its own padding joins the
   height budget — shrinking the headline alone can't stop a short laptop from
   pushing the chip strip past the fold. Same vw+vh capping as the type above;
   the conversation and its chart keep their natural size. */
.hero--fit .console-body {
  padding-block: clamp(15px, 2.3vh, 24px) clamp(11px, 1.7vh, 18px);
}

.hero--fit .chips {
  padding-block: clamp(10px, 1.5vh, 16px) clamp(10px, 1.5vh, 18px);
}

/* In flow the mouse hint costs ~100px of the one screen it is pointing away
   from. Float it over the hero instead — it is a hint, not a row. */
.hero--fit .hero-scroll {
  position: absolute;
  left: 50%;
  bottom: clamp(8px, 1.5vh, 20px);
  margin: 0;
  transform: translateX(-50%);
}

.hero .h1 {
  margin-block: var(--sp-3) var(--sp-5);
  letter-spacing: -.042em;
}

.hero .lede {
  margin-bottom: var(--sp-6);
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Drifting mesh-gradient wash — the depth layer under everything */
.hero-aurora {
  position: absolute;
  inset: -25% -12% -8% -12%;
  z-index: -3;
  pointer-events: none;
  /* Weighted right-and-top: colour pools behind the visual, the copy column
     stays near-black so the headline keeps its contrast. */
  background:
    radial-gradient(36% 40% at 78% 16%, rgba(79, 214, 232, .20), transparent 64%),
    radial-gradient(40% 44% at 62% 76%, rgba(139, 124, 246, .12), transparent 66%),
    radial-gradient(34% 38% at 15% 30%, rgba(168, 224, 74, .10), transparent 64%),
    radial-gradient(26% 30% at 4% 82%, rgba(201, 247, 126, .07), transparent 62%);
  animation: auroraDrift 26s var(--ease-io) infinite alternate;
  will-change: transform;
}

@keyframes auroraDrift {
  0% {
    transform: translate3d(0, 0, 0) scale(1);
  }

  50% {
    transform: translate3d(-2%, 1.5%, 0) scale(1.06);
  }

  100% {
    transform: translate3d(2%, -1%, 0) scale(1.02);
  }
}

/* Technical grid, faded out radially so it never fights the copy */
.hero-mesh {
  position: absolute;
  inset: 0;
  z-index: -3;
  pointer-events: none;
  opacity: .7;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, .055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, .055) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(115% 85% at 50% 0%, #000 8%, transparent 70%);
  mask-image: radial-gradient(115% 85% at 50% 0%, #000 8%, transparent 70%);
}

/* Headline: a white highlight travels over the brand gradient. Two layers
   rather than one wide gradient, so the cyan→lime identity never scrolls
   out of the word — only the glint moves. */
.hero .accent {
  background-image:
    linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .9) 50%, transparent 60%),
    var(--grad-ai);
  background-size: 240% 100%, 100% 100%;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  animation: titleShine 7s var(--ease-io) infinite;
}

@keyframes titleShine {

  0%,
  18% {
    background-position: 165% 0, 0 0;
  }

  100% {
    background-position: -75% 0, 0 0;
  }
}

/* Hero CTA — the primary keeps a soft halo so it reads as the one action */
.hero-cta .btn-primary {
  box-shadow: 0 12px 34px -10px rgba(168, 224, 74, .55),
    0 0 0 1px rgba(168, 224, 74, .22),
    inset 0 1px 0 rgba(255, 255, 255, .38);
}

.hero-cta .btn-ghost {
  border-color: var(--line-hard);
}

/* Proof strip — one glass rail, hairline-divided, mono numerals in lime */
.hero-meta {
  margin-top: var(--sp-6);
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  width: fit-content;
  max-width: 100%;
  border-radius: var(--r-md);
  border: 1px solid var(--line-soft);
  background: linear-gradient(180deg, rgba(255, 255, 255, .04), rgba(255, 255, 255, .012));
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), var(--sh-2);
  overflow: hidden;
}

.hero-meta span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 11px 18px;
  font-family: var(--ff-mono);
  font-size: 12px;
  color: var(--ink-2);
  white-space: nowrap;
}

.hero-meta b {
  color: var(--lime-2);
  font-weight: 600;
}

.hero-meta i {
  flex: none;
  align-self: stretch;
  width: 1px;
  height: auto;
  border-radius: 0;
  background: var(--line-soft);
  opacity: 1;
}

/* Trailing "live" item gets the heartbeat */
.hero-meta .is-live::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ok);
  animation: live 2.2s var(--ease-io) infinite;
}

/* Scroll cue */
.hero-scroll {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 24px;
  height: 38px;
  margin: var(--sp-8) auto 0;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-hard);
  background: var(--surface);
  transition: border-color var(--dur-2) var(--ease);
}

.hero-scroll:hover {
  border-color: rgba(168, 224, 74, .5);
}

.hero-scroll span {
  width: 3px;
  height: 7px;
  margin-top: 7px;
  border-radius: var(--r-pill);
  background: var(--lime);
  animation: scrollCue 1.9s var(--ease-io) infinite;
}

@keyframes scrollCue {
  0% {
    opacity: 0;
    transform: translateY(0);
  }

  35% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: translateY(13px);
  }
}

/* Neural canvas behind hero.
   canvas is a replaced element: `inset:0` alone leaves it at its intrinsic
   300x150, so the explicit 100%/100% is doing real work here. */
.neural {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
  opacity: .7;
  /* Weighted to the right so the mesh sits behind the visual, not the copy */
  mask-image: radial-gradient(62% 82% at 70% 46%, #000 8%, transparent 76%);
  -webkit-mask-image: radial-gradient(62% 82% at 70% 46%, #000 8%, transparent 76%);
}

/* Floating orbs — parallax-driven */
.orb {
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  filter: blur(70px);
  pointer-events: none;
  will-change: transform;
}

.orb-a {
  width: 420px;
  height: 420px;
  top: -120px;
  right: -80px;
  background: rgba(79, 214, 232, .16);
}

.orb-b {
  width: 380px;
  height: 380px;
  bottom: -140px;
  left: -100px;
  background: rgba(168, 224, 74, .15);
}

/* ------------------------------------------------------- AZZY CONSOLE ---- */

/* Registering the angle lets the conic beam interpolate smoothly instead of
   snapping. Unsupported browsers fall back to a static gradient edge. */
@property --beam-a {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

/* Wrapper carries the underglow — the console itself clips its own overflow */
.hero-visual {
  position: relative;
}

.hero-visual::before {
  content: '';
  position: absolute;
  inset: 8% -7% -9% -7%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(58% 58% at 50% 58%, rgba(79, 214, 232, .18), transparent 70%);
  filter: blur(38px);
}

.console {
  position: relative;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(18, 24, 38, .92), rgba(8, 11, 19, .95));
  box-shadow: var(--sh-3), inset 0 1px 0 rgba(255, 255, 255, .07);
  overflow: hidden;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* A light that travels the full border, not just the top edge */
.console::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--beam-a),
      transparent 0deg 186deg,
      rgba(79, 214, 232, .75) 244deg,
      rgba(168, 224, 74, 1) 288deg,
      rgba(201, 247, 126, .5) 310deg,
      transparent 336deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: beamSpin 7s linear infinite;
  pointer-events: none;
  z-index: 3;
}

@keyframes beamSpin {
  to {
    --beam-a: 360deg;
  }
}

/* Cursor spotlight — driven by --mx/--my from pointerFX in site.js */
.console::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 0%),
      rgba(168, 224, 74, .10), transparent 62%);
  opacity: 0;
  transition: opacity var(--dur-3) var(--ease);
  pointer-events: none;
  z-index: 2;
}

.console:hover::after {
  opacity: 1;
}

.console-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--ff-mono);
  font-size: 11.5px;
  color: var(--ink-3);
}

.console-head .l {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-2);
}

.dot-live {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 0 rgba(62, 207, 124, .55);
  animation: live 2.2s var(--ease-io) infinite;
}

@keyframes live {
  0% {
    box-shadow: 0 0 0 0 rgba(62, 207, 124, .5);
  }

  70% {
    box-shadow: 0 0 0 8px rgba(62, 207, 124, 0);
  }

  100% {
    box-shadow: 0 0 0 0 rgba(62, 207, 124, 0);
  }
}

.console-body {
  padding: var(--sp-5) 18px 18px;
  min-height: 402px;
  display: flex;
  flex-direction: column;
}

.msg {
  display: flex;
  gap: 10px;
  margin-bottom: var(--sp-4);
  font-size: var(--fs-sm);
  line-height: 1.6;
}

.msg-label {
  flex: none;
  font-family: var(--ff-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .1em;
  padding: 3px 7px;
  border-radius: 5px;
  height: fit-content;
  margin-top: 2px;
}

.msg-label.you {
  color: var(--ink-3);
  background: var(--surface-2);
}

.msg-label.bot {
  color: #08120a;
  background: var(--grad-ai);
}

.msg-you .txt {
  color: var(--ink);
  font-weight: 500;
}

.msg-bot .txt {
  color: var(--ink-2);
}

.caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  background: var(--lime);
  vertical-align: -2px;
  margin-left: 2px;
  animation: blink 1s steps(2) infinite;
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

.thinking {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 4px 0 var(--sp-4) 46px;
}

.thinking i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lime);
  opacity: .35;
  animation: think 1.3s var(--ease-io) infinite;
}

.thinking i:nth-child(2) {
  animation-delay: .18s;
}

.thinking i:nth-child(3) {
  animation-delay: .36s;
}

@keyframes think {

  0%,
  100% {
    opacity: .25;
    transform: translateY(0);
  }

  45% {
    opacity: 1;
    transform: translateY(-4px);
  }
}

.viz {
  display: block;
  margin-top: var(--sp-4);
}

.msg .txt {
  min-width: 0;
}

.console-foot {
  margin-top: auto;
  padding-top: var(--sp-4);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-family: var(--ff-mono);
  font-size: 11px;
  color: var(--ink-3);
  border-top: 1px solid var(--line-soft);
}

.console-foot .tools {
  color: var(--lime-2);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding: var(--sp-4) 18px 18px;
  border-top: 1px solid var(--line-soft);
}

.chip {
  font-size: 12px;
  font-weight: 500;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  color: var(--ink-3);
  border: 1px solid var(--line);
  background: var(--surface);
  transition: all var(--dur-2) var(--ease);
}

.chip:hover {
  color: var(--ink);
  border-color: rgba(168, 224, 74, .4);
  background: rgba(168, 224, 74, .07);
}

.chip[aria-current='true'] {
  color: var(--lime-2);
  border-color: rgba(168, 224, 74, .5);
  background: rgba(168, 224, 74, .11);
}

/* — Console viz blocks — */
.viz-panel {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: rgba(0, 0, 0, .28);
  overflow: hidden;
}

.viz-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--ff-mono);
  font-size: 10.5px;
  color: var(--ink-3);
}

.viz-map svg {
  width: 100%;
  height: 156px;
  background: linear-gradient(160deg, #070b14, #0b1220);
}

.route-line {
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.route-stop {
  transform-box: fill-box;
  transform-origin: center;
}

.viz-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  padding: 9px 12px;
  border-top: 1px solid var(--line-soft);
  font-family: var(--ff-mono);
  font-size: 10.5px;
  color: var(--ink-3);
}

.viz-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.viz-legend i {
  width: 7px;
  height: 7px;
  border-radius: 2px;
}

.viz-chart {
  padding: 12px;
}

.viz-chart .row {
  display: grid;
  grid-template-columns: 108px 1fr 52px;
  align-items: center;
  gap: 10px;
  margin-bottom: 9px;
  font-size: 12px;
}

.viz-chart .row:last-child {
  margin-bottom: 0;
}

.viz-chart .bar {
  height: 7px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .06);
  overflow: hidden;
}

.viz-chart .bar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--grad-ai);
  transition: width 1.1s var(--ease);
}

.viz-chart .val {
  text-align: right;
  font-family: var(--ff-mono);
  font-size: 11.5px;
  color: var(--ink);
}

.viz-confirm {
  padding: 12px;
}

.viz-confirm .ttl {
  font-family: var(--ff-mono);
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--warn);
  margin-bottom: 10px;
}

.viz-confirm .kv {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  font-size: 12.5px;
  color: var(--ink-3);
  border-bottom: 1px solid var(--line-soft);
}

.viz-confirm .kv b {
  color: var(--ink);
  font-weight: 500;
  text-align: right;
}

.viz-confirm .actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.viz-confirm .actions .btn {
  --btn-py: 8px;
  --btn-px: 15px;
  font-size: 12.5px;
}

.viz-table {
  overflow-x: auto;
}

.viz-table table {
  width: 100%;
  font-size: 12px;
  min-width: 340px;
}

.viz-table th {
  text-align: left;
  padding: 9px 12px;
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--line);
  font-weight: 500;
}

.viz-table td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-2);
}

.viz-table tr:last-child td {
  border-bottom: 0;
}

.badge {
  font-family: var(--ff-mono);
  font-size: 10px;
  padding: 2px 7px;
  border-radius: 4px;
}

.badge.ok {
  color: var(--ok);
  background: rgba(62, 207, 124, .13);
}

.badge.assumed {
  color: var(--warn);
  background: rgba(245, 193, 68, .13);
}

/* ------------------------------------------------------- PLATFORM WIRE-FLOW ---- */
/* A staggered "circuit" of three cards wired together by glowing elbows.
   Geometry per link lives in --x1/--x2/--h so the elbow, its glow and the
   travelling pulse all read from one source of truth.                      */
.wire {
  position: relative;
  display: block;
  /* Every pad, gap and rhythm below is a multiple of --u, so the whole
     diagram scales down on a short viewport instead of overflowing it. */
  --u: clamp(7.5px, 1.02vh, 11.5px);
}

.wire-card {
  position: relative;
  z-index: 1;
  padding: calc(var(--u) * 1.8);
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .014));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--sh-3), inset 0 1px 0 rgba(255, 255, 255, .07);
}

/* Stagger — card 2 pushed right, so the wires have somewhere to run */
.wire-card--1 {
  margin-right: 30%;
}

.wire-card--2 {
  margin-left: 30%;
}

.wire-card--3 {
  margin-right: 14%;
}

/* The wire "enters" the card: a gradient hairline lighting one corner */
.wire-card.is-lit::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background: linear-gradient(var(--lit, 135deg), var(--lime) 0%, rgba(168, 224, 74, .35) 18%, transparent 46%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
}

.wire-card--3.is-lit {
  --lit: 225deg;
}

/* — card internals — */
.wire-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: calc(var(--u) * -1.8) calc(var(--u) * -1.8) calc(var(--u) * 1.5);
  padding: calc(var(--u) * .95) calc(var(--u) * 1.25);
  border-bottom: 1px solid var(--line-soft);
}

.wire-chrome i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .16);
}

.wire-chrome i:nth-child(1) {
  background: #ff5f57;
}

.wire-chrome i:nth-child(2) {
  background: #febc2e;
}

.wire-chrome i:nth-child(3) {
  background: #28c840;
}

.wire-chrome span {
  flex: 1;
  height: calc(var(--u) * 1.4);
  margin-left: 8px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .045);
}

.wire-step {
  display: block;
  font-family: var(--ff-mono);
  font-size: clamp(9px, 1.12vh, 10.5px);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--lime-2);
  margin-bottom: calc(var(--u) * .55);
}

.wire-title {
  font-family: var(--ff-display);
  font-weight: 600;
  font-size: clamp(16px, min(1.6vw, 2.05vh), 23px);
  letter-spacing: -.025em;
  line-height: 1.2;
  color: var(--ink);
  margin-bottom: calc(var(--u) * .6);
}

.wire-copy {
  font-size: clamp(11.5px, 1.42vh, 13.5px);
  line-height: 1.55;
  color: var(--ink-2);
}

.wire-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: calc(var(--u) * 1.3);
  padding: calc(var(--u) * .85) calc(var(--u) * 1.15);
  border-radius: var(--r-sm);
  border: 1px solid var(--line-soft);
  background: rgba(0, 0, 0, .28);
  font-size: clamp(11px, 1.32vh, 12.5px);
  color: var(--ink-3);
}

.wire-row .mono {
  color: var(--lime-2);
  font-size: clamp(10.5px, 1.28vh, 12px);
}

/* Option rows — the "select" beat of the flow */
.wire-opts {
  display: grid;
  gap: calc(var(--u) * .7);
  margin-top: calc(var(--u) * 1.3);
}

.wire-opts li {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1.1);
  padding: calc(var(--u) * .92) calc(var(--u) * 1.25);
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: rgba(0, 0, 0, .22);
  font-size: clamp(12px, 1.52vh, 14px);
  color: var(--ink-2);
}

.wire-opts li svg {
  width: calc(var(--u) * 1.6);
  height: calc(var(--u) * 1.6);
  margin-left: auto;
  opacity: .5;
}

.wire-opts li.is-on {
  color: var(--ink);
  border-color: rgba(168, 224, 74, .55);
  background: rgba(168, 224, 74, .08);
  box-shadow: 0 0 0 1px rgba(168, 224, 74, .14), 0 10px 26px -14px rgba(168, 224, 74, .7);
}

.wire-opts li.is-on svg {
  opacity: 1;
  color: var(--lime-2);
}

.wire-radio {
  flex: none;
  position: relative;
  width: calc(var(--u) * 1.55);
  height: calc(var(--u) * 1.55);
  border-radius: 50%;
  border: 1.5px solid var(--line-hard);
}

.is-on .wire-radio {
  border-color: var(--lime);
}

.is-on .wire-radio::after {
  content: '';
  position: absolute;
  inset: 22%;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: 0 0 8px 1px rgba(168, 224, 74, .9);
}

.wire-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(var(--u) * .65);
  margin-top: calc(var(--u) * 1.5);
}

.wire-stats div {
  padding: calc(var(--u) * .92) calc(var(--u) * 1.05);
  border-radius: var(--r-sm);
  border: 1px solid var(--line-soft);
  background: rgba(0, 0, 0, .26);
}

.wire-stats b {
  display: block;
  font-family: var(--ff-display);
  font-size: clamp(13px, 1.72vh, 16px);
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
  line-height: 1.25;
}

.wire-stats span {
  font-family: var(--ff-mono);
  font-size: clamp(8.5px, 1.02vh, 9.5px);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ---- the wires ---- */
/* --drop extends the wire past the gap and down the next card's edge, so it
   terminates ON that card rather than bumping its top border. */
.wire-link {
  position: relative;
  height: calc(var(--u) * 5);
  --drop: calc(var(--u) * 4.4);
}

.wire-link--1 {
  --x1: 20%;
  --x2: 30%;
}

/* down at 20%, right into card 2's left edge */
.wire-link--2 {
  --x1: 86%;
  --x2: 93%;
}

/* down at 93%, left into card 3's right edge */

.wire-elbow,
.wire-track {
  position: absolute;
  top: 0;
  height: calc(100% + var(--drop));
  left: var(--x1);
  right: calc(100% - var(--x2));
}

.wire-elbow {
  border: 0 solid var(--lime);
  filter: drop-shadow(0 0 6px rgba(168, 224, 74, .65));
}

/* link 1: down the left, then right along the bottom */
.wire-link--1 .wire-elbow {
  border-left-width: 1.5px;
  border-bottom-width: 1.5px;
  border-bottom-left-radius: calc(var(--u) * 1.5);
}

/* link 2: down the right, then left along the bottom */
.wire-link--2 .wire-elbow {
  border-right-width: 1.5px;
  border-bottom-width: 1.5px;
  border-bottom-right-radius: calc(var(--u) * 1.5);
}

.wire-dot {
  position: absolute;
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: 0 0 12px 2px rgba(168, 224, 74, .85);
}

.wire-link--1 .wire-dot--a {
  left: var(--x1);
  top: 0;
}

.wire-link--1 .wire-dot--b {
  left: var(--x2);
  top: calc(100% + var(--drop));
}

.wire-link--2 .wire-dot--a {
  left: var(--x2);
  top: 0;
}

.wire-link--2 .wire-dot--b {
  left: var(--x1);
  top: calc(100% + var(--drop));
}

/* Travelling packet. Sibling of the elbow so the draw-in clip can't eat it. */
.wire-track {
  pointer-events: none;
}

.wire-pulse {
  position: absolute;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: #f4ffe2;
  box-shadow: 0 0 12px 3px rgba(168, 224, 74, .95);
  opacity: 0;
}

/* ---- draw-on, once the flow scrolls into view ---- */
.wire.in-view .wire-elbow {
  animation: elbowDraw .95s var(--ease) backwards;
}

.wire.in-view .wire-link--2 .wire-elbow {
  animation-delay: .5s;
}

@keyframes elbowDraw {
  0% {
    clip-path: inset(0 calc(100% - 3px) 100% 0);
  }

  55% {
    clip-path: inset(0 calc(100% - 3px) 0 0);
  }

  100% {
    clip-path: inset(0 0 0 0);
  }
}

/* link 2 draws right-to-left, so its clip must open from the other side */
@keyframes elbowDraw2 {
  0% {
    clip-path: inset(0 0 100% calc(100% - 3px));
  }

  55% {
    clip-path: inset(0 0 0 calc(100% - 3px));
  }

  100% {
    clip-path: inset(0 0 0 0);
  }
}

.wire.in-view .wire-link--2 .wire-elbow {
  animation-name: elbowDraw2;
}

.wire.in-view .wire-dot {
  animation: dotPop .4s var(--ease) backwards;
}

.wire.in-view .wire-link--1 .wire-dot--a {
  animation-delay: .05s;
}

.wire.in-view .wire-link--1 .wire-dot--b {
  animation-delay: .85s;
}

.wire.in-view .wire-link--2 .wire-dot--a {
  animation-delay: .55s;
}

.wire.in-view .wire-link--2 .wire-dot--b {
  animation-delay: 1.35s;
}

@keyframes dotPop {
  from {
    opacity: 0;
    transform: scale(.2);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

.wire.in-view .wire-link--1 .wire-pulse {
  animation: pulseRun1 3.6s var(--ease-io) 1.4s infinite;
}

.wire.in-view .wire-link--2 .wire-pulse {
  animation: pulseRun2 3.6s var(--ease-io) 2.2s infinite;
}

@keyframes pulseRun1 {
  0% {
    left: 0;
    top: 0;
    opacity: 0;
  }

  8% {
    opacity: 1;
  }

  46% {
    left: 0;
    top: 100%;
  }

  84% {
    left: 100%;
    top: 100%;
    opacity: 1;
  }

  92%,
  100% {
    left: 100%;
    top: 100%;
    opacity: 0;
  }
}

@keyframes pulseRun2 {
  0% {
    left: 100%;
    top: 0;
    opacity: 0;
  }

  8% {
    opacity: 1;
  }

  46% {
    left: 100%;
    top: 100%;
  }

  84% {
    left: 0;
    top: 100%;
    opacity: 1;
  }

  92%,
  100% {
    left: 0;
    top: 100%;
    opacity: 0;
  }
}

@media (max-width: 980px) {

  /* Stack straight down — the stagger has no room to read */
  .wire-card--1,
  .wire-card--2,
  .wire-card--3 {
    margin-inline: 0;
  }

  /* Stacked: cap the width so the diagram stays a readable column on a
     tablet instead of stretching edge to edge. */
  .wire { max-width: 620px; margin-inline: auto; }

  /* Stacked: no stagger to route around, so the wire is a straight drop */
  .wire-link {
    height: calc(var(--u) * 4.6);
    --drop: 0px;
  }

  .wire-link--1,
  .wire-link--2 {
    --x1: 50%;
    --x2: 50%;
  }
}

@media (max-width: 560px) {
  .wire-stats {
    grid-template-columns: 1fr 1fr;
  }

  .wire-stats div:last-child {
    grid-column: span 2;
  }
}

/* --------------------------------------------------------------- STATS --- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--line);
  overflow: hidden;
}

.stat {
  padding: var(--sp-6) var(--sp-5);
  background: var(--bg-1);
  text-align: center;
  transition: background var(--dur-2) var(--ease);
}

.stat:hover {
  background: var(--bg-2);
}

.stat .n {
  font-family: var(--ff-display);
  font-weight: 600;
  font-size: clamp(28px, 3vw, 40px);
  letter-spacing: -.03em;
  line-height: 1.1;
  background: var(--grad-ai);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.stat .n.is-text {
  font-size: clamp(15px, 1.5vw, 19px);
  letter-spacing: -.02em;
}

.stat .l {
  margin-top: 6px;
  font-family: var(--ff-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ====================================================== AZZY HERO STAGE ====
   ai.html only. index.html runs a split hero (copy left, console right); this
   centres the copy and makes the console the core of a stage, with live data
   panels branching off it. Same console component, deliberately different
   composition, so the two pages don't read as the same page twice.
   ========================================================================== */
.aihero-head {
  max-width: 880px;
  margin-inline: auto;
  text-align: center;
}

.aihero-head .lede {
  margin-inline: auto;
}

.aihero-head .hero-cta {
  justify-content: center;
}

.aihero-stage {
  --stub: clamp(14px, 2.2vw, 30px);
  margin-top: clamp(34px, 5vw, 60px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.62fr) minmax(0, 1fr);
  gap: var(--stub);
  align-items: center;
}

.aihero-rail {
  display: grid;
  gap: clamp(14px, 2vw, 22px);
  align-content: center;
}

/* --- a live data panel --- */
.aip {
  position: relative;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, .012));
  box-shadow: var(--sh-2), inset 0 1px 0 rgba(255, 255, 255, .06);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  padding: 12px 13px 13px;
  transition: border-color var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}

.aip:hover {
  border-color: rgba(79, 214, 232, .34);
  transform: translateY(-2px);
}

.aip-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--ff-mono);
  font-size: 9.5px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 9px;
}

.aip-h b {
  color: var(--ink-2);
  font-weight: 500;
  letter-spacing: .06em;
}

.aip-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-2);
  padding: 3px 0;
}

.aip-row .k {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.aip-row .v {
  font-family: var(--ff-mono);
  font-size: 11.5px;
  color: var(--ink);
  flex: none;
}

/* Meter track. The fill is a child so the width can be set inline per row. */
.aip-bar {
  height: 4px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .07);
  overflow: hidden;
  flex: 1.1;
}

.aip-bar i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--grad-ai);
}

.aip-bar.is-warn i {
  background: linear-gradient(90deg, #f5c144, #ff9f45);
}

.aip-big {
  font-family: var(--ff-display);
  font-weight: 600;
  font-size: clamp(19px, 1.7vw, 24px);
  letter-spacing: -.03em;
  background: var(--grad-ai);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.aip-sub {
  font-family: var(--ff-mono);
  font-size: 10.5px;
  color: var(--ink-3);
  margin-top: 2px;
}

.aip-live {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
  background: var(--ok);
  animation: live 2.2s var(--ease-io) infinite;
}

/* Connector stubs into the console. Deliberately static hairlines — the
   travelling-packet treatment belongs to the constellation on index.html. */
.aip::after,
.aip::before {
  content: '';
  position: absolute;
  top: 50%;
  pointer-events: none;
}

.aihero-rail--l .aip::after {
  left: 100%;
  width: var(--stub);
  height: 1px;
  background: linear-gradient(90deg, rgba(79, 214, 232, .6), rgba(79, 214, 232, 0));
}

.aihero-rail--l .aip::before {
  left: calc(100% - 3px);
  width: 5px;
  height: 5px;
  margin-top: -2px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 7px 1px rgba(79, 214, 232, .7);
}

.aihero-rail--r .aip::after {
  right: 100%;
  width: var(--stub);
  height: 1px;
  background: linear-gradient(270deg, rgba(168, 224, 74, .6), rgba(168, 224, 74, 0));
}

.aihero-rail--r .aip::before {
  right: calc(100% - 3px);
  width: 5px;
  height: 5px;
  margin-top: -2px;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: 0 0 7px 1px rgba(168, 224, 74, .7);
}

/* The console is the core here, so it gets a wider halo than on index */
.aihero-core {
  position: relative;
}

.aihero-core::before {
  content: '';
  position: absolute;
  inset: -8% -10%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(55% 55% at 50% 50%, rgba(79, 214, 232, .20), transparent 70%);
  filter: blur(44px);
}

.aihero-stage .hero-meta {
  margin-inline: auto;
}

@media (max-width: 1080px) {

  /* Rails drop below the core and pair up; the stubs would point at nothing. */
  .aihero-stage {
    grid-template-columns: 1fr;
  }

  .aihero-core {
    order: -1;
    max-width: 620px;
    margin-inline: auto;
    width: 100%;
  }

  .aihero-rail {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .aip::after,
  .aip::before {
    display: none;
  }
}

/* Phones: drop the meters so each panel is two short lines, and hold the 2-up
   grid. Four full-width panels under a 540px console pushed the hero ~400px
   past index.html's — too much scrolling before the page even starts. */
@media (max-width: 680px) {
  .aip {
    padding: 10px 11px 11px;
  }

  .aip-bar {
    display: none;
  }

  .aip-row {
    font-size: 11.5px;
    padding: 2px 0;
  }

  .aip-h {
    font-size: 9px;
    margin-bottom: 7px;
  }

  .aip-big {
    font-size: 17px;
  }
}

@media (max-width: 400px) {
  .aihero-rail {
    grid-template-columns: 1fr;
  }
}

/* -------------------------------------------------------- PAIN / PROOF --- */
.pain-card {
  display: flex;
  flex-direction: column;
}

.pain-stat {
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: clamp(34px, 4vw, 46px);
  letter-spacing: -.04em;
  line-height: 1;
  color: var(--danger);
  margin-bottom: var(--sp-4);
}

.pain-stat.warn {
  color: var(--warn);
}

.pain-stat.info {
  color: var(--info);
}

.pain-label {
  font-size: var(--fs-sm);
  color: var(--ink-2);
  margin-bottom: auto;
  padding-bottom: var(--sp-5);
}

.pain-fix {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 13px;
  color: var(--lime-2);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-soft);
}

.pain-fix .arw {
  flex: none;
}

/* ------------------------------------------------------------- MARQUEE --- */
.marquee {
  position: relative;
  overflow: hidden;
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 34s linear infinite;
}

.marquee:hover .marquee-track {
  animation-play-state: paused;
}

@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

.marquee-item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding-inline: clamp(20px, 3vw, 40px);
  font-family: var(--ff-display);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -.02em;
  color: var(--ink-3);
  white-space: nowrap;
  transition: color var(--dur-2) var(--ease);
}

.marquee-item:hover {
  color: var(--ink-2);
}

.marquee-item .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--lime);
  opacity: .5;
}

/* ------------------------------------------------------- DISPATCH MAP ---- */
/* Two panes: the map canvas, and a rail of the runs currently in motion.
   Everything is vector + DOM, so it stays crisp and costs no image bytes. */
.dispatch {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 304px;
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  overflow: hidden;
  background: linear-gradient(160deg, #070b14, #0a1120);
  box-shadow: var(--sh-3);
}

.dispatch-map {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  border-right: 1px solid var(--line);
  background:
    radial-gradient(90% 70% at 30% 20%, rgba(79, 214, 232, .07), transparent 60%),
    linear-gradient(160deg, #070b14, #0a1120);
}

/* Faint street grid under the drawn road network */
.dispatch-map::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, .028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .028) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(85% 85% at 50% 50%, #000, transparent);
  -webkit-mask-image: radial-gradient(85% 85% at 50% 50%, #000, transparent);
}

.dispatch-head {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 13px;
  border-radius: var(--r-pill);
  background: rgba(4, 6, 12, .72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--line);
  font-family: var(--ff-mono);
  font-size: 11px;
  color: var(--ink-2);
}

.dispatch-legend {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 5;
  display: flex;
  gap: 12px;
  padding: 7px 13px;
  border-radius: var(--r-pill);
  background: rgba(4, 6, 12, .72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--line);
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.dispatch-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.dispatch-legend i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c);
}

/* Status bar under both panes. Floating it over the map put it on top of the
   depot and the stop pins, so it lives outside the canvas instead. */
.dispatch-foot {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
  background: rgba(4, 6, 12, .5);
}

.dispatch-foot div {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 11px 20px;
  border-right: 1px solid var(--line-soft);
}

.dispatch-foot b {
  font-family: var(--ff-mono);
  font-size: 13px;
  color: var(--ink);
}

.dispatch-foot span {
  font-size: 9.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.dispatch-foot .warn b {
  color: var(--warn);
}

.dispatch-foot .upd {
  margin-left: auto;
  border-right: 0;
  font-family: var(--ff-mono);
  font-size: 10.5px;
  color: var(--ink-3);
}

.dispatch-map svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.dispatch-map svg.roads {
  z-index: 0;
}

.dispatch-map svg.routes {
  z-index: 1;
}

.roads .street {
  fill: none;
  stroke: rgba(255, 255, 255, .05);
  stroke-width: 5;
  stroke-linecap: round;
}

.roads .street.major {
  stroke: rgba(255, 255, 255, .075);
  stroke-width: 8;
}

.roads .water {
  fill: rgba(79, 214, 232, .045);
  stroke: rgba(79, 214, 232, .1);
  stroke-width: 1;
}

.roads .block {
  fill: rgba(255, 255, 255, .016);
}

/* Paths carry pathLength="1" so one dash value drives both the draw-on and
   the completed/remaining split. */
.dispatch-map svg.routes path {
  fill: none;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

/* Remaining leg: dotted and dim. Completed leg: lit, and stopped short at
   --o so the two together read as "12 of 18 stops done". */
.routes .rt-rest {
  opacity: .3;
  stroke-width: 2;
  stroke-dasharray: .012 .014 !important;
  stroke-dashoffset: 0 !important;
}

.routes .rt-done {
  filter: drop-shadow(0 0 6px currentColor);
}

.dispatch.in-view .rt-done {
  animation: draw 2.2s var(--ease) forwards;
}

.rt-done.d2 {
  animation-delay: .3s;
}

.rt-done.d3 {
  animation-delay: .6s;
}

@keyframes draw {
  to {
    stroke-dashoffset: var(--o, 0);
  }
}

/* A short lit dash that runs the length of the route — reads as movement
   without animating any layout. */
.routes .rt-live {
  stroke-width: 3.4;
  opacity: .9;
  stroke-dasharray: .05 .95 !important;
  filter: drop-shadow(0 0 7px currentColor);
  animation: comet 4.6s linear infinite;
}

.routes .rt-live.b {
  animation-duration: 6.2s;
  animation-delay: -2s;
}

@keyframes comet {
  from {
    stroke-dashoffset: 1;
  }

  to {
    stroke-dashoffset: 0;
  }
}

/* Hub, numbered stops, driver beacons — HTML so circles stay circular
   whatever the panel's aspect ratio does to the SVG. */
.hub,
.stop,
.beacon {
  position: absolute;
  z-index: 3;
  transform: translate(-50%, -50%);
}

.hub {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 9px;
  color: #08120a;
  background: var(--grad-ai);
  box-shadow: 0 0 18px -2px rgba(168, 224, 74, .7);
}

.hub svg {
  position: static;
  width: 14px;
  height: 14px;
}

.stop {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  font-family: var(--ff-mono);
  font-size: 9px;
  color: var(--c);
  background: rgba(4, 6, 12, .92);
  border: 1.5px solid var(--c);
}

.stop.done {
  color: #08120a;
  background: var(--c);
  border-color: transparent;
}

/* Named .exc, not .alert — .alert is the auth page's message component, and
   its padding inflates this pin into a rounded rectangle. */
.stop.exc {
  border-color: var(--warn);
  color: var(--warn);
  box-shadow: 0 0 12px -1px rgba(245, 193, 68, .6);
}

.beacon {
  z-index: 4;
}

.beacon b {
  display: block;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--bk);
  border: 2px solid rgba(4, 6, 12, .9);
  box-shadow: 0 0 14px 2px var(--bk);
}

.beacon i {
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1.5px solid var(--bk);
  opacity: 0;
  animation: ripple 2.6s var(--ease-out) infinite;
}

@keyframes ripple {
  0% {
    transform: scale(.5);
    opacity: .85;
  }

  100% {
    transform: scale(3.2);
    opacity: 0;
  }
}

/* ----------------------------------------------------------- RUN RAIL --- */
.dispatch-rail {
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, rgba(255, 255, 255, .022), transparent);
}

.rail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 16px;
  border-bottom: 1px solid var(--line-soft);
}

.rail-head h4 {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}

.rail-head span {
  font-family: var(--ff-mono);
  font-size: 10px;
  color: var(--ink-3);
}

.run {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--line-soft);
  transition: background var(--dur-2) var(--ease);
}

.run:hover {
  background: rgba(255, 255, 255, .03);
}

.run-av {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  font-family: var(--ff-display);
  font-size: 11.5px;
  font-weight: 700;
  color: #08120a;
  background: var(--c);
}

.run-name {
  font-size: 12.5px;
  color: var(--ink);
  font-weight: 500;
}

.run-meta {
  font-family: var(--ff-mono);
  font-size: 10px;
  color: var(--ink-3);
  margin-top: 1px;
}

.run-bar {
  height: 3px;
  margin-top: 7px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .08);
  overflow: hidden;
}

.run-bar i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--c);
  width: var(--p);
}

.run-chip {
  font-family: var(--ff-mono);
  font-size: 9px;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 4px 8px;
  border-radius: 5px;
  color: var(--ink-3);
  background: var(--surface);
}

.run-chip.ok {
  color: var(--ok);
  background: rgba(62, 207, 124, .13);
}

.run-chip.warn {
  color: var(--warn);
  background: rgba(245, 193, 68, .13);
}

.run-chip.info {
  color: var(--info);
  background: rgba(90, 181, 247, .13);
}

/* Azzy's read on the board — the AI thread the rest of the site promises */
.rail-azzy {
  margin-top: auto;
  padding: 14px 16px;
  border-top: 1px solid var(--line-soft);
  background: var(--grad-ai-soft);
}

.rail-azzy .l {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--ff-mono);
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--lime-2);
}

/* .spark is scoped to the nav, so the rail draws its own */
.rail-azzy .spark {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: 0 0 8px 1px rgba(168, 224, 74, .9);
  animation: pulse 2.4s var(--ease-io) infinite;
}

.rail-azzy p {
  margin-top: 7px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
}

.rail-azzy .act {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--lime-2);
}

.dpop {
  position: absolute;
  z-index: 4;
  width: 218px;
  transform: translate(14px, -112%);
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: rgba(9, 13, 22, .93);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--line-hard);
  box-shadow: var(--sh-3);
  font-size: 12px;
}

.dpop-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.dpop-pill {
  font-family: var(--ff-mono);
  font-size: 9.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 4px;
  color: var(--ok);
  background: rgba(62, 207, 124, .14);
}

.dpop-time {
  font-family: var(--ff-mono);
  font-size: 10.5px;
  color: var(--ink-3);
}

.dpop-awb {
  font-family: var(--ff-mono);
  font-size: 13px;
  color: var(--lime-2);
  margin-bottom: 2px;
}

.dpop-cust {
  color: var(--ink);
  font-weight: 600;
  font-size: 13px;
}

.dpop-sub {
  color: var(--ink-3);
  font-size: 11.5px;
  margin-bottom: 10px;
}

.dpop-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding-top: 9px;
  border-top: 1px solid var(--line-soft);
  font-size: 11px;
  color: var(--ink-3);
}

.dpop-foot b {
  color: var(--ink);
  font-family: var(--ff-mono);
}

.dpop-more {
  color: var(--lime-2);
  white-space: nowrap;
}

/* ------------------------------------------------------- DIRECTOR LOOP --- */
.director {
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  overflow: hidden;
  background: linear-gradient(180deg, rgba(18, 24, 38, .9), rgba(8, 11, 19, .94));
  box-shadow: var(--sh-3);
}

.director-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--ff-mono);
  font-size: 11.5px;
  color: var(--ink-3);
}

.director-head .timer {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--lime-2);
}

.director-row {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 13px 18px;
  font-size: 13px;
  color: var(--ink-2);
  border-bottom: 1px solid var(--line-soft);
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}

.director.in-view .director-row {
  opacity: 1;
  transform: none;
}

.director-row:last-child {
  border-bottom: 0;
}

.director-row b {
  color: var(--ink);
  font-weight: 600;
}

.ph {
  flex: none;
  margin-top: 1px;
  font-family: var(--ff-mono);
  font-size: 9.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 4px;
}

.ph.plan {
  color: var(--info);
  background: rgba(90, 181, 247, .14);
}

.ph.exec {
  color: var(--lime-2);
  background: rgba(168, 224, 74, .14);
}

.ph.verify {
  color: var(--ok);
  background: rgba(62, 207, 124, .14);
}

.ph.replan {
  color: var(--warn);
  background: rgba(245, 193, 68, .14);
}

/* --------------------------------------------------------------- TABS ---- */
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: var(--sp-6);
}

.tab {
  padding: 9px 17px;
  border-radius: var(--r-pill);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-3);
  border: 1px solid var(--line);
  background: var(--surface);
  transition: all var(--dur-2) var(--ease);
}

.tab:hover {
  color: var(--ink);
  border-color: var(--line-hard);
}

.tab[aria-selected='true'] {
  color: #08120a;
  background: var(--grad-ai);
  border-color: transparent;
  font-weight: 600;
  box-shadow: 0 8px 20px -8px rgba(168, 224, 74, .5);
}

.tabpanel[hidden] {
  display: none;
}

/* ------------------------------------------------------------ ACCORDION -- */
.faq {
  border-top: 1px solid var(--line);
}

.faq-item {
  border-bottom: 1px solid var(--line);
}

.faq-q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  padding: var(--sp-5) 0;
  text-align: left;
  font-family: var(--ff-display);
  font-size: clamp(16px, 1.4vw, 18.5px);
  font-weight: 500;
  letter-spacing: -.02em;
  color: var(--ink);
  transition: color var(--dur-2) var(--ease);
}

.faq-q:hover {
  color: var(--lime-2);
}

.faq-ico {
  flex: none;
  position: relative;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid var(--line-hard);
  transition: transform var(--dur-3) var(--ease), border-color var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}

.faq-ico::before,
.faq-ico::after {
  content: '';
  position: absolute;
  inset: 50% 7px auto 7px;
  height: 1.5px;
  border-radius: 2px;
  background: currentColor;
  transform: translateY(-50%);
  transition: transform var(--dur-3) var(--ease), opacity var(--dur-2) var(--ease);
}

.faq-ico::after {
  transform: translateY(-50%) rotate(90deg);
}

.faq-q[aria-expanded='true'] {
  color: var(--lime-2);
}

.faq-q[aria-expanded='true'] .faq-ico {
  border-color: rgba(168, 224, 74, .5);
  background: rgba(168, 224, 74, .1);
  transform: rotate(180deg);
}

.faq-q[aria-expanded='true'] .faq-ico::after {
  transform: translateY(-50%) rotate(0deg);
  opacity: 0;
}

.faq-a {
  overflow: hidden;
  height: 0;
  transition: height var(--dur-3) var(--ease);
}

.faq-a p {
  padding-bottom: var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--ink-2);
  max-width: 68ch;
}

/* -------------------------------------------------------------- PRICING -- */
/* Three headline plans at full scale, each one framed as "everything in the
   plan before, plus…". Enterprise rides underneath in a full-width rail so
   the trio keeps its presence instead of shrinking to a fourth column. */
.plans {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-5);
  align-items: stretch;
}

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 2.2vw, 34px);
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, .012));
  box-shadow: var(--sh-2), inset 0 1px 0 rgba(255, 255, 255, .05);
  transition: transform var(--dur-3) var(--ease), border-color var(--dur-3) var(--ease), box-shadow var(--dur-3) var(--ease);
}

.plan:hover {
  transform: translateY(-5px);
  border-color: rgba(168, 224, 74, .3);
  box-shadow: var(--sh-3);
}

.plan.featured {
  border-color: rgba(168, 224, 74, .55);
  background: linear-gradient(180deg, rgba(168, 224, 74, .075), rgba(79, 214, 232, .022));
  box-shadow: var(--sh-glow), var(--sh-3);
}

.plan-name {
  font-family: var(--ff-display);
  font-weight: 600;
  font-size: 20px;
  letter-spacing: -.02em;
  color: var(--lime-2);
}

.plan-price {
  margin-top: var(--sp-5);
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: clamp(36px, 3.4vw, 50px);
  line-height: 1;
  letter-spacing: -.045em;
  color: var(--ink);
}

.plan-price small {
  font-family: var(--ff-body);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-3);
}

.plan-cap {
  margin-top: var(--sp-4);
  font-size: 13px;
  color: var(--ink-2);
}

.plan-cap b {
  color: var(--lime-2);
  font-weight: 600;
}

.plan-rule {
  height: 1px;
  margin: var(--sp-5) 0;
  background: linear-gradient(90deg, var(--line-hard), transparent);
}

.plan-inc {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
}

.plan-list {
  display: grid;
  gap: 12px;
  margin-top: var(--sp-4);
}

.plan-list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13.5px;
  color: var(--ink-2);
}

/* Ringed tick — the mark that carries the whole page's rhythm */
.plan-list .ck,
.plan-wide .ck {
  flex: none;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  margin-top: 1px;
  border-radius: 50%;
  color: var(--lime-2);
  border: 1px solid rgba(168, 224, 74, .42);
  background: rgba(168, 224, 74, .09);
}

.plan-list .ck svg,
.plan-wide .ck svg {
  width: 11px;
  height: 11px;
}

.plan-wide .ck {
  width: 17px;
  height: 17px;
  margin-top: 0;
}

.plan-list .ai-feat {
  color: var(--lime-2);
  font-weight: 500;
}

.plan-foot {
  margin-top: auto;
  padding-top: var(--sp-6);
}

.plan-foot .btn {
  width: 100%;
}

.plan-most,
.plan:not(.featured) .plan-foot::after {
  display: block;
  width: fit-content;
  margin: var(--sp-4) auto 0;
  padding: 6px 16px;
  border-radius: var(--r-pill);
  font-family: var(--ff-mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--lime-2);
  background: rgba(168, 224, 74, .1);
  border: 1px solid rgba(168, 224, 74, .3);
}

/* The badge only exists on the featured card, so the others reserve an
   identical box — otherwise their buttons sit lower than its. Built from the
   same declarations, so the two can't drift apart. */
.plan:not(.featured) .plan-foot::after {
  content: 'Most chosen';
  visibility: hidden;
}

/* Enterprise rail */
.plan-wide {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-6);
  margin-top: var(--sp-5);
  padding: clamp(22px, 2vw, 30px) clamp(24px, 2.4vw, 34px);
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: linear-gradient(115deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .012) 60%);
  transition: border-color var(--dur-3) var(--ease);
}

.plan-wide:hover {
  border-color: rgba(168, 224, 74, .28);
}

.plan-wide .plan-price {
  margin-top: var(--sp-2);
  font-size: clamp(26px, 2.2vw, 32px);
}

.plan-wide ul {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 20px;
  margin-top: var(--sp-4);
}

.plan-wide li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-2);
}

/* Closing strip — icon, one line of intent, one action */
.cta-strip {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-5);
  margin-top: var(--sp-7);
  padding: clamp(20px, 2vw, 26px) clamp(22px, 2.4vw, 32px);
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: linear-gradient(115deg, rgba(168, 224, 74, .08), rgba(255, 255, 255, .02) 58%);
}

.cta-strip .ico {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  color: #08120a;
  background: var(--grad-ai);
  box-shadow: 0 12px 30px -12px rgba(168, 224, 74, .7);
}

.cta-strip .ico svg {
  width: 24px;
  height: 24px;
}

.cta-strip h3 {
  font-family: var(--ff-display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
}

.cta-strip p {
  margin-top: 3px;
  font-size: 13.5px;
  color: var(--ink-3);
}

/* Dotted field — corner texture, purely decorative */
.deco-dots {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  width: 140px;
  height: 140px;
  background-image: radial-gradient(rgba(168, 224, 74, .55) 1.6px, transparent 1.7px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(70% 70% at 50% 50%, #000, transparent 76%);
  mask-image: radial-gradient(70% 70% at 50% 50%, #000, transparent 76%);
}

.deco-dots.tr {
  top: 26%;
  right: 3%;
}

.deco-dots.bl {
  bottom: 6%;
  left: 2.5%;
}

.price-list {
  margin: var(--sp-5) 0 var(--sp-6);
  display: grid;
  gap: 11px;
}

.price-list li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 13.5px;
  color: var(--ink-2);
}

.price-list .ck {
  flex: none;
  color: var(--lime-2);
  margin-top: 2px;
}

/* Billing period toggle */
.billing {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--surface);
}

.billing button {
  padding: 8px 18px;
  border-radius: var(--r-pill);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-3);
  transition: color var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}

.billing button:hover {
  color: var(--ink);
}

.billing button[aria-pressed='true'] {
  color: #08120a;
  background: var(--grad-ai);
  box-shadow: 0 6px 16px -8px rgba(168, 224, 74, .6);
}

.save-pill {
  display: inline-block;
  margin-left: 10px;
  font-family: var(--ff-mono);
  font-size: 11px;
  color: var(--lime-2);
  background: rgba(168, 224, 74, .09);
  border: 1px solid rgba(168, 224, 74, .24);
  padding: 4px 10px;
  border-radius: var(--r-pill);
}

/* --------------------------------------------------------------- FORM ---- */
.form {
  padding: var(--sp-6);
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 255, 255, .04), rgba(255, 255, 255, .012));
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: var(--sh-2);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-bottom: var(--sp-4);
}

.field label {
  font-family: var(--ff-mono);
  font-size: 10.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  font-family: var(--ff-body);
  font-size: var(--fs-sm);
  color: var(--ink);
  background: rgba(0, 0, 0, .3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  transition: border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}

.field textarea {
  resize: vertical;
  min-height: 118px;
  line-height: 1.6;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--ink-3);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: rgba(168, 224, 74, .6);
  box-shadow: 0 0 0 3px var(--glow);
  background: rgba(0, 0, 0, .45);
}

.field select {
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%237c8798' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}

.field select option {
  background: #0a0e18;
  color: var(--ink);
}

.form-note {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: var(--sp-4);
  text-align: center;
}

.contact-line {
  font-size: var(--fs-sm);
  color: var(--ink-2);
}

.contact-line .lbl {
  display: block;
  margin-bottom: 5px;
  font-family: var(--ff-mono);
  font-size: 10.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.contact-line a {
  color: var(--lime-2);
}

.contact-line a:hover {
  text-decoration: underline;
}

/* ----------------------------------------------------------- CTA BAND ---- */
.cta-band {
  position: relative;
  padding: clamp(48px, 6vw, 80px) clamp(24px, 4vw, 56px);
  border-radius: var(--r-xl);
  border: 1px solid rgba(168, 224, 74, .22);
  text-align: center;
  overflow: hidden;
  background:
    radial-gradient(90% 130% at 50% 0%, rgba(168, 224, 74, .14), transparent 62%),
    radial-gradient(70% 100% at 88% 100%, rgba(79, 214, 232, .1), transparent 60%),
    linear-gradient(180deg, rgba(16, 21, 33, .9), rgba(6, 9, 16, .9));
  box-shadow: var(--sh-3);
}

.cta-band::before {
  content: '';
  position: absolute;
  top: 0;
  left: 15%;
  right: 15%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--lime), transparent);
}

.cta-band .h2 {
  margin-inline: auto;
  margin-bottom: var(--sp-4);
  max-width: 18ch;
}

.cta-band .lede {
  margin-inline: auto;
  margin-bottom: var(--sp-6);
  max-width: 52ch;
}

.cta-band .hero-cta {
  justify-content: center;
}

/* --------------------------------------------------------------- FOOTER -- */
.footer {
  padding-block: var(--sp-9) var(--sp-6);
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .4));
}

.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--sp-7) var(--sp-5);
  padding-bottom: var(--sp-8);
}

.footer h4 {
  font-family: var(--ff-mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 500;
  margin-bottom: var(--sp-4);
}

.footer ul {
  display: grid;
  gap: 11px;
}

.footer ul a {
  font-size: var(--fs-sm);
  color: var(--ink-2);
  transition: color var(--dur-2) var(--ease);
}

.footer ul a:hover {
  color: var(--lime-2);
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--line-soft);
  font-size: 12.5px;
  color: var(--ink-3);
}

.footer-bottom .mono {
  color: var(--ink-3);
}

/* -------------------------------------------------------- UI MOCKUPS ---- */
/* Vector product shots, built from markup — crisp at any DPI, ~0 bytes,
   and they never 404 the way a screenshot file can.                       */
.mock {
  display: flex;
  flex-direction: column;
  aspect-ratio: 16 / 10;
  /* fixes heading alignment across a row */
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: linear-gradient(160deg, #080c15, #0b1120);
  overflow: hidden;
  margin-bottom: var(--sp-5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
}

.mock-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
}

.mock-bar i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .13);
}

.mock-bar span {
  margin-left: auto;
  font-family: var(--ff-mono);
  font-size: 9px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mock-body {
  flex: 1;
  min-height: 0;
  padding: 12px;
  display: grid;
  gap: 9px;
  align-content: start;
  overflow: hidden;
}

/* Wide bento tiles get a banner-proportioned mock instead of a tall one */
.bento>.is-hero .mock,
.bento>.is-full .mock {
  aspect-ratio: 3.4 / 1;
}

.mock-kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 7px;
}

.mock-kpi {
  padding: 9px 10px;
  border-radius: 8px;
  background: rgba(255, 255, 255, .028);
  border: 1px solid var(--line-soft);
}

.mock-kpi b {
  display: block;
  font-family: var(--ff-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ink);
  line-height: 1.2;
}

.mock-kpi span {
  font-family: var(--ff-mono);
  font-size: 8.5px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mock-rows {
  display: grid;
  gap: 5px;
}

.mock-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .02);
  font-size: 10.5px;
  color: var(--ink-3);
}

.mock-row .mono {
  font-size: 9.5px;
  color: var(--ink-2);
}

.mock-pill {
  font-family: var(--ff-mono);
  font-size: 8.5px;
  letter-spacing: .05em;
  padding: 2px 7px;
  border-radius: 4px;
  white-space: nowrap;
}

.mock-pill.ok {
  color: var(--ok);
  background: rgba(62, 207, 124, .14);
}

.mock-pill.warn {
  color: var(--warn);
  background: rgba(245, 193, 68, .14);
}

.mock-pill.info {
  color: var(--info);
  background: rgba(90, 181, 247, .14);
}

.mock-spark {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 46px;
  padding-top: 4px;
}

.mock-spark i {
  flex: 1;
  border-radius: 2px 2px 0 0;
  background: var(--grad-ai);
  opacity: .75;
}

/* -------------------------------------------------- CONSTELLATION ------- */
/* Hub-and-spoke map: one AI core wired to the capabilities it drives.
   The board is a square viewBox (1000×1000) so the SVG connectors and the
   HTML nodes share one coordinate space — nodes are placed in % of the same
   square, which keeps every line landing on an edge at any width. */
/* Fit-to-screen shell: the section claims exactly one viewport, the head
   takes what its text needs, and the board is handed whatever is left — so
   the map is never sliced in half by the fold on a laptop. */
.section--screen {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100svh;
  /* Asymmetric on purpose: the nav is sticky, so the top var(--nav-h) of any
     full-screen section is permanently spoken for. Reserving it is what makes
     the remaining band — the part actually visible — read as centred. */
  padding-block: calc(var(--nav-h) + clamp(14px, 2.4vh, 44px)) clamp(14px, 2.4vh, 44px);
}

.section--screen>.wrap {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  /* auto would floor the column at its content height and push the board
     back past the fold; 0 lets the stage below actually give ground. */
  min-height: 0;
}

.section--screen .section-head {
  flex: none;
  margin-bottom: clamp(12px, 2.2vh, 30px);
}

/* The board's leftover box. container-type:size publishes this height as
   cqh, which is what lets the square below size off height with no magic
   constant. max-height can't do that job: it clamps the box but not the
   ratio, so the SVG would letterbox and every %-placed node would drift
   off the end of its connector. */
.constel-stage {
  /* Basis 0, not auto: an auto basis would make this box's height depend on
     the board, and the board's width depends on this box's height — Chrome
     spots the cycle and hands back 0cqh, collapsing the map entirely. */
  flex: 1 1 0;
  /* Below this the labels stop being readable, so a very short window grows
     the section past the fold rather than crushing the map. It also caps how
     small 100cqh can get, which keeps the board from spilling out. */
  min-height: 320px;
  container-type: size;
  display: grid;
  place-items: center;
}

.constel {
  position: relative;
  width: 100%;
  max-width: 880px;
  /* Height-aware square: never wider than the stage is tall. Browsers with no
     cqh support simply drop this line and keep the pair above. */
  width: min(100%, 880px, 100cqh);
  margin-inline: auto;
  aspect-ratio: 1 / 1;
  container-type: inline-size;
}

/* Short-and-wide screens: stacking starves the board of the one axis it
   cares about. Set the head alongside instead — the section still ends at
   the fold, but the map keeps most of its size. The stage stays stretched
   rather than centred, because container-type:size needs a height that comes
   from the row, not from its own contents. */
@media (min-width: 1000px) and (max-height: 900px) {
  .section--screen>.wrap {
    flex-direction: row;
    gap: clamp(28px, 4vw, 72px);
  }

  .section--screen .section-head {
    flex: 0 1 38%;
    align-self: center;
    max-width: none;
    margin-bottom: 0;
    margin-inline: 0;
    text-align: left;
  }

  .section--screen .section-head .lede {
    margin-inline: 0;
  }

  .constel-stage {
    flex: 1 1 62%;
    min-width: 0;
  }
}

.constel-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Only one board is ever live; the media query below swaps them. */
.constel-svg--tall {
  display: none;
}

/* Stroke widths are in user units: the board only renders between ~640px and
   880px wide, so the 0.64–0.88 scale keeps these visually stable. */
.constel-line {
  fill: none;
  stroke: rgba(255, 255, 255, .12);
  stroke-width: 1.8;
}

/* Travelling packet. pathLength=1000 normalises every spoke, so one dash
   pattern and one duration read identically on a long and a short run. */
.constel-pulse {
  fill: none;
  stroke: var(--cyan);
  stroke-width: 3.4;
  stroke-linecap: round;
  stroke-dasharray: 58 942;
  filter: drop-shadow(0 0 5px rgba(79, 214, 232, .85));
  animation: constelFlow 4.4s linear infinite;
  /* Deliberately not --d: the reveal stagger owns that name and would
     inherit its own value down into these paths. */
  animation-delay: var(--pd, 0s);
}

.constel-pulse.is-lime {
  stroke: var(--lime);
  filter: drop-shadow(0 0 5px rgba(168, 224, 74, .8));
}

@keyframes constelFlow {
  from {
    stroke-dashoffset: 0;
  }

  to {
    stroke-dashoffset: -1000;
  }
}

/* --- node --- */
.cn {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  width: 15.5%;
  display: block;
}

/* Ambient halo — sits behind the tile inside the node's own stacking context */
.cn::after {
  content: '';
  position: absolute;
  inset: -34%;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(79, 214, 232, .22), transparent 64%);
  filter: blur(16px);
  opacity: .9;
  transition: opacity var(--dur-3) var(--ease);
  pointer-events: none;
}

.cn-box {
  position: relative;
  aspect-ratio: 1 / 1;
  display: grid;
  place-items: center;
  border-radius: 20%;
  background: linear-gradient(168deg, #0b1019 0%, #05070d 100%);
  box-shadow: var(--sh-3), inset 0 1px 0 rgba(255, 255, 255, .05);
  transition: transform var(--dur-3) var(--ease), box-shadow var(--dur-3) var(--ease);
}

/* Gradient hairline drawn as a masked ring so the radius stays exact */
.cn-box::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: linear-gradient(200deg, rgba(139, 124, 246, .95), rgba(79, 214, 232, .9) 52%, rgba(168, 224, 74, .95));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.cn-box svg {
  width: 46%;
  height: 46%;
  color: var(--ink);
}

.cn-label {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  text-align: center;
  font-family: var(--ff-display);
  font-weight: 500;
  font-size: 13px;
  font-size: clamp(11px, 1.85cqw, 15px);
  line-height: 1.3;
  letter-spacing: -.012em;
  color: var(--ink-2);
  transition: color var(--dur-2) var(--ease);
}

.cn-label b {
  display: block;
  font-family: var(--ff-mono);
  font-weight: 400;
  font-size: clamp(8.5px, 1.3cqw, 11px);
  letter-spacing: .04em;
  color: var(--ink-3);
  margin-top: 3px;
}

/* --- core --- */
.cn.is-core {
  width: 21%;
}

.cn.is-core::after {
  inset: -40%;
  background: radial-gradient(circle, rgba(168, 224, 74, .24), rgba(79, 214, 232, .14) 45%, transparent 66%);
}

.cn.is-core .cn-box {
  border-radius: 18%;
}

.cn.is-core .cn-box::before {
  padding: 2px;
  background: linear-gradient(200deg, rgba(139, 124, 246, 1), rgba(79, 214, 232, 1) 46%, rgba(201, 247, 126, 1));
}

/* Breathing ring — the only element that says "this one is alive" */
.cn.is-core .cn-box::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 0 rgba(168, 224, 74, .35);
  animation: constelBreathe 3.4s var(--ease-io) infinite;
  pointer-events: none;
}

@keyframes constelBreathe {

  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(168, 224, 74, .34);
  }

  60% {
    box-shadow: 0 0 0 14px rgba(168, 224, 74, 0);
  }
}

.cn.is-core .cn-label {
  top: auto;
  bottom: calc(100% + 16px);
  font-size: clamp(13px, 2.3cqw, 19px);
  font-weight: 600;
  color: var(--ink);
}

.cn.is-core .cn-label b {
  font-size: clamp(9px, 1.4cqw, 11.5px);
  color: var(--lime-2);
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* --- interaction --- */
.cn:hover .cn-box,
.cn:focus-visible .cn-box {
  transform: translateY(-5px);
}

.cn:hover::after,
.cn:focus-visible::after {
  opacity: 1;
  filter: blur(20px);
}

.cn:hover .cn-label {
  color: var(--ink);
}

.cn:focus-visible {
  outline: none;
}

.cn:focus-visible .cn-box {
  box-shadow: var(--sh-3), 0 0 0 2px var(--lime-2);
}

/* ------------------------------------------------------ BLOOM PANEL ----- */
/* Dark stage that holds the step cards. Its own near-black keeps the cards'
   blooms reading as light sources rather than as flat colour fills. */
.flow-panel {
  position: relative;
  padding: clamp(24px, 3.2vw, 46px);
  border-radius: var(--r-xl);
  border: 1px solid var(--line-soft);
  background:
    radial-gradient(120% 80% at 50% -8%, rgba(255, 255, 255, .05), transparent 58%),
    #020407;
  box-shadow: var(--sh-3), inset 0 1px 0 rgba(255, 255, 255, .05);
  overflow: hidden;
}

.flow-panel>.h2 {
  margin-bottom: clamp(22px, 2.6vw, 38px);
}

.flow-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.5vw, 20px);
}

.flow-card {
  display: flex;
  flex-direction: column;
  min-height: clamp(300px, 30vw, 400px);
  padding: clamp(20px, 2vw, 28px);
  border-radius: var(--r-lg);
  border-color: var(--line-soft);
  background: linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .008));
}

/* The bloom. One rule serves every card — placement, size and hue come from
   per-card custom properties, so a new variant is three numbers, not a class. */
.flow-card .bloom {
  position: absolute;
  left: var(--bx, 50%);
  top: var(--by, 100%);
  width: var(--bs, 118%);
  aspect-ratio: 1 / 1.1;
  z-index: 0;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(closest-side,
      rgba(201, 247, 126, .92), rgba(79, 214, 232, .72) 46%,
      rgba(139, 124, 246, .28) 72%, transparent 84%);
  filter: blur(34px);
  opacity: .95;
  pointer-events: none;
  transition: transform var(--dur-4) var(--ease), opacity var(--dur-4) var(--ease);
}

/* Light scrim only. The heavy lifting for legibility is the text-shadow on
   the copy below, which darkens exactly where glyphs are instead of flattening
   the whole lower half of the card and erasing the bloom with it. */
.flow-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background: linear-gradient(0deg, rgba(3, 5, 10, .46) 0%, rgba(3, 5, 10, .18) 44%, transparent 72%);
  pointer-events: none;
}

.flow-card:hover .bloom {
  transform: translate(-50%, -50%) scale(1.16);
  opacity: 1;
}

.flow-ico {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  color: var(--ink);
  background: radial-gradient(circle at 32% 26%, rgba(255, 255, 255, .16), rgba(255, 255, 255, .03));
  border: 1px solid rgba(255, 255, 255, .22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2), 0 8px 22px -12px #000;
  transition: transform var(--dur-3) var(--ease), border-color var(--dur-3) var(--ease);
}

.flow-ico svg {
  width: 22px;
  height: 22px;
}

.card:hover .flow-ico {
  transform: translateY(-2px) scale(1.06);
  border-color: rgba(255, 255, 255, .42);
}

/* Fixed offset, not margin-top:auto — bottom-anchoring would let a card with
   one extra line of body copy drag its "Step n" out of line with the others. */
.flow-body {
  position: relative;
  z-index: 1;
  margin-top: clamp(56px, 8vw, 106px);
}

.flow-n {
  font-family: var(--ff-display);
  font-size: clamp(27px, 2.7vw, 38px);
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: 1;
  color: #fff;
}

.flow-card .h3 {
  margin: 10px 0 8px;
}

.flow-card p {
  color: var(--ink-2);
}

/* Per-glyph scrim — keeps the copy readable where it crosses the bloom */
.flow-n,
.flow-card .h3,
.flow-card p {
  text-shadow: 0 1px 14px rgba(2, 4, 9, .92), 0 0 4px rgba(2, 4, 9, .7);
}

/* ------------------------------------------------------- SHOWCASE ------- */
.showcase {
  align-items: center;
}

.bar-list {
  display: grid;
  gap: var(--sp-5);
  margin-top: var(--sp-6);
}

.bar-list li {
  position: relative;
  padding-left: 24px;
}

/* Glowing rule — the lit edge is the whole point, so it gets a real bloom */
.bar-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 3px;
  bottom: 3px;
  width: 4px;
  border-radius: 4px;
  background: linear-gradient(180deg, var(--cyan), var(--lime));
  box-shadow: 0 0 12px rgba(79, 214, 232, .8), 0 0 30px rgba(168, 224, 74, .35);
}

.bar-list p {
  font-size: var(--fs-sm);
  line-height: 1.7;
  color: var(--ink-2);
}

.bar-list b {
  color: var(--ink);
}

/* --- tilted product shot --- */
.showcase-visual {
  position: relative;
  perspective: 1500px;
}

.dash {
  position: relative;
  z-index: 1;
  padding: clamp(14px, 1.5vw, 20px);
  border-radius: var(--r-lg);
  border: 1px solid rgba(255, 255, 255, .13);
  background: linear-gradient(168deg, #0c1220 0%, #05070d 100%);
  box-shadow:
    0 40px 90px -34px #000,
    0 0 46px -12px rgba(79, 214, 232, .42),
    inset 0 1px 0 rgba(255, 255, 255, .08);
  transform: rotateY(-15deg) rotateX(7deg) rotate(-1.5deg);
  transform-origin: 50% 50%;
  transition: transform 1s var(--ease), box-shadow 1s var(--ease);
}

.showcase-visual:hover .dash {
  transform: rotateY(-6deg) rotateX(2deg) rotate(0deg);
  box-shadow: 0 44px 96px -34px #000, 0 0 62px -10px rgba(79, 214, 232, .6), inset 0 1px 0 rgba(255, 255, 255, .1);
}

/* Second screen, parked behind and further away — depth without an image.
   Sized to its own contents: a wide, half-empty panel stops reading as a
   card behind the dashboard and starts reading as a stray background shape. */
.dash-back {
  position: absolute;
  /* translateZ pulls this toward the perspective origin as well as back, so
     it lands lower than `top` alone implies — hence the extra lift here. */
  right: -4%;
  top: -31%;
  width: 50%;
  z-index: 0;
  padding: 13px 15px 11px;
  border-radius: var(--r-md);
  border: 1px solid rgba(255, 255, 255, .11);
  background: linear-gradient(168deg, #101a2c, #06090f);
  box-shadow: 0 26px 58px -26px #000, inset 0 1px 0 rgba(255, 255, 255, .07);
  /* Same orientation as the front panel, pushed back in z so the shared
     perspective does the shrinking rather than a hand-picked scale. */
  transform: rotateY(-15deg) rotateX(7deg) rotate(-1.5deg) translateZ(-60px);
  opacity: .92;
  transition: transform 1s var(--ease);
  pointer-events: none;
}

/* Both panels straighten together — one turning without the other reads broken */
.showcase-visual:hover .dash-back {
  transform: rotateY(-6deg) rotateX(2deg) rotate(0deg) translateZ(-60px);
}

.dash-back .db-lbl {
  display: block;
  font-family: var(--ff-mono);
  font-size: 8.5px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 5px;
}

.dash-back .db-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 2px;
}

.dash-back .db-n {
  font-family: var(--ff-display);
  font-size: 19px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -.03em;
}

.dash-back .db-d {
  font-family: var(--ff-mono);
  font-size: 9.5px;
  color: var(--ok);
}

.dash-back svg {
  width: 100%;
  height: 40px;
}

.dash-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: 12px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--line-soft);
}

.dash-title {
  font-size: clamp(15px, 1.3vw, 18px);
  margin-bottom: 14px;
}

.dash-kpis {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}

.dash-kpi {
  padding: 12px 14px;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .03);
  border: 1px solid var(--line-soft);
}

.dash-kpi .k {
  display: block;
  font-size: 10.5px;
  color: var(--ink-3);
  margin-bottom: 4px;
}

.dash-kpi b {
  font-family: var(--ff-display);
  font-size: clamp(17px, 1.6vw, 22px);
  letter-spacing: -.03em;
  margin-right: 7px;
}

.dash-kpi .delta {
  font-family: var(--ff-mono);
  font-size: 10px;
  color: var(--ok);
}

.dash-kpi .sub {
  display: block;
  font-size: 9.5px;
  color: var(--ink-3);
  margin-top: 4px;
}

.dash-chart {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 8px;
}

.dash-y {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  font-family: var(--ff-mono);
  font-size: 8.5px;
  color: var(--ink-3);
  text-align: right;
  padding-bottom: 16px;
}

.dash-plot {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: clamp(6px, .8vw, 12px);
  height: clamp(120px, 13vw, 168px);
  /* Gridlines drawn by the background so no extra elements are needed */
  background-image: linear-gradient(rgba(255, 255, 255, .055) 1px, transparent 1px);
  background-size: 100% 25%;
  background-position: 0 -1px;
  padding-bottom: 16px;
}

.dcol {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 3px;
}

.dcol i {
  width: clamp(7px, .8vw, 11px);
  border-radius: 3px;
  height: 0;
  transition: height .62s var(--ease);
  /* 14 bars, so the per-bar step has to stay small — at 70ms the last pair
     was still climbing 1.8s in, long enough to be read as a broken chart. */
  transition-delay: calc(var(--i, 0) * 38ms);
}

.dcol .up {
  background: linear-gradient(180deg, var(--lime-2), var(--lime-deep));
  box-shadow: 0 0 12px -3px rgba(168, 224, 74, .7);
}

.dcol .down {
  background: linear-gradient(180deg, var(--warn), #a97c14);
}

.dash[data-inview].in-view .dcol i {
  height: var(--h, 0%);
}

.dcol span {
  position: absolute;
  bottom: -16px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--ff-mono);
  font-size: 8.5px;
  color: var(--ink-3);
}

.dash-legend {
  display: flex;
  gap: 16px;
  justify-content: flex-end;
  margin-top: 12px;
  font-family: var(--ff-mono);
  font-size: 9px;
  color: var(--ink-3);
}

.dash-legend .lg {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.dash-legend .lg::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 2px;
}

.dash-legend .ok::before {
  background: var(--lime);
}

.dash-legend .warn::before {
  background: var(--warn);
}

/* ------------------------------------------------------- CTA GLOW ------- */
/* Same job as .cta-band, but lit from the bottom edge and it captures an
   email. .cta-band stays as-is — the other pages still use it. */
.cta-glow {
  position: relative;
  padding: clamp(38px, 5vw, 68px) clamp(24px, 4vw, 56px) clamp(40px, 5vw, 66px);
  border-radius: var(--r-xl);
  text-align: center;
  background: linear-gradient(180deg, rgba(19, 25, 38, .92), rgba(6, 9, 16, .96));
  box-shadow: var(--sh-3);
}

/* Ring that brightens toward the bottom, plus a bloom spilling below it */
.cta-glow::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .1) 34%, rgba(79, 214, 232, .85) 82%, var(--lime-2) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* Bloom under the card. The gradient cores sit at ~42% of this box so the
   brightest point lands on the card's bottom edge, not below it. */
.cta-glow::after {
  content: '';
  position: absolute;
  left: 7%;
  right: 7%;
  bottom: -26px;
  height: 62px;
  z-index: -1;
  background:
    radial-gradient(48% 44% at 50% 42%, rgba(214, 248, 255, .6), transparent 70%),
    radial-gradient(72% 64% at 50% 44%, rgba(79, 214, 232, .82), rgba(168, 224, 74, .42) 52%, transparent 78%);
  filter: blur(17px);
  pointer-events: none;
}

.cta-glow .h2 {
  margin-inline: auto;
  max-width: 20ch;
  margin-bottom: var(--sp-4);
}

.cta-glow .lede {
  margin-inline: auto;
  max-width: 46ch;
  margin-bottom: var(--sp-6);
}

/* Inline capture — one pill, input and button share the shell */
.capture {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  max-width: 560px;
  margin-inline: auto;
}

.capture input {
  flex: 1 1 260px;
  min-width: 0;
  font-family: var(--ff-body);
  font-size: var(--fs-sm);
  color: var(--ink);
  background: rgba(0, 0, 0, .45);
  border: 1px solid var(--line-hard);
  border-radius: var(--r-pill);
  padding: 13px 20px;
  transition: border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease);
}

.capture input::placeholder {
  color: var(--ink-3);
}

.capture input:focus {
  outline: none;
  border-color: rgba(168, 224, 74, .65);
  box-shadow: 0 0 0 3px var(--glow);
}

.capture .btn {
  flex: 0 0 auto;
  --btn-py: 13px;
  --btn-px: 26px;
}

.capture-note {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: var(--sp-4);
}

.capture-note a {
  color: var(--lime-2);
}

.capture-note a:hover {
  text-decoration: underline;
}

/* ------------------------------------------------------- SCROLL REVEAL --- */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .75s var(--ease-out), transform .75s var(--ease-out);
  transition-delay: var(--d, 0ms);
  will-change: opacity, transform;
}

.reveal.in {
  opacity: 1;
  transform: none;
}

.reveal-l {
  transform: translateX(-28px);
}

.reveal-r {
  transform: translateX(28px);
}

.reveal-s {
  transform: translateY(14px) scale(.97);
}

/* ------------------------------------------------------------ UTILITIES -- */
.mt-4 {
  margin-top: var(--sp-4);
}

.mt-5 {
  margin-top: var(--sp-5);
}

.mt-6 {
  margin-top: var(--sp-6);
}

.mt-7 {
  margin-top: var(--sp-7);
}

.mb-5 {
  margin-bottom: var(--sp-5);
}

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

.split {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

.stack-5 {
  display: grid;
  gap: var(--sp-5);
}

.flow>*+* {
  margin-top: var(--sp-4);
}

/* --------------------------------------------------------- RESPONSIVE ---- */
@media (max-width: 1080px) {

  .bento>.card,
  .bento>.card.is-wide {
    grid-column: span 3;
  }

  .bento>.card.is-hero {
    grid-column: span 6;
  }

  /* Two-up, and the featured plan leads so it is never the orphan row */
  .plans {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .plans .featured {
    order: -1;
  }

  .plan-wide,
  .cta-strip {
    grid-template-columns: 1fr;
    text-align: center;
    justify-items: center;
  }

  .plan-wide .plan-price,
  .plan-wide ul {
    justify-content: center;
  }

  .plan-wide .btn,
  .cta-strip .btn {
    width: 100%;
    max-width: 320px;
  }
}

@media (max-width: 980px) {
  :root {
    --nav-h: 62px;
  }

  .nav-links {
    display: none;
  }

  .nav-ask {
    display: none;
  }

  .nav-cta .btn-ghost {
    display: none;
  }

  .burger {
    display: inline-flex;
  }

  .hero-grid,
  .split {
    grid-template-columns: 1fr;
  }

  .hero-grid {
    gap: var(--sp-7);
  }

  /* Rail drops under the map and the runs sit two-up */
  .dispatch {
    grid-template-columns: 1fr;
  }

  .dispatch-map {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .dispatch-rail {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .rail-head,
  .rail-azzy {
    grid-column: 1 / -1;
  }

  .run:nth-child(even) {
    border-left: 1px solid var(--line-soft);
  }

  .hero-mesh {
    background-size: 48px 48px;
    opacity: .4;
  }

  .hero-scroll {
    display: none;
  }

  .grid-3,
  .grid-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .footer-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .console-body {
    min-height: 360px;
  }

  .flow-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Stacked under the copy the shot faces the reader straight on, so most
     of the yaw comes off — a hard tilt here just costs legibility. */
  .dash {
    transform: rotateY(-6deg) rotateX(3deg);
  }

  /* Once the shot stacks under the copy there is nothing above it but that
     copy, and the second panel can only sit on top of it. It exists to give
     the side-by-side composition depth, so it goes rather than collides. */
  .dash-back {
    display: none;
  }
}

@media (max-width: 680px) {
  :root {
    --section-y: clamp(60px, 12vw, 84px);
  }

  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr;
  }

  /* Pin the stat grid to 2 columns so the span rule below has a fixed
     row width to reason about (auto-fit would drift between 1 and 2). */
  .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* An odd-indexed last tile starts its own row, so it would otherwise sit
     beside a dead cell. Only that case spans — even counts stay untouched. */
  .stats .stat:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }

  /* is-full must be reset too, or its span 6 adds implicit columns that
     auto-placement then fills sideways instead of stacking. */
  .bento {
    grid-template-columns: 1fr;
  }

  .bento>.card,
  .bento>.card.is-wide,
  .bento>.card.is-hero,
  .bento>.card.is-full {
    grid-column: span 1;
  }

  /* Text-only bento (AI showcase) stays two-up instead of stacking */
  .bento-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-4);
  }

  .bento-2>.card {
    padding: var(--sp-4);
  }

  .bento-2>.card .icon {
    width: 36px;
    height: 36px;
    border-radius: 11px;
    margin-bottom: var(--sp-4);
  }

  .bento-2>.card .icon svg {
    width: 18px;
    height: 18px;
  }

  .bento-2>.card .h3 {
    font-size: 15px;
  }

  .bento-2>.card p {
    font-size: 12.5px;
    line-height: 1.6;
  }

  .bento-2>.card .tag {
    margin-top: var(--sp-3);
    font-size: 10.5px;
    padding: 3px 8px;
  }

  .plans {
    grid-template-columns: 1fr;
  }

  .deco-dots {
    display: none;
  }

  .card {
    padding: var(--sp-5);
  }

  .flow-grid {
    grid-template-columns: 1fr;
  }

  .flow-card {
    min-height: 260px;
  }

  .flow-panel {
    padding: var(--sp-5);
  }

  .dash {
    transform: none;
  }

  .dash-kpis {
    grid-template-columns: 1fr;
  }

  .capture {
    flex-direction: column;
    align-items: stretch;
  }

  .capture input,
  .capture .btn {
    flex: 1 1 auto;
    width: 100%;
  }

  .hero-cta .btn {
    flex: 1 1 100%;
  }

  .dispatch-map {
    aspect-ratio: 4 / 5;
  }

  .dispatch-foot div {
    padding: 10px 14px;
  }

  .dispatch-foot .upd {
    display: none;
  }

  .dispatch-legend {
    display: none;
  }

  /* Back to one run per row — two columns squeezed the names onto three lines */
  .dispatch-rail {
    grid-template-columns: 1fr;
  }

  .run:nth-child(even) {
    border-left: 0;
  }

  .dpop {
    width: 190px;
    transform: translate(-50%, -118%);
  }

  .dpop-foot {
    flex-wrap: wrap;
    gap: 4px 8px;
  }

  /* All three link lists side by side, with the brand blurb spanning the row
     above them. The desktop 24px column gap would eat a quarter of the width
     three-up, so the gutter goes fluid too. */
  .footer-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-6) clamp(8px, 3vw, 18px);
  }

  .footer-grid>:first-child {
    grid-column: 1 / -1;
  }

  /* Three columns inside a phone leave roughly 100px each, and the longest
     item — hello@azmile.ai — has to survive that. Scale the links with the
     viewport so it stays on one line instead of breaking mid-address. */
  .footer ul a {
    font-size: clamp(11px, 3.2vw, 14px);
  }

  .footer ul {
    gap: 13px;
  }

  .console-body {
    min-height: 340px;
    padding-inline: 14px;
  }

  .viz-chart .row {
    grid-template-columns: 88px 1fr 44px;
  }

  /* Proof strip becomes a tile grid. The 1px gap over a line-coloured
     container draws the hairlines, so any item count stays even. */
  .hero-meta {
    width: 100%;
    display: grid;
    /* Fixed 2-up, same reasoning as .stats: the orphan rule below needs a
       known row width, and auto-fit drifts between 1 and 3 columns here. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    background: var(--line-soft);
  }

  .hero-meta i {
    display: none;
  }

  /* ai.html runs 5 items, index 4. On an odd count the last one starts its own
     row and would sit beside a dead cell — of-type, because the <i> dividers
     are still children even though they're display:none. */
  .hero-meta span:last-of-type:nth-of-type(odd) {
    grid-column: 1 / -1;
  }

  /* Columns are sized for the longest label, but drop nowrap anyway so a
     longer string on another page wraps instead of clipping. */
  .hero-meta span {
    background: #080b13;
    padding: 11px 14px;
    white-space: normal;
  }

  /* The board IS the section, so a phone keeps it rather than degrading to a
     list — same core, same five spokes, same travelling packets, re-laid out
     portrait. Everything below re-establishes the desktop board after the
     mobile resets earlier in this query, then retunes it for the small scale. */
  .section--screen {
    /* Tighter than the desktop rhythm: on a short viewport every pixel spent
       on padding comes straight out of the board's width, which is derived
       from whatever height is left over. The bottom used to reserve the
       mobile dock as well; with that gone it is just notch clearance. */
    padding-block: calc(var(--nav-h) + 10px)
      calc(10px + env(safe-area-inset-bottom, 0px));
  }

  .section--screen .section-head {
    margin-bottom: clamp(8px, 1.8vh, 18px);
  }

  /* The head is the only thing competing with the board for height, so it
     gives up a step of scale here — scoped, so other sections keep theirs. */
  .section--screen .section-head .h2 {
    font-size: clamp(21px, 6.4vw, 27px);
  }

  .section--screen .section-head .lede {
    font-size: 13.5px;
    line-height: 1.55;
    margin-top: 8px;
  }

  /* Two columns of spokes plus a core need more height than width, so the
     board turns portrait and the SVG swaps to the 1000x1400 geometry. */
  .constel {
    aspect-ratio: 1 / var(--board-ar, 1.4);
    /* Height-first: divide the leftover height by the ratio to get the width
       it implies, and take whichever of that and the available width is
       smaller. Same trick as the desktop rule, ratio-corrected. */
    width: min(100%, 420px, calc(100cqh / var(--board-ar, 1.4)));
  }

  .constel-svg--wide {
    display: none;
  }

  .constel-svg--tall {
    display: block;
  }

  /* Stroke widths are user units, and this board renders ~230-420px wide
     against a 1000-unit viewBox — roughly half the desktop scale, so the
     hairline and the packet both need about double the units to land at the
     same on-screen weight. */
  .constel-svg--tall .constel-line {
    stroke-width: 3.8;
  }

  .constel-svg--tall .constel-pulse {
    stroke-width: 7.5;
  }

  /* Below this the labels stop being legible; a shorter viewport scrolls a
     little rather than shrinking the board into illegibility. */
  .constel-stage {
    min-height: 300px;
  }

  .cn {
    /* Portrait coordinates, with the square board's as a fallback so a node
       without --mx still lands somewhere sane. */
    left: var(--mx, var(--x));
    top: var(--my, var(--y));
    width: 19%;
  }

  .cn.is-core {
    width: 23%;
  }

  /* The halo is sized in % of the node, so it survives the scale change — but
     the blur is in px and would swamp a 45px tile at its desktop radius. */
  .cn::after {
    filter: blur(10px);
  }

  .cn.is-core .cn-box {
    border-radius: 19%;
  }

  /* Labels sit closer in: at this scale the desktop 14/16px gaps are a large
     fraction of the gap between two rows. */
  .cn-label {
    top: calc(100% + 7px);
    font-size: clamp(10.5px, 3.4cqw, 14px);
  }

  .cn-label b {
    font-size: clamp(8px, 2.5cqw, 10.5px);
    margin-top: 2px;
  }

  .cn.is-core .cn-label {
    bottom: calc(100% + 8px);
    font-size: clamp(13px, 4.4cqw, 18px);
  }

  .cn.is-core .cn-label b {
    font-size: clamp(8.5px, 2.7cqw, 11px);
    letter-spacing: .1em;
  }

  /* Touch feedback — there is no hover on a phone. */
  .cn:active .cn-box {
    transform: scale(.95);
    transition-duration: .1s;
  }

  .cn:hover .cn-box,
  .cn:focus-visible .cn-box {
    transform: none;
  }
}

/* A short phone in portrait — a 640px-class device, or a taller one with the
   browser's own chrome taking its cut — cannot show the head, the paragraph
   and a legible board inside one screen. The board IS the argument in this
   section, so the paragraph is what gives way; the heading still carries it. */
@media (max-width: 680px) and (max-height: 700px) {
  .section--screen .section-head .lede {
    display: none;
  }

  .section--screen .section-head {
    margin-bottom: 10px;
  }

  .constel-stage {
    min-height: 260px;
  }

  /* Tool names go 2-up. They're identifiers that must not truncate, so buy
     the width back: smaller type, tighter padding, and drop the ▮ marker. */
  .tag-grid,
  .tag-grid.is-wide {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tabpanel {
    padding: var(--sp-4);
  }

  /* buys ~16px back for the columns */
  .tag-grid .tag {
    font-size: 10px;
    padding: 6px 7px;
    gap: 0;
    justify-content: center;
    text-align: center;
    min-width: 0;
    /* The base .tag is nowrap. `update_shipment_status` needs ~153px and a
       390px phone gives ~147px, so it has to be allowed to wrap — these are
       identifiers, and a second line beats spilling out of the pill. */
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.35;
  }

  .tag-grid .tag::before {
    content: none;
  }
}

/* ------------------------------------------------- REDUCED MOTION ------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }

  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }

  .marquee-track {
    animation: none;
  }

  /* Land the completed leg on its real value, not the full path, or the
     board claims every stop is done. */
  .rt-done {
    stroke-dashoffset: var(--o, 0) !important;
  }

  .rt-live {
    animation: none;
    opacity: 0;
  }

  .route-line {
    stroke-dashoffset: 0;
  }

  .route-stop {
    transform: scale(1) !important;
  }

  .director-row {
    opacity: 1;
    transform: none;
  }

  .viz-chart .bar i {
    transition: none;
  }

  /* These animate a paint position, so freezing mid-cycle can leave them
     blank. Park each on a deliberate resting frame instead. */
  .hero-aurora {
    animation: none;
    transform: none;
  }

  .hero .accent {
    animation: none;
    background-position: 50% 0;
  }

  .console::before {
    animation: none;
    --beam-a: 285deg;
  }

  .hero-scroll span {
    animation: none;
    opacity: 1;
  }

  /* Freezing the packets mid-run would strand a bright dash on a random
     spoke, so drop them entirely and leave the static wiring. */
  .constel-pulse {
    animation: none;
    display: none;
  }

  .cn.is-core .cn-box::after {
    animation: none;
    box-shadow: 0 0 0 3px rgba(168, 224, 74, .2);
  }
}

/* No-JS fallback — content must never be hidden behind a script */
.no-js .reveal {
  opacity: 1;
  transform: none;
}

.no-js .faq-a {
  height: auto;
}

/* The routes wait for an in-view flag that only JS sets */
.no-js .rt-done {
  stroke-dashoffset: var(--o, 0);
}

/* The bars grow on the in-view flag, so without JS they'd stay flat at 0 */
.no-js .dash .dcol i {
  height: var(--h, 0%);
}

/* Nothing extra is needed for the board — the whole .constel is a .reveal, so
   the rule above already un-hides it. A `transform: none` here would land on
   the nodes and cancel the translate that centres every one of them on its
   coordinate. */

/* ==========================================================================
   AUTH — /login. Split shell: brand panel + glass sign-in card.
   Reuses the tokens, .btn, .field and .mock primitives above. Every selector
   is scoped under .auth*, so these rules cost the marketing pages nothing.
   ========================================================================== */
.auth {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1.04fr .96fr;
}

/* ---------------------------------------------------------- BRAND PANEL -- */
.auth-aside {
  position: relative;
  isolation: isolate;
  /* keeps the ambient layers inside the panel */
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--sp-7);
  padding: clamp(30px, 3.4vw, 58px);
  border-right: 1px solid var(--line-soft);
  background: linear-gradient(165deg, #070b14, #04060c 62%);
}

/* Negative z-index children paint over the panel's own background but under
   its content — same aurora recipe as the hero, kept inside the panel. */
.auth-aside::before {
  content: '';
  position: absolute;
  inset: -22%;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(38% 42% at 74% 12%, rgba(79, 214, 232, .22), transparent 64%),
    radial-gradient(42% 46% at 56% 74%, rgba(139, 124, 246, .14), transparent 66%),
    radial-gradient(36% 40% at 12% 36%, rgba(168, 224, 74, .14), transparent 64%);
  animation: auroraDrift 26s var(--ease-io) infinite alternate;
  will-change: transform;
}

.auth-aside::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .55;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, .05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, .05) 1px, transparent 1px);
  background-size: 56px 56px;
  -webkit-mask-image: radial-gradient(105% 78% at 22% 0%, #000 6%, transparent 72%);
  mask-image: radial-gradient(105% 78% at 22% 0%, #000 6%, transparent 72%);
}

.auth-aside .brand {
  margin-right: 0;
  align-self: flex-start;
}

.auth-pitch {
  max-width: 30ch;
}

.auth-pitch h1 {
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: clamp(30px, 3vw, 44px);
  line-height: 1.1;
  letter-spacing: -.03em;
  color: var(--ink);
}

.auth-pitch p {
  margin-top: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--ink-2);
}

.auth-points {
  margin-top: var(--sp-6);
  display: grid;
  gap: 11px;
}

.auth-points li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13.5px;
  color: var(--ink-2);
}

.auth-points svg {
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 3px;
  color: var(--lime-2);
}

/* Sized from viewport height, not width, so the panel never outgrows a
   laptop window and pushes the caption off the bottom edge. */
.auth-preview .mock {
  aspect-ratio: 16 / 8.4;
  height: clamp(140px, 24vh, 252px);
  width: auto;
  max-width: 100%;
  margin-bottom: var(--sp-3);
}

.auth-preview .cap {
  font-family: var(--ff-mono);
  font-size: 10.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* ------------------------------------------------------------ CARD SIDE -- */
.auth-main {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-5);
  padding: clamp(26px, 4vw, 56px) clamp(18px, 4vw, 44px);
  padding-bottom: calc(clamp(26px, 4vw, 56px) + env(safe-area-inset-bottom));
}

.auth-card {
  width: 100%;
  max-width: 456px;
  padding: clamp(24px, 2.6vw, 34px);
  border-radius: var(--r-xl);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .012));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--sh-3), inset 0 1px 0 rgba(255, 255, 255, .07);
}

.auth-card>.brand {
  display: none;
  margin: 0 0 var(--sp-5);
}

.auth-h {
  font-family: var(--ff-display);
  font-size: 25px;
  font-weight: 700;
  letter-spacing: -.025em;
  color: var(--ink);
}

.auth-sub {
  margin-top: 7px;
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

.auth-head {
  margin-bottom: var(--sp-6);
}

/* Step rail — three beads, filled up to the live step */
.auth-rail {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: var(--sp-5);
}

.auth-rail i {
  height: 3px;
  flex: 1;
  border-radius: var(--r-pill);
  background: var(--line);
  transition: background var(--dur-2) var(--ease);
}

.auth-rail i.on {
  background: var(--grad-ai);
}

/* Each step is a sibling panel; [hidden] from the reset does the switching,
   so the entrance animation restarts every time one is revealed. */
.auth-step {
  animation: authStepIn .4s var(--ease-out) both;
}

@keyframes authStepIn {
  from {
    opacity: 0;
    transform: translateY(9px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* ------------------------------------------------------------- MESSAGES -- */
.alert {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 11px 13px;
  margin-bottom: var(--sp-5);
  border: 1px solid;
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  line-height: 1.55;
}

.alert svg {
  flex: none;
  width: 15px;
  height: 15px;
  margin-top: 1px;
}

.alert-err {
  color: #ffbcbc;
  background: rgba(255, 107, 107, .09);
  border-color: rgba(255, 107, 107, .3);
}

.alert-ok {
  color: #b3f0cd;
  background: rgba(62, 207, 124, .09);
  border-color: rgba(62, 207, 124, .3);
}

.alert-info {
  color: #bfe4ff;
  background: rgba(90, 181, 247, .09);
  border-color: rgba(90, 181, 247, .3);
}

.alert-warn {
  color: #f8dfa2;
  background: rgba(245, 193, 68, .09);
  border-color: rgba(245, 193, 68, .3);
}

.alert b {
  display: block;
  color: inherit;
  font-weight: 600;
}

/* Field additions — label row with a trailing link, hints, error text */
.field-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.field-top a,
.field-top button {
  font-size: 12px;
  color: var(--lime-2);
  font-family: var(--ff-body);
  letter-spacing: 0;
  text-transform: none;
}

.field-top a:hover,
.field-top button:hover {
  text-decoration: underline;
}

.field .hint {
  font-size: 12px;
  color: var(--ink-3);
}

.field .err {
  font-size: 12px;
  color: var(--danger);
  display: flex;
  align-items: center;
  gap: 6px;
}

.field input[aria-invalid="true"] {
  border-color: rgba(255, 107, 107, .55);
}

.field input[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 3px rgba(255, 107, 107, .16);
}

.field input:disabled {
  opacity: .55;
  cursor: not-allowed;
}

/* Password field — reveal toggle sits inside the control */
.pw {
  position: relative;
}

.pw input {
  padding-right: 46px;
}

.pw-toggle {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--r-sm);
  color: var(--ink-3);
  transition: color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}

.pw-toggle:hover {
  color: var(--ink);
  background: var(--surface);
}

.pw-toggle svg {
  width: 17px;
  height: 17px;
}

.caps {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--warn);
}

/* Identity chip — who you are signing in as, with a way back */
.ident {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 7px 7px 8px;
  margin-bottom: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, .3);
}

.ident .avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--grad-ai);
  color: #08120a;
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: 12.5px;
}

.ident .who {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ident .who small {
  display: block;
  font-size: 11px;
  color: var(--ink-3);
}

.ident .swap {
  flex: none;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: 600;
  color: var(--lime-2);
  transition: background var(--dur-1) var(--ease);
}

.ident .swap:hover {
  background: rgba(168, 224, 74, .1);
}

/* ------------------------------------------------------------- CONTROLS -- */
.btn-block {
  width: 100%;
}

.btn[aria-busy="true"] {
  pointer-events: none;
  opacity: .8;
}

.spinner {
  width: 15px;
  height: 15px;
  flex: none;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  opacity: .75;
  animation: spin .7s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.row-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: var(--sp-5);
}

.check {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
}

.check input {
  -webkit-appearance: none;
  appearance: none;
  flex: none;
  width: 17px;
  height: 17px;
  border: 1px solid var(--line-hard);
  border-radius: 5px;
  background: rgba(0, 0, 0, .35) no-repeat center center;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}

.check input:checked {
  border-color: transparent;
  background-color: var(--lime);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 24 24' fill='none' stroke='%2308120a' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
}

.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: var(--sp-5) 0;
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.divider::before,
.divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}

.auth-alt {
  display: grid;
  gap: 10px;
}

.auth-alt .btn {
  justify-content: center;
}

.auth-alt .btn svg {
  width: 17px;
  height: 17px;
}

.auth-switch {
  margin-top: var(--sp-5);
  text-align: center;
  font-size: 13px;
  color: var(--ink-3);
}

.auth-switch a,
.auth-switch button {
  color: var(--lime-2);
  font-size: 13px;
  font-weight: 500;
}

.auth-switch a:hover,
.auth-switch button:hover {
  text-decoration: underline;
}

/* ------------------------------------------------------------ OTP INPUT -- */
.otp {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
  margin-bottom: var(--sp-4);
}

.otp input {
  width: 100%;
  padding: 14px 0;
  font-family: var(--ff-mono);
  font-size: 20px;
  text-align: center;
  color: var(--ink);
  background: rgba(0, 0, 0, .3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  transition: border-color var(--dur-2) var(--ease), box-shadow var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}

.otp input:focus {
  outline: none;
  border-color: rgba(168, 224, 74, .6);
  box-shadow: 0 0 0 3px var(--glow);
  background: rgba(0, 0, 0, .45);
}

.otp input.filled {
  border-color: rgba(168, 224, 74, .4);
}

.otp.bad input {
  border-color: rgba(255, 107, 107, .5);
}

.otp.bad {
  animation: shake .34s var(--ease-io);
}

@keyframes shake {

  0%,
  100% {
    transform: translateX(0);
  }

  25% {
    transform: translateX(-6px);
  }

  75% {
    transform: translateX(6px);
  }
}

/* Big status glyph for the sent / done panels */
.auth-glyph {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-bottom: var(--sp-5);
  border-radius: 16px;
  color: var(--lime-2);
  background: linear-gradient(150deg, rgba(168, 224, 74, .18), rgba(79, 214, 232, .08));
  border: 1px solid rgba(168, 224, 74, .24);
}

.auth-glyph svg {
  width: 24px;
  height: 24px;
}

/* Footer under the card */
.auth-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 16px;
  width: 100%;
  max-width: 456px;
  font-size: 12px;
  color: var(--ink-3);
  text-align: center;
}

.auth-foot a:hover {
  color: var(--ink-2);
  text-decoration: underline;
}

.auth-secure {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.auth-secure svg {
  width: 13px;
  height: 13px;
}

@media (max-width: 980px) {
  .auth {
    grid-template-columns: 1fr;
  }

  .auth-aside {
    display: none;
  }

  .auth-card>.brand {
    display: inline-flex;
  }

  .auth-main {
    justify-content: flex-start;
    padding-top: clamp(34px, 9vw, 64px);
  }
}

/* Very short windows: drop the product shot rather than crush the panel */
@media (max-height: 660px) {
  .auth-preview {
    display: none;
  }
}

@media (max-width: 420px) {
  .otp {
    gap: 6px;
  }

  .otp input {
    padding: 12px 0;
    font-size: 17px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .auth-aside::before {
    animation: none;
    transform: none;
  }

  .auth-step {
    animation: none;
  }

  .otp.bad {
    animation: none;
  }

  /* The global reduce rule freezes every animation, which would leave the
     spinner as a static broken ring. Loading state is information, not
     decoration — keep it turning, just slowly. */
  .spinner {
    animation-duration: 1.4s !important;
    animation-iteration-count: infinite !important;
  }
}

/* ==========================================================================
   CARD LIGHT SYSTEM
   Every card is lit by three things, and only three:

     1  BACKGROUND LIGHT — the hue washing up the inside of the card
     2  GLOW LIGHT       — the bloom thrown out past the lit bottom edge
     3  COMPONENT LIGHT  — chips, ticks, tags and rules tinted from that hue

   All three read off one rgb triple (--lit) plus one ink (--lit-ink), so a new
   hue is two values. Brightness is three more (--lit-wash / -bloom / -rim) and
   those three are ALL that :hover changes — var() substitutes at computed-value
   time, so the box-shadow still animates between the two states.

   Appended last on purpose. It re-states the .card / .plan / .auth-card
   surfaces defined earlier rather than editing them in place, which keeps the
   whole lighting model in one readable block instead of scattered across four
   component sections.
   ========================================================================== */

:root {
  --lit-lime: 168 224 74;
  --lit-cyan: 79 214 232;
  --lit-violet: 139 124 246;
  --lit-mint: 62 207 124;
  --lit-amber: 245 193 68;
  --lit-rose: 255 107 107;
  --lit-azure: 90 181 247;
}

/* Defaults — lime is the signature, so an unmarked card is a lime card.
   .form is in the list because it is a card in everything but its class name:
   same radius, same border, same background recipe. Leaving it out just made
   the contact page's biggest surface the one unlit thing on it. */
.card,
.plan,
.auth-card,
.form {
  --lit: var(--lit-lime);
  --lit-ink: var(--lime-2);

  /* 1 — inner background light. Cut hard from .22: this is the wash that sits
     under the body copy in the lower third of a card, so it was the single
     biggest drag on text contrast. */
  --lit-wash: .085;

  /* 2 — outer glow light. Negative is deliberate and load-bearing: CSS clamps
     alpha to [0,1], so every hue layer in --lit-shadow resolves to alpha 0 and
     the bloom is OFF at rest. That is what makes the page read crisp. The
     "subtle AI glow" now lives in the rim below and on :hover only.
     Anything >= 0 here turns the haze back on. */
  --lit-bloom: -0.52;

  /* 3 — the lit bottom edge. This is what carries the aesthetic at rest now
     that the bloom is off, so it is held near its old value. */
  --lit-rim: .62;
}

/* Hue variants — one class opts any card into a different light. */
.lit-lime {
  --lit: var(--lit-lime);
  --lit-ink: #c9f77e;
}

.lit-cyan {
  --lit: var(--lit-cyan);
  --lit-ink: #8fe9f4;
}

.lit-violet {
  --lit: var(--lit-violet);
  --lit-ink: #b7adfb;
}

.lit-mint {
  --lit: var(--lit-mint);
  --lit-ink: #7fe4a9;
}

.lit-amber {
  --lit: var(--lit-amber);
  --lit-ink: #ffd977;
}

.lit-rose {
  --lit: var(--lit-rose);
  --lit-ink: #ff9c9c;
}

.lit-azure {
  --lit: var(--lit-azure);
  --lit-ink: #94ccfb;
}

/* A grid of cards should read as a set of lights rather than one swatch
   repeated four times. Pain cards opt out — their hue is carried by the stat
   they already colour, and is assigned further down. */
.grid>.card:nth-child(4n+2):not(.pain-card),
.bento>.card:nth-child(4n+2) {
  --lit: var(--lit-cyan);
  --lit-ink: #8fe9f4;
}

.grid>.card:nth-child(4n+3):not(.pain-card),
.bento>.card:nth-child(4n+3) {
  --lit: var(--lit-violet);
  --lit-ink: #b7adfb;
}

.grid>.card:nth-child(4n+4):not(.pain-card),
.bento>.card:nth-child(4n+4) {
  --lit: var(--lit-mint);
  --lit-ink: #7fe4a9;
}

/* Opt a single grid out of the rotation so every card keeps the default lime.
   The rotation rules above score (0,4,0), so the trailing :nth-child(n) is
   here purely to reach (0,5,0) and win regardless of source order. */
.grid.lit-uniform>.card:not(.pain-card):nth-child(n),
.bento.lit-uniform>.card:nth-child(n) {
  --lit: var(--lit-lime);
  --lit-ink: var(--lime-2);
}

/* ------------------------------------------------- 1 + 2 — THE SURFACE --- */
/* The shadow stack lives in a custom property so :hover can re-point at the
   same stack to out-specify the earlier .card:hover / .plan:hover rules,
   without restating fourteen lines of shadow. */
.card,
.plan,
.auth-card,
.form {
  --lit-shadow:
    /* the light bleeding back up inside the card off its own lit edge */
    inset 0 -22px 34px -24px rgb(var(--lit) / var(--lit-rim)),
    inset 0 1px 0 rgba(255, 255, 255, .09),
    /* the bloom outside: a near-white core under the edge, falling off to hue */
    0 1px 8px 0px rgba(255, 255, 255, .10),
    0 4px 14px -2px rgb(var(--lit) / calc(var(--lit-bloom) * 1.05)),
    0 14px 34px -8px rgb(var(--lit) / calc(var(--lit-bloom) * .8)),
    0 30px 70px -20px rgb(var(--lit) / calc(var(--lit-bloom) * .58)),
    0 56px 120px -40px rgb(var(--lit) / calc(var(--lit-bloom) * .42)),
    var(--sh-2);

  position: relative;
  /* .auth-card lacks it, and the rim below is absolute */

  /* Hue moved OUT of the soft layers and into this hairline. With the bloom off
     and the wash cut, a neutral white border left every card reading lime — the
     cyan and violet identity had nowhere left to show. A 1px tinted edge is
     crisp by construction, so it buys back the colour at zero cost in haze. */
  border-color: rgb(var(--lit) / .3);
  background:
    /* the hot pool of light gathering at the bottom edge. Kept low and tight:
       a taller pool climbs into whatever sits in the last third of the card
       and eats it — the .plan CTA is the case that proves it. */
    radial-gradient(94% 46% at 50% 108%, rgb(var(--lit) / calc(var(--lit-wash) * 2.1)), transparent 74%),
    /* and its thinner wash up the body of the card */
    linear-gradient(0deg,
      rgb(var(--lit) / calc(var(--lit-wash) * .85)),
      rgb(var(--lit) / calc(var(--lit-wash) * .22)) 54%,
      transparent 88%),
    radial-gradient(84% 46% at 50% -16%, rgba(255, 255, 255, .055), transparent 62%),
    linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, .008));
  box-shadow: var(--lit-shadow);
}

/* The lit edge itself. A pseudo-element, not an inset shadow, because the rim
   is brightest at the centre and fades to hue at the corners — a gradient,
   which box-shadow cannot do. With the bloom off this line is the whole
   "lit object" read, so the white core is pulled back from .92 to .55: less
   white means more of the card's actual hue survives in the one crisp element
   that still shows it. */
.card::after,
.plan::after,
.auth-card::after,
.form::after {
  content: '';
  position: absolute;
  left: 11%;
  right: 11%;
  bottom: 0;
  height: 1.5px;
  z-index: 2;
  border-radius: 2px;
  pointer-events: none;
  background: linear-gradient(90deg,
      transparent,
      rgb(var(--lit) / var(--lit-rim)) 14%,
      rgba(255, 255, 255, calc(var(--lit-rim) * .55)) 50%,
      rgb(var(--lit) / var(--lit-rim)) 86%,
      transparent);
  transition: left var(--dur-3) var(--ease), right var(--dur-3) var(--ease);
}

/* A big passive panel is not a thing you pick up, so .form takes the light but
   sits out the hover lift — and its bloom is damped, since a full-height panel
   throwing a card's worth of glow floods everything beside it. */
.form {
  --lit-bloom: -1;
  --lit-wash: .06;
}

/* Hover is now the ONLY place the bloom exists, which is what keeps the page
   crisp at rest while still feeling alive under the cursor. Kept well below the
   old .72 — this is a hint of light, not the old halo. */
.card:hover,
.plan:hover,
.auth-card:hover {
  --lit-wash: .15;
  --lit-bloom: .2;
  --lit-rim: .95;
  border-color: rgb(var(--lit) / .34);
  box-shadow: var(--lit-shadow);
}

.card:hover::after,
.plan:hover::after,
.auth-card:hover::after {
  left: 6%;
  right: 6%;
}

/* Flow cards keep their own scrim — it is what makes their .bloom legible.
   Restated here because the rim rule above would otherwise replace it. */
.flow-card::after {
  left: 0;
  right: 0;
  top: 0;
  height: auto;
  z-index: 0;
  border-radius: inherit;
  background: linear-gradient(0deg, rgba(3, 5, 10, .46) 0%, rgba(3, 5, 10, .18) 44%, transparent 72%);
}

/* …and it must survive :hover, which pinches the rim inwards on a normal card */
.flow-card:hover::after {
  left: 0;
  right: 0;
}

/* The cursor spotlight tracks the card's own hue instead of always lime. */
.card::before {
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
      rgb(var(--lit) / .15), transparent 60%);
}

/* Flow cards already carry a light source — the .bloom element. They take the
   outer glow only; an inner wash on top of the bloom just flattens it. */
.flow-card {
  --lit-wash: 0;
  --lit-bloom: -1;
  border-color: var(--line-soft);
  background: linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .008));
}

.flow-card:hover {
  --lit-wash: 0;
  --lit-bloom: .14;
}

/* Pain cards inherit the hue of the stat they lead with, so the light and the
   number agree instead of arguing. */
.pain-card {
  --lit: var(--lit-rose);
  --lit-ink: #ff9c9c;
}

.pain-card:has(.pain-stat.warn) {
  --lit: var(--lit-amber);
  --lit-ink: #ffd977;
}

.pain-card:has(.pain-stat.info) {
  --lit: var(--lit-azure);
  --lit-ink: #94ccfb;
}

/* The pricing trio reads as three lights, with the brand lime reserved for the
   plan we actually want chosen. */
.plans>.plan:nth-child(1) {
  --lit: var(--lit-cyan);
  --lit-ink: #8fe9f4;
}

.plans>.plan:nth-child(3) {
  --lit: var(--lit-violet);
  --lit-ink: #b7adfb;
}

/* A ghost button is nearly transparent, so anything sitting in the pool at the
   foot of a card needs its own floor or the light swallows it. */
.card .btn-ghost,
.plan .btn-ghost {
  background: rgba(5, 8, 14, .5);
  border-color: rgba(255, 255, 255, .16);
}

.card .btn-ghost:hover,
.plan .btn-ghost:hover {
  background: rgba(5, 8, 14, .34);
  border-color: rgb(var(--lit) / .5);
}

/* The featured plan is the one card that earns a standing bloom — it is a
   deliberate focal point, not decoration. Kept low so it reads as emphasis
   rather than haze. */
.plan.featured {
  --lit-wash: .11;
  --lit-bloom: .18;
  --lit-rim: .9;
  border-color: rgb(var(--lit) / .5);
  background:
    radial-gradient(128% 88% at 50% 118%, rgb(var(--lit) / var(--lit-wash)), transparent 68%),
    radial-gradient(90% 50% at 50% -14%, rgba(79, 214, 232, .07), transparent 62%),
    linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .01));
  box-shadow: var(--lit-shadow);
}

.plan.featured:hover {
  --lit-wash: .16;
  --lit-bloom: .28;
}

/* ------------------------------------------- 3 — THE COMPONENT'S LIGHT --- */
/* A chip's own glow is a fixed value, NOT derived from --lit-bloom. It used to
   be `calc(--lit-bloom + .3)`, which quietly went negative — and so clamped to
   invisible — the moment the card bloom was turned off. A 44px chip casting a
   tight glow was never the haze problem; the card-sized bloom was. */
.icon,
.step-n {
  color: var(--lit-ink);
  background: linear-gradient(150deg, rgb(var(--lit) / .18), rgb(var(--lit) / .05));
  border: 1px solid rgb(var(--lit) / .28);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .15),
    0 6px 16px -12px rgb(var(--lit) / .5);
}

.card:hover .icon {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .2),
    0 8px 20px -11px rgb(var(--lit) / .58);
}

.card .tag:not(.tag--neutral),
.plan .tag:not(.tag--neutral) {
  color: var(--lit-ink);
  background: rgb(var(--lit) / .1);
  border-color: rgb(var(--lit) / .28);
  box-shadow: 0 4px 14px -8px rgb(var(--lit) / .5);
}

/* The stat is the card's brightest glyph, so it gets a real halo. */
.pain-stat,
.pain-stat.warn,
.pain-stat.info {
  color: var(--lit-ink);
  text-shadow: 0 0 28px rgb(var(--lit) / .45);
}

.pain-fix {
  color: var(--lit-ink);
  border-top-color: rgb(var(--lit) / .22);
}

/* Pricing internals — same hue, so the plan reads as one lit object. */
.plan-name,
.plan-cap b,
.plan-list .ai-feat {
  color: var(--lit-ink);
}

.plan-list .ck,
.price-list .ck {
  color: var(--lit-ink);
  border-color: rgb(var(--lit) / .45);
  background: rgb(var(--lit) / .1);
  box-shadow: 0 0 14px -4px rgb(var(--lit) / .45);
}

/* The one horizontal rule in a card is the closest thing it has to a meter —
   light it from the left and let it bloom. */
.plan-rule {
  background: linear-gradient(90deg, rgb(var(--lit) / .6), rgb(var(--lit) / .14) 62%, transparent);
  box-shadow: 0 0 12px rgb(var(--lit) / .35);
}

.plan-most {
  color: var(--lit-ink);
  background: rgb(var(--lit) / .12);
  border-color: rgb(var(--lit) / .34);
  box-shadow: 0 6px 18px -12px rgb(var(--lit) / .6);
}

/* Login: the step rail is this card's progress bar, so it glows like one. */
.auth-rail i.on {
  box-shadow: 0 0 12px rgb(var(--lit) / .7);
}

.auth-points svg {
  color: var(--lit-ink);
}

/* Narrow screens stack the cards, so neighbouring blooms pile into each other
   and turn the column muddy. The bloom is already off at rest, so all this has
   left to do is keep the hover state from re-lighting it on a touch device,
   where :hover sticks after a tap. */
@media (max-width: 720px) {

  .card,
  .plan,
  .auth-card,
  .form {
    --lit-wash: .07;
    --lit-bloom: -1;
  }

  .card:hover,
  .plan:hover {
    --lit-wash: .1;
    --lit-bloom: -1;
  }
}