/* ================================================================
   Waypoint — style.css  (structure & style: sunday.ai)
   Palette: #FFF · #E5E5E5 · #A1DCFE · #262626
   Grid: 6 columns · 40px margins · 20px gutters · full width
   ================================================================ */

/* ---------- Fonts ----------
   ascent/descent overrides recenter Helvetica Neue vertically:
   measured cap height = 0.712em, so ascent − descent must equal it
   (0.86 − 0.14 = 0.72) or caps sit high in every centered box. */
@font-face {
  font-family: "Helvetica Neue W";
  src: url("../assets/fonts/HelveticaNeue-Roman.woff2?v=2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  ascent-override: 86%;
  descent-override: 14%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Helvetica Neue W";
  src: url("../assets/fonts/HelveticaNeue-Medium.woff2?v=2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  ascent-override: 86%;
  descent-override: 14%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Helvetica Neue W";
  src: url("../assets/fonts/HelveticaNeue-Bold.woff2?v=2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  ascent-override: 86%;
  descent-override: 14%;
  line-gap-override: 0%;
}

/* ---------- Tokens ---------- */
:root {
  --white: #ffffff;
  --grey: #e5e5e5;
  --card: #f2f2f2;   /* card surfaces (lighter than --grey) */
  /* span between the ‹ › brackets — shared by the preloader logo and the hero
     so the blink hand-off is seamless. The word font caps at 140px (~573px wide)
     around 1647px, so the span must already clear it there: 51vw hits ~840px at
     that point, and it caps at 900px on wider screens. */
  --hero-span: min(clamp(520px, 51vw, 900px), calc(100vw - 48px));   /* never wider than the phone */
  --sky: #a1dcfe;
  --ink: #262626;

  --margin: 40px;   /* grid margin */
  --gutter: 20px;   /* grid gutter */
  --bleed: 40px;    /* inset for full-width media cards */

  --r-lg: 18px;
  --r-md: 14px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  /* iOS Safari inflates type inside long text blocks — hardest in landscape,
     where it re-scales body copy AND headings and blows the layout out of the
     column. Never let it: the type here is already fluid. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
html.lock { overflow: hidden; }
/* menu open: the page is dimmed behind the pill and scrolling is blocked in
   js (by swallowing wheel/touchmove) rather than with overflow:hidden —
   toggling overflow on the scroll container re-resolves every position:sticky
   on the page, which made the tech pin and the carousel jump out of view. */
.pill-scrim {
  position: fixed;
  inset: 0;
  z-index: 9000;               /* above the whole page, under .site-header */
  background: rgba(20, 20, 20, 0.5);
  opacity: 0;
  visibility: hidden;
  touch-action: none;
  transition: opacity 0.4s var(--ease), visibility 0s linear 0.4s;
}
html.menu-open .pill-scrim {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.4s var(--ease), visibility 0s linear 0s;
}
body {
  font-family: "Helvetica Neue W", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 400;
  color: var(--ink);
  background: var(--ink); /* revealed behind .page at the footer */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;   /* clip (not hidden): hidden makes body a scroll container and breaks position: sticky */
}
a { color: inherit; text-decoration: none; }
video { display: block; }
::selection { background: var(--sky); color: var(--ink); }

/* the white page container — contracts near the footer (see main.js) */
.page {
  background: var(--white);
  position: relative;
  z-index: 1;   /* paints above the fixed .egg underlay */
  /* curtain bottom edge over the footer underlay is always rounded */
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* ---------- Layout primitives ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  column-gap: var(--gutter);
  width: 100%;
  padding-inline: var(--margin);
}
.bleed { padding-inline: var(--bleed); width: 100%; }

.media-card {
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--grey);
}
.media-card > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  position: absolute;
  inset: 0;
}

.chip {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--white);
  background: rgba(38, 38, 38, 0.45);
  backdrop-filter: blur(8px);
  padding: 8px 13px;
  border-radius: 999px;
  white-space: nowrap;
}
.chip-top { top: 14px; left: 14px; }
.chip-bottom { bottom: 14px; left: 14px; }
.chip-play { top: 50%; left: 50%; translate: -50% -50%; }

.card-label { font-size: 14px; font-weight: 700; letter-spacing: 0.01em; }
.card-body { font-size: 14px; line-height: 1.5; }

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .egg-line, .chip-lite { opacity: 1; transform: none; transition: none; }
  .car-tabs { opacity: 1; pointer-events: auto; transition: none; }
  .hero-line, .hero-brackets { animation: none; }
  html { scroll-behavior: auto; }
}

/* ================================================================
   Wordmark  ‹ Waypoint ›  (shared by preloader + hero)
   ================================================================ */
.wordmark {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(28px, 5vw, 110px);
  font-size: clamp(48px, 8.5vw, 150px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  white-space: nowrap;
}
.wordmark .bracket { height: 0.62em; width: auto; flex: 0 0 auto; }
.bracket.flip { transform: scaleX(-1); }
.wm-word { display: grid; grid-template-columns: 1fr; }
.wm-word i {
  font-style: normal;
  min-width: 0;
  overflow: hidden;              /* clips horizontally for the reveal */
  padding-block: 0.2em;          /* room so ascenders/descenders aren't clipped */
  margin-block: -0.2em;          /* cancel the padding in layout */
}

/* ================================================================
   Preloader — folded mark rotates + unfolds into ‹ Waypoint ›
   ================================================================ */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 9500;   /* covers the header too, at load */
  display: grid;
  place-items: center;
}
/* dark cover — sits behind the mark; swipes away right→left to unveil the hero */
.pre-cover {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--ink);
  clip-path: inset(0 0 0 0);
  transition: clip-path 0.2s cubic-bezier(0.76, 0, 0.24, 1);
}
.preloader .pre-mark { position: relative; z-index: 1; }
/* percentage loader — bottom-right, styled like the hero "Scroll" element */
.pre-pct {
  position: absolute;
  z-index: 1;
  right: var(--margin);
  bottom: 30px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--white);
  font-size: 14px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition: opacity 0.35s var(--ease);
}
.pre-spin {
  width: 15px;
  height: 15px;
  animation: preSpin 0.9s linear infinite;
}
@keyframes preSpin { to { rotate: 360deg; } }
/* stage 0 (folded): brackets rotated into the folded plus mark, no text
   stage 1 (.spin):  brackets rotate upright
   stage 2 (.unfold): brackets spread to the EXACT hero-bracket positions
                      (width + space-between match .hero-brackets), word reveals
   stage 3 (.blink):  word + dark bg dissolve away, leaving the brackets in place */
.pre-mark {
  /* --bh = bracket height, matched to the hero brackets so the sizes line up */
  --bh: clamp(56px, 8vw, 150px);
  color: var(--white);
  font-size: clamp(52px, 8.5vw, 140px);   /* matches the hero text size (brackets use --bh) */
  width: var(--bh);                       /* folded: tight, brackets overlap */
  gap: 0.06em;
  transition: width 0.9s var(--ease), gap 0.9s var(--ease);
}
.pre-mark .bracket {
  height: var(--bh);
  rotate: 135deg;
  /* folded offsets are kept as a fixed fraction of the bracket height so the
     plus stays aligned at any bracket size (X = 0.21·bh, Y = 0.129·bh). */
  translate: calc(var(--bh) * 0.21) calc(var(--bh) * 0.129);
  transition: rotate 0.8s var(--ease), translate 0.8s var(--ease);
}
.pre-mark .bracket.flip { translate: calc(var(--bh) * -0.21) calc(var(--bh) * -0.129); }
.preloader.spin .pre-mark .bracket { rotate: 0deg; translate: 0 0; }
.pre-mark .wm-word {
  grid-template-columns: 0fr;
  opacity: 0;
  transition: grid-template-columns 0.9s var(--ease), opacity 0.5s var(--ease);
}
/* unfold: spread the brackets to the hero positions, reveal the word */
.preloader.unfold .pre-mark { width: var(--hero-span); justify-content: space-between; gap: 0; }
.preloader.unfold .pre-mark .wm-word { grid-template-columns: 1fr; opacity: 1; }
/* swipe: cover wipes away right→left unveiling the hero; word fades, brackets stay */
.preloader.swipe { pointer-events: none; }
.preloader.swipe .pre-cover { clip-path: inset(0 100% 0 0); }
.preloader.swipe .pre-mark .wm-word { opacity: 0; }
.preloader.swipe .pre-pct { opacity: 0; }
.preloader.gone { display: none; }

/* ================================================================
   Header — pill that expands into a sunday-style panel
   ================================================================ */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 9010;   /* the menu opens over everything on the page */
  display: flex;
  justify-content: center;
  padding-top: 20px;
  padding-inline: var(--bleed);   /* pill sizes to this padded box, not 100vw */
  pointer-events: none;
}
.pill {
  pointer-events: auto;
  width: min(400px, 100%);
  background: var(--white);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(38, 38, 38, 0.06), 0 10px 34px rgba(38, 38, 38, 0.12);
  overflow: hidden;
  transition: width 0.6s var(--ease);
}
.pill.open { width: min(1000px, 100%); }
.pill-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 7px;
  height: 56px;
}
.pill-logo {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  background: var(--ink);
  border-radius: 12px;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.pill-logo svg { width: 20px; height: 20px; color: var(--white); }
.pill-logo:hover { background: var(--grey); }
.pill-logo:hover svg { color: var(--ink); }
.pill-name {
  flex: 1;
  text-align: center;
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.01em;
}
.pill-toggle {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border: 0;
  background: transparent;
  border-radius: 12px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: background 0.3s var(--ease);
}
.pill-toggle:hover { background: var(--ink); }
.pill-toggle:hover span { background: var(--white); }
.pill-toggle span {
  display: block;
  width: 17px;
  height: 1.8px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 0.45s var(--ease), background 0.3s var(--ease);
}
.pill-toggle span + span { margin-top: 5px; }
.pill.open .pill-toggle span:first-child { transform: translateY(3.4px) rotate(45deg); }
.pill.open .pill-toggle span:last-child { transform: translateY(-3.4px) rotate(-45deg); }

.pill-drawer {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.6s var(--ease);
}
.pill.open .pill-drawer { grid-template-rows: 1fr; }
/* .pill-panel must stay AUTO-height: it's the drawer's grid item, and a
   definite height on it sizes the 0fr track to that height instead of
   collapsing it — the closed pill then hangs open. The 394px lives on the
   content below, so max-content (and with it the 1fr reveal) still lands on
   the fixed 1000 × 450 box (450 = 394 + the 56px bar). */
.pill-panel {
  min-height: 0;
  overflow: hidden;
}
.panel-main {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: 40px;
  padding: 30px 34px 34px;
  height: 394px;
}
/* two columns: nav + slogan on the left, video + its meta row on the right.
   min-width:0 matters — a grid item sized by its content would otherwise be
   free to grow past the pill (the video's intrinsic width is 1920px). */
.panel-col { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
/* social row — sits on the column floor, diagonally opposite the meta row.
   40px buttons, 16px marks, 8px apart. */
.panel-social {
  display: flex;
  gap: 8px;
  margin-top: auto;
}
.soc {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: var(--grey);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 0.25s var(--ease);
}
/* the mark is a mask, so one colour drives it and the hover can invert */
.soc i {
  width: 16px;
  height: 16px;
  background: var(--ink);
  -webkit-mask: var(--m) center / contain no-repeat;
  mask: var(--m) center / contain no-repeat;
  transition: background 0.25s var(--ease);
}
.soc:hover { background: var(--ink); }
.soc:hover i { background: var(--white); }
.panel-nav { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.panel-nav a {
  font-size: clamp(22px, 2vw, 30px);
  font-weight: 500;
  letter-spacing: -0.02em;
  padding: 6px 12px;
  margin-left: -12px;
  border-radius: 10px;
  opacity: 0;
  transform: translateY(-8px);
  /* order: opacity, transform, background, color — the stagger delay below
     targets only the first two so the hover fill (bg/color) is never delayed */
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease),
              background 0s, color 0s;
  transition-delay: 0s, 0s, 0s, 0s;
}
/* entrance cascade — --base/--step drive the whole thing, so the touch block
   below can compress it to fit a shorter reveal by changing two numbers */
.panel-nav a:nth-child(2) { --i: 1; }
.panel-nav a:nth-child(3) { --i: 2; }
.panel-nav a:nth-child(4) { --i: 3; }
.panel-nav a:nth-child(5) { --i: 4; }
.panel-nav a:nth-child(6) { --i: 5; }
.pill.open .panel-nav a {
  opacity: 1;
  transform: none;
  --d: calc(var(--base, 0.12s) + var(--i, 0) * var(--step, 0.05s));
  transition-delay: var(--d), var(--d), 0s, 0s;
}
.panel-nav a:hover { background: var(--ink); color: var(--white); }
/* "Soon" tag rides next to a label whose destination doesn't exist yet */
.panel-nav a { display: inline-flex; align-items: center; gap: 10px; }
.nav-soon {
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(38, 38, 38, 0.07);
  color: rgba(38, 38, 38, 0.5);
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.panel-nav a:hover .nav-soon { background: rgba(255, 255, 255, 0.18); color: var(--white); }
/* full column width at a locked 16:9 — declared rather than derived from the
   panel box, so the ratio holds at every pill width. 6px corners match the
   framed videos in the carousel (.car-frame). */
.panel-media {
  position: relative;
  flex: 0 0 auto;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 6px;
  overflow: hidden;
  background: var(--grey);
}
.panel-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* under the video, ends flush with the column's corners. margin-top:auto
   drops it to the column floor (level with the slogan opposite) now that the
   16:9 video no longer eats the full height; it's a no-op once the column is
   content-sized, where the padding alone sets the gap. */
.panel-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 16px;
  font-size: 14px;
  font-weight: 500;
  color: rgba(38, 38, 38, 0.55);
}
.panel-meta a { display: inline-flex; align-items: center; gap: 7px; color: var(--ink); }
.panel-meta .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--sky); }

/* touch: the reveal used to hitch. The 34px blurred shadow had to be
   re-rasterised on every frame while the box grew, the cascade outlasted the
   reveal itself, and the panel video started loading the instant it played
   (that last one is deferred in main.js). */
@media (max-width: 760px), (pointer: coarse) {
  .pill {
    box-shadow: 0 1px 2px rgba(38, 38, 38, 0.08), 0 4px 12px rgba(38, 38, 38, 0.10);
    transition-duration: 0.42s;
  }
  .pill-drawer { transition-duration: 0.42s; }
  .panel-nav a { --base: 0.08s; --step: 0.028s; }
}

/* ================================================================
   Scroll progress rail
   ================================================================ */
