/* ============================================================
   Doppelganger home — one story, told as the visitor's own
   questions, in as little scroll as it needs. The plate states
   the thesis over the aerial (media/hero.mp4, Pexels 28638515,
   free license); the black veil page voices the objection
   ("another one of those AI promises") and the deck answers it
   with four receipts — a rail listing all four on the left,
   half-screen cards stacking on the right, scroll or click
   (70vh of runway per transition); a second pinned sequence shows
   the four things you're hiring one at a time — a conveyor of cards
   on the paper ground, tabs under the title; then the
   closing page: the mission centered, the brand signing off at
   the bottom, the footer arriving over the darkening hire stage
   the way the objection page arrives over the hero.
   Orbitron carries only the wordmark and hero one-liner. The
   rest stays in a plain system face so the offer reads quickly.
   styles.css still serves brand/partners/legal.
   ============================================================ */

@font-face {
  font-family: "Orbitron";
  font-style: normal;
  font-weight: 400 900;
  font-display: optional;
  src: url("fonts/orbitron-latin.woff2") format("woff2");
}

:root {
  /* the app's palette (packages/ui globals.css): pure white ground, a
     zero-chroma ramp — no warm cast anywhere */
  color-scheme: light;
  --paper: #ffffff;
  --panel: #fafafa;
  --ink: #0a0a0a;
  --ink-70: rgba(10, 10, 10, 0.72);
  --ink-55: #737373;
  --ink-12: rgba(10, 10, 10, 0.12);
  --snow: #ffffff;
  --snow-80: rgba(255, 255, 255, 0.84);
  --snow-60: rgba(255, 255, 255, 0.62);
  --rail: clamp(24px, 7vw, 96px);
  --font-display: "Orbitron", ui-sans-serif, system-ui, sans-serif;
  --font-body:
    ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

/* page-to-page scrolling: each beat snaps into place; no rubber-band —
   the elastic bounce would drag the plate off the document edge and
   expose the ground behind it */
html {
  scroll-behavior: smooth;
  scroll-snap-type: y mandatory;
  overscroll-behavior: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
    scroll-snap-type: none;
  }
}

/* WebKit doesn't honor scroll-snap-stop: always under momentum: one flick
   sails through several 70vh beats — half the receipts deck skipped, the
   employee cards never seen. home.js tags
   Apple-engine browsers with this class (skipping reduced-motion, which
   keeps snap off entirely); proximity keeps the gentle landings near each
   anchor without the hard gating WebKit won't enforce anyway. The scrub
   itself is scroll-position math in home.js, so free resting points mid-
   transition render fine — the same frames Chrome shows mid-scroll. */
html.snap-loose {
  scroll-snap-type: y proximity;
}

/* the hero is sticky, and a stuck element is a broken snap target (its
   snap position rides along with the scroll) — so the top of the page
   snaps to this fixed anchor instead */
.snap-top {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
}

.snap-top {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

body {
  margin: 0;
  /* the ground is night, not paper: the parallax lifts the hero off the
     viewport floor, and the receipts deck's feathered edge crosses that
     strip — dark ground keeps the fade black instead of leaking white
     (the light sections paint their own paper) */
  background: var(--ink);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

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

svg {
  display: block;
}

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 4px;
}

::selection {
  background: rgba(10, 10, 10, 0.2);
}

/* ---- the plate: footage, scrims, the thesis ---- */

/* pinned: the page holds still while the black page scrolls up over it */
.hero {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  overflow: clip;
}

.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* softened and dimmed so the copy owns the frame; the scale hides the
     transparent fringe a CSS blur leaves at the edges */
  filter: blur(4px) saturate(1.06) brightness(0.84);
  transform: scale(1.06);
}

/* legibility insurance — a bright top for the ink nav, a dark floor, and a
   soft pool of shade centered behind the copy */
.scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(rgba(255, 255, 255, 0.45), transparent 130px),
    radial-gradient(62% 72% at 50% 56%, rgba(10, 10, 10, 0.55), transparent 68%),
    linear-gradient(to top, rgba(10, 10, 10, 0.55), rgba(10, 10, 10, 0.22) 32%, transparent 58%);
}

/* fade-to-black: home.js raises this over the plate as the night page
   arrives, so the curtain lands on an already-dark frame instead of
   cutting across the video */
.hero-veil {
  position: absolute;
  z-index: 4;
  inset: 0;
  background: #0a0a0a;
  opacity: 0;
  pointer-events: none;
}

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

/* ---- the thesis, centered on the plate ---- */

.hero-copy {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 var(--rail);
  text-align: center;
  color: var(--snow);
  text-shadow: 0 1px 26px rgba(10, 9, 8, 0.45);
}

.hero-copy .cta-row {
  justify-content: center;
  margin-top: 38px;
}

/* the plate's CTA: standard size, prominent through light */
.hero-copy .btn {
  padding: 16px 34px;
  font-size: 14px;
  box-shadow: 0 12px 40px rgba(255, 255, 255, 0.18);
}

.hero-copy .btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 50px rgba(255, 255, 255, 0.26);
}

.eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--snow-80);
}

/* the rotating trade on the headline's middle line: "automate your /
   whole·barber·tutoring·… / business" (home.js drives it; without JS or
   under reduced motion the static word just stands). The outgoing word
   slides up and out of the clipped box while the incoming one rises into
   its place, and the box itself eases to the new word's width so the
   centered line re-balances instead of snapping. vertical-align: bottom,
   not baseline — an overflow:hidden inline-block's baseline is its bottom
   edge, which would shove the word above the surrounding text. */
.word-rotator {
  --rotator-pad-y: 0px;
  --rotator-pad-x: 0px;
  position: relative;
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  white-space: nowrap;
  /* content-box keeps home.js's width math honest wherever a skin (like the
     highlight pill) adds padding: it measures and animates the bare word,
     padding rides on top */
  box-sizing: content-box;
  padding: var(--rotator-pad-y) var(--rotator-pad-x);
  margin: calc(-1 * var(--rotator-pad-y)) 0;
  transition: width 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

/* zero-width strut: mid-swap both words are absolute, so this is what keeps
   the box one line tall. Its letter-spacing must stay 0 or the inherited
   tracking gives the "zero-width" space an advance and nudges the settled
   word off the absolute words' center. */
.word-rotator::before {
  content: "\200B";
  letter-spacing: 0;
}

/* the headline rotator: its own centered row between "automate your" and
   "business", wearing a translucent highlight pill. A block, not an
   inline-block between <br>s — when the widest word's pill overruns a phone
   viewport, an inline pill evicts the following <br> onto an orphan line
   and the headline gains a row mid-swap; a block just overflows by the few
   pixels. width: fit-content is the resting width home.js's px animation
   returns to; auto margins center it, and their vertical half holds the
   pill clear of the rows above and below. em values track the h1's
   clamp()ed font-size across breakpoints. */
.hero-rotator {
  --rotator-pad-y: 0.1em;
  --rotator-pad-x: 0.3em;
  display: block;
  width: fit-content;
  margin: 0.12em auto;
  border-radius: 999px;
  background: rgba(10, 10, 10, 0.35);
}

/* the app's metallic heading sheen (packages/ui globals.css
   heading-gradient, dark variant): solid snow at the cap fading to 55% at
   the baseline, clipped to the glyphs. On the rotating words only — each
   word carries its own gradient rather than inheriting a parent-level
   clip, whose painted glyphs would sit under the headline pill's
   background. */
.rotator-word {
  background-image: linear-gradient(to bottom, var(--snow), rgba(255, 255, 255, 0.55));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* no transition on the base class: the transitions live only on the
   animating states below, so stepping into or out of them (the pin into
   absolute-centered position, and the settle back into flow when home.js
   strips the classes) is a discrete swap between visually identical
   states — with a base transition, the settle would animate the centering
   translateX back to none as a visible sideways slide */
.rotator-word {
  display: inline-block;
}

/* both swapping words are absolute and centered (left 50% + translateX) so
   the slide stays centered in the pill while the box re-sizes around it.
   The incoming word waits below the fold, absolute also so it can be
   measured without widening the box before the width transition starts.
   top matches the padding because absolute positioning anchors to the
   padding box. 150%, not ~110%: the clip edge is the padding box, so a
   word parked one line-height away would still peek into the highlight's
   padding band. */
.rotator-word.is-entering {
  position: absolute;
  top: var(--rotator-pad-y);
  left: 50%;
  transform: translate(-50%, 150%);
  opacity: 0;
  transition:
    transform 0.55s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

.rotator-word.is-entering.is-in {
  transform: translate(-50%, 0);
  opacity: 1;
}

.rotator-word.is-leaving {
  position: absolute;
  top: var(--rotator-pad-y);
  left: 50%;
  transform: translate(-50%, 0);
}

.rotator-word.is-leaving.is-out {
  transform: translate(-50%, -150%);
  opacity: 0;
  transition:
    transform 0.55s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---- nav: ink on the bright sky; Orbitron lives here, on the logo ---- */

.nav {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  margin: 0 auto;
  max-width: 1240px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 0 32px;
  height: 84px;
}

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

.logo-mark {
  height: 22px;
  width: auto;
}

.brand-word {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.btn {
  display: inline-flex;
  align-items: center;
  padding: 15px 30px;
  /* pill, page-wide — founder call; the square-cornered CTA is dead */
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* the ring: a 3px band held 3px off the pill so the ground shows through
     the gap (outline-offset is the gap; a border or box-shadow can't leave
     one) */
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

.btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 30px rgba(10, 10, 10, 0.35);
}

.btn:active {
  transform: translateY(0) scale(0.99);
}

/* the always-on ring outranks the site focus style (same specificity,
   later in the file) — restate the focus treatment above it */
.btn:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

/* on the dark valley the button flips: snow plate, ink text */
.btn-snow {
  background: var(--snow);
  color: var(--ink);
  outline-color: var(--snow);
}

/* the one-liner carries the brand face */
h1 {
  margin: 18px 0 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(23px, 5.4vw, 66px);
  line-height: 1.08;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  max-width: 100%;
}

.cta-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 32px;
}

.scroll-cue {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  color: var(--snow-60);
  font-size: 18px;
  transition: color 0.15s ease;
}

.scroll-cue:hover {
  color: var(--snow);
}

@media (prefers-reduced-motion: no-preference) {
  .scroll-cue {
    animation: cue-bob 2.6s ease-in-out infinite;
  }

  @keyframes cue-bob {
    0%,
    100% {
      transform: translate(-50%, 0);
    }

    50% {
      transform: translate(-50%, 6px);
    }
  }
}

/* with the veils running, the arriving night pages lead with a feathered
   edge — their tops dissolve into the darkening page beneath instead of
   drawing a line (the class guards no-JS and reduced-motion, where the
   veils never rise and a soft edge would expose the bright page). The two
   veiled arrivals only: the receipts deck over the plate, and the closing
   page over the hire stage. */
html.veiled .cases,
html.veiled .site-footer {
  background: linear-gradient(to bottom, rgba(10, 10, 10, 0), #0a0a0a min(26svh, 280px));
}

/* phones pin the mission's rotating word to its own line (the sentence
   around it is too tight there to absorb a long trade without re-wrapping);
   the break is inert on wide screens */
.phone-br {
  display: none;
}

@media (max-width: 620px) {
  .phone-br {
    display: inline;
  }

  /* phones wrap naturally — the set break is for wide screens */
  .statement-br {
    display: none;
  }
}

/* ---- use-case cards: normal flow on phones, sticky stack on wide screens ---- */

.cases {
  position: relative;
  z-index: 2;
  background: var(--paper);
}

.case {
  position: relative;
}

/* the paper ground must span the full viewport even while the content
   column is capped — cap the body, not the section. Centered on the
   axis, like the plate and the night page. */
.case-body {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
}

.case {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  padding: 0 var(--rail);
  color: var(--ink);
  overflow: clip;
}

.case-body {
  margin: auto;
  padding: 96px 0 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 960px;
  text-align: center;
}

/* ---- the deck: one plain promise, the work, then the result ---- */

/* THE header voice — every page headline wears this one style; the
   footer's mission line (.foot-mission-line) mirrors it */
.deck-title {
  margin: 0;
  max-width: 18ch;
  font-family: var(--font-body);
  font-size: clamp(38px, 4.4vw, 62px);
  font-weight: 740;
  line-height: 1.02;
  letter-spacing: -0.05em;
  text-wrap: balance;
}

.case-body > .cta-row {
  justify-content: center;
  margin-top: 30px;
}

/* ---- horizontally paginated use-case deck ---- */

/* four cards: 70vh of runway per transition — quicker than a full
   viewport each, so the deck costs ~3 screens of scroll instead of 4.
   The ground is the same ink as the band above — the deck continues the
   night seamlessly and the paper cards carry all the contrast. */
.cases {
  position: relative;
  height: 310vh;
  height: 310svh;
  min-height: 310vh;
  min-height: 310svh;
  background: var(--ink);
}

/* the pinned stage splits: the rail lists every receipt on the deck's own
   black ground, the cards stack on the right half */
.cases-stage {
  position: sticky;
  z-index: 2;
  top: 0;
  height: 100vh;
  height: 100svh;
  padding: 14px;
  /* the split holds the employee section's 1240px content column on very
     wide screens (the extra 28px covers the stage's own frame); the ink
     ground stays full-bleed on the section behind it */
  max-width: calc(1240px + 28px);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(300px, 0.92fr) minmax(0, 1.08fr);
  column-gap: clamp(14px, 1.6vw, 32px);
  overflow: hidden;
  overflow: clip;
}

/* the rail: scroll and it follows, click and it drives (home.js binds the
   same .case-pagination links the old dots used) */
.deck-rail {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 clamp(18px, 3vw, 64px);
  color: var(--snow);
}

.case-pagination {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
}

/* a service group: just its name — the card carries the detail */
.case-pagination a {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 20px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.4);
  transition: color 0.18s ease;
}

.case-pagination strong {
  font-size: clamp(20px, 1.9vw, 29px);
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.03em;
}

.case-pagination a:hover {
  color: var(--snow-80);
}

.case-pagination a[aria-current="page"] {
  color: var(--snow);
}

.deck-rail .btn {
  margin-top: 34px;
  align-self: flex-start;
}

.case-snap-point {
  position: absolute;
  left: 0;
  width: 1px;
  height: 1px;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

.case-snap-one {
  top: 0;
}

.case-snap-two {
  top: 70vh;
  top: 70svh;
}

.case-snap-three {
  top: 140vh;
  top: 140svh;
}

.case-snap-four {
  top: 210vh;
  top: 210svh;
}

/* grid-stack: the four cards share the one cell and center between the
   deck's breathing room, so each card hugs its content — on a tall
   screen it stays the size of its story instead of stretching to fill
   the column (the clamp still guards the short-screen fit). NOT the
   old abs-pos + height: fit-content + margin auto hug — shipped
   Safari resolves fit-content on an abs-pos box as stretch and the
   cards filled the whole column. */
.case-deck {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0;
  display: grid;
  align-items: center;
  padding-block: clamp(10px, calc(10svh - 50px), 48px);
}

.case {
  position: relative;
  grid-area: 1 / 1;
  width: 100%;
  min-height: 0;
  padding: 0 clamp(30px, 3.4vw, 64px);
  border: 1px solid rgba(10, 10, 10, 0.12);
  border-radius: clamp(24px, 3vw, 38px);
  background: var(--paper);
  box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.14);
  overflow: hidden;
  overflow: clip;
  transition: opacity 0.18s ease;
  transform-origin: center;
  will-change: transform;
}

.case.is-active {
  z-index: 1;
  transform: translateX(0) scale(1);
  opacity: 1;
  pointer-events: auto;
}

.case.is-before {
  z-index: 1;
  transform: translate3d(-12px, 8px, 0) rotate(-0.08deg) scale(0.988);
  opacity: 1;
  pointer-events: none;
}

/* pre-JS parks match the slide-up entrance home.js scrubs: the waiting
   card sits a full viewport below the stage's clip */
.case.is-next {
  z-index: 2;
  transform: translateY(100vh);
  transform: translateY(100svh);
  opacity: 1;
  pointer-events: none;
}

.case.is-after {
  z-index: 3;
  transform: translateY(100vh);
  transform: translateY(100svh);
  opacity: 1;
  pointer-events: none;
}

.no-js {
  scroll-snap-type: none;
}

.no-js .cases {
  height: auto;
  min-height: 0;
  padding: 0;
  overflow: visible;
}

.no-js .cases-stage {
  position: relative;
  height: auto;
  padding: 8px;
  overflow: visible;
}

.no-js .case-snap-point {
  display: none;
}

/* no-JS keeps the section headline too — the band, not the whole rail */
.no-js .deck-rail {
  display: block;
  padding: 56px clamp(20px, 6vw, 48px);
  text-align: center;
}

.no-js .deck-rail .deck-title {
  margin-inline: auto;
}

.no-js .deck-rail .case-pagination,
.no-js .deck-rail .btn {
  display: none;
}

.no-js .cases-stage {
  display: block;
}

.no-js .use-case-header .deck-title {
  display: block;
}

.no-js .capabilities .btn {
  display: inline-flex;
}

.no-js .case-deck {
  width: 100%;
  height: auto;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.no-js .case {
  position: relative;
  inset: auto;
  width: 100%;
  height: auto;
  min-height: 100vh;
  min-height: 100svh;
  transform: none;
  opacity: 1;
  pointer-events: auto;
}

/* the hire sequence unpins the same way the deck does */
.no-js .hire {
  position: relative;
  top: auto;
  height: auto;
  min-height: 0;
}

.no-js .hire-stage {
  position: relative;
  height: auto;
  display: block;
  overflow: visible;
}

.no-js .hire-snap-point,
.no-js .hire-nav {
  display: none;
}

.no-js .hire-panels {
  height: auto;
  margin-top: 0;
  overflow: visible;
}

.no-js .hire-panels::before,
.no-js .hire-panels::after {
  display: none;
}

.no-js .hire-panel {
  position: relative;
  inset: auto;
  height: auto;
  margin-block: 0;
  transform: none;
  pointer-events: auto;
}

.no-js .hire-panel + .hire-panel {
  margin-top: 12px;
}

@media (prefers-reduced-motion: reduce) {
  .case {
    transition: none;
  }
}

.case-body {
  width: 100%;
  max-width: 660px;
  min-height: inherit;
  margin: 0 auto;
  padding: clamp(34px, 5svh, 68px) 0 clamp(30px, 4.5svh, 60px);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  text-align: left;
}

/* the rail carries each card's title on wide screens; the h2 returns on
   stacked layouts, wearing the shared header voice */
.use-case-header .deck-title {
  display: none;
}

/* the group eyebrow above each receipt's title — stacked layouts only,
   where the rail that names the groups is gone */
.deck-group {
  display: none;
}

/* one CTA lives on the rail; the per-card buttons stay hidden everywhere
   with JS (founder: they look out of place on the stacked cards) and
   return only on the no-JS fallback, where the rail's CTA is gone */
.capabilities .btn {
  display: none;
}

/* "piece by piece", literally: each card wears its piece number as a giant
   ghost numeral cropped by the card's top-right corner */
.case-deck {
  counter-reset: case-piece;
}

.case {
  counter-increment: case-piece;
}

.case::before {
  content: "0" counter(case-piece);
  position: absolute;
  z-index: 0;
  top: -0.12em;
  right: -0.03em;
  font-size: clamp(140px, 14vw, 220px);
  font-weight: 740;
  line-height: 1;
  letter-spacing: -0.06em;
  font-variant-numeric: tabular-nums;
  color: rgba(10, 10, 10, 0.05);
  pointer-events: none;
  user-select: none;
}

.use-case-grid {
  margin-top: clamp(20px, 3svh, 36px);
  display: grid;
  grid-template-columns: 1fr;
  align-items: start;
  gap: clamp(16px, 2.2svh, 26px);
}

/* a heavy index band opens the content — the light rules below answer it */
.capabilities {
  padding-top: clamp(16px, 2.4svh, 24px);
  border-top: 3px solid var(--ink);
}

/* the card's headline wears the page's title voice (.deck-title) — on wide
   screens the rail holds the card's h2, so this line carries the card */
.capabilities-intro {
  margin: 0;
  max-width: 16ch;
  font-size: clamp(32px, 3.4vw, 52px);
  font-weight: 740;
  line-height: 1.04;
  letter-spacing: -0.045em;
}

/* the list IS the card now: each service reads big in the rail's own voice,
   behind a numbered index that keeps the rows measured */
.capabilities ul {
  counter-reset: capability;
  list-style: none;
  margin: clamp(22px, 3.4svh, 36px) 0 0;
  padding: 0;
  border-top: 1px solid var(--ink-12);
}

/* each row is the fact-rows recipe: a bold name and one muted line, hung
   from the numbered index column */
.capabilities li {
  counter-increment: capability;
  padding: clamp(13px, 2.2svh, 20px) 0;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: clamp(16px, 2vw, 26px);
  align-items: baseline;
  border-bottom: 1px solid var(--ink-12);
  font-size: clamp(19px, 1.6vw, 24px);
  font-weight: 650;
  line-height: 1.25;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.capabilities li::before {
  content: counter(capability, decimal-leading-zero);
  grid-column: 1;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-55);
}

.capabilities li strong {
  grid-column: 2;
  font-weight: 650;
}

.capabilities li span {
  grid-column: 2;
  margin-top: 5px;
  font-size: clamp(14px, 1.05vw, 15.5px);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: -0.005em;
  color: var(--ink-55);
}

.capabilities .btn {
  margin-top: clamp(26px, 4svh, 36px);
}

.proof-asset {
  min-width: 0;
  padding: 14px;
  border: 1px solid var(--ink-12);
  border-radius: 24px;
  background: var(--panel);
  box-shadow: 0 18px 60px rgba(10, 10, 10, 0.1);
}

.source-clips {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.source-clip {
  position: relative;
  height: 78px;
  border-radius: 12px;
  overflow: hidden;
  background-image:
    linear-gradient(to top, rgba(10, 10, 10, 0.55), transparent 65%), url("media/hero-poster.jpg");
  background-size: 220%;
}

.source-clip-one {
  background-position: 28% 52%;
}

.source-clip-two {
  background-position: 52% 46%;
}

.source-clip-three {
  background-position: 74% 54%;
}

.source-clip span,
.result-badge {
  position: absolute;
  left: 9px;
  bottom: 7px;
  font-size: 10px;
  font-weight: 600;
  color: var(--snow);
}

.edit-prompt {
  margin: 10px 0;
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 86px 1fr;
  align-items: center;
  border-radius: 11px;
  background: var(--paper);
}

.edit-prompt span,
.result-features span,
.listening-footer span,
.resolved-pill {
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-55);
}

.edit-prompt p {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
}

.video-result {
  padding: 10px;
  border-radius: 16px;
  background: var(--paper);
}

.result-frame {
  position: relative;
  height: clamp(140px, 19svh, 200px);
  border-radius: 11px;
  overflow: hidden;
  background-image:
    linear-gradient(to top, rgba(10, 10, 10, 0.68), transparent 68%), url("media/hero-poster.jpg");
  background-size: cover;
  background-position: center;
}

.result-badge {
  top: 10px;
  bottom: auto;
  padding: 5px 7px;
  border-radius: 5px;
  background: rgba(10, 10, 10, 0.62);
}

.result-caption {
  position: absolute;
  right: 22px;
  bottom: 18px;
  left: 22px;
  margin: 0;
  color: var(--snow);
  font-size: clamp(19px, 2vw, 27px);
  font-weight: 700;
  line-height: 1.1;
  text-align: center;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.5);
}

.edit-timeline {
  height: 12px;
  margin-top: 8px;
  display: flex;
  gap: 3px;
}

.edit-timeline span {
  flex: 1;
  border-radius: 2px;
  background: var(--ink);
}

.edit-timeline span:nth-child(2),
.edit-timeline span:nth-child(4) {
  flex: 0.45;
  background: var(--ink-12);
}

.result-features {
  margin-top: 7px;
  display: flex;
  justify-content: center;
  gap: 18px;
}

.support-proof,
.listening-proof,
.script-proof,
.schedule-proof,
.books-proof {
  padding: 0;
  overflow: hidden;
  background: var(--paper);
}

.support-toolbar,
.listening-toolbar,
.schedule-toolbar,
.books-toolbar {
  min-height: 56px;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 11px;
  border-bottom: 1px solid var(--ink-12);
  background: var(--panel);
}

.support-toolbar div,
.listening-toolbar div,
.schedule-toolbar div,
.books-toolbar div {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.support-toolbar strong,
.listening-toolbar strong,
.schedule-toolbar strong,
.books-toolbar strong {
  font-size: 13px;
}

.support-toolbar span,
.listening-toolbar span,
.schedule-toolbar span,
.books-toolbar > div span {
  font-size: 11px;
  color: var(--ink-55);
}

.listening-toolbar time,
.schedule-toolbar time {
  margin-left: auto;
  font-size: 10px;
  color: var(--ink-55);
}

.support-email,
.support-thanks,
.mention,
.schedule-row,
.books-note {
  padding: 13px 18px;
  border-bottom: 1px solid var(--ink-12);
}

.support-email > span,
.support-thanks > span,
.script-prompt > span,
.script-line > span,
.mention-source,
.schedule-time {
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-55);
}

.support-email p,
.mention p,
.schedule-row p,
.books-note p {
  margin: 6px 0 0;
  font-size: 14px;
  font-weight: 550;
  line-height: 1.45;
}

.support-answer {
  background: var(--panel);
}

.support-toolbar,
.books-toolbar {
  justify-content: space-between;
}

/* the listening brief: overheard posts, each with the signal that made
   the agent keep it — the schedule's day rows and the books' invoice
   note share the same grammar: a small label, the line, a status pill */
.mention,
.schedule-row,
.books-note {
  position: relative;
}

.mention p,
.schedule-row p,
.books-note p {
  padding-right: 84px;
}

.mention-signal,
.schedule-state {
  position: absolute;
  top: 12px;
  right: 16px;
  padding: 4px 9px;
  border: 1px solid var(--ink-12);
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  white-space: nowrap;
}

.listening-footer {
  min-height: 46px;
  padding: 10px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--panel);
}

.listening-footer strong {
  font-size: 13px;
}

/* the books: three ledger lines, plain words on the left, the number on
   the right — "Kept" is the line the owner actually reads */
.books-line {
  padding: 11px 18px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid var(--ink-12);
}

.books-line span {
  font-size: 12px;
  font-weight: 550;
  color: var(--ink-55);
}

.books-line strong {
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

.books-net strong {
  font-size: 19px;
  letter-spacing: -0.02em;
}

/* the script: one note in, four beats out */
.script-prompt {
  padding: 14px 18px;
  border-bottom: 1px solid var(--ink-12);
  background: var(--panel);
}

.script-prompt p {
  margin: 6px 0 0;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
}

.script-line {
  display: grid;
  grid-template-columns: 58px 1fr;
  gap: 14px;
  align-items: start;
  padding: 13px 18px;
  border-bottom: 1px solid var(--ink-12);
}

.script-line > span {
  padding-top: 3px;
}

.script-line p {
  margin: 0;
  font-size: 14px;
  font-weight: 550;
  line-height: 1.45;
}

.resolved-pill {
  padding: 6px 9px;
  border: 1px solid var(--ink-12);
  border-radius: 999px;
  color: var(--ink);
}

.support-thanks {
  min-height: 88px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-bottom: 0;
}

.support-thanks strong {
  margin-top: 8px;
  font-size: clamp(34px, 5vw, 62px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.055em;
}

@media (min-width: 901px) {
  .case-body {
    min-height: 100%;
  }
}

/* ---- the paper pages: what you're hiring, the tools, the fair question ---- */

.page {
  position: relative;
  z-index: 2;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 84px var(--rail) 72px;
  background: var(--paper);
  color: var(--ink);
  scroll-snap-align: start;
}

.page-body {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
}

/* headers keep the deck's left-aligned grammar, not the hire
   spotlight's centered one */
.page-header .deck-title {
  max-width: 20ch;
}

.page-lead {
  margin: 22px 0 0;
  max-width: 52ch;
  font-size: clamp(16px, 1.25vw, 18px);
  line-height: 1.6;
  color: var(--ink-70);
}

/* ---- what you're hiring: four points, one card at a time ----
   The founder's call: don't show the whole hire at once. The page pins
   (the deck's scroll plumbing on the paper ground) and scrolling rides
   a conveyor of content-height cards through a clipped window — tabs
   under the title are the indicator and the controls. No fades, no
   stacking, so the two pinned sequences stay distinct species. */

/* one positioning box for the sticky hire section, its snap anchors, and
   the closing page: the anchors stay stable in document space while .hire
   rides its pin, and the footer inside gives the pin its room to hold */
.hire-run {
  position: relative;
}

/* sticky through its own last viewport: top = -(310 - 100)svh pins the
   section the moment its final screen is on stage, so the closing page
   slides up OVER a compositor-held stage — the hero's cover transition,
   with none of the frame-lag a JS counter-scroll shows. home.js only
   adds the 0.22 recede and the veil on top of this hold. */
.hire {
  position: sticky;
  top: -210vh;
  top: -210svh;
  height: 310vh;
  height: 310svh;
  min-height: 310vh;
  min-height: 310svh;
  background: var(--paper);
}

/* header, tabs and card center together as one group — the window
   hugs the tallest card (home.js measures and sets its height), so
   nothing is anchored to the top of the viewport */
.hire-stage {
  position: sticky;
  z-index: 2;
  top: 0;
  height: 100vh;
  height: 100svh;
  /* lean vertical budget: header + tabs + card + CTA must share 100svh */
  padding: clamp(22px, 3.5svh, 44px) var(--rail);
  display: flex;
  flex-direction: column;
  /* safe: when the tallest card outgrows a short viewport, pin to the
     top so the title stays readable instead of clipping both edges */
  justify-content: safe center;
  overflow: hidden;
  overflow: clip;
}

/* fade-to-black over the held hire stage as the footer slides up over it —
   the hero-veil's twin, raised by home.js (wide pinned mode only; stacked
   and reduced-motion layouts keep it at rest) */
.hire-veil {
  position: absolute;
  z-index: 4;
  inset: 0;
  background: #0a0a0a;
  opacity: 0;
  pointer-events: none;
}

/* the stage's own CTA, centered under the card window — parked at the
   window's bottom rim, so shorter cards leave calm air above it */
.hire-stage .cta-row {
  flex: none;
  justify-content: center;
  margin-top: clamp(14px, 2svh, 20px);
}

/* a height-starved viewport: shrink the air (never the type) before
   clipping the card; safe center (on .hire-stage) keeps the title on
   screen when even that is not enough */
@media (max-height: 830px) {
  .hire-stage {
    padding-top: 18px;
    padding-bottom: 18px;
  }

  .hire-nav {
    margin-top: 18px;
  }

  .hire-stage .cta-row {
    margin-top: 12px;
  }
}

/* this page speaks from the center — the spotlight beat among the
   left-aligned pages */
.hire-stage .page-header {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  text-align: center;
}

.hire-stage .deck-title {
  margin-inline: auto;
}

/* the sticky stage can't be a snap target, so fixed anchors pace the
   four steps — 70vh apiece, the deck's own cadence. They sit on
   .hire-run, NOT inside .hire: the section itself is sticky, and an
   anchor inside a stuck box rides the scroll — scrolling up from the
   footer would sail past the last step. */
.hire-snap-point {
  position: absolute;
  left: 0;
  width: 1px;
  height: 1px;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

.hire-snap-one {
  top: 0;
}

.hire-snap-two {
  top: 70vh;
  top: 70svh;
}

.hire-snap-three {
  top: 140vh;
  top: 140svh;
}

.hire-snap-four {
  top: 210vh;
  top: 210svh;
}

/* one thing on stage: the panels live in a clipped window and slide
   up through it with the scroll — home.js scrubs the conveyor, and
   is-active is the pre-JS floor */
.hire-panels {
  position: relative;
  flex: none;
  /* pre-JS fallback only — home.js sets the real height to the
     tallest card plus room for the edge veils */
  height: min(56svh, 520px);
  width: 100%;
  max-width: 1240px;
  /* the tabs-to-card gap = this margin + the 28px of veil air above
     the top-anchored card — constant across steps */
  margin: clamp(14px, 2svh, 20px) auto 0;
  overflow: hidden;
  overflow: clip;
}

/* soft edges: a whisper of ground at the window's rim, so a card in
   transit dissolves into white instead of clipping hard */
.hire-panels::before,
.hire-panels::after {
  content: "";
  position: absolute;
  z-index: 2;
  left: 0;
  right: 0;
  height: 28px;
  pointer-events: none;
}

.hire-panels::before {
  top: 0;
  background: linear-gradient(to bottom, var(--paper), rgba(255, 255, 255, 0));
}

.hire-panels::after {
  bottom: 0;
  background: linear-gradient(to top, var(--paper), rgba(255, 255, 255, 0));
}

/* each panel is a visible card, so what slides through the window
   reads as a container arriving — hairline and soft lift on the paper
   ground, the deck cards' radius. The card hugs its content rather
   than filling the stage: top-anchored past the veil (bottom: auto,
   height stays auto) — every card's top edge lands at the same 28px,
   so the tabs-to-card gap never varies, and a shorter card's spare
   air sits between it and the CTA below. NOT height: fit-content
   with inset: 0 — shipped Safari resolves fit-content on an abs-pos
   box as stretch, and the cards ballooned to the full window (the JS
   tallest-card measurement then grew the window every frame). */
.hire-panel {
  position: absolute;
  inset: 28px 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  align-items: center;
  column-gap: clamp(36px, 4.5vw, 90px);
  padding: clamp(30px, 4.5svh, 52px) clamp(32px, 4vw, 72px);
  border: 1px solid var(--ink-12);
  border-radius: clamp(24px, 3vw, 38px);
  background: var(--paper);
  /* pre-JS floor: park well past the window even for a short card */
  transform: translate3d(0, 160%, 0);
  pointer-events: none;
  will-change: transform;
}

.hire-panel.is-active {
  transform: none;
  pointer-events: auto;
}

.hire-copy {
  min-width: 0;
}

.hire-visual {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hire-panel h3 {
  margin: 0;
  max-width: 16ch;
  font-size: clamp(30px, 3.2vw, 48px);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.04em;
}

/* the one lead voice — same numbers as .page-lead */
.hire-panel-lead {
  margin: 18px 0 0;
  max-width: 48ch;
  font-size: clamp(16px, 1.25vw, 18px);
  line-height: 1.62;
  color: var(--ink-70);
}

/* the tabs: one segmented control under the title. The ink thumb is
   the indicator — home.js interpolates its position along the scroll,
   so it glides between segments exactly as the cards trade places. */
.hire-nav {
  position: relative;
  /* confine the labels' difference blend to the nav's own track + thumb:
     without this, engines blend them against the whole page and the
     white labels punch through the closing veil (seen in Safari) */
  isolation: isolate;
  align-self: center;
  flex: none;
  margin-top: clamp(24px, 4.5svh, 44px);
  display: flex;
  padding: 6px;
  border: 1px solid var(--ink-12);
  border-radius: 999px;
  background: var(--panel);
}

.hire-nav-thumb {
  position: absolute;
  z-index: 1;
  top: 6px;
  bottom: 6px;
  left: 0;
  width: 0;
  border-radius: 999px;
  background: var(--ink);
}

/* labels are white and blend by difference, so each letter inverts
   itself the instant the thumb slides beneath it — no half-covered,
   half-legible states mid-scroll */
.hire-nav button {
  appearance: none;
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  padding: 12px 24px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 570;
  letter-spacing: -0.01em;
  color: #fff;
  opacity: 0.5;
  mix-blend-mode: difference;
  cursor: pointer;
  transition: opacity 0.18s ease;
}

.hire-nav button:hover {
  opacity: 0.8;
}

.hire-nav button[aria-current="step"] {
  opacity: 1;
}

/* the thread bubbles, shared by several of the channel demos; the base
   colors are the web app's own monochrome — each branded demo re-dresses
   them in its channel's palette below */
/* regular weight, deliberately: every one of these apps sets its
   message text in the regular cut, and a semibold bubble is the tell
   that a screenshot is fake */
.chat-bubble {
  max-width: 84%;
  padding: 10px 15px;
  border-radius: 18px;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.4;
}

.chat-bubble p {
  margin: 0;
}

.chat-you {
  align-self: flex-end;
  border-bottom-right-radius: 5px;
  background: var(--ink);
  color: var(--snow);
}

.chat-agent {
  align-self: flex-start;
  border: 1px solid var(--ink-12);
  border-bottom-left-radius: 5px;
  background: var(--paper);
}

.chat-attachment span {
  display: block;
  margin-bottom: 3px;
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-55);
}

.chat-attachment p {
  font-size: 12px;
}

/* ---- the channel picker: six doors, each with its own demo. A
   horizontal strip of app-icon tiles directly under the stage, so the
   switcher reads as part of the demo it drives. Resting buttons are
   the bare tiles; the pressed one slides its name open beside the
   tile, so the row stays quiet and the selection announces itself ---- */

.channel-picker {
  margin-top: 16px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}

/* a grid, not a flex row: the name sits in a 0fr track that animates
   to 1fr, so its width interpolates to the exact text width — a
   max-width guess overshoots, which made the centered row swell and
   settle (bounce) on every switch */
.channel-picker button {
  appearance: none;
  display: grid;
  grid-template-columns: auto 0fr;
  align-items: center;
  padding: 4px;
  border: 0;
  border-radius: 15px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 570;
  letter-spacing: -0.01em;
  color: var(--ink-70);
  text-align: left;
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    grid-template-columns 0.25s ease,
    padding 0.25s ease;
}

.channel-picker button:hover {
  background: rgba(10, 10, 10, 0.035);
  color: var(--ink);
}

/* selected is a light grey wash, not an ink slab — the colored tiles
   are the loud thing in this list, and an ink row fought them */
.channel-picker button[aria-pressed="true"] {
  background: rgba(10, 10, 10, 0.07);
  color: var(--ink);
  font-weight: 640;
  grid-template-columns: auto 1fr;
  padding-right: 12px;
}

/* the name rides collapsed inside every button (still read to screen
   readers) and slides open on the pressed one; margin, track and
   padding share one duration and easing so the button's total width
   moves as a single smooth sum */
.pick-name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  transition:
    margin-left 0.25s ease,
    opacity 0.2s ease;
}

.channel-picker button[aria-pressed="true"] .pick-name {
  margin-left: 9px;
  opacity: 1;
}

/* the tiles: each channel's real mark on its app color — recognition
   at a glance, like a row of home-screen icons. Email has no owner and
   wears the house ink; Web is our own app and wears its white. */
.pick-logo {
  flex: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 11px;
}

.pick-logo svg {
  width: 22px;
  height: 22px;
}

/* per-brand size correction, measured from each path's drawn bounds:
   the iMessage bubble fills only ~16px of a 22px box, and Telegram's
   plane is reframed to a tight box (see the HTML), so both get their
   own size to land the drawn glyph at ~18px like the rest */
.pick-imessage .pick-logo svg {
  width: 25px;
  height: 25px;
}

.pick-telegram .pick-logo svg {
  width: 18px;
  height: 18px;
}

.pick-imessage .pick-logo {
  background: linear-gradient(180deg, #6be66f, #0fbe33);
  color: #fff;
}

.pick-telegram .pick-logo {
  background: linear-gradient(180deg, #37aee2, #1e96c8);
  color: #fff;
}

.pick-slack .pick-logo {
  background: #4a154b;
  color: #fff;
}

.pick-slack .pick-logo svg {
  width: 20px;
  height: 20px;
}

.pick-buzz .pick-logo {
  background: #141414;
  color: #d7d72e;
}

.pick-buzz .pick-logo svg {
  width: 25px;
  height: auto;
}

.pick-email .pick-logo {
  background: var(--ink);
  color: var(--snow);
}

.pick-web .pick-logo {
  background: var(--paper);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink-12);
}

.pick-email .pick-logo svg,
.pick-web .pick-logo svg {
  width: 20px;
  height: 20px;
}

/* the stage keeps one footprint so switching demos never resizes the
   card mid-conveyor */
.channel-stage {
  position: relative;
  width: min(100%, 560px);
  /* a little air around the resting demo; the height itself comes
     from the grid below, not from this floor */
  min-height: 390px;
  /* every demo occupies the same grid cell, so the stage is always as
     tall as the TALLEST demo — switching can never resize the card
     (a per-breakpoint min-height went stale once and made the switch
     jump; this can't) */
  display: grid;
  align-items: center;
}

/* --demo-pad is the card's inset; the bled headers (telegram's bar,
   slack's workspace strip, web's browser chrome) count on it to reach
   the card edge, so change it here, not in a demo */
.channel-demo {
  --demo-pad: 22px;
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  visibility: hidden;
  width: 100%;
  padding: var(--demo-pad) var(--demo-pad) 24px;
  border: 1px solid var(--ink-12);
  border-radius: 22px;
  background: var(--panel);
  box-shadow: 0 24px 48px -32px rgba(10, 10, 10, 0.28);
  text-align: left;
}

.channel-demo.is-active {
  visibility: visible;
}

@media (prefers-reduced-motion: no-preference) {
  .channel-demo.is-active {
    animation: demo-in 0.28s ease;
  }

  @keyframes demo-in {
    from {
      opacity: 0;
      transform: translateY(10px);
    }

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

.demo-avatar {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ink);
  color: var(--snow);
}

.demo-avatar svg {
  height: 16px;
  width: auto;
}

/* iMessage: the centered contact header and the Delivered receipt,
   in Messages' own dress — white ground, the blue send bubble, the
   gray receive bubble, Apple's gray for every receipt */
.demo-imessage {
  background: #fff;
  box-shadow: 0 24px 48px -32px rgba(10, 124, 255, 0.4);
}

.demo-imessage .chat-you {
  background: #0a7cff;
  color: #fff;
}

.demo-imessage .chat-agent {
  border: 0;
  background: #e9e9eb;
  color: var(--ink);
}

.demo-imessage .chat-attachment span {
  color: #8e8e93;
}

.demo-imessage .demo-stamp,
.demo-imessage .demo-delivered {
  color: #8e8e93;
}

.im-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin-bottom: 2px;
}

.im-head strong {
  font-size: 12.5px;
  font-weight: 600;
}

.demo-stamp {
  margin: 0 0 2px;
  text-align: center;
  font-size: 10px;
  color: var(--ink-55);
}

.demo-delivered {
  margin: -2px 2px 0 0;
  align-self: flex-end;
  font-size: 10.5px;
  font-weight: 500;
  color: var(--ink-55);
}

/* Telegram: a left-aligned top bar, times and ticks inside bubbles —
   Telegram's dress: the sky-tinted chat wallpaper, a white header bar
   bled to the card edge, the pale-green send bubble with green ticks,
   plain white receive bubbles, blue everywhere Telegram puts blue */
.demo-telegram {
  background: linear-gradient(180deg, #e9f1f7, #dcebf3);
  box-shadow: 0 24px 48px -32px rgba(42, 171, 238, 0.45);
}

.tg-head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: calc(var(--demo-pad) * -1) calc(var(--demo-pad) * -1) 4px;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(10, 10, 10, 0.08);
  border-radius: 22px 22px 0 0;
  background: #fff;
}

.demo-telegram .demo-avatar {
  background: linear-gradient(180deg, #53b0f0, #2aabee);
}

.demo-telegram .chat-you {
  background: #effdde;
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(16, 35, 47, 0.15);
}

.demo-telegram .chat-agent {
  border: 0;
  background: #fff;
  box-shadow: 0 1px 2px rgba(16, 35, 47, 0.15);
}

.demo-telegram .chat-you .tg-meta {
  color: #4fae4e;
  opacity: 1;
}

.demo-telegram .chat-agent .tg-meta {
  color: #a0acb6;
  opacity: 1;
}

.tg-id {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tg-id strong {
  font-size: 13px;
}

.tg-id small {
  font-size: 10.5px;
  color: #2aabee;
}

.tg-meta {
  margin-left: 8px;
  font-size: 8.5px;
  letter-spacing: 0.04em;
  opacity: 0.65;
  white-space: nowrap;
}

/* Slack: #channel header, square avatars, name rows with the APP badge —
   Slack's dress: the aubergine workspace bar with its search pill, a
   white channel below it, a raspberry initial avatar for the human, the
   blue mention pill, Slack's own gray for times and the APP badge (the
   doppelganger keeps its ink-black app icon) */
.demo-slack {
  background: #fff;
  box-shadow: 0 24px 48px -32px rgba(74, 21, 75, 0.4);
}

.slack-top {
  display: flex;
  justify-content: center;
  margin: calc(var(--demo-pad) * -1) calc(var(--demo-pad) * -1) 2px;
  padding: 9px 16px;
  border-radius: 22px 22px 0 0;
  background: #4a154b;
}

.slack-top p {
  margin: 0;
  padding: 3px 28px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.22);
  font-size: 10.5px;
  font-weight: 550;
  color: #fff;
}

.slack-chan {
  margin: 0 0 4px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ink-12);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.slack-msg {
  margin-top: 6px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.slack-avatar {
  flex: none;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  background: #e01e5a;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
}

.slack-avatar-app {
  background: var(--ink);
  color: var(--snow);
}

.slack-avatar svg {
  height: 14px;
  width: auto;
}

.slack-name {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
}

.slack-name small {
  margin-left: 4px;
  font-size: 10px;
  font-weight: 500;
  color: #616061;
}

.slack-app {
  display: inline-block;
  margin-left: 2px;
  padding: 1px 4px;
  border-radius: 3px;
  background: #e8e8e8;
  color: #616061;
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 0.06em;
  vertical-align: 1px;
}

.slack-text {
  margin: 2px 0 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
}

.slack-mention {
  padding: 0 3px 1px;
  border-radius: 4px;
  background: rgba(29, 155, 209, 0.13);
  color: #1264a3;
  font-weight: 550;
}

/* Buzz: a named group thread, everyone in one place — in Buzz's real
   dress: the desktop app is mostly black and #d7d72e is its primary,
   so the thread wears near-black ground, a chartreuse send bubble,
   charcoal receive bubbles, chartreuse sender names */
.demo-buzz {
  background: #141414;
  box-shadow: 0 24px 48px -32px rgba(215, 215, 46, 0.5);
}

.demo-buzz .buzz-head {
  border-bottom-color: rgba(255, 255, 255, 0.14);
}

.demo-buzz .buzz-head strong {
  color: var(--snow);
}

.demo-buzz .buzz-head small {
  color: var(--snow-60);
}

.demo-buzz .chat-you {
  background: #d7d72e;
  color: #141414;
}

.demo-buzz .chat-agent {
  border: 0;
  background: #262626;
  color: var(--snow-80);
}

.demo-buzz .buzz-name {
  color: rgba(215, 215, 46, 0.85);
}

.buzz-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  margin-bottom: 6px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ink-12);
}

.buzz-head strong {
  font-size: 13px;
}

.buzz-head small {
  font-size: 10.5px;
  color: var(--ink-55);
}

.buzz-msg {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.buzz-name {
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-55);
}

.buzz-you {
  align-items: flex-end;
}

/* Email: subject, meta rows, a short body — a mail reading pane is
   white in every client, so white is the whole dress */
.demo-email {
  background: #fff;
}

.email-subject {
  margin: 0 0 10px;
  font-size: 15.5px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.email-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 7px 0;
  border-top: 1px solid var(--ink-12);
}

.email-row span {
  flex: none;
  width: 36px;
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-55);
}

.email-row p {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
}

.email-body {
  margin-top: 2px;
  padding-top: 12px;
  border-top: 1px solid var(--ink-12);
}

.email-body p {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.55;
  color: var(--ink-70);
}

.email-body p:last-child {
  margin-bottom: 0;
}

/* Web: browser chrome over the app's own chat. The app really is
   monochrome, so the bubbles keep the base dress — the only color the
   truth allows is the browser's own: macOS traffic lights and the green
   working dot */
.web-chrome {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: calc(var(--demo-pad) * -1) calc(var(--demo-pad) * -1) 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--ink-12);
  border-radius: 22px 22px 0 0;
  background: var(--paper);
}

.web-chrome span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.web-chrome span:nth-child(1) {
  background: #ff5f57;
}

.web-chrome span:nth-child(2) {
  background: #febc2e;
}

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

.web-chrome p {
  margin: 0 0 0 8px;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--panel);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: var(--ink-70);
}

.web-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.web-status {
  margin: 4px 0 0;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-55);
}

/* the live dot beside "Working" — the one green the monochrome app
   allows itself */
.status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #30d158;
}

@media (prefers-reduced-motion: no-preference) {
  .status-dot {
    animation: live-pulse 2.4s ease-in-out infinite;
  }

  @keyframes live-pulse {
    0%,
    100% {
      box-shadow: 0 0 0 0 rgba(48, 209, 88, 0.4);
    }

    50% {
      box-shadow: 0 0 0 5px rgba(48, 209, 88, 0);
    }
  }
}

/* ---- the four powers and the three security promises share one
   grammar: fact rows in the open — hairline-separated on the panel's
   own paper, no card, no toolbar (founder call: big type, big chips,
   less card). Each row is a house stroke glyph on a tile, a bold
   name, one muted explaining line, and a mono receipt line that SHOWS
   the claim: model chips, deliverable files, a schedule, the live
   Working status, a masked credential, the allow/ask/deny control,
   the approval pair. The two text panels read as one system. ---- */

.fact-rows {
  margin: 0;
  padding: 0;
  list-style: none;
  width: min(100%, 580px);
  text-align: left;
}

/* pure type rows — no per-row icon (boxed tiles, then bare margin
   glyphs, were each cut as cheap-looking; the tags' brand marks below
   carry all the visual) */
.fact {
  padding: 19px 0 21px;
  border-top: 1px solid var(--ink-12);
}

.fact:last-child {
  border-bottom: 1px solid var(--ink-12);
}

.fact-text {
  min-width: 0;
}

/* calm weight — a founder round overshot into 20px/650 and was pulled
   back: the rows should read as a list, not four headlines */
.fact-text b {
  display: block;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.3;
  color: var(--ink);
}

.fact-text p {
  margin: 5px 0 0;
  font-size: 15.5px;
  font-weight: 450;
  line-height: 1.55;
  color: var(--ink-55);
  text-wrap: pretty;
}

/* the receipt line: what the row claims, shown in the product's own
   mono voice — chips, a segmented control, the live status */
.fact-text .fact-meta {
  margin-top: 11px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* bare tokens separate by air, not borders — the wider column gap
     is what keeps them reading as distinct tags */
  gap: 10px 18px;
  line-height: 1;
}

.fact-meta-label {
  font-size: 15px;
  color: var(--ink-55);
}

/* tags carry a small mark before the label — a real brand mark
   (models; Slack/GitHub/Linear) or a house stroke glyph (deliverables,
   approve/decline) — so each SHOWS what it names. They speak in the
   tool roster's own label voice (body face, 14.5/570), NOT mono
   uppercase (read as out of place — founder call), and wear no pill
   dress; the one dressed state is the solid ink pill, the hire-nav
   thumb's language, reserved for the active value (Ask) and the
   primary action (Approve). */
.fact-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--ink);
  white-space: nowrap;
}