.rail {
  position: fixed;
  right: 14px;
  top: 50%;
  translate: 0 -50%;
  z-index: 90;
  background: var(--white);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(38, 38, 38, 0.08), 0 8px 24px rgba(38, 38, 38, 0.12);
  padding: 12px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.rail i {
  width: 3px;
  height: 5px;
  border-radius: 2px;
  background: rgba(38, 38, 38, 0.28);
  transition: height 0.4s var(--ease), background 0.4s var(--ease);
}
.rail i.on { height: 18px; background: var(--ink); }

/* ================================================================
   Hero — full-bleed sky video with ‹ Waypoint ›
   ================================================================ */
.hero {
  /* --p: 0 → 1 tucks the video into a rounded inset card on scroll */
  --p: 0;
  position: relative;
  height: 100vh;
  height: 100svh;
  color: var(--white);
}
.hero-video {
  position: absolute;
  top: calc(var(--p) * var(--bleed));
  left: calc(var(--p) * var(--bleed));
  width: calc(100% - 2 * var(--p) * var(--bleed));
  height: calc(100% - 2 * var(--p) * var(--bleed));
  object-fit: cover;
  border-radius: calc(var(--p) * var(--r-lg));
}
.hero-inner {
  position: relative;
  z-index: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* open central band so the object + brackets sit between the lines */
  gap: clamp(200px, 34vh, 420px);
  text-align: center;
  padding-inline: var(--margin);
}
.hero-line {
  font-size: clamp(52px, 8.5vw, 140px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.0;
  /* delayed so the rise happens as the preloader blinks away (blink at 4.3s) */
  animation: heroRise 1.2s var(--ease) 4.35s both;
}
.hero-line:last-child { animation-delay: 4.55s; }
/* returning visitors skip the intro — the hero can't wait on a preloader
   that never runs, so the lines rise immediately instead */
html.intro-seen .preloader { display: none; }
html.intro-seen .hero-line { animation-delay: 0.15s; }
html.intro-seen .hero-line:last-child { animation-delay: 0.35s; }
/* brackets pinned to the viewport's vertical centre, at the side edges,
   framing whatever object sits in the middle of the footage */
.hero-brackets {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  width: var(--hero-span);
  translate: -50% -50%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  pointer-events: none;
  /* always visible — hidden behind the preloader until the blink reveals them
     exactly where the preloader's brackets already sit */
}
.hero-brackets .bracket { height: clamp(56px, 8vw, 150px); }
@keyframes heroRise {
  from { opacity: 0; transform: translateY(36px); }
  to   { opacity: 1; transform: none; }
}
.hero-foot {
  position: absolute;
  z-index: 1;
  left: 0;
  right: 0;
  bottom: 30px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-inline: var(--margin);
  font-size: 14px;
  font-weight: 500;
}
.hero-foot a { display: inline-flex; align-items: center; gap: 7px; }
.scroll-arrow {
  width: 15px;
  height: 15px;
  display: inline-block;
  animation: nudge 2.2s ease-in-out infinite;
}
@keyframes nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(4px); } }

/* ================================================================
   Statement + story card
   ================================================================ */
.statement { padding-block: clamp(90px, 13vh, 170px) 0; }
.statement-text {
  grid-column: 1 / 7;
  font-size: clamp(26px, 3.4vw, 52px);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.16;
}
/* stat cards — big-number metrics with an arrow, divider and caption */
.stat-grid {
  margin-top: clamp(70px, 10vh, 130px);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--gutter);
}
.stat-card {
  background: var(--card);
  border-radius: var(--r-lg);
  padding: 24px;
  min-height: clamp(300px, 40vh, 420px);
  display: flex;
  flex-direction: column;
}
.stat-label {
  font-size: 14px;
  font-weight: 500;
  color: rgba(38, 38, 38, 0.5);
}
.stat-main {
  margin-top: auto;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}
.stat-arrow {
  font-size: clamp(22px, 2.4vw, 34px);
  line-height: 1;
  color: var(--ink);
}
.stat-arrow.down { color: #e5484d; }   /* red — reduction */
.stat-arrow.up { color: #30a46c; }     /* green — increase */
.stat-value {
  font-size: clamp(40px, 4.6vw, 78px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.9;
}
.stat-divider {
  border-top: 1px solid var(--grey);
  margin: 22px 0 18px;
}
.stat-desc {
  font-size: 14px;
  line-height: 1.45;
  color: rgba(38, 38, 38, 0.7);
  max-width: 30ch;
}

/* chain marquee — endless horizontal scroll of protocol cards */
.chain-marquee {
  margin-top: clamp(70px, 10vh, 130px);
  overflow: hidden;
}
.chain-track {
  display: flex;
  width: max-content;
  animation: chainScroll 45s linear infinite;
}
/* hover-pause only where hover is real — on touch a tap leaves a sticky
   :hover behind, which froze the marquee until you tapped somewhere else */
@media (hover: hover) {
  .chain-marquee:hover .chain-track { animation-play-state: paused; }
}
.chain-group {
  display: flex;
  gap: var(--gutter);
  padding-right: var(--gutter);
}
.chain-card {
  position: relative;
  flex: 0 0 auto;
  width: clamp(230px, 18vw, 300px);
  aspect-ratio: 4 / 5;
  background: var(--card);
  border-radius: var(--r-lg);
  padding: 24px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  transition: background 0.3s var(--ease);
}
.chain-card:hover { background: var(--grey); }
.chain-card:hover .cap-plus { background: var(--ink); }
.chain-card:hover .cap-plus::before,
.chain-card:hover .cap-plus::after { background: var(--white); }
.chain-card .cap-plus { right: auto; left: 16px; }
/* protocol logo — the SVG is used as a mask so one colour drives it:
   muted grey at rest, ink on card hover */
.chain-logo {
  position: absolute;
  inset: 0;
  margin: auto;
  width: var(--lsize, 90px);
  height: var(--lsize, 90px);
  background-color: rgba(38, 38, 38, 0.22);
  -webkit-mask: var(--logo) center / contain no-repeat;
  mask: var(--logo) center / contain no-repeat;
  transition: background-color 0.3s var(--ease);
}
.chain-card:hover .chain-logo { background-color: var(--ink); }
/* on touch the marquee becomes a plain swipeable rail — no animation to
   fight the finger, and no sticky :hover tint left behind after a tap
   (must sit after the hover rules above to override them) */
@media (max-width: 760px), (pointer: coarse) {
  /* the rail is display-only on touch: the css keyframes run untouched, which
     is the only version that stays glass-smooth. No swipe, no js driving it,
     nothing that re-rasterises the masked logos mid-flight. */
  .chain-card:hover { background: var(--card); }
  .chain-card:hover .cap-plus { background: rgba(38, 38, 38, 0.08); }
  .chain-card:hover .cap-plus::before,
  .chain-card:hover .cap-plus::after { background: var(--ink); }
  .chain-card:hover .chain-logo { background-color: rgba(38, 38, 38, 0.22); }
}
.chain-name {
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
}
@keyframes chainScroll {
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .chain-track { animation: none; }
}

/* ================================================================
   Staircase
   ================================================================ */
.stair { height: 230vh; }
.stair-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--white);
}
.stair-line {
  display: flex;
  gap: 0.28em;
  font-size: clamp(48px, 8.5vw, 150px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
}
.stair-word {
  transform: translate(calc(var(--sp, 1) * var(--sx, 0) * 1vw),
                       calc(var(--sp, 1) * var(--sy, 0) * 1vh));
  will-change: transform;
}
.stair-copy {
  margin-top: 44px;
  max-width: 52ch;
  text-align: center;
  font-size: 20px;
  line-height: 1.55;
  padding-inline: var(--margin);
  opacity: var(--cp, 0);
  translate: 0 calc((1 - var(--cp, 0)) * 20px);
}
.stair-copy a { text-decoration: underline; text-underline-offset: 3px; }

/* ================================================================
   Feature blocks
   ================================================================ */
.feature { padding-top: clamp(70px, 10vh, 120px); }
.feature-card {
  height: 88vh;
  min-height: 420px;
  display: grid;
  place-items: center;
}

/* capability card grid ("What agents call") */
.cap-heading {
  font-size: clamp(30px, 3.4vw, 52px);
  font-weight: 500;
  letter-spacing: -0.02em;
  margin-bottom: clamp(28px, 4vh, 48px);
}
.capability-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gutter);
  margin-top: var(--gutter);   /* tight gap below the video */
}
.cap-card {
  position: relative;
  background: var(--card);
  border-radius: var(--r-lg);
  aspect-ratio: 3 / 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  padding: 24px;
  transition: background 0.3s var(--ease);
}
.cap-card:hover { background: var(--grey); }
.cap-plus {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(38, 38, 38, 0.08);
  transition: background 0.25s var(--ease);
}
.cap-plus::before,
.cap-plus::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--ink);
  border-radius: 2px;
}
.cap-plus::before { width: 12px; height: 1.6px; }
.cap-plus::after { width: 1.6px; height: 12px; }
.cap-card:hover .cap-plus { background: var(--ink); }
.cap-card:hover .cap-plus::before,
.cap-card:hover .cap-plus::after { background: var(--white); }
.cap-icon { width: clamp(48px, 5vw, 68px); height: auto; color: var(--ink); }
.cap-label { font-size: clamp(15px, 1.4vw, 18px); font-weight: 500; }

/* dot-grid icons — rebuild dot-by-dot on card hover */
.dot-icon {
  width: clamp(64px, 6.5vw, 92px);
  height: auto;
  color: var(--ink);
}
.dot-icon circle,
.dot-icon rect {
  transform-box: fill-box;
  transform-origin: center;
}
/* on hover the dots pop back in, staggered by their --i index → a "rebuild" */
.cap-card:hover .dot-icon circle,
.cap-card:hover .dot-icon rect {
  animation: dotPop 0.42s var(--ease) both;
  animation-delay: calc(var(--i) * 45ms);
}
@keyframes dotPop {
  0%   { transform: scale(0);    opacity: 0; }
  55%  { transform: scale(1.35); opacity: 1; }
  100% { transform: scale(1);    opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .cap-card:hover .dot-icon circle,
  .cap-card:hover .dot-icon rect,
  .hiw-icon.digit-rebuild .hiw-digit circle,
  .hiw-icon.rebuild .hiw-symbol circle,
  .hiw-card:not(.active):hover .hiw-digit circle,
  .hiw-card.active:hover .hiw-symbol circle,
  .hiw-card.dot-rebuild .hiw-rail-dots i,
  .hiw-card:not(.active):hover .hiw-rail-dots i { animation: none; }
  .hiw-card.active:hover video { transform: none; }
  .car-card:hover video,
  .car-card:hover .car-frame img { transform: none; }
}
/* temporary dots/squares compare switch */
.cap-set.is-hidden { display: none; }
.cap-switch {
  display: flex;
  justify-content: center;
  gap: 3px;
  width: fit-content;
  margin: 18px auto 0;
  background: var(--white);
  border: 1px solid rgba(38, 38, 38, 0.08);
  border-radius: 999px;
  padding: 3px;
}
.cap-switch-btn {
  border: 0;
  background: transparent;
  font: 500 12px/1 "Helvetica Neue W", sans-serif;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.cap-switch-btn.active { background: var(--ink); color: var(--white); }
.feature-title {
  position: relative;
  z-index: 1;
  color: var(--white);
  font-size: clamp(34px, 4.6vw, 76px);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.05;
  text-align: center;
  padding-inline: 20px;
  text-shadow: 0 2px 24px rgba(38, 38, 38, 0.25);
}

.sub-row {
  display: grid;
  gap: var(--gutter);
  margin-top: var(--gutter);
  align-items: stretch;
}
.sub-row.cols-2 { grid-template-columns: 1fr 1.35fr; }
.sub-row.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.sub-row .media-card { aspect-ratio: 16 / 10; }
.sub-row.cols-2 .media-card { aspect-ratio: 16 / 8.5; }
/* Desktop 3-col: the media cards share the row with the (tall) text card. Let
   them fill the cell — matching its height and their own column width — rather
   than letting aspect-ratio derive width from the stretched height, which
   overflowed the column. Scoped >1000px so the stacked breakpoints keep 16/10. */
@media (min-width: 1001px) {
  .sub-row.cols-3 .media-card { aspect-ratio: auto; height: 100%; min-width: 0; }
}

.text-card {
  background: var(--card);
  border-radius: var(--r-lg);
  padding: 22px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 60px;
}
.text-card .card-body { max-width: 46ch; font-size: 18px; }

/* ================================================================
   Technology
   ================================================================ */
.tech {
  /* curtain reveal (sunday.ai-style): the section is pulled one screen up
     behind the page; its inner screen pins fullscreen while the white page
     above scrolls away, uncovering it. 440vh = 100vh hidden behind the
     curtain + 100vh reveal (heading alone, centered) + 100vh interior scroll
     (console rises, heading glides up, copy/buttons appear) + 40vh hold
     + 100vh where the sky stays put while the next white section slides
     over it (the exit parallax — the inverse of the entry curtain). */
  position: relative;
  z-index: 0;
  margin-top: -100vh;
  height: 380vh;   /* trimmed: the curtain follows soon after the copy lands */
  /* wrapper matches the pin: if a webview's vh/lvh disagree with the real
     visible height, the sliver behind the pin blends in instead of
     flashing the white page */
  background: var(--ink);
}
.tech-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100lvh;   /* iPad/webview UAs where 100vh < the toolbar-hidden viewport */
  height: 100svh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(40px, 6vh, 80px) var(--bleed);
  background: var(--ink);
  /* faint dot grid over the ink — quiet console-paper texture */
  background-image: radial-gradient(#1F1F1F 1.5px, transparent 1.6px);
  background-size: 36px 36px;
  background-position: center;
  color: var(--white);
  text-align: center;
}
/* the sections above are the curtain — they must paint (opaquely) above the
   pulled-up tech screen while it hides behind them */
.statement,
.hiw {
  position: relative;
  z-index: 2;
  background: var(--white);
}
/* the curtain's bottom edge is always rounded (the sky shows through the
   corner notches) */
.hiw { border-radius: 0 0 var(--r-lg) var(--r-lg); }
.tech-title {
  position: relative;
  z-index: 0;
  font-size: clamp(52px, 8.5vw, 140px);   /* same scale as the hero lines */
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
  margin-bottom: 0;
  /* --ty (scroll-driven, in js): holds the heading at viewport centre during
     the reveal, then glides it up to its natural spot as the console rises */
  translate: 0 var(--ty, 0px);
  will-change: translate;
}
/* typewriter caret — blinks while the heading types, fades out after */
.tech-title .k { color: inherit; }   /* MCP — plain white now */
.tech-title .type-text { position: relative; }
/* session nodes — three dark cards floating over the heading, joined by
   dotted connectors; they drift upward as the pin scrolls (js parallax) */
.tech-nodes {
  position: absolute;
  inset: 0;
  z-index: 1;             /* over the heading, like the reference */
  pointer-events: none;
}
.tech-links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;   /* connector dots sit on top of the card edges */
  pointer-events: none;
}
.tech-node {
  position: absolute;
  width: clamp(230px, 24vw, 320px);   /* fluid — squeezes with the screen */
  min-height: 236px;   /* keeps the roomy middle from the reference */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 18px 20px 18px;
  background: #101010;
  border-radius: var(--r-lg);
  text-align: left;
  will-change: transform;
}
/* loosely-aligned row under the heading — hugs the centre on wide monitors,
   falls back to edge-relative spacing when the window squeezes */
/* the constellation's resting shape. The offsets tune where each card
   settles at the TOP of its parallax travel — js only adds the rise. */
.tn-1 { left: max(4%, calc(50% - 575px)); top: calc(64% + 40px); }
.tn-2 { left: calc(50% - clamp(230px, 24vw, 320px) / 2); top: 58%; }
.tn-3 { right: max(4%, calc(50% - 575px)); top: calc(67% - 60px); }
.tn-top {
  display: flex;
  align-items: center;
  align-self: stretch;
  gap: 10px;
  font-size: 14px;
  font-weight: 500;
}
.tn-top svg { width: 17px; height: 17px; flex: 0 0 auto; }
.tn-top svg[viewBox="0 0 20 12"] { width: 21px; }
.tn-dots {
  margin-left: auto;
  color: rgba(255, 255, 255, 0.55);
  font-size: 18px;
  line-height: 1;
}
/* flex pushes the copy block to the card floor — the middle stays airy */
.tech-node h3 { font-size: 18px; font-weight: 500; margin: auto 0 8px; }
/* the card carrying the agent marks is the tall one */
.tn-3 h3 { margin-top: 24px; }
.tn-3 { min-height: 272px; }
.tech-node p {
  font-size: 18px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.6);
  margin: 0;
  max-width: 30ch;
  transition: color 0.25s var(--ease);
}
/* the svgs carry ~20% built-in padding — the negative lead keeps the first
   mark flush with the text edge, negative gaps pull the rest together.
   Marks are css masks (white fill) so each can tint to its brand colour
   on hover (--m / --c set inline per mark) */