.fact-chip svg {
  flex: none;
  width: 17px;
  height: 17px;
}

.fact-chip-ink {
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--snow);
}

/* each brand mark in its brand's own hex (Simple Icons data, same
   provenance as the tool roster); Kimi and GitHub are black brands,
   so ink IS their color and they need no rule */
.chip-claude svg {
  color: #d97757;
}

.chip-gemini svg {
  color: #8e75b2;
}

.chip-deepseek svg {
  color: #5786fe;
}

.chip-slack svg {
  color: #4a154b;
}

.chip-linear svg {
  color: #5e6ad2;
}

.fact-live {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 450;
  color: var(--ink-55);
}

/* ---- the tools roster, plus the one that's missing: mark-plus-name
   rows in three columns, the same tile-and-label rhythm the channel
   roster uses one panel over ---- */

/* the <defs> carrier itself never paints */
.tool-sprite {
  display: none;
}

/* columns sized to their widest label, spread to the full width: a
   fr-based grid wrapped "Google Calendar" onto two lines at narrower
   panels, which broke the row rhythm */
.tool-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  width: min(100%, 560px);
  display: grid;
  grid-template-columns: repeat(3, max-content);
  justify-content: space-between;
  gap: 4px 8px;
}

/* nowrap columns can't shrink, so the row scales with the panel — one
   size fits only the widest panel, and below that the three columns
   would push past the card */