.tn-agents {
  display: flex;
  margin-top: auto;
  margin-left: -12px;
  pointer-events: auto;   /* hover works despite the inert node layer */
}
.tn-agents i {
  display: block;
  width: 60px;
  height: 60px;
  background: rgba(255, 255, 255, 0.92);
  -webkit-mask: var(--m) center / contain no-repeat;
  mask: var(--m) center / contain no-repeat;
  transition: background 0.25s var(--ease);
}
.tn-agents i:hover { background: var(--c); }
.tn-agents i + i { margin-left: -8px; }
/* the copy command hangs just below the first card and rides its parallax
   (.tech-node prefix outranks the later .btn-copy { position: relative }) */
.tech-node .tn-copy {
  position: absolute;
  top: calc(100% + 14px);
  left: 0;
  width: 100%;
  height: 48px;
  justify-content: space-between;
  padding-right: 12px;   /* air between the copy icon and the pill edge */
  border-radius: 12px;
  pointer-events: auto;
  background: #101010;
  border: 0;
}
.tech-node .tn-copy:hover { background: #1c1c1c; }
.tech-node .copy-pop { background: var(--white); color: var(--ink); }
/* command truncates with an ellipsis instead of wrapping when squeezed */
.tech-node .tn-copy .btn-copy-cmd {
  flex: 1;
  min-width: 0;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* white "Connect" pill inside the first card — label + circled plus */
.tech-node .tn-connect {
  display: flex;
  align-items: center;
  /* full width of the card, so the circled icon rides the right edge */
  justify-content: space-between;
  width: 100%;
  gap: 12px;
  margin-top: 22px;
  height: 44px;
  padding: 0 5px 0 22px;
  border: 0;
  border-radius: 999px;
  background: var(--white);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  pointer-events: auto;
  transition: background 0.2s var(--ease);
}
.tech-node .tn-connect:hover { background: var(--grey); }
.tn-connect-icon {
  display: inline-flex;
  width: 34px;
  height: 34px;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: rgba(38, 38, 38, 0.08);
  transition: background 0.2s var(--ease);
}
.tn-connect-icon svg { width: 17px; height: 17px; }
.tech-node .tn-connect:hover .tn-connect-icon { background: var(--ink); color: var(--white); }
/* budget slider — same pill language as the copy command, hangs under
   the third card; the invisible range input makes the whole pill draggable */
.tech-node .tn-budget {
  position: absolute;
  top: calc(100% + 14px);
  left: 0;
  width: 100%;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-left: 18px;
  border-radius: 12px;
  background: #101010;
  overflow: hidden;
  pointer-events: auto;
}
/* grey fill grows from the left with the slider value */
.tech-node .tn-budget::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: calc(var(--fill, 0.16) * 100%);
  background: #1c1c1c;
}
.tn-budget-label {
  position: relative;
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.55);
}
.tn-budget-val {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding-right: 18px;
  font-size: 14px;
  font-weight: 500;
  color: var(--white);
}
.tn-budget input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
/* narrow desktop: slim the cards and fall back to edge-relative spacing */
@media (max-width: 1260px) {
  .tech-node { min-height: 205px; padding: 16px 18px 14px; }
  .tn-3 { min-height: 235px; }
}
/* (the old "hide the constellation on touch" rule lived here. It keyed off
   pointer:coarse, so it also hid the nodes on a landscape tablet — where
   there is plenty of room for them. Narrow screens get the stacked layout
   from the 900px block instead.) */