.tool-grid li {
  display: flex;
  align-items: center;
  gap: clamp(8px, 0.8vw, 11px);
  min-width: 0;
  padding: 5px 6px 5px 5px;
  border-radius: 13px;
  font-size: clamp(13.5px, 1.05vw, 15px);
  font-weight: 570;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--ink);
}

/* the app's own accounts-table tile, miniaturized — what you see here
   is what you see once the account is connected */
.tool-mark {
  flex: none;
  width: clamp(28px, 2.4vw, 34px);
  height: clamp(28px, 2.4vw, 34px);
  display: grid;
  place-items: center;
  border: 1px solid var(--ink-12);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
}

.tool-mark svg {
  width: clamp(15px, 1.3vw, 18px);
  height: clamp(15px, 1.3vw, 18px);
}

/* Each mark in its own brand color. Hex provenance, so a future edit
   can check rather than guess: Simple Icons' current data for most;
   its v11 data for Slack/Excel/Outlook (v13's brand purge dropped
   them, which is the same release the marks themselves are pinned to);
   and Granola's read off its own app icon — a dark spiral on olive, so
   it takes the tile rather than the glyph. Marks with no rule here are
   brands whose own logo is black (Notion, GitHub, X, Resend) or, for
   Luma, measurably neutral — ink is their brand color, not a fallback. */
.t-gmail .tool-mark {
  color: #ea4335;
}

.t-google-calendar .tool-mark {
  color: #4285f4;
}

.t-google-drive .tool-mark {
  color: #4285f4;
}

.t-google-sheets .tool-mark {
  color: #34a853;
}

.t-microsoft-outlook .tool-mark {
  color: #0078d4;
}

.t-microsoft-excel .tool-mark {
  color: #217346;
}

.t-airtable .tool-mark {
  color: #18bfff;
}

.t-slack .tool-mark {
  color: #4a154b;
}

.t-linear .tool-mark {
  color: #5e6ad2;
}

.t-stripe .tool-mark {
  color: #635bff;
}

.t-loops .tool-mark {
  color: #fc5200;
}

.t-spotify .tool-mark {
  color: #1ed760;
}

.t-instagram .tool-mark {
  color: #ff0069;
}

.t-google .tool-mark {
  color: #4285f4;
}

.t-granola .tool-mark {
  border-color: transparent;
  background: #b2c248;
  color: #1c1c1c;
}

/* the missing tile is the invitation — a dashed row across all three
   columns, so it reads as the end of the list rather than a 21st tool */
.tool-grid .tool-request {
  grid-column: 1 / -1;
  /* not the flex row its siblings are — the link fills the span */
  display: block;
  margin-top: 4px;
  padding: 0;
}