.type-caret {
  display: inline-block;
  margin-left: 0.05em;
  font-weight: 400;
  animation: caretBlink 1.1s steps(1) infinite;
}
.type-caret.done {
  animation: none;
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}
@keyframes caretBlink {
  0%, 55% { opacity: 1; }
  56%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .type-caret { display: none; }
}
.tech-terminal {
  width: min(680px, 100%);
  /* rests high, overlapping the centre-fixed heading — --cy (scroll-driven,
     in js) lifts it up from below the fold and over the heading */
  margin: clamp(24px, 4vh, 60px) auto 0;
  translate: 0 var(--cy, 0px);
  position: relative;
  z-index: 2;
  background: var(--ink);
  border-radius: var(--r-lg);
  overflow: hidden;
  text-align: left;
  box-shadow: 0 24px 70px rgba(38, 38, 38, 0.28);
  /* box-shadow only — translate is scroll-driven (--cy) and must not lag */
  transition: box-shadow 0.4s var(--ease);
  will-change: translate;
}
/* deeper shadow when hovering the console window */
.tech-terminal:hover { box-shadow: 0 44px 110px rgba(38, 38, 38, 0.45); }
.term-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 14px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.term-bar i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  transition: background 0.3s var(--ease);
}
/* traffic-light colours light up on hover, like a mac window */
.tech-terminal:hover .term-bar i:nth-child(1) { background: #ff5f57; }
.tech-terminal:hover .term-bar i:nth-child(2) { background: #febc2e; }
.tech-terminal:hover .term-bar i:nth-child(3) { background: #28c840; }
/* title centred in the bar */
.term-bar span {
  position: absolute;
  left: 50%;
  translate: -50% 0;
  font-size: 14px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.45);
}
.tech-terminal pre {
  padding: 26px 24px 30px;
  overflow-x: auto;
  font: 400 13.5px/1.75 "SF Mono", ui-monospace, "Menlo", monospace;
  color: rgba(255, 255, 255, 0.88);
}
.tech-terminal .c { color: rgba(255, 255, 255, 0.38); }
.tech-terminal .k { color: var(--sky); }
.tech-terminal .s { color: #cdeeff; }
.tech-terminal .f { color: var(--sky); }
.tech-terminal .n { color: #cdeeff; }

.tech-copy {
  /* clear breathing room below the console */
  margin: clamp(40px, 6vh, 70px) auto 0;
  max-width: 54ch;
  font-size: 20px;
  line-height: 1.55;
}
.tech-copy a { text-decoration: underline; text-underline-offset: 3px; }
/* copy + buttons appear late in the interior scroll (--io: 0 → 1, in js) */
.tech-copy,
.tech-actions {
  opacity: var(--io, 0);
  translate: 0 calc((1 - var(--io, 0)) * 30px);
}
@media (prefers-reduced-motion: reduce) {
  .tech-title, .tech-terminal, .tech-copy, .tech-actions {
    opacity: 1;
    translate: none;
  }
}
.btn-pill {
  display: inline-flex;
  align-items: center;
  height: 40px;
  background: var(--white);
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  padding: 0 22px;
  border-radius: 999px;
  border: 1px solid rgba(38, 38, 38, 0.08);
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.btn-pill:hover { background: var(--ink); color: var(--white); }
/* pill with a circled icon on the right, like the console's copy button */
.btn-pill.btn-pill-icon { display: inline-flex; align-items: center; gap: 8px; padding-right: 7px; }
.pill-icon {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: rgba(38, 38, 38, 0.08);
  transition: background 0.2s var(--ease);
}
.pill-icon svg { width: 15px; height: 15px; }
.btn-pill-icon:hover .pill-icon { background: rgba(255, 255, 255, 0.2); }
.btn-copy {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  background: var(--ink);
  color: var(--white);
  padding: 5px 5px 5px 18px;
  border-radius: 999px;
  border: 1px solid var(--ink);
  cursor: pointer;
  font: inherit;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease);
}
.btn-copy:hover { background: #333333; border-color: #454545; }
.btn-copy-cmd {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 14px;
  letter-spacing: 0.01em;
}
.btn-copy-prompt { color: var(--sky); margin-right: 6px; }
.btn-copy-icon {
  display: inline-flex;
  width: 28px;
  height: 28px;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  transition: background 0.2s var(--ease);
}
.btn-copy-icon svg { width: 15px; height: 15px; }
.btn-copy:hover .btn-copy-icon { background: rgba(255, 255, 255, 0.2); }
.btn-copy.copied .btn-copy-icon,
.btn-copy.copied:hover .btn-copy-icon { background: var(--sky); color: var(--ink); }
/* "Copied" confirmation — same dark pill as the rail tooltip, floats above the button */
.copy-pop {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 10px);
  translate: -50% 4px;
  z-index: 10;
  background: var(--ink);
  color: var(--white);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 8px 13px;
  border-radius: 999px;
  pointer-events: none;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.25s var(--ease), translate 0.25s var(--ease);
}
.copy-pop.show { opacity: 1; translate: -50% 0; }
/* carousel card typography — identical across media and text cards */
.car-card .card-label { font-size: 18px; }
.car-card .card-body { font-size: 18px; line-height: 1.5; max-width: 44ch; }

/* ================================================================
   Designed / carousel
   ================================================================ */
.designed {
  /* full-width section (no card) so the carousel can bleed past the edges.
     Pulled -100vh up over the tech pin's exit stretch: the sky stays put
     while this white sheet slides on top of it (inverse curtain).
     100px padding = the tight gap the group leads with at entry. */
  padding-top: 100px;
  margin-top: -100vh;
  margin-bottom: clamp(50px, 7vh, 90px);   /* breathing room after the scrub releases */
  position: relative;
  z-index: 2;
  background: var(--white);
}
/* soft shadow above the sheet edge as it slides over the pinned sky —
   a gradient strip, far cheaper to composite than a huge box-shadow */
.designed::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 0;
  right: 0;
  height: 90px;
  background: linear-gradient(to top, rgba(38, 38, 38, 0.14), rgba(38, 38, 38, 0));
  pointer-events: none;
}
/* scrub room as real content (NOT padding — sticky only sticks within the
   parent's content box): the carousel stays pinned while this scrolls past.
   125vh: ~26vh rest stops at both ends of the sweep (P_LO/P_HI dead zones),
   and the section releases right as the end pause finishes — the carousel
   scrolls away WITH the FAQ trailing at a fixed distance, so nothing ever
   creeps up underneath a still-pinned carousel */
.designed::after {
  content: "";
  display: block;
  height: 125vh;
}
/* heading + carousel group — --dy (scroll-driven, in js) starts it higher
   (less dead space above the heading) and rubberbands it down to its
   resting spot as the section pins */
/* the heading + carousel group is its OWN sticky layer: it scrolls up with
   the sheet, then natively pins at its landing height (--gtop, set in js as
   the centred rest position) while the white sheet keeps sliding behind it.
   Compositor-level pinning — no JS counter-translate, no shake. */
.car-group {
  display: flex;
  flex-direction: column;
  position: sticky;
  top: var(--gtop, 20vh);
}
/* small pill tagline that sits above a section heading */
.section-tag {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  margin-inline: var(--margin);
  margin-bottom: 14px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 8px 13px;
  border-radius: 999px;
  background: var(--card);
  color: rgba(38, 38, 38, 0.55);
}
/* simple left-aligned section heading, same as "How it works" */
.designed-title {
  text-align: left;
  padding-inline: var(--margin);
  font-size: clamp(30px, 3.4vw, 52px);
  font-weight: 500;
  letter-spacing: -0.02em;
  margin-bottom: 32px;
}
.carousel { position: static; margin-top: 0; }
.car-track {
  display: flex;
  gap: var(--gutter);
  overflow-x: auto;
  scrollbar-width: none;
  padding-inline: var(--margin);
  scroll-padding-inline: var(--margin);
}
.car-track::-webkit-scrollbar { display: none; }
.car-card {
  flex: 0 0 auto;
  scroll-snap-align: start;
  border-radius: var(--r-lg);
  overflow: hidden;
  height: clamp(380px, 55vh, 560px);
}
/* slight zoom-in on hover, same move as the "How it works" open card */
.car-card video,
.car-card .car-frame img { transition: transform 0.55s cubic-bezier(0.45, 0.05, 0.15, 1); }
.car-card:hover video,
.car-card:hover .car-frame img { transform: scale(1.04); }
.car-media { position: relative; width: min(480px, 78vw); background: var(--ink); }
.car-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.car-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  padding: 22px;
  color: var(--white);
  background: linear-gradient(to bottom, rgba(38, 38, 38, 0.55), rgba(38, 38, 38, 0) 55%);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.car-overlay .card-body { color: rgba(255, 255, 255, 0.85); }
.car-text {
  width: min(840px, 90vw);
  background: var(--card);
  display: grid;
  /* media side runs a little wider so the framed video reads as an equal
     partner to the text column (the 14px frame inset eats into it) */
  grid-template-columns: 1fr 1.2fr;
}
.car-text-copy { padding: 22px; display: flex; flex-direction: column; gap: 10px; }
.car-text-media { position: relative; }
/* rounded frame clips the video, so the hover zoom stays masked inside it */
.car-frame {
  position: absolute;
  inset: 14px;
  border-radius: 6px;
  overflow: hidden;
}
.car-frame video,
.car-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.car-tint { background: var(--card); }   /* same light grey as the other cards */

/* chat graphics floating over the framed videos */
.car-chat {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px;
  pointer-events: none;
}
.chat-msg {
  max-width: 88%;
  padding: 12px 16px;
  border-radius: 16px;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
}
.chat-msg p { margin: 0; }
.chat-msg p + p { margin-top: 8px; }
.chat-msg.user {
  align-self: flex-end;
  background: var(--ink);
  color: var(--white);
  border-bottom-right-radius: 6px;
}
.chat-msg.agent {
  align-self: flex-start;
  /* fixed width so every agent bubble matches — the rate card would
     otherwise shrink-wrap to its rows and read narrower than the rest */
  width: 88%;
  background: var(--white);
  color: var(--ink);
  border-bottom-left-radius: 6px;
  box-shadow: 0 1px 2px rgba(38, 38, 38, 0.08), 0 10px 30px rgba(38, 38, 38, 0.12);
}
.chat-meta {
  font-size: 12px;
  font-weight: 500;
  color: rgba(38, 38, 38, 0.4);
}

/* ---- Two plain bubbles: a report, then the action it triggered ---- */
.car-chat-stack { gap: 6px; }
/* sized to their text, unlike the fixed-width rate card above */
.chat-msg.agent.chat-auto {
  width: auto;
  max-width: 88%;
  border-radius: 16px;
}
/* the first one is set, not shrink-wrapped, and gives way on narrow frames */
.chat-msg.agent.chat-first { width: 300px; }
/* The corners that face each other tighten, the way a run of messages reads.
   Written against the full .chat-msg.agent.chat-auto selector — the shorthand
   border-radius above is three classes deep and would otherwise outrank them. */
.chat-msg.agent.chat-auto:has(+ .chat-auto) { border-bottom-left-radius: 6px; }
.chat-msg.agent.chat-auto + .chat-msg.agent.chat-auto { border-top-left-radius: 6px; }
/* The running line: black text with a grey pulse travelling through it.
   no-repeat matters — the default tiles the gradient, so several pulses run
   at once and the loop appears to cut mid-sweep. At 250% width the pulse
   starts clear of the right edge and ends clear of the left, so each pass
   crosses the whole line before the next begins. */
.chat-note {
  font-weight: 500;
  background-image: linear-gradient(
    90deg,
    var(--ink) 40%,
    rgba(38, 38, 38, 0.26) 50%,
    var(--ink) 60%
  );
  background-repeat: no-repeat;
  background-size: 250% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  animation: chatSweep 3.2s linear infinite;
}
@keyframes chatSweep {
  from { background-position: 100% 0; }
  to { background-position: 0% 0; }
}
.chat-spin {
  width: 14px;
  height: 14px;
  margin-right: 8px;
  vertical-align: -2px;
  /* its own colour, or background-clip's transparent text would erase it */
  color: rgba(38, 38, 38, 0.45);
  transform-origin: center;
  animation: chatSpin 0.85s linear infinite;
}
.chat-strong { font-weight: 500; }
/* running-a-command line — spinner + muted label, like a tool call in flight */
.chat-run {
  display: flex;
  align-items: center;
  gap: 8px;
  color: rgba(38, 38, 38, 0.45);
  font-size: 13px;
}
.chat-run .run-spin {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  transform-origin: center;
  animation: chatSpin 0.85s linear infinite;
}
.chat-run .run-arrow {
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
  color: rgba(38, 38, 38, 0.42);
}
@keyframes chatSpin { to { transform: rotate(360deg); } }
/* label shimmers left → right while the command runs */
.chat-run span {
  background: linear-gradient(
    90deg,
    rgba(38, 38, 38, 0.3) 35%,
    rgba(38, 38, 38, 0.85) 50%,
    rgba(38, 38, 38, 0.3) 65%
  );
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: chatShimmer 3.4s linear infinite;
}
@keyframes chatShimmer {
  from { background-position: 125% 0; }
  to { background-position: -125% 0; }
}
/* live rate comparison rows — mono, best path highlighted in sky */
.chat-rates {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-bottom: 10px;
}
.chat-rate {
  position: relative;
  overflow: hidden;
  display: flex;
  justify-content: space-between;
  gap: 20px;
  padding: 7px 10px;   /* matches the deploy card's input rows */
  border-radius: 8px;
  background: #f5f5f5;                 /* unfilled track */
  color: rgba(38, 38, 38, 0.7);
  font-size: 13px;
  cursor: pointer;
  pointer-events: auto;   /* the chat layer itself is inert */
  transition: background 0.2s var(--ease);
}
/* how far each route got — a static freeze-frame per row (--p, inline) */
.chat-rate::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: calc(var(--p, 1) * 100%);
  background: var(--grey);
  transition: background 0.2s var(--ease);
}
.chat-rate > span { position: relative; z-index: 1; }
.chat-rate:hover { background: #efefef; }
.chat-rate:hover::before { background: #dedede; }
.chat-rate.best { background: rgba(161, 220, 254, 0.32); color: var(--ink); }
.chat-rate.best::before { background: var(--sky); }
.chat-rate.best:hover { background: rgba(161, 220, 254, 0.45); }
.chat-rate.best:hover::before { background: #8ad2fd; }
/* Deny / Confirm pair, right-aligned, with key hints like the app */
.chat-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}
.chat-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 7px 6px 12px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  pointer-events: auto;   /* the chat layer itself is inert */
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.chat-btn i {
  font-style: normal;
  font-size: 11px;
  line-height: 1;
  padding: 4px 6px;
  border-radius: 6px;
}
.chat-btn.deny {
  background: var(--white);
  border: 1px solid rgba(38, 38, 38, 0.12);
  color: var(--ink);
}
.chat-btn.deny i { background: var(--card); }
.chat-btn.deny:hover { background: var(--card); border-color: rgba(38, 38, 38, 0.28); }
.chat-btn.confirm { background: var(--ink); color: var(--white); }
.chat-btn.confirm i { background: rgba(255, 255, 255, 0.16); }
.chat-btn.confirm:hover { background: #3d3d3d; }
/* deploy checklist rows — each fills in, then settles into a table row */
.chat-fields {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-top: 10px;
}
.chat-field {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  background: var(--card);
  box-shadow: inset 0 0 0 1px transparent;
  font-size: 13px;
  color: rgba(38, 38, 38, 0.45);
  transition: background 0.25s var(--ease), box-shadow 0.25s var(--ease), color 0.25s var(--ease);
}
.chat-field b { font-weight: 400; }
.chat-field i { font-style: normal; color: var(--ink); }
/* being filled: 1px solid sky border with a 2px 50% sky ring outside it */
.chat-field.active {
  background: var(--white);
  box-shadow: inset 0 0 0 1px var(--sky), 0 0 0 2px rgba(161, 220, 254, 0.5);
}
.chat-field.active i::after {
  content: "|";
  margin-left: 1px;
  color: var(--ink);
  animation: caretBlink 1.1s steps(1) infinite;
}
/* filled: label left, value right — reads as a table item */
.chat-field.done { justify-content: space-between; }
.chat-field.done i { font-weight: 500; }
/* availability check that runs before the value settles into the row */
.chat-tag {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  white-space: nowrap;
}
.chat-tag:empty { display: none; }
.chat-tag em { font-style: normal; }
.chat-tag svg { width: 12px; height: 12px; flex: 0 0 auto; }
.chat-tag.pending { color: rgba(38, 38, 38, 0.42); }
.chat-tag.pending svg { transform-origin: center; animation: chatSpin 0.85s linear infinite; }
.chat-tag.ok { color: #1a9c5b; }
/* "strategies" card: agent is still typing */
.chat-typing {
  display: inline-flex;
  gap: 5px;
  align-items: center;
  padding: 15px 18px;
}
.chat-typing i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(38, 38, 38, 0.4);
  animation: chatDot 1.2s ease-in-out infinite;
}
.chat-typing i:nth-child(2) { animation-delay: 0.15s; }
.chat-typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes chatDot {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

.car-tabs {
  /* anchored to the group itself (just below the cards) so tabs pin and
     release in perfect lockstep with the carousel — no independent sticky
     layer, no jump when the section lets go */
  position: absolute;
  top: calc(100% + 24px);
  left: 50%;
  translate: -50% 0;
  display: flex;
  gap: 4px;
  background: var(--white);
  border-radius: 999px;
  padding: 4px;
  box-shadow: 0 1px 2px rgba(38, 38, 38, 0.08), 0 10px 30px rgba(38, 38, 38, 0.12);
  /* only visible while the carousel is pinned and scrubbing (.show from js) */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s var(--ease);
}
.car-tabs.show { opacity: 1; pointer-events: auto; }
.car-tab {
  border: 0;
  background: transparent;
  font: 500 14px/1 "Helvetica Neue W", sans-serif;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 16px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
/* idle tabs hover light grey — the dark backdrop is the sliding pill */
.car-tab:hover { background: rgba(38, 38, 38, 0.07); color: var(--ink); }
.car-tab { position: relative; z-index: 1; }
.car-tab.active { background: transparent; color: var(--white); }
.car-tab.active:hover { background: transparent; }
.car-tab-pill {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: 0;
  border-radius: 999px;
  background: var(--ink);
  z-index: 0;
  overflow: hidden;
  /* transform, not left — composited glide, no layout work per frame */
  transform: translateX(4px);
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1),
              width 0.35s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}

/* ================================================================
   Interlude band
   ================================================================ */
.interlude {
  margin: 0;                 /* full-bleed to the screen edges */
  background: var(--sky);
  padding: clamp(99px, 15.4vh, 198px) var(--margin);  /* ~10% taller */
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;   /* inter-inner (logo) sits dead-center */
}
/* button lifted out of flow so the logo stays centered; parked near the bottom */
.interlude .btn-dark {
  position: absolute;
  left: 50%;
  bottom: clamp(36px, 6vh, 68px);
  translate: -50% 0;
}
.inter-inner {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 40px;
}
.inter-left, .inter-right { font-size: 24px; font-weight: 500; }
.inter-left { text-align: left; }
.inter-right { text-align: right; }
.inter-logo { width: clamp(72px, 9vw, 130px); color: var(--ink); }
.btn-dark {
  display: inline-flex;
  align-items: center;
  height: 40px;
  background: var(--ink);
  color: var(--white);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  padding: 0 22px;
  border-radius: 999px;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.btn-dark:hover { background: var(--white); color: var(--ink); }

/* ================================================================
   FAQ
   ================================================================ */
.faq {
  /* roomier top: the accordion pull-up animation starts just off-screen */
  padding-block: clamp(80px, 9.5vh, 110px) clamp(90px, 13vh, 160px);
  overflow-anchor: none;   /* keep scroll anchoring from hopping while items resize */
}
.faq-label { grid-column: 1 / 3; font-size: 18px; font-weight: 500; }
.faq-list { grid-column: 4 / 7; }
.faq-list details { border-bottom: 1px solid var(--grey); }
.faq-list details:first-child { border-top: 1px solid var(--grey); }
.faq-list summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 21px 2px;
  font-size: 18px;
  font-weight: 500;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary:hover { color: rgba(38, 38, 38, 0.6); }
.chev {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-right: 1.6px solid var(--ink);
  border-bottom: 1.6px solid var(--ink);
  transform: rotate(45deg);
  transition: transform 0.35s var(--ease);
  margin-right: 4px;
}
.faq-list details.expanded .chev { transform: rotate(225deg); }
/* animated open/close: height via grid-rows + a sweeping gradient mask that
   softly unveils/hides the text (--reveal animated via @property) */
@property --reveal {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}
.faq-body {
  display: grid;
  grid-template-rows: 0fr;
  /* gentler symmetric ease than the global --ease: with single-open, a
     collapse and an expand run at once — an aggressive ease-out front-loads
     both motions and the clicked item snaps upward while unfolding */
  transition: grid-template-rows 0.55s cubic-bezier(0.45, 0.05, 0.15, 1);
}
.faq-body-inner {
  min-height: 0;
  overflow: hidden;
  --reveal: 0%;
  -webkit-mask-image: linear-gradient(to bottom, #000 var(--reveal), transparent calc(var(--reveal) + 26%));
          mask-image: linear-gradient(to bottom, #000 var(--reveal), transparent calc(var(--reveal) + 26%));
  transition: --reveal 0.6s cubic-bezier(0.45, 0.05, 0.15, 1);
}
.faq-list details.expanded .faq-body { grid-template-rows: 1fr; }
.faq-list details.expanded .faq-body-inner { --reveal: 120%; }
.faq-list details p {
  padding: 0 2px 24px;
  font-size: 18px;
  line-height: 1.55;
  color: rgba(38, 38, 38, 0.72);
  max-width: 60ch;
}
@media (prefers-reduced-motion: reduce) {
  .faq-body, .faq-body-inner { transition: none; }
}

/* ================================================================
   How it works — expanding cards (one open, rest collapsed to icon rails)
   ================================================================ */
.hiw {
  padding-top: clamp(150px, 20vh, 260px);
  /* breathing room above the curtain edge before the tech reveal starts */
  padding-bottom: clamp(140px, 18vh, 220px);
  /* squeeze as it lifts — js drives the same inset+round clip as the footer */
  will-change: clip-path;
}
.hiw-title {
  text-align: left;
  padding-inline: var(--margin);
  font-size: clamp(30px, 3.4vw, 52px);
  font-weight: 500;
  letter-spacing: -0.02em;
  margin-bottom: 32px;
}
.hiw-row {
  display: flex;
  gap: var(--gutter);
  align-items: stretch;   /* rails follow the open card's height */
}
.hiw-card {
  position: relative;
  flex: 1 1 0;   /* rails: narrow icon slivers (active card's grow sets the ratio) */
  min-width: 0;
  background: var(--card);
  border-radius: var(--r-lg);
  overflow: hidden;
  cursor: pointer;
  /* same gentle in-out as the FAQ — grow/shrink reads as one glide */
  transition: flex-grow 0.55s cubic-bezier(0.45, 0.05, 0.15, 1),
              background-color 0.3s var(--ease);
}
/* rail cards react to hover: a slight grey tint (the number rebuild is below) */
.hiw-card:not(.active):hover { background: #e7e7e7; cursor: pointer; }
/* row height is set by main.js to the FINAL active card's 16:9 height — a
   fixed height while widths animate, so the swap can't jump vertically.
   (aspect-ratio on the card itself derived height from the ANIMATING width,
   which collapsed and re-grew the row on every switch) */
.hiw-card.active { flex-grow: 8; cursor: default; }
.hiw-card video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: filter 0.55s cubic-bezier(0.45, 0.05, 0.15, 1),
              transform 0.55s cubic-bezier(0.45, 0.05, 0.15, 1),
              opacity 0.55s cubic-bezier(0.45, 0.05, 0.15, 1);
}
/* autoplay control — pause/play with a circular 8s countdown, top-right of
   the open card only */
.hiw-play {
  position: absolute;
  top: 22px;
  right: 22px;
  z-index: 2;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--white);
  display: none;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.25s var(--ease);
}
.hiw-card.active .hiw-play { display: inline-flex; }
.hiw-play:hover { background: rgba(255, 255, 255, 0.3); }
.hiw-ring {
  /* explicit box — sizing a replaced element by `inset` alone is resolved
     differently per engine (Safari shrank/shifted it, breaking alignment) */
  position: absolute;
  top: -6px;
  left: -6px;
  width: calc(100% + 12px);
  height: calc(100% + 12px);
  transform: rotate(-90deg);
  overflow: visible;
}
.hiw-ring circle {
  fill: none;
  stroke-width: 2;
}
.hiw-ring .ring-track { stroke: rgba(255, 255, 255, 0.22); }
.hiw-ring .ring-prog {
  stroke: var(--white);
  stroke-linecap: round;
  stroke-dasharray: 144.5;   /* 2π·23 — flush against the button edge */
  stroke-dashoffset: calc(144.5 * (1 - var(--prog, 0)));
}
/* pause bars ↔ play triangle */
.hiw-play-icon { position: relative; width: 12px; height: 12px; }
.hiw-play-icon::before,
.hiw-play-icon::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 3px;
  border-radius: 1px;
  background: var(--white);
}
.hiw-play-icon::before { left: 1.5px; }
.hiw-play-icon::after { right: 1.5px; }
.hiw-play.paused .hiw-play-icon::before {
  left: 3px;
  width: 0;
  background: transparent;
  border-left: 10px solid var(--white);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-radius: 0;
}
.hiw-play.paused .hiw-play-icon::after { display: none; }
@media (prefers-reduced-motion: reduce) {
  .hiw-play { display: none !important; }   /* no autoplay, no control */
}
/* open card: slight zoom-in on hover */
.hiw-card.active:hover video { transform: scale(1.04); }
/* retracted rails: video dissolves out (blurring as it fades) to the light
   grey card behind it */
.hiw-card:not(.active) video { opacity: 0; filter: blur(16px); transform: scale(1.8); }
/* legibility gradient under the copy on the open card */
.hiw-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(38, 38, 38, 0.8), rgba(38, 38, 38, 0) 58%);
  opacity: 0;
  transition: opacity 0.55s cubic-bezier(0.45, 0.05, 0.15, 1);
  pointer-events: none;
}
.hiw-card.active::after { opacity: 1; }
/* dot-grid icon (no badge), like the capability cards.
   Positioned absolutely so it can glide between top-left (open) and
   dead-center (rail) — top/left/translate all interpolate smoothly. */
.hiw-icon {
  position: absolute;
  top: 22px;
  left: 22px;
  z-index: 1;
  width: 52px;
  height: 52px;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: left 0.55s cubic-bezier(0.45, 0.05, 0.15, 1),
              translate 0.55s cubic-bezier(0.45, 0.05, 0.15, 1),
              width 0.55s cubic-bezier(0.45, 0.05, 0.15, 1),
              height 0.55s cubic-bezier(0.45, 0.05, 0.15, 1),
              color 0.3s var(--ease);
}
.hiw-card.active .hiw-icon {          /* plain white dots, larger on the open card */
  color: #fff;
  width: 80px;
  height: 80px;
}
.hiw-card:not(.active) .hiw-icon {
  left: 50%;                              /* stays at the top, centered in the rail */
  translate: -50% 0;
  color: var(--ink);                      /* dark dots on the grey rail */
}
/* two stacked glyphs: the digit (1–4) on rails, the symbol when expanded.
   They crossfade; the incoming symbol's dots also rebuild (see below). */
.hiw-icon svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.3s var(--ease);
}
.hiw-symbol { opacity: 0; }
.hiw-card.active .hiw-digit  { opacity: 0; }
.hiw-card.active .hiw-symbol { opacity: 1; }
.hiw-icon svg circle { transform-box: fill-box; transform-origin: center; }
/* rebuild the dots (staggered by index) — on expand (JS adds .rebuild) and
   when the mouse is over the ICON region (not the whole card) */
.hiw-icon.digit-rebuild .hiw-digit circle,
.hiw-icon.rebuild .hiw-symbol circle,
.hiw-card:not(.active):hover .hiw-digit circle,
.hiw-card.active:hover .hiw-symbol circle {
  animation: dotPop 0.42s var(--ease) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}
.hiw-icon svg circle:nth-child(1)  { --i: 0; }
.hiw-icon svg circle:nth-child(2)  { --i: 1; }
.hiw-icon svg circle:nth-child(3)  { --i: 2; }
.hiw-icon svg circle:nth-child(4)  { --i: 3; }
.hiw-icon svg circle:nth-child(5)  { --i: 4; }
.hiw-icon svg circle:nth-child(6)  { --i: 5; }
.hiw-icon svg circle:nth-child(7)  { --i: 6; }
.hiw-icon svg circle:nth-child(8)  { --i: 7; }
.hiw-icon svg circle:nth-child(9)  { --i: 8; }
.hiw-icon svg circle:nth-child(10) { --i: 9; }
.hiw-icon svg circle:nth-child(11) { --i: 10; }
.hiw-icon svg circle:nth-child(12) { --i: 11; }
/* fixed-width copy block so lines don't rewrap while the card is growing —
   the card's overflow:hidden clips it mid-animation */
.hiw-copy {
  position: absolute;
  left: 22px;
  bottom: 22px;
  z-index: 1;
  width: min(46ch, 56vw);
  display: flex;
  flex-direction: column;
  gap: 10px;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.hiw-card.active .hiw-copy {
  opacity: 1;
  transform: none;
  transition: opacity 0.45s var(--ease) 0.22s, transform 0.45s var(--ease) 0.22s;
}
/* author line breaks in the card copy — desktop only; on touch the card is
   narrow and the text has to wrap on its own */
.lb-desk { display: inline; }
@media (max-width: 760px), (pointer: coarse) {
  .lb-desk { display: none; }
}
.hiw-card .card-label { font-size: 18px; font-weight: 700; color: var(--white); }
.hiw-card .card-body { font-size: 18px; line-height: 1.5; max-width: 44ch; color: rgba(255, 255, 255, 0.85); }
/* closed rails carry the step name dead-centre (same words as the touch tab
   slider) plus an index read-out of 1–4 dots at the floor. The dot-matrix
   digit at the top of the rail is untouched. */
.hiw-rail-label {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  z-index: 1;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: rgba(38, 38, 38, 0.5);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), color 0.3s var(--ease);
}
.hiw-rail-dots {
  position: absolute;
  bottom: 26px;
  left: 50%;
  translate: -50% 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 7px;
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
}
.hiw-rail-dots i {
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: rgba(38, 38, 38, 0.22);
}
/* the index dots rebuild exactly like the digit above them — same pop, same
   40ms stagger, same triggers (.dot-rebuild is set alongside .digit-rebuild
   in main.js, plus card hover) */
.hiw-card.dot-rebuild .hiw-rail-dots i,
.hiw-card:not(.active):hover .hiw-rail-dots i {
  animation: dotPop 0.42s var(--ease) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}
.hiw-rail-dots i:nth-child(1) { --i: 0; }
.hiw-rail-dots i:nth-child(2) { --i: 1; }
.hiw-rail-dots i:nth-child(3) { --i: 2; }
.hiw-rail-dots i:nth-child(4) { --i: 3; }
/* both belong to the closed state — they clear out before the card opens */
.hiw-card.active .hiw-rail-label,
.hiw-card.active .hiw-rail-dots { opacity: 0; transition-duration: 0.18s; }
.hiw-card:not(.active):hover .hiw-rail-label { color: rgba(38, 38, 38, 0.75); }
/* squeezed desktop: below ~1220px the rail is under 98px and "Sessions" no
   longer fits across it, so the name turns 90° left and reads bottom-up.
   `rotate` resolves after `translate`, so the -50%/-50% centring still lands
   the line box (and with it the baseline) on the card's centre. */
@media (min-width: 761px) and (max-width: 1220px) {
  .hiw-rail-label { rotate: -90deg; }
}
/* under 1000px the rail is ~78px — the rotated name keeps its full length but
   drops a size so it stays in proportion with the shrinking box */
@media (min-width: 761px) and (max-width: 999px) {
  .hiw-rail-label { font-size: 14px; }
}
/* touch devices (phones AND tablets): tall open frame on top, the closed
   boxes in one row below it — flex order pins the active card to the first
   line no matter which card is open, the rails then share the second line.
   Rail height is EXPLICIT (not aspect-derived): Safari stretches
   aspect-ratio items in wrapped flex lines, which blew the boxes up. */
@media (max-width: 760px), (pointer: coarse) {
  /* Card height for touch layouts. The portrait formula (card width x 1.4666)
     runs away on a tablet in portrait, and 86vh collapses on a phone in
     landscape — so the result is clamped at both ends. */
  :root {
    --touch-card-h: clamp(320px, min(calc((100vw - 2 * var(--bleed)) * 1.4666), 88vh), 620px);
  }
  .hiw-row { flex-direction: row; flex-wrap: wrap; height: auto !important; }
  /* explicit height (≈3:4 of the card width, capped) — Safari mangles
     aspect-ratio on items inside wrapped flex lines, collapsing the card */
  .hiw-card.active {
    order: 0;
    flex: 0 0 100%;
    aspect-ratio: auto;
    height: var(--touch-card-h);
    max-height: none;
  }
  .hiw-card:not(.active) { order: 1; flex: 1 1 0; height: 112px; min-height: 0; aspect-ratio: auto; align-self: flex-start; }
  /* open-card copy stretches the full card width */
  .hiw-copy { width: calc(100% - 44px); }
  .hiw-card .card-body { max-width: none; }
  /* digits dead-centre in the bottom boxes */
  .hiw-card:not(.active) .hiw-icon { top: 50%; left: 50%; translate: -50% -50%; }
  /* the step names live in the tab slider here — the 112px boxes keep only
     their digit, so the rail label and index dots stay out of the layout */
  .hiw-rail-label, .hiw-rail-dots { display: none; }
  /* NO layout morphing — a box teleports between rows when the active card
     changes, so animating flex/size/position just looks broken. Cards swap
     instantly; only colours and the dot rebuild animate. */
  .hiw-card { transition: background-color 0.3s var(--ease); }
  .hiw-icon { transition: color 0.3s var(--ease); }
  .hiw-card video { transition: none; }
  /* one-way: the revealed video FADES IN (destination-state transition),
     while a demoted card still hides instantly via the rule above */
  .hiw-card.active video { transition: opacity 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94); }
  /* no hover-zoom on touch — iOS applies sticky :hover on tap, which
     snapped the freshly revealed video to scale(1.04) */
  .hiw-card.active:hover video { transform: none; }
  .hiw-copy { transition: none; }
  .hiw-card.active .hiw-copy { transition: none; }
  .hiw-card::after { transition: none; }
  .hiw-icon svg { transition: none; }
  /* the open card's icon at desktop scale */
  .hiw-card.active .hiw-icon { width: 80px; height: 80px; }
}
@media (max-width: 760px) {
  /* tech section: smaller code (title bar keeps its size), tighter copy,
     and the CTAs stack as two full-width rows */
  .tech-terminal pre { font-size: 10px; }
  .tech-copy { font-size: 18px; }
  /* keep "$ npx waypoint init" on a single line on phones */
  .tech-title { white-space: nowrap; font-size: 7.6vw; }
  /* CTAs stack as two rows but hug their content, centred */
  .tech-actions { flex-direction: column; align-items: center; padding-inline: var(--margin); }
  .tech-actions .btn-copy,
  .tech-actions .btn-pill { width: auto; justify-content: center; }
  /* tighter tail under the last HIW card */
  .hiw { padding-bottom: 48px; }
  /* more air before the FAQ */
  .faq { padding-top: 130px; }
}

/* hero hint label: "Scroll" on desktop, "Swipe" on touch-sized screens */
.lbl-swipe { display: none; }
@media (max-width: 1024px) {
  .lbl-scroll { display: none; }
  .lbl-swipe { display: inline; }
}

/* touch devices (phones AND tablets, any orientation): the carousel is a
   native swipe — no pin, no scrub room, no scroll-jack (it judders under
   touch momentum scrolling). The exit parallax goes with it: the shorter
   section can't cover a -100vh overlap, so the tech pin ends at its hold
   (340vh) and the white sheet follows in plain flow. */
@media (max-width: 760px), (pointer: coarse) {
  .designed::after { height: 0; }
  .car-group { position: static; }
  .car-track { scroll-snap-type: x mandatory; }
  .car-tabs { opacity: 1; pointer-events: auto; }
  /* autoplay countdown fills the active pill, same as the HIW step tabs */
  .car-tab-pill::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, 0.07);
    transform-origin: left center;
    transform: scaleX(var(--prog, 0));
  }
  .designed { margin-top: 0; }
}

/* ================================================================
   Tech / MCP section — stacked layout for narrow windows AND for every
   touch device. A landscape tablet has the width for the pinned desktop
   constellation but not the performance: sticky + scroll-driven parallax
   stutters on iPad, so it gets the plain-scrolling stack too (with the
   column capped so the cards don't stretch across the screen).
   main.js's techNarrow() must match this query exactly — when the two
   disagreed, a stacked layout got drawn with desktop connectors.
   ================================================================ */
@media (max-width: 900px), (pointer: coarse) {
  /* plain natural scroll — no curtain, no pin */
  .tech { height: auto; margin-top: 0; }
  .tech-pin {
    position: static;
    height: auto;
    padding-top: 110px;
    padding-bottom: 70px;
  }
  .tech-title { translate: none; }
  .tech-nodes {
    display: flex;
    position: relative;   /* the connector svg overlays the stack */
    flex-direction: column;
    gap: 46px;            /* room for the vertical elbows between cards */
    margin-top: 44px;
    pointer-events: auto;
    /* capped and centred so the stack stays compact on a wide tablet
       instead of the cards stretching the full screen width */
    width: min(100%, 640px);
    margin-inline: auto;
  }
  .tech-node {
    position: static;
    width: 76%;
    min-height: 200px;
    padding: 16px 18px 18px;   /* bottom matches the sides */
  }
  /* staggered right — left — right, joined centre to centre */
  .tn-1 { align-self: flex-end; }
  .tn-2 { align-self: flex-start; }
  .tn-3 { align-self: flex-end; }
  /* pills live inside the cards here — the pill-carrying cards get back
     the air the plain ones have */
  .tn-1, .tn-2, .tn-3 { min-height: 270px; }
  /* relative (not static) so the grey fill stays clipped inside the pill */
  .tech-node .tn-budget {
    position: relative;
    top: auto;
    width: 100%;
    margin-top: 22px;
    background: #202020;
  }
  .tech-node .tn-budget::before { background: #2a2a2a; }
  /* relative (not static) so the "Copied" pop anchors to the button
     itself instead of some positioned ancestor up the tree */
  .tech-node .tn-copy {
    position: relative;
    top: auto;
    width: 100%;
    margin-top: 22px;
    background: #202020;
  }
}


/* ================================================================
   Pre-footer band (dark)
   ================================================================ */
/* padding-inline follows the footer squeeze (--sq, set in main.js) so the dark
   box scales inward with the contracting card instead of being cropped */
.band { padding-inline: calc(var(--bleed) + var(--sq, 0px)); }
.band-inner {
  background: var(--ink);
  border-radius: var(--r-lg);
  min-height: 67vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  text-align: center;
  padding: 60px var(--margin);
}
.band-inner p { color: var(--white); font-size: 14px; font-weight: 500; }
.band-inner p span { color: var(--sky); }
.band-inner .btn-pill { border-color: transparent; }
/* same hover as the 404's back button: a light grey pill with the circled
   icon inverting to ink */
.band-inner .btn-pill:hover { background: var(--grey); color: var(--ink); }
.band-inner .btn-pill-icon:hover .pill-icon { background: var(--ink); color: var(--white); }
.band-actions {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
}
/* p5 sketch underlay — concentric tangent circles behind the CTA content */
.band-inner { position: relative; overflow: hidden; }
.band-sketch { position: absolute; inset: 0; z-index: 0; }
.band-sketch canvas { display: block; }
/* video underlay (currently the rotating earth, in place of the sketch) —
   sized by the box HEIGHT, native aspect, centred; the ink band shows on
   the sides rather than the video being stretched to the full width */
.band-video {
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% 0;
  height: 100%;
  width: auto;
  z-index: 0;
}
.band-inner .band-title,
.band-inner .btn-pill { position: relative; z-index: 1; }
.band-inner .band-title {
  font-size: clamp(30px, 3.4vw, 52px);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.15;
  max-width: 22ch;
}

/* ================================================================
   Footer (inside .page, white)
   ================================================================ */
.footer {
  padding: 20px var(--bleed) var(--bleed);
  /* --sq grows on scroll (set in main.js) as the card clips inward at the
     footer; padding the content in by the same amount keeps the side padding
     constant, so the footer looks squeezed rather than cropped. */
  padding-inline: calc(var(--bleed) + var(--sq, 0px));
}
.news-strip {
  background: #f2f2f2;
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  /* twice the old 68px: the 40px pill plus 48px of air on each side. The
     760px block below sets its own padding for the stacked layout. */
  padding: 48px 20px;
  margin-bottom: 56px;
}
.news-strip p { font-size: 14px; }
.news-strip p strong { font-weight: 700; margin-right: 10px; }
.news-strip p span { color: rgba(38, 38, 38, 0.55); }
.news-strip .btn-pill { padding: 0 16px; font-size: 14px; }
.news-strip .btn-pill-icon { padding-right: 7px; }   /* circled icon hugs the edge */
/* inverted by default — dark pill, green glyph. Hover flips it to white with
   a hairline edge and puts the green in the disc instead of the glyph. */
.news-strip .news-cta {
  background: var(--ink);
  color: var(--white);
  border-color: transparent;
}
.news-strip .news-cta .pill-icon {
  background: rgba(255, 255, 255, 0.2);
  color: #7aca96;
}
.news-strip .news-cta:hover {
  background: var(--white);
  color: var(--ink);
  border-color: rgba(38, 38, 38, 0.12);
}
.news-strip .news-cta:hover .pill-icon { background: #7aca96; color: var(--ink); }
/* and the whole strip inverts under it */
.news-strip,
.news-strip p strong,
.news-strip p span { transition: background 0.3s var(--ease), color 0.3s var(--ease); }
.news-strip:has(.news-cta:hover) { background: var(--ink); }
.news-strip:has(.news-cta:hover) p strong { color: var(--white); }
.news-strip:has(.news-cta:hover) p span { color: rgba(255, 255, 255, 0.55); }

.footer .grid { padding-inline: calc(var(--margin) - var(--bleed)); }
.foot-grid { row-gap: 40px; }
.foot-tag { grid-column: 1 / 4; font-size: 14px; font-weight: 500; }
.foot-col { grid-column: span 1; display: flex; flex-direction: column; gap: 8px; }
.foot-col h5 { font-size: 14px; font-weight: 700; margin-bottom: 4px; }
.foot-col a { font-size: 14px; color: rgba(38, 38, 38, 0.6); transition: color 0.25s; }
.foot-col a:hover { color: var(--ink); }
.foot-legal {
  margin-top: 220px;
  padding-block: 24px 0;
  font-size: 14px;
  color: rgba(38, 38, 38, 0.55);
}
.foot-legal span { grid-column: 1 / 4; }
.foot-legal a { grid-column: span 1; }
.foot-legal a:hover { color: var(--ink); }
/* the Legal column only exists on phones (desktop keeps the legal strip) */
.foot-col-legal { display: none; }

/* ================================================================
   Easter-egg band — sits on the blue body behind .page
   ================================================================ */
.egg {
  /* fixed fullscreen underlay — behind the page; the white page squeezes and
     scrolls up over it, exposing the edges (sunday.ai pattern). Hidden until
     the scroll nears the footer (.near, from js) so top-overscroll bounces
     can't flash the footer image behind the hero. */
  visibility: hidden;
  position: fixed;
  inset: 0;
  z-index: 0;
  background: var(--ink) url("../assets/images/footer bg.jpg") center / cover no-repeat;
  padding: 0 var(--margin);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;   /* content lives in the reveal zone at the bottom */
  gap: 20px;
  overflow: hidden;
}
/* in-flow spacer after .page — its height IS the final reveal: scrolling stops
   with this much of the underlay showing. Derived from the wordmark's actual
   rendered height (width-driven: (100vw − 2·margin) · 297/1271) plus a fixed
   240px for the line + chips + headroom, so the text is never swallowed on
   wide screens. Capped so at least 160px of the white page stays visible. */
.egg.near { visibility: visible; }
.egg-spacer {
  height: var(--reveal-h);
}
:root {
  /* the final footer reveal height — shared by the spacer and (on phones)
     the egg itself */
  --reveal-h: min(calc((100vw - 2 * var(--margin)) * 0.2337 + 240px), calc(100vh - 160px));
}
@media (max-width: 760px) {
  /* phones: bottom-anchored 70vh underlay — taller than the reveal band so
     overscroll bounces show image (not black body), but far from full-height
     so the picture isn't absurdly zoomed inside the band */
  .egg {
    top: auto;
    height: 70vh;
  }
}
.egg-line { font-size: 14px; font-weight: 500; color: rgba(255, 255, 255, 0.72); }
.egg-chips { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.chip-lite {
  display: inline-flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.85);
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  padding: 9px 14px;
}
/* enter as the curtain uncovers them (.egg gets .in from main.js) */
.egg-line, .chip-lite {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.egg.in .egg-line, .egg.in .chip-lite { opacity: 1; transform: none; }
.egg.in .egg-line { transition-delay: 0s; }
.egg.in .chip-lite:nth-child(1) { transition-delay: 0.1s; }
.egg.in .chip-lite:nth-child(2) { transition-delay: 0.18s; }
.egg.in .chip-lite:nth-child(3) { transition-delay: 0.26s; }
/* full-width wordmark standing on the base, letters filled by a video */
.egg-wordmark {
  width: 100%;
  height: auto;
  display: block;
  /* text block sits just above the wordmark, low in the reveal zone */
  margin-top: clamp(36px, 6vh, 72px);
}

/* ================================================================
   Tooltip — dark pill that shows text info on hover of [data-tip]
   ================================================================ */
.tip {
  position: fixed;
  z-index: 9600;   /* tooltips read above the open menu */
  background: var(--ink);
  color: var(--white);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 8px 13px;
  border-radius: 999px;
  pointer-events: none;
  white-space: nowrap;
  opacity: 0;
  translate: 0 4px;
  transition: opacity 0.25s var(--ease), translate 0.25s var(--ease);
}
.tip.show { opacity: 1; translate: 0 0; }
@media (hover: none) { .tip { display: none; } }

/* ================================================================
   Responsive
   ================================================================ */
@media (max-width: 1000px) {
  :root { --margin: 40px; }
  .capability-grid { grid-template-columns: repeat(2, 1fr); }
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .sub-row.cols-3 { grid-template-columns: 1fr 1fr; }
  .sub-row.cols-3 .text-card { grid-column: 1 / 3; min-height: 240px; }
  .faq-label { grid-column: 1 / 7; margin-bottom: 24px; }
  .faq-list { grid-column: 1 / 7; }
  /* narrow: the second column drops under the first, the panel goes back to
     content height, and the slogan is dropped (no floor left to sit on) */
  .panel-main { grid-template-columns: 1fr; gap: 24px; height: auto; padding-bottom: 30px; }
  /* stacked: the social row keeps its own gap under the nav instead of being
     pushed to a floor that no longer exists */
  .panel-social { margin-top: 22px; }
  /* .panel-media keeps its 16:9 here — one ratio in both layouts */
}

@media (max-width: 760px) {
  /* one consistent 16px edge/gutter on mobile — margin, grid gutter, and the
     full-width bleed (was 40px, so cards no longer sat further in than text) */
  :root { --margin: 16px; --gutter: 16px; --bleed: 16px; }

  /* other 20px spacings → 16px on mobile (font-sizes left as-is) */
  .site-header { padding-top: 16px; }
  /* the 34px desktop inset is a big share of a 375px pill — tighten it so the
     nav sits closer to the logo's own 7px edge */
  .panel-main { padding: 24px 20px 20px; }
  .footer { padding-top: 16px; }
  .egg { gap: 16px; }
  .feature-title { padding-inline: 16px; }

  .statement-text { grid-column: 1 / 7; }
  .stat-grid { grid-template-columns: 1fr; }
  .stat-card { min-height: 260px; }

  .sub-row.cols-2, .sub-row.cols-3 { grid-template-columns: 1fr; }
  .sub-row.cols-3 .text-card { grid-column: auto; }
  .sub-row .media-card, .sub-row.cols-2 .media-card { aspect-ratio: 16 / 11; }
  .text-card { min-height: 220px; gap: 40px; }

  .feature-card { height: 72svh; min-height: 0; }
  .cap-card { aspect-ratio: 1 / 1; }

  /* same card height as the open How-it-works card on touch; the media
     row stretches to soak up the extra height */
  .car-card { height: var(--touch-card-h); }
  /* the chat graphics keep their desktop layout and are simply scaled to
     fit the narrower frame (--cs is frameWidth / 430, set in main.js) */
  .car-chat {
    width: 430px;
    height: calc(100% / var(--cs, 1));
    transform: scale(var(--cs, 1));
    transform-origin: top left;
  }
}

/* the split card only STACKS when the screen is genuinely narrow — a phone
   in landscape is wide and short, where stacking is exactly wrong (it needs
   height the viewport doesn't have). Width-based, never pointer-based. */
@media (max-width: 760px) {
  .car-text {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    width: min(420px, 88vw);
  }
  .car-text-media { min-height: 280px; }   /* room for the chat bubbles */

  .inter-inner { grid-template-columns: 1fr; text-align: center; gap: 28px; justify-items: center; }
  .inter-left, .inter-right { text-align: center; }

  /* tall, airy signup box — content centred with generous breathing room */
  .news-strip { flex-direction: column; gap: 10px; text-align: center; padding-block: 100px; }
  /* headline and sub-line stack as two clean rows */
  .news-strip p strong { display: block; margin-right: 0; margin-bottom: 2px; }
  /* 2×2 column grid: Explore·About / Social·Legal */
  .foot-tag { grid-column: 1 / 7; }
  .foot-col { grid-column: span 3; }
  .foot-col-legal { display: flex; }
  /* the legal strip shrinks to just the © line (links live in the Legal col) */
  .foot-legal a { display: none; }
  .foot-legal span { grid-column: 1 / 7; }
  .foot-legal { row-gap: 8px; margin-top: 48px; }

  .rail { display: none; }
}

/* ================================================================
   HIW window embeds — Directory / Accounts / Console / New session
   (built in snippets/ lab; standalone-page rules in here are inert
   on the main site and kept for parity with the lab)
   ================================================================ */
/* ================================================================
   SNIPPET 01 — Directory (console window, light theme)
   ================================================================ */
.dir-page { padding: 120px var(--bleed) 80px; }
.dir-window {
  width: min(1160px, 100%);
  margin: 0 auto;
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: var(--r-lg);
  overflow: hidden;
  text-align: left;
  box-shadow: 0 24px 70px rgba(38, 38, 38, 0.14);
  transition: box-shadow 0.4s var(--ease);
}
.dir-window:hover { box-shadow: 0 34px 90px rgba(38, 38, 38, 0.2); }
/* light re-skin of the site's terminal title bar */
.dir-window .term-bar { border-bottom: 1px solid rgba(38, 38, 38, 0.08); }
.dir-window .term-bar i { background: rgba(38, 38, 38, 0.14); }
.dir-window:hover .term-bar i:nth-child(1) { background: #ff5f57; }
.dir-window:hover .term-bar i:nth-child(2) { background: #febc2e; }
.dir-window:hover .term-bar i:nth-child(3) { background: #28c840; }
.dir-window .term-bar span { color: rgba(38, 38, 38, 0.4); font-weight: 700; }

.dir-body { padding: 28px 28px 32px; }
.dir-head {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 28px;
}
.dir-title {
  font-size: clamp(24px, 2.4vw, 32px);
  font-weight: 500;
  letter-spacing: -0.02em;
  margin-right: auto;
}
.dir-search {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: 230px;
  height: 44px;
  padding: 0 16px;
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: 999px;
  color: rgba(38, 38, 38, 0.35);
  transition: border-color 0.3s var(--ease);
}
.dir-search:focus-within { border-color: rgba(38, 38, 38, 0.4); }
.dir-search svg { width: 15px; height: 15px; flex: 0 0 auto; }
.dir-search input {
  border: 0;
  outline: 0;
  background: transparent;
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
}
.dir-search input::placeholder { color: rgba(38, 38, 38, 0.35); }

/* filter button + dropdown (replaces the tab slider) */
.dir-filter { position: relative; }
.dir-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  padding: 0 18px;
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: 999px;
  font: 500 14px/1 "Helvetica Neue W", sans-serif;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.dir-filter-btn:hover { background: rgba(38, 38, 38, 0.05); }
.dir-filter-btn[aria-expanded="true"] { border-color: rgba(38, 38, 38, 0.4); }
.dir-filter-btn svg { width: 15px; height: 15px; }
.dir-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 20;
  min-width: 168px;
  background: var(--white);
  border-radius: var(--r-md);
  padding: 6px;
  box-shadow: 0 1px 2px rgba(38, 38, 38, 0.08), 0 10px 30px rgba(38, 38, 38, 0.16);
  display: flex;
  flex-direction: column;
  gap: 2px;
  opacity: 0;
  translate: 0 4px;
  pointer-events: none;
  transition: opacity 0.25s var(--ease), translate 0.25s var(--ease);
}
.dir-filter.open .dir-menu { opacity: 1; translate: 0 0; pointer-events: auto; }
.dir-item {
  border: 0;
  background: transparent;
  font: 500 14px/1 "Helvetica Neue W", sans-serif;
  color: var(--ink);
  text-align: left;
  padding: 10px 12px;
  border-radius: 9px;
  cursor: pointer;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.dir-item:hover { background: rgba(38, 38, 38, 0.06); }
.dir-item.active { background: var(--ink); color: var(--white); }

.dir-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gutter);
}
.dir-card {
  position: relative;   /* anchors the corner arrow button */
  background: var(--card);
  border-radius: var(--r-lg);
  padding: 22px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  cursor: pointer;
  transition: background 0.3s var(--ease);
}
/* corner arrow — the chain-card plus button, with a ↗ instead of the + */
.dir-go {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(38, 38, 38, 0.08);
  display: grid;
  place-items: center;
  color: var(--ink);
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.dir-go svg { width: 18px; height: 18px; }
.dir-card:hover .dir-go { background: var(--ink); color: var(--white); }
.dir-card.dark .dir-go { background: rgba(255, 255, 255, 0.12); color: var(--white); }
.dir-card.dark:hover .dir-go { background: var(--white); color: var(--ink); }
.dir-card:hover { background: #eaeaea; }
.dir-card.dark { background: var(--ink); color: var(--white); }
.dir-card.dark:hover { background: #333333; }
.dir-icon {
  width: 46px;
  height: 46px;
  color: var(--ink);
  margin-bottom: auto;   /* pushes the text block to the card's bottom */
}
.dir-icon svg { width: 100%; height: 100%; display: block; }
.dir-card.dark .dir-icon { color: var(--white); }
.dir-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.01em;
  margin-top: 40px;
}
/* status tag — green/red dot + label, 12px like the meta line */
.dir-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.01em;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(38, 38, 38, 0.05);
  color: rgba(38, 38, 38, 0.45);
}
.dir-status i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #28c840;   /* traffic-light green, same as the term-bar dots */
}
.dir-status.offline i { background: #ff5f57; }
.dir-card.dark .dir-status { background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.55); }
.dir-meta { font-size: 12px; color: rgba(38, 38, 38, 0.5); margin-top: 8px; }
.dir-meta i { font-style: normal; margin: 0 3px; }
.dir-card.dark .dir-meta { color: rgba(255, 255, 255, 0.55); }
/* filtered out */
.dir-card.off { display: none; }

/* inert search field — the snippet is a static showcase now */
.dir-search input[readonly] { cursor: default; }

/* ---- the Directory window embedded in HIW card 1 (decorative clone) ----
   The clone keeps its natural 1160px layout; lab.js scales it to the card,
   so every size inside tracks the card width — fully responsive. */
.hiw-embed {
  position: absolute;
  z-index: 0;              /* over the video, under the card's icon/copy/play */
  left: 50%;
  top: 50%;
  width: 78%;
  translate: -50% -50%;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s var(--ease), visibility 0s linear 0.4s;
}
.hiw-card.active .hiw-embed {
  opacity: 1;
  visibility: visible;
  /* wait out the card's grow animation before fading in */
  transition: opacity 0.4s var(--ease) 0.3s;
}
.hiw-embed .dir-window,
.hiw-embed .con-window {
  width: 1160px;           /* natural size — js applies the scale() */
  transform-origin: 0 0;
  border: 0;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}
.hiw-embed .dir-window:hover,
.hiw-embed .con-window:hover { box-shadow: 0 40px 100px rgba(0, 0, 0, 0.45); }
/* the title's vw-clamp tracks the viewport, not the 1160px layout — pin it */
.hiw-embed .dir-title { font-size: 32px; }
/* narrow mode (~tablet scale and down, toggled by lab.js): the 3rd column
   goes away and the window relaxes to a 780px two-column layout */
.hiw-embed.narrow { width: 60%; }   /* taller 2-col window needs a smaller footprint */
.hiw-embed.narrow .dir-window { width: 780px; }
.hiw-embed.narrow .dir-grid { grid-template-columns: repeat(2, 1fr); }
.hiw-embed.narrow .dir-card:nth-child(3),
.hiw-embed.narrow .dir-card:nth-child(6) { display: none; }

/* breakpoints apply only to the standalone snippet page — the HIW embed
   keeps its 1160px desktop layout and scales as one unit instead */
@media (max-width: 1000px) { .dir-page .dir-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .dir-page .dir-grid { grid-template-columns: 1fr; } }

/* ================================================================
   SNIPPET 02 — Accounts & delegations (green portfolio chart)
   ================================================================ */
.acc-page { padding: 120px var(--bleed) 80px; }
.acc-wrap { width: min(1160px, 100%); margin: 0 auto; }
/* match the Directory window's height — the frame must not hug the content.
   The frame is FIXED on desktop: opening dropdowns scrolls the side list
   instead of growing the window. */
.acc-page .dir-body { display: flex; flex-direction: column; }
/* minmax(0,1fr): a plain 1fr row would still grow to fit the open lists */
.acc-page .acc-layout { flex: 1; grid-template-rows: auto minmax(0, 1fr); }
@media (min-width: 1001px) {
  .acc-page .dir-body { height: 552px; }
  .acc-page .acc-layout { min-height: 0; }
  .acc-page .acc-groups {
    align-self: stretch;
    overflow-y: auto;
    scrollbar-width: none;   /* scrolls, but keeps the showcase clean */
  }
  .acc-page .acc-groups::-webkit-scrollbar { display: none; }
}
.acc-layout {
  display: grid;
  grid-template-columns: 1fr 430px;
  grid-template-areas:
    "title title"
    "chart side";
  gap: 24px var(--gutter);
  align-items: start;
}
.acc-title {
  grid-area: title;
  font-size: clamp(24px, 2.4vw, 32px);
  font-weight: 500;
  letter-spacing: -0.02em;
}

/* segmented pills — same recipe as the carousel tabs (visual only here) */
.acc-seg {
  display: flex;
  gap: 4px;
  background: var(--white);
  border-radius: 999px;
  padding: 4px;
}
.acc-seg button {
  border: 0;
  background: transparent;
  font: 500 14px/1 "Helvetica Neue W", sans-serif;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 14px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.acc-seg button:hover { background: rgba(38, 38, 38, 0.07); }
.acc-seg button.active { background: var(--ink); color: var(--white); }

/* account dropdowns — collapsible cards, assets inside */
.acc-groups {
  grid-area: side;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.acc-group {
  flex-shrink: 0;   /* don't compress when the side list scrolls */
  background: var(--card);
  border-radius: var(--r-md);
  overflow: hidden;
}
.acc-group-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  border: 0;
  background: transparent;
  font: inherit;
  color: var(--ink);
  text-align: left;
  padding: 16px;
  cursor: pointer;
  transition: background 0.25s var(--ease);
}
.acc-group-head:hover { background: rgba(38, 38, 38, 0.04); }
.acc-group-head strong { font-size: 14px; font-weight: 700; letter-spacing: 0.01em; }
.acc-group-total { margin-left: auto; font-size: 14px; color: rgba(38, 38, 38, 0.55); }
.acc-chev {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: rgba(38, 38, 38, 0.55);
  transition: rotate 0.35s var(--ease);
}
.acc-group.open .acc-chev { rotate: 180deg; }
/* body collapses via the 0fr→1fr grid trick — height animates smoothly */
.acc-group-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s var(--ease);
}
.acc-group.open .acc-group-body { grid-template-rows: 1fr; }
/* expanded content: a white box within the gray card — rounded top corners
   and a visible stroke. Styled on the list (not the 0fr wrapper) so the
   border collapses away with the content when the group closes. */
.acc-group-inner { overflow: hidden; min-height: 0; }
.acc-group-inner .acc-list {
  background: var(--white);
  border: 1.5px solid rgba(38, 38, 38, 0.08);
  border-radius: var(--r-md);
  padding: 2px 16px 6px;
}
.acc-group-inner .acc-row:first-child { border-top: 0; }
.acc-connect {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  border: 0;
  background: var(--card);
  border-radius: var(--r-md);
  font: inherit;
  color: var(--ink);
  text-align: left;
  padding: 16px;
  cursor: pointer;
  transition: background 0.25s var(--ease);
}
.acc-connect:hover { background: rgba(38, 38, 38, 0.1); }
.acc-connect svg { width: 16px; height: 16px; flex: 0 0 auto; color: rgba(38, 38, 38, 0.55); }
.acc-connect strong { font-size: 14px; font-weight: 700; letter-spacing: 0.01em; }

/* chart card — fills the window height, chart pinned to the bottom */
.acc-chart-card {
  grid-area: chart;
  align-self: stretch;
  background: var(--card);
  border-radius: var(--r-lg);
  padding: 24px;
  display: flex;
  flex-direction: column;
}
.acc-chart-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 24px;
}
.acc-sub { font-size: 12px; color: rgba(38, 38, 38, 0.5); margin-bottom: 6px; }
.acc-value-row { display: flex; align-items: flex-start; gap: 8px; }
.acc-value-row .acc-pill { margin-top: 7px; }
.acc-value { font-size: 44px; line-height: 1.05; font-weight: 500; letter-spacing: -0.02em; }
/* green delta pill beside the balance */
.acc-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 5px 10px;
  border-radius: 999px;
  background: rgba(40, 200, 64, 0.14);
  color: #1a9e46;
}
.acc-pill svg { width: 10px; height: 10px; }
.up { color: #22a04a; }
.down { color: #e5484d; }

/* dot-matrix chart — one element per column, dots drawn by a repeating
   radial-gradient so each column is just height = dots × cell */
.acc-chart { --cell: 14px; margin-top: auto; padding-top: 40px; }
.acc-dots {
  display: flex;
  height: calc(var(--cell) * 14);
}
.acc-mgroup {
  flex: 1;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}
.acc-col {
  display: block;
  width: var(--cell);
  background-image: radial-gradient(circle, currentColor calc(var(--cell) * 0.26), transparent calc(var(--cell) * 0.26 + 0.5px));
  background-size: var(--cell) var(--cell);
}
/* past months rest light; the current month is ink. Hovering any month
   makes THAT one ink and quiets the rest (labels follow along). */
.acc-mgroup .acc-col { color: rgba(38, 38, 38, 0.2); transition: color 0.3s var(--ease); }
.acc-mgroup:last-child .acc-col { color: var(--ink); }
.acc-dots:has(.acc-mgroup:hover) .acc-col { color: rgba(38, 38, 38, 0.2); }
.acc-dots .acc-mgroup:hover .acc-col { color: var(--ink); }
.acc-months {
  display: flex;
  margin-top: 16px;
  font-size: 12px;
  letter-spacing: 0.01em;
}
.acc-months span { flex: 1; transition: color 0.3s var(--ease); }
.acc-months .past { color: rgba(38, 38, 38, 0.4); }
.acc-months .now { color: var(--ink); font-weight: 700; }
.acc-chart:has(.acc-mgroup:hover) .acc-months span { color: rgba(38, 38, 38, 0.4); font-weight: 400; }
.acc-chart:has(.acc-mgroup:nth-child(1):hover) .acc-months span:nth-child(1),
.acc-chart:has(.acc-mgroup:nth-child(2):hover) .acc-months span:nth-child(2),
.acc-chart:has(.acc-mgroup:nth-child(3):hover) .acc-months span:nth-child(3) { color: var(--ink); font-weight: 700; }

/* asset rows */
.acc-list { list-style: none; }
.acc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
  border-top: 1px solid rgba(38, 38, 38, 0.08);
}
.acc-cell { display: flex; flex-direction: column; gap: 4px; }
.acc-cell.right { align-items: flex-end; text-align: right; }
.acc-cell strong { font-size: 18px; font-weight: 500; letter-spacing: -0.01em; }
.acc-cell span { font-size: 12px; color: rgba(38, 38, 38, 0.5); }
.acc-cell span.up { color: #22a04a; }
.acc-cell span.down { color: #e5484d; }

/* breakpoints apply only to the standalone snippet page — the HIW embed
   keeps its desktop layout and scales as one unit instead */
@media (max-width: 1000px) {
  .acc-page .acc-layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas: "title" "chart" "side";
  }
}
@media (max-width: 640px) { .acc-page .acc-chart { --cell: 6px; } }

/* ---- Accounts window embedded in HIW card 2 (decorative clone) ---- */
.hiw-embed.embed-acc .dir-body { height: 552px; display: flex; flex-direction: column; }
.hiw-embed.embed-acc .acc-layout { flex: 1; min-height: 0; grid-template-rows: auto minmax(0, 1fr); }
.hiw-embed.embed-acc .acc-groups { align-self: stretch; overflow-y: auto; scrollbar-width: none; }
.hiw-embed.embed-acc .acc-groups::-webkit-scrollbar { display: none; }
.hiw-embed.embed-acc .acc-title { font-size: 32px; }   /* pin the vw-clamp */
/* narrow mode: the side list goes away, single column at 780px */
.hiw-embed.embed-acc.narrow .dir-window { width: 780px; }
.hiw-embed.embed-acc.narrow .dir-body { height: auto; }
.hiw-embed.embed-acc.narrow .acc-layout {
  grid-template-columns: 1fr;
  grid-template-rows: auto;
  grid-template-areas: "title" "chart";
}
.hiw-embed.embed-acc.narrow .acc-groups { display: none; }

/* ================================================================
   SNIPPET 03 — Console (dark theme): terminal + scrolling tool rail
   ================================================================ */
.con-page { padding: 120px var(--bleed) 80px; }
.con-wrap { width: min(1160px, 100%); margin: 0 auto; }
.con-window {
  background: var(--ink);
  border-radius: var(--r-lg);
  overflow: hidden;
  text-align: left;
  box-shadow: 0 24px 70px rgba(38, 38, 38, 0.28);
  transition: box-shadow 0.4s var(--ease);
}
.con-window:hover { box-shadow: 0 44px 110px rgba(38, 38, 38, 0.45); }
.con-window:hover .term-bar i:nth-child(1) { background: #ff5f57; }
.con-window:hover .term-bar i:nth-child(2) { background: #febc2e; }
.con-window:hover .term-bar i:nth-child(3) { background: #28c840; }
.con-window .term-bar span { font-weight: 700; }
.con-body {
  display: grid;
  /* explorer | console | rail sized so the cards match the Directory grid
     (354px card + 24px padding each side) */
  grid-template-columns: 230px 1fr 402px;
  height: 552px;
}

/* explorer tree */
.con-tree {
  padding: 20px 12px;
  border-right: 1px solid rgba(255, 255, 255, 0.08);
  overflow-y: auto;
  scrollbar-width: none;
}
.con-tree::-webkit-scrollbar { display: none; }
.tree-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 0;
  background: transparent;
  font: 500 14px/1 "Helvetica Neue W", sans-serif;
  color: rgba(255, 255, 255, 0.8);
  text-align: left;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.tree-head:hover { background: rgba(255, 255, 255, 0.06); color: var(--white); }
.tree-chev {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  color: rgba(255, 255, 255, 0.45);
  rotate: -90deg;
  transition: rotate 0.3s var(--ease);
}
.tree-folder.open > .tree-head .tree-chev { rotate: 0deg; }
.tree-kids {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.35s var(--ease);
}
.tree-folder.open > .tree-kids { grid-template-rows: 1fr; }
.tree-kids > div { overflow: hidden; min-height: 0; }
.tree-file {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.55);
  padding: 7px 10px 7px 30px;
  border-radius: 8px;
  cursor: default;
  white-space: nowrap;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.tree-file:hover { background: rgba(255, 255, 255, 0.04); color: rgba(255, 255, 255, 0.85); }
.tree-file svg { width: 13px; height: 13px; flex: 0 0 auto; color: rgba(255, 255, 255, 0.4); }
.tree-root-file { padding-left: 10px; }
.con-code {
  padding: 26px 24px 30px;
  overflow: auto;
  font: 400 13.5px/1.75 "SF Mono", ui-monospace, "Menlo", monospace;
  color: rgba(255, 255, 255, 0.88);
  border-right: 1px solid rgba(255, 255, 255, 0.08);
}
.con-window .c { color: rgba(255, 255, 255, 0.38); }
.con-window .k { color: var(--sky); }
.con-window .s { color: #cdeeff; }
.con-window .f { color: var(--sky); }
.con-window .n { color: #cdeeff; }
.con-window .ok { color: #28c840; }
.con-window .warn { color: #febc2e; }
/* the tool rail: the search floats over the cards, which scroll beneath it */
.con-rail {
  position: relative;
  min-height: 0;
}
/* dark glass pill — blur shows the cards passing under it */
.con-search {
  position: absolute;
  top: 24px;
  left: 24px;
  right: 24px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  padding: 0 16px;
  background: rgba(38, 38, 38, 0.55);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.5);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 12px 28px rgba(0, 0, 0, 0.18);
}
.con-search svg { width: 15px; height: 15px; flex: 0 0 auto; }
.con-search input {
  border: 0;
  outline: 0;
  background: transparent;
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--white);
  cursor: default;
}
.con-search input::placeholder { color: rgba(255, 255, 255, 0.5); }
.con-side {
  height: 100%;
  padding: 84px 24px 24px;   /* clears the floating search */
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
  scrollbar-width: none;
}
.con-side::-webkit-scrollbar { display: none; }
.con-side .dir-card,
.con-side .dir-card.dark {
  flex-shrink: 0;
  min-height: 150px;
  background: rgba(255, 255, 255, 0.07);
  color: var(--white);
}
.con-side .dir-card:hover,
.con-side .dir-card.dark:hover { background: rgba(255, 255, 255, 0.11); }
.con-side .dir-icon { color: var(--white); }
.con-side .dir-name svg { color: rgba(255, 255, 255, 0.6); }
.con-side .dir-meta { color: rgba(255, 255, 255, 0.5); }
.con-side .dir-status { background: rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.6); }
.con-side .dir-go { background: rgba(255, 255, 255, 0.12); color: var(--white); }
.con-side .dir-card:hover .dir-go { background: var(--white); color: var(--ink); }
/* breakpoints apply only to the standalone snippet page — the HIW embed
   keeps its desktop layout and scales as one unit instead */
@media (max-width: 1000px) {
  .con-page .con-body { grid-template-columns: 1fr; height: auto; }
  .con-page .con-tree { border-right: 0; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
  .con-page .con-code { border-right: 0; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
  .con-page .con-side { max-height: 420px; }
}

/* ---- Console window embedded in HIW card 4 (decorative clone) ----
   narrow mode: the card rail goes away, explorer + console at 780px */
.hiw-embed.embed-con.narrow .con-window { width: 780px; }
.hiw-embed.embed-con.narrow .con-body { grid-template-columns: 230px 1fr; }
.hiw-embed.embed-con.narrow .con-rail { display: none; }
.hiw-embed.embed-con.narrow .con-code { border-right: 0; }

/* ================================================================
   SNIPPET 04 — Connect to account (light console window, delegation)
   ================================================================ */
.cn-page { padding: 120px var(--bleed) 80px; }
.cn-wrap { width: min(1160px, 100%); margin: 0 auto; }
.cn-body {
  position: relative;
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 48px;
}
@media (min-width: 1001px) { .cn-page .dir-body { height: 552px; } }
.cn-close {
  position: absolute;
  top: 24px;
  right: 28px;
  z-index: 2;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(38, 38, 38, 0.45);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.cn-close:hover { background: rgba(38, 38, 38, 0.06); color: var(--ink); }
.cn-close svg { width: 15px; height: 15px; }

/* left: title, tag, copy, actions pinned to the bottom */
.cn-left { display: flex; flex-direction: column; align-items: flex-start; min-height: 0; }
.cn-title { font-size: clamp(24px, 2.4vw, 32px); font-weight: 500; letter-spacing: -0.02em; }
.cn-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 16px 0 18px;
  font-size: 12px;
  font-weight: 500;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--card);
  color: rgba(38, 38, 38, 0.6);
}
.cn-tag i { width: 6px; height: 6px; border-radius: 50%; background: #28c840; }
.cn-copy { font-size: 14px; line-height: 1.6; color: rgba(38, 38, 38, 0.55); max-width: 34ch; }
.cn-actions { margin-top: auto; display: flex; align-items: center; gap: 20px; }
.cn-approve {
  border: 0;
  background: var(--ink);
  color: var(--white);
  font: 500 14px/1 "Helvetica Neue W", sans-serif;
  height: 44px;
  padding: 0 22px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.25s var(--ease);
}
.cn-approve:hover { background: #333333; }
.cn-cancel {
  border: 0;
  background: transparent;
  font: 500 14px/1 "Helvetica Neue W", sans-serif;
  color: rgba(38, 38, 38, 0.45);
  cursor: pointer;
  transition: color 0.25s var(--ease);
}
.cn-cancel:hover { color: var(--ink); }

/* right: the form, scrolling behind the fixed frame */
.cn-form {
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
  display: flex;
  flex-direction: column;
  gap: 26px;
  padding-right: 56px;   /* keeps the close ✕ clear of the fields */
}
@media (max-width: 1000px) { .cn-form { padding-right: 0; } }
.cn-form::-webkit-scrollbar { display: none; }
.cn-label { display: block; font-size: 12px; color: rgba(38, 38, 38, 0.5); margin-bottom: 8px; }
.cn-select { position: relative; }
.cn-select select,
.cn-input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 46px;
  padding: 0 16px;
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: var(--r-md);
  font: 400 14px/1 "Helvetica Neue W", sans-serif;
  color: var(--ink);
  outline: 0;
  transition: border-color 0.25s var(--ease);
  cursor: pointer;
}
.cn-input { cursor: text; }
.cn-select select:hover, .cn-select select:focus,
.cn-input:hover, .cn-input:focus { border-color: rgba(38, 38, 38, 0.4); }
.cn-select svg {
  position: absolute;
  right: 15px;
  top: 50%;
  translate: 0 -50%;
  width: 14px;
  height: 14px;
  color: rgba(38, 38, 38, 0.45);
  pointer-events: none;
}
.cn-help { font-size: 12px; color: rgba(38, 38, 38, 0.45); margin-top: 8px; }
.cn-list { list-style: none; }
.cn-list li {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 13px 0;
}
.cn-list li + li { border-top: 1px solid rgba(38, 38, 38, 0.08); }
.cn-list strong { display: block; font-size: 14px; font-weight: 700; letter-spacing: 0.01em; }
.cn-list span { display: block; font-size: 12px; line-height: 1.5; color: rgba(38, 38, 38, 0.5); margin-top: 3px; }
/* toggle switch — green when on, like the status dots */
.cn-toggle {
  flex: 0 0 auto;
  position: relative;
  width: 40px;
  height: 22px;
  margin-top: 2px;
  border: 0;
  border-radius: 999px;
  background: rgba(38, 38, 38, 0.16);
  cursor: pointer;
  transition: background 0.25s var(--ease);
}
.cn-toggle i {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
  transition: translate 0.25s var(--ease);
}
.cn-toggle.on { background: #28c840; }
.cn-toggle.on i { translate: 18px 0; }
.cn-seg { background: var(--card); display: inline-flex; }   /* hug content */

/* breakpoints apply only to the standalone snippet page — the HIW embed
   keeps its desktop layout and scales as one unit instead */
@media (max-width: 1000px) {
  .cn-page .cn-body { grid-template-columns: 1fr; gap: 32px; }
  .cn-page .cn-actions { margin-top: 8px; }
}

/* ---- Connect window embedded in HIW card 3 (decorative clone) ---- */
.hiw-embed.embed-cn .dir-body { height: 552px; }
/* narrow mode: single column — title/tag/copy above the form (which becomes
   a boxed gray container), actions below it */
.hiw-embed.embed-cn.narrow .dir-window { width: 780px; }
.hiw-embed.embed-cn.narrow .dir-body { height: auto; }
.hiw-embed.embed-cn.narrow .cn-body { display: flex; flex-direction: column; gap: 18px; }
.hiw-embed.embed-cn.narrow .cn-left { display: contents; }   /* children join the column */
.hiw-embed.embed-cn.narrow .cn-title { order: 1; }
.hiw-embed.embed-cn.narrow .cn-tag { order: 2; margin: 0; align-self: flex-start; }   /* hug */
.hiw-embed.embed-cn.narrow .cn-copy { display: none; }
.hiw-embed.embed-cn.narrow .cn-form {
  order: 4;
  background: var(--card);
  border-radius: var(--r-md);
  padding: 20px;
  /* capped + scrollable so the window fits short 16:9 cards */
  max-height: 360px;
  overflow-y: auto;
}
/* footprint: modest on squat desktop cards, generous on portrait touch cards */
.hiw-embed.embed-cn.narrow { width: 54%; }
@media (max-width: 760px), (pointer: coarse) {
  /* all windows same size on touch (cn listed again to outrank its 54%) */
  .hiw-embed.narrow,
  .hiw-embed.embed-cn.narrow { width: 82%; }
}
.hiw-embed.embed-cn.narrow .cn-seg { background: var(--white); }
.hiw-embed.embed-cn.narrow .cn-actions { order: 5; margin-top: 6px; }


/* ================================================================
   HIW step tabs — on touch layouts the collapsed number cards go
   away and a sliding tab pill picks the step instead
   ================================================================ */
.hiw-tabs { display: none; }
@media (max-width: 760px), (pointer: coarse) {
  /* cards stack in one cell and crossfade instead of swapping instantly */
  .hiw-row { display: grid; grid-template-columns: 1fr; }
  .hiw-card,
  .hiw-card.active,
  .hiw-card:not(.active) {
    grid-area: 1 / 1;
    order: 0;
    height: var(--touch-card-h);
    align-self: stretch;
  }
  .hiw-card {
    transition: opacity 0.5s var(--ease), transform 0.5s var(--ease),
      visibility 0s linear 0s;
  }
  /* the outgoing card keeps its open-card looks while it fades out, so the
     crossfade reads as one image dissolving into the next */
  .hiw-card video { opacity: 1 !important; filter: none !important; transform: none !important; }
  .hiw-card::after { opacity: 1; }
  .hiw-card:not(.active) .hiw-icon { top: 22px; left: 22px; translate: none; color: var(--white); }
  .hiw-card:not(.active) {
    opacity: 0;
    transform: scale(0.985);
    visibility: hidden;
    pointer-events: none;
    transition-delay: 0s, 0s, 0.5s;   /* hide only after the fade finishes */
  }
  .hiw-card.active { opacity: 1; transform: none; visibility: visible; }
  /* the windows are purely visual on touch — no taps, no inner scrolling */
  .hiw-embed { pointer-events: none; }
  /* the UI rises into the card from below its clipped edge instead of just
     fading up from nothing (the card's overflow hides where it starts).
     The -50% pair is the embed's centring — the slide rides on top of it */
  .hiw-embed {
    opacity: 0;
    translate: -50% calc(-50% + 140px);
    transition: opacity 0.3s var(--ease), translate 0.3s var(--ease), visibility 0s linear 0.3s;
  }
  .hiw-card.active .hiw-embed {
    opacity: 1;
    translate: -50% -50%;
    transition: opacity 0.6s var(--ease) 0.14s, translate 0.95s var(--ease) 0.08s, visibility 0s;
  }
  /* no hover on touch — traffic lights wear their colors permanently */
  .term-bar i:nth-child(1) { background: #ff5f57; }
  .term-bar i:nth-child(2) { background: #febc2e; }
  .term-bar i:nth-child(3) { background: #28c840; }
  .hiw-tabs {
    position: relative;
    display: flex;
    gap: 4px;
    width: fit-content;
    margin: 20px auto 0;
    background: var(--white);
    border-radius: 999px;
    padding: 4px;
    box-shadow: 0 1px 2px rgba(38, 38, 38, 0.08), 0 10px 30px rgba(38, 38, 38, 0.12);
  }
  .hiw-tab {
    position: relative;
    z-index: 1;
    border: 0;
    background: transparent;
    font: 500 14px/1 "Helvetica Neue W", sans-serif;
    color: var(--ink);
    display: inline-flex;
    align-items: center;
    height: 40px;
    padding: 0 14px;
    border-radius: 999px;
    cursor: pointer;
    transition: color 0.3s var(--ease);
  }
  .hiw-tab.active { color: var(--white); }
  .hiw-tab-pill {
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 0;
    width: 0;
    border-radius: 999px;
    background: var(--ink);
    z-index: 0;
    overflow: hidden;
    transform: translateX(4px);
    transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1),
                width 0.35s cubic-bezier(0.22, 1, 0.36, 1);
    will-change: transform;
  }
  /* subtle fill inside the pill, driven by the autoplay countdown (--prog) */
  .hiw-tab-pill::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, 0.07);
    transform-origin: left center;
    transform: scaleX(var(--prog, 0));
  }
}

/* ================================================================
   Custom circle cursor — white dot blended with "difference", so it
   reads black on white surfaces and white on dark ones (fine pointers
   only; touch devices keep no cursor, coarse pointers are untouched)
   ================================================================ */
@media (pointer: fine) {
  /* transparent 1×1 png first — some browsers (Safari) intermittently
     ignore a bare `cursor: none`, but always honor an image cursor */
  html.has-cursor-dot,
  html.has-cursor-dot * {
    cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=") 0 0, none !important;
  }
  .cursor-dot {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 12000;
    pointer-events: none;
    /* blend on the moving wrapper itself — a transformed parent would
       isolate the stacking context and kill the inversion */
    mix-blend-mode: difference;
  }
  .cursor-dot i {
    position: absolute;
    left: 0;
    top: 0;
    translate: -50% -50%;
    display: block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #fff;
    opacity: 0;
    transition: width 0.25s var(--ease), height 0.25s var(--ease), opacity 0.2s var(--ease);
  }
  .cursor-dot.on i { opacity: 1; }
  .cursor-dot.grow i { width: 44px; height: 44px; }
}

/* ================================================================
   Media is decorative — never draggable or long-press-saveable
   ================================================================ */
img,
video,
svg {
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* ================================================================
   BLOG index — big wordmark, filter rail + 3-up article grid
   ================================================================ */
.blog { padding-top: calc(clamp(120px, 17vh, 200px) - 40px); }
/* same scale as the hero lines and the MCP heading */
.blog-title {
  padding-inline: var(--margin);
  /* pinned to one line box (= the caret's height) so the box can't resize
     between the empty "|" state and the typed word */
  min-height: 1em;
  font-size: clamp(52px, 8.5vw, 140px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
}
/* four columns: filters hold the first, the articles run 3-up across the rest */
.blog-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  column-gap: var(--gutter);
  padding-inline: var(--margin);
  margin-top: calc(clamp(48px, 7vh, 90px) - 30px);
}
.blog-filters { grid-column: 1 / 2; }
.filter-label {
  font-size: 14px;
  font-weight: 500;
  color: rgba(38, 38, 38, 0.5);
  margin-bottom: 14px;
}
.filter-list { display: flex; flex-wrap: wrap; gap: 8px; }
.filter {
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  padding: 8px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--card);
  color: rgba(38, 38, 38, 0.6);
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.filter:hover { background: var(--grey); color: var(--ink); }
.filter.on { background: var(--ink); color: var(--white); }

.blog-posts {
  grid-column: 2 / 5;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: var(--gutter);
  row-gap: clamp(34px, 5vh, 60px);
  align-content: start;
  /* filtering animates this height in js — same symmetric curve as the FAQ
     accordion, so whatever sits below rides up or down at the same pace */
  overflow: hidden;
  transition: height 0.55s cubic-bezier(0.45, 0.05, 0.15, 1);
}
/* cards rise in one after another once the heading has finished typing
   (.ready is set in the page script) */
.post { opacity: 0; transform: translateY(22px); }
.blog-posts.ready .post {
  opacity: 1;
  transform: none;
  transition: opacity 0.75s var(--ease), transform 0.75s var(--ease);
  transition-delay: calc(var(--i, 0) * 95ms);
}
.post:nth-child(2) { --i: 1; }
.post:nth-child(3) { --i: 2; }
.post:nth-child(4) { --i: 3; }
.post:nth-child(5) { --i: 4; }
@media (prefers-reduced-motion: reduce) {
  .post { opacity: 1; transform: none; }
}
/* filtering: cards leaving fade down, cards arriving rise in like they do on
   first load. Survivors are FLIPped to their new grid slots in js. */
.blog-posts.ready .post.is-leaving {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.26s var(--ease), transform 0.26s var(--ease);
  transition-delay: 0s;
}
.blog-posts.ready .post.is-entering {
  opacity: 0;
  transform: translateY(22px);
  transition: none;
}
.post { display: flex; }
/* an author `display` beats the UA's [hidden] rule regardless of specificity,
   so the filter's hidden cards need this or they stay in the grid */
.post[hidden] { display: none; }
/* the 14px inset is always there so the hover card can't shift the layout —
   only its background fades in (same idea as .car-frame inside .car-card) */
.post-link {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 14px;
  border-radius: var(--r-lg);   /* same as .car-card */
  background: transparent;
  transition: background 0.35s var(--ease);
}
.post-link:hover { background: var(--card); }
.post-media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  border-radius: 6px;   /* same as .car-frame inside a carousel card */
  overflow: hidden;
  background: var(--card);
}
.post-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.55s cubic-bezier(0.45, 0.05, 0.15, 1);
}
.post-link:hover .post-media img { transform: scale(1.04); }
.post-title {
  margin-top: 18px;
  margin-bottom: 24px;   /* the floor gap when the title runs two lines */
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.25;
}
/* date and "Read article" occupy the same slot and cross-fade on hover.
   auto margin drops it to the card floor, so one- and two-line titles line
   their dates up on the same baseline */
.post-meta {
  position: relative;
  margin-top: auto;
  height: 20px;
  font-size: 14px;
  font-weight: 500;
}
.post-meta span {
  position: absolute;
  top: 0;
  left: 0;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  white-space: nowrap;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.post-date { color: rgba(38, 38, 38, 0.5); }
.post-read { opacity: 0; transform: translateY(7px); }
.post-read svg { width: 16px; height: 16px; }
.post-link:hover .post-date { opacity: 0; transform: translateY(-7px); }
.post-link:hover .post-read { opacity: 1; transform: none; }

.blog + .band { margin-top: clamp(90px, 14vh, 170px); }
/* pages under /blog/ (listing and articles) drop the newsletter strip, so
   the footer columns need their own air under the CTA band */
.blog-page .footer { padding-top: clamp(56px, 8vh, 96px); }

@media (max-width: 1200px) {
  /* the filter rail moves above the grid so the cards keep full width and
     stay 3-up instead of being squeezed by the rail's column */
  .blog-grid { grid-template-columns: 1fr; row-gap: 34px; }
  .blog-filters, .blog-posts { grid-column: 1 / -1; }
}
@media (max-width: 1000px) {
  .blog-posts { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
  /* the pill sits 16px from the top and is 56px tall — give the heading real
     air under it rather than the ~26px the shared clamp leaves */
  .blog { padding-top: 150px; }
}
@media (max-width: 620px) {
  .blog-posts { grid-template-columns: 1fr; }
  .post-link { padding: 10px; }
  .post-title { margin-top: 14px; }
}