.tool-request a {
  display: block;
  padding: 10px 14px;
  border: 1px dashed rgba(10, 10, 10, 0.28);
  border-radius: 12px;
  text-align: center;
  font-size: 14px;
  font-weight: 570;
  color: var(--ink-70);
  transition:
    background 0.15s ease,
    border-color 0.15s ease,
    color 0.15s ease;
}

.tool-request a:hover {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--snow);
}

/* ---- the site footer: a complete final page, not a utility band ---- */

.site-footer {
  position: relative;
  z-index: 3;
  overflow: clip;
  height: 100vh;
  height: 100svh;
  min-height: 0;
  max-height: 100vh;
  max-height: 100svh;
  padding: clamp(48px, 7svh, 72px) clamp(18px, 2.4vw, 46px) 24px;
  display: flex;
  flex-direction: column;
  background: var(--ink);
  color: var(--snow);
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

.foot-inner {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
}

/* the same contained halo the black pages carry, pooled behind the
   centered mission line — this is the mission page's atmosphere, not the
   old utility band's top-edge glow */
.site-footer::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse 50% 46% at 50% 44%,
    rgba(255, 255, 255, 0.08),
    rgba(255, 255, 255, 0.032) 45%,
    rgba(255, 255, 255, 0.01) 72%,
    transparent
  );
}

.foot-closing {
  position: relative;
  z-index: 1;
  flex: 1;
  width: 100vw;
  max-width: none;
  margin-inline: calc(50% - 50vw);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* the mission, centered on the page like the old black mission page */
.foot-mission {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 var(--rail);
}

/* the mission signs off in the same header voice as the objection */
.foot-mission-line {
  margin: 0;
  max-width: 44ch;
  font-size: clamp(38px, 4.4vw, 62px);
  font-weight: 740;
  line-height: 1.08;
  letter-spacing: -0.05em;
  text-align: center;
  text-wrap: balance;
  color: var(--snow);
}

.foot-mission-line strong {
  font-weight: inherit;
}

/* the bottom of the closing page: the brand alone, centered, signing the
   site off — Terms/Privacy stay as quiet corner links (the reachable
   privacy URL is what Google OAuth verification checks) */
.foot-bottom {
  position: relative;
  z-index: 1;
  max-width: 1240px;
  width: 100%;
  margin: 24px auto 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px 0;
}

.foot-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--snow);
}

.foot-brand .logo-mark {
  height: 30px;
}

.foot-brand .brand-word {
  font-size: 17px;
}

.foot-links {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  display: flex;
  gap: 18px;
  font-size: 13.5px;
}

.foot-links a {
  color: rgba(255, 255, 255, 0.38);
  transition: color 0.15s ease;
}

.foot-links a:hover {
  color: var(--snow);
}

/* Short laptops: the pinned stage has a hard ceiling, and the channels
   and capabilities panels are the tall ones, so their rosters, stages
   and rows give back the height the window can't spare. The stacked
   layout only takes over below 701px, so between there and 880px this
   is the whole safety margin.

   THIS BLOCK MUST STAY LAST of the panel CSS. Every declaration here
   has the same specificity as the base rule it overrides, so it only
   wins by source order — parked above those rules (where it first
   lived) it silently does nothing, which is exactly how the tools half
   of it sat dead until the capabilities panel overflowed and exposed
   it. Add new panel components ABOVE this block, never below. */
@media (min-height: 701px) and (max-height: 880px) {
  .channel-picker {
    margin-top: 12px;
  }

  .pick-logo {
    width: 34px;
    height: 34px;
    border-radius: 9px;
  }

  .pick-logo svg {
    width: 19px;
    height: 19px;
  }

  .pick-imessage .pick-logo svg {
    width: 21px;
    height: 21px;
  }

  .pick-telegram .pick-logo svg {
    width: 15px;
    height: 15px;
  }

  .pick-buzz .pick-logo svg {
    width: 21px;
  }

  .channel-stage {
    min-height: 330px;
  }

  .chat-bubble {
    font-size: 14px;
    padding: 9px 14px;
  }

  .tool-grid li {
    padding: 3px 8px 3px 3px;
    font-size: 13.5px;
  }

  .tool-mark {
    width: 30px;
    height: 30px;
  }

  .tool-mark svg {
    width: 16px;
    height: 16px;
  }

  .tool-request a {
    padding: 8px 14px;
  }

  /* tightened so the fact rows stay under the channels card, and
     those panels never become the one that sets the window height */
  .fact {
    padding: 12px 0 14px;
    column-gap: 14px;
  }

  .fact-text b {
    font-size: 14.5px;
  }

  .fact-text p {
    margin-top: 3px;
    font-size: 13px;
    line-height: 1.5;
  }

  .fact-text .fact-meta {
    margin-top: 8px;
    gap: 6px 12px;
  }

  .fact-meta-label {
    font-size: 12.5px;
  }

  .fact-chip {
    gap: 6px;
    font-size: 13px;
  }

  .fact-chip svg {
    width: 14px;
    height: 14px;
  }

  .fact-chip-ink {
    padding: 6px 13px;
  }

  .fact-live {
    font-size: 12.5px;
  }
}

/* the pinned hire stage on short laptops: header + tabs + the tallest card
   already spend the whole viewport, so the CTA under the card holds a
   permanent half-clip at the bottom edge for the entire pinned sequence.
   Below ~800px of height it can never fit — drop it (the hero and deck
   rail each carry the same CTA). Wide pinned mode only:
   under 701px height or reduced motion the section unpins and the CTA
   rides in flow. */
@media (min-width: 1101px) and (min-height: 701px) and (max-height: 799px) and (prefers-reduced-motion: no-preference) {
  .hire-stage .cta-row {
    display: none;
  }
}

@media (max-width: 1100px), (max-height: 700px), (prefers-reduced-motion: reduce) {
  /* no snapping at all off the wide pinned layout: nothing is scrubbed
     here, the stacked cards are taller than a phone screen, and iPhone
     Safari fought even proximity snap on a page this tall (founder call
     2026-08-24 — it felt really bad; don't bring proximity back).
     html.snap-loose must be named too: iPhone Safari carries that class
     (Apple engine), and its (0,1,1) proximity rule out-specifies a bare
     `html` here — the footer kept snapping without this. */
  html,
  html.snap-loose {
    scroll-snap-type: none;
  }

  .cases {
    height: auto;
    min-height: 0;
    padding: 0;
    overflow: visible;
  }

  /* too small for the rail-and-cards split → the receipts go full screen:
     no side frame, and the card chrome goes below. The 8px vertical pad
     survives as the ink seam above and below the stack. */
  .cases-stage {
    position: relative;
    top: auto;
    height: auto;
    padding: 8px 0;
    max-width: none;
    margin-inline: 0;
    display: block;
    overflow: visible;
  }

  .case-snap-point {
    display: none;
  }

  /* stacked layouts drop the rail's nav and CTA but keep its headline:
     "We automate your business piece by piece" returns as the section's
     title band on the ink ground — centered like the employee band, the
     symmetric padding holding the headline mid-band — and each card
     carries its own title and CTA again */
  .deck-rail {
    display: block;
    padding: 56px clamp(20px, 6vw, 48px);
    text-align: center;
  }

  .deck-rail .deck-title {
    margin-inline: auto;
  }

  .deck-rail .case-pagination,
  .deck-rail .btn {
    display: none;
  }

  .use-case-header .deck-title {
    display: block;
  }

  .deck-group {
    display: block;
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-55);
  }

  .case-deck {
    width: 100%;
    height: auto;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow: visible;
    scroll-snap-type: none;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .case-deck::-webkit-scrollbar {
    display: none;
  }

  .case {
    position: relative;
    inset: auto;
    flex: 0 0 auto;
    width: 100%;
    height: auto;
    min-height: auto;
    margin: 0;
    padding: 0 clamp(20px, 6vw, 48px);
    border: 0;
    border-radius: 0;
    box-shadow: none;
    transform: none !important;
    opacity: 1;
    pointer-events: auto;
    scroll-snap-align: none;
  }

  /* no card corner to crop the ghost numeral against — it stays a deck flourish */
  .case::before {
    display: none;
  }

  .case-body {
    min-height: 0;
    max-width: 1240px;
    padding: 56px 0 48px;
  }

  .use-case-grid {
    margin-top: 34px;
    grid-template-columns: 1fr;
    gap: 34px;
  }

  /* the card's h2 is back as the headline here — the label steps down a
     rung so the two don't compete */
  .capabilities-intro {
    max-width: none;
    font-size: clamp(23px, 4.6vw, 32px);
  }

  .proof-asset {
    width: 100%;
    max-width: 680px;
  }

  .page {
    min-height: 0;
    padding-top: 72px;
    padding-bottom: 56px;
  }

  /* the hire sequence unpins like the deck: the indicator goes, the
     four panels stack in order and read top to bottom */
  .hire {
    position: relative;
    top: auto;
    height: auto;
    min-height: 0;
  }

  /* the employee panels follow the deck: too small for the spread split →
     full-screen pages, no card chrome, and the deck's own 8px ink seam
     between panels. The visual props inside keep their own dress. */
  .hire-stage {
    position: relative;
    height: auto;
    padding: 0 0 56px;
    display: block;
    overflow: visible;
  }

  /* the section header wears the deck band's dress — ink ground, snow
     text — and symmetric padding keeps the headline vertically centered
     in its band; the band itself separates header from panels */
  .hire-stage .page-header {
    background: var(--ink);
    color: var(--snow);
    padding: 56px clamp(20px, 6vw, 48px);
  }

  .hire-snap-point,
  .hire-nav {
    display: none;
  }

  .hire-panels {
    height: auto;
    margin-top: 0;
    overflow: visible;
  }

  .hire-panels::before,
  .hire-panels::after {
    display: none;
  }

  .hire-panel {
    position: relative;
    inset: auto;
    height: auto;
    margin-block: 0;
    padding: 34px clamp(20px, 6vw, 48px) 38px;
    grid-template-columns: minmax(0, 1fr);
    row-gap: 26px;
    border: 0;
    border-radius: 0;
    transform: none !important;
    pointer-events: auto;
  }

  .hire-panel + .hire-panel {
    margin-top: 0;
    border-top: 8px solid var(--ink);
  }
}

@media (max-width: 620px) {
  :root {
    --rail: 20px;
  }

  .nav {
    padding: 0 20px;
    height: 68px;
  }

  .btn {
    padding: 13px 24px;
  }

  .hero-copy {
    padding-bottom: env(safe-area-inset-bottom);
  }

  h1 {
    margin-top: 14px;
    font-size: clamp(29px, 9.2vw, 39px);
    line-height: 1.06;
  }

  .hero-copy .cta-row {
    width: 100%;
    margin-top: 30px;
  }

  .hero-copy .btn {
    width: min(100%, 320px);
    justify-content: center;
    padding: 15px 22px;
  }

  .case-body {
    padding-top: 48px;
    padding-bottom: 32px;
    gap: 0;
  }

  .use-case-grid {
    margin-top: 28px;
    gap: 28px;
  }

  .capabilities ul {
    margin-top: 20px;
  }

  .capabilities li {
    padding-block: 12px;
    font-size: 17px;
  }

  .capabilities li span {
    margin-top: 3px;
    font-size: 13.5px;
  }

  .proof-asset {
    padding: 10px;
    border-radius: 18px;
  }

  .source-clip {
    height: 62px;
    border-radius: 9px;
  }

  .edit-prompt {
    grid-template-columns: 70px 1fr;
  }

  .result-frame {
    height: 150px;
  }

  .result-features {
    gap: 10px;
  }

  .support-proof,
  .listening-proof,
  .schedule-proof,
  .books-proof {
    padding: 0;
  }

  .support-email,
  .support-thanks,
  .mention,
  .schedule-row,
  .books-note {
    padding: 13px 14px;
  }

  .support-thanks {
    min-height: 82px;
  }

  .mention p,
  .schedule-row p,
  .books-note p {
    padding-right: 58px;
    font-size: 13.5px;
  }

  .mention-signal,
  .schedule-state {
    top: 11px;
    right: 12px;
  }

  .books-line {
    padding: 11px 14px;
  }

  .deck-title {
    font-size: clamp(34px, 11vw, 47px);
    letter-spacing: -0.055em;
  }

  .case-body > .cta-row {
    margin-top: 20px;
  }

  .page {
    padding-top: 60px;
    padding-bottom: 48px;
  }

  .page-lead {
    margin-top: 16px;
    font-size: 16px;
  }

  /* the full-screen chrome-less treatment comes from the stacked block;
     phones only tighten the section's vertical rhythm */
  .hire-stage {
    padding: 0 0 48px;
  }

  .hire-stage .page-header,
  .deck-rail {
    padding-block: 48px;
  }

  .channel-stage {
    min-height: 0;
  }

  /* the opened name overflowed the chip row and wrapped it on phone
     widths — the active chip stays icon-only here (the grey wash still
     marks it, and the name still reads to screen readers) */
  .channel-picker button[aria-pressed="true"] {
    grid-template-columns: auto 0fr;
    padding-right: 4px;
  }

  .channel-picker button[aria-pressed="true"] .pick-name {
    margin-left: 0;
    opacity: 0;
  }

  .script-prompt,
  .script-line {
    padding: 12px 14px;
  }

  .script-line {
    grid-template-columns: 46px 1fr;
    gap: 10px;
  }

  /* three columns of mark-plus-name don't fit a phone — two do */
  .tool-grid {
    grid-template-columns: repeat(2, max-content);
    gap: 3px 6px;
  }

  .tool-grid li {
    gap: 9px;
    padding: 4px 6px 4px 4px;
    font-size: 13px;
  }

  .tool-mark {
    width: 29px;
    height: 29px;
  }

  .tool-mark svg {
    width: 16px;
    height: 16px;
  }

  .tool-request a {
    padding: 9px 11px;
    font-size: 13.5px;
  }

  /* the fact rows on a phone: the same rows, a touch tighter */
  .fact {
    padding: 15px 0 17px;
    column-gap: 13px;
  }

  .fact-text b {
    font-size: 16.5px;
  }

  .fact-text p {
    font-size: 14.5px;
  }

  .fact-text .fact-meta {
    gap: 7px 12px;
  }

  .fact-meta-label {
    font-size: 14px;
  }

  .fact-chip {
    gap: 7px;
    font-size: 14.5px;
  }

  .fact-chip svg {
    width: 15px;
    height: 15px;
  }

  .fact-chip-ink {
    padding: 8px 15px;
  }

  .fact-live {
    font-size: 14px;
  }

  .site-footer {
    height: 100vh;
    height: 100svh;
    min-height: 0;
    max-height: 100vh;
    max-height: 100svh;
    padding-top: 36px;
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }

  .foot-closing {
    margin-bottom: 0;
  }

  /* the mission statement shares the hero h1's phone scale */
  .foot-mission-line {
    font-size: clamp(29px, 9.2vw, 39px);
  }

  /* the corner links would crowd the centered brand on a phone shoulder —
     stack them beneath it instead */
  .foot-bottom {
    margin-top: 16px;
    flex-direction: column;
    gap: 12px;
  }

  .foot-brand {
    gap: 9px;
  }

  .foot-brand .logo-mark {
    height: 24px;
  }

  .foot-brand .brand-word {
    font-size: 14px;
  }

  .foot-links {
    position: static;
    transform: none;
    gap: 16px;
    font-size: 9px;
  }
}

@media (max-width: 620px) and (max-height: 740px) {
  .site-footer {
    padding-top: 24px;
  }

  .foot-bottom {
    margin-top: 10px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-snap-type: none;
  }
}
