/* ==========================================================================
   claude.lupl.com — styles.css
   Black & white minimal editorial. Single accent: Lupl dark teal #007681.
   --------------------------------------------------------------------------
   1.  Tokens (color, type, space, motion)
   2.  Reset + base
   3.  Layout primitives
   4.  Type
   5.  Buttons + links
   6.  Animation utilities
   7.  Nav
   8.  Hero
   9.  Section: gap statement + checks
   10. Section: category claim
   11. Section: capability beats
   12. Section: manifesto
   13. Section: branched CTA
   14. Section: security (inverted)
   15. Footer
   16. Responsive overrides
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* Canvas */
  --bg:            #FFFFFF;
  --bg-soft:       #FAFAF7;          /* warm off-white for section breaks */
  --bg-inverted:   #0A0A0A;          /* black for security + footer */
  --bg-inverted-2: #141414;

  /* Ink */
  --ink:           #0E0E0E;
  --ink-2:         #3A3A3A;
  --ink-3:         #6B6B6B;
  --ink-4:         #A8A8A8;
  --ink-on-dark:   #F4F4F2;
  --ink-on-dark-2: #B8B8B5;
  --ink-on-dark-3: #7A7A77;

  /* Rules */
  --line:          rgba(0,0,0,0.08);
  --line-strong:   rgba(0,0,0,0.16);
  --line-on-dark:  rgba(255,255,255,0.10);
  --line-on-dark-strong: rgba(255,255,255,0.20);

  /* Accent — Lupl dark teal, single accent across the site */
  --teal:          #007681;
  --teal-dark:     #005A63;
  --teal-soft:     rgba(0,118,129,0.10);
  --teal-line:     rgba(0,118,129,0.30);

  /* Type — Plus Jakarta Sans (FS Meridian-adjacent humanist sans) for
     display, Inter for body, JetBrains Mono for code/labels. */
  --font-display:  'Plus Jakarta Sans', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-body:     'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono:     'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Space (8pt scale) */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;
  --s-9: 96px;
  --s-10: 128px;
  --s-11: 160px;

  /* Radius */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 20px;
  --r-pill: 999px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --d-fast: 180ms;
  --d-med:  320ms;
  --d-slow: 720ms;

  /* Layout */
  --max-w: 1240px;
  --pad-x: 32px;
}

@media (max-width: 720px) {
  :root { --pad-x: 20px; }
}


/* --------------------------------------------------------------------------
   2. RESET + BASE
   -------------------------------------------------------------------------- */

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* `clip` instead of `hidden` so position: sticky still works on
     descendant sticky elements (the stack section relies on it). */
  overflow-x: clip;
}

img, svg, video { display: block; max-width: 100%; }
button { font: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }

/* No italics anywhere on this site — em is used purely for accent color. */
em, i, cite, address { font-style: normal; }

::selection { background: var(--teal); color: #fff; }

:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Skip link — visible on focus only, jumps past nav to #main */
.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  padding: 12px 18px;
  background: var(--teal);
  color: #fff;
  font-weight: 600;
  font-size: 14px;
  border-radius: 0 0 8px 0;
  transform: translateY(-110%);
  transition: transform var(--d-fast) var(--ease-out);
  z-index: 200;
}
.skip-link:focus { transform: translateY(0); }


/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */

.container {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--pad-x);
}

.container-narrow {
  max-width: 920px;
  margin: 0 auto;
  padding: 0 var(--pad-x);
}

/* Edge-aligned wide container — pulls the eye to the full screen width.
   Used by editorial sections (gap statement, claim showcase) that need the
   typography to dominate horizontally rather than sit in a 1240px tube. */
.container-edge {
  max-width: none;
  margin: 0 auto;
  padding: 0 clamp(28px, 5vw, 96px);
}

section {
  padding: var(--s-11) 0;
  position: relative;
}

section.tight { padding: var(--s-10) 0; }

@media (max-width: 880px) {
  section { padding: var(--s-9) 0; }
  section.tight { padding: 72px 0; }
}

.rule {
  border: 0;
  height: 1px;
  background: var(--line);
  margin: 0;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.eyebrow .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--teal);
}

.eyebrow.on-dark { color: var(--ink-on-dark-2); }
.eyebrow.on-dark .dot { background: var(--teal); box-shadow: 0 0 0 3px rgba(0,118,129,0.20); }


/* --------------------------------------------------------------------------
   4. TYPE
   -------------------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--ink);
}

.h-display {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(44px, 7vw, 96px);
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--ink);
}

.h-large {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 5.4vw, 72px);
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.h-medium {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: var(--ink);
}

.h-small {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(22px, 2.4vw, 30px);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.lede {
  font-family: var(--font-body);
  font-size: clamp(18px, 1.5vw, 22px);
  line-height: 1.5;
  color: var(--ink-2);
  font-weight: 400;
  max-width: 60ch;
}

.label-mono {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 500;
}

.accent { color: var(--teal); }
em.accent, .h-display em, .h-large em, .h-medium em { font-style: normal; }

/* On-dark variants */
.h-display.on-dark,
.h-large.on-dark,
.h-medium.on-dark,
.h-small.on-dark { color: var(--ink-on-dark); }

.lede.on-dark { color: var(--ink-on-dark-2); }


/* --------------------------------------------------------------------------
   5. BUTTONS + LINKS
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.005em;
  border: 1px solid transparent;
  transition:
    background var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out),
    transform var(--d-fast) var(--ease-out),
    box-shadow var(--d-fast) var(--ease-out),
    border-color var(--d-fast) var(--ease-out);
  white-space: nowrap;
  cursor: pointer;
}

.btn .arrow {
  display: inline-block;
  transition: transform var(--d-fast) var(--ease-out);
}

.btn:hover .arrow { transform: translateX(3px); }

/* Primary — solid teal */
.btn-primary {
  background: var(--teal);
  color: #fff;
  box-shadow: 0 1px 0 rgba(0,0,0,0.04), 0 8px 24px -10px rgba(0,118,129,0.45);
}
.btn-primary:hover {
  background: var(--teal-dark);
  transform: translateY(-1px);
  box-shadow: 0 2px 0 rgba(0,0,0,0.04), 0 14px 32px -12px rgba(0,118,129,0.55);
}

/* On dark hero — white pill with teal text on hover */
.btn-on-dark {
  background: #fff;
  color: var(--ink);
  box-shadow: 0 1px 0 rgba(0,0,0,0.04), 0 14px 40px -10px rgba(0,0,0,0.5);
}
.btn-on-dark:hover {
  background: #fff;
  color: var(--teal);
  transform: translateY(-1px);
}

/* Ghost / secondary */
.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
}
.btn-ghost:hover {
  border-color: var(--ink);
  background: rgba(0,0,0,0.03);
}

.btn-ghost.on-dark {
  color: var(--ink-on-dark);
  border-color: var(--line-on-dark-strong);
}
.btn-ghost.on-dark:hover {
  background: rgba(255,255,255,0.06);
  border-color: rgba(255,255,255,0.4);
}

/* Text link with arrow */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: var(--teal);
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
  transition: color var(--d-fast) var(--ease-out);
}
.link-arrow:hover { color: var(--teal-dark); }
.link-arrow.on-dark { color: #fff; }
.link-arrow.on-dark:hover { color: var(--teal); }
.link-arrow .arrow { transition: transform var(--d-fast) var(--ease-out); display: inline-block; }
.link-arrow:hover .arrow { transform: translateX(3px); }


/* --------------------------------------------------------------------------
   6. ANIMATION UTILITIES
   -------------------------------------------------------------------------- */

/* Block reveal — section fades up on enter */
[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity var(--d-slow) var(--ease-out),
    transform var(--d-slow) var(--ease-out);
  will-change: opacity, transform;
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger — apply data-reveal to children of [data-reveal-stagger] */
[data-reveal-stagger] > [data-reveal] {
  transition-delay: 0ms;
}
[data-reveal-stagger].is-visible > [data-reveal]:nth-child(1) { transition-delay: 0ms; }
[data-reveal-stagger].is-visible > [data-reveal]:nth-child(2) { transition-delay: 80ms; }
[data-reveal-stagger].is-visible > [data-reveal]:nth-child(3) { transition-delay: 160ms; }
[data-reveal-stagger].is-visible > [data-reveal]:nth-child(4) { transition-delay: 240ms; }
[data-reveal-stagger].is-visible > [data-reveal]:nth-child(5) { transition-delay: 320ms; }
[data-reveal-stagger].is-visible > [data-reveal]:nth-child(6) { transition-delay: 400ms; }

/* SCROLL-DRIVEN progressive reveal.
   The JS computes each element's progress from its viewport position on every
   rAF tick and writes inline opacity + transform. The CSS just provides:
     - The hidden initial state (prevents FOUC before JS runs)
     - A reduced-motion fallback that shows everything immediately. */
[data-reveal-step] {
  opacity: 0;
  transform: translateY(20px);
  will-change: opacity, transform;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal-step] {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* Hide [data-word-reveal] text until JS has split it into spans.
   Guarded behind .js so the no-JS fallback still shows the text. */
.js [data-word-reveal] { visibility: hidden; }
.js [data-word-reveal] .word { visibility: visible; }

/* Word-by-word reveal */
.word-reveal { display: inline; }
.word-reveal .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.4em);
  transition:
    opacity 600ms var(--ease-out),
    transform 600ms var(--ease-out);
  will-change: opacity, transform;
}
.word-reveal.is-visible .word {
  opacity: 1;
  transform: translateY(0);
}
.word-reveal .word .space { display: inline-block; width: 0.28em; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  .word-reveal .word {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}


/* --------------------------------------------------------------------------
   7. NAV
   -------------------------------------------------------------------------- */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: 72px;
  display: flex;
  align-items: center;
  transition:
    background var(--d-med) var(--ease-out),
    border-color var(--d-med) var(--ease-out),
    box-shadow var(--d-med) var(--ease-out);
  border-bottom: 1px solid transparent;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  background: rgba(0,0,0,0.15);
}

/* When scrolled off the hero — light frosted bar */
.nav.is-scrolled {
  background: rgba(255,255,255,0.85);
  border-bottom-color: var(--line);
}

/* Nav container is edge-aligned — logo sits hard-left, CTA hard-right.
   Overrides the default .container max-width so the brand mark anchors to
   the actual screen edge rather than the 1240px column. */
.nav .container {
  max-width: none;
  padding: 0 clamp(16px, 2vw, 28px);
}

.nav-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;   /* left links | centred logo | right CTA */
  align-items: center;
  width: 100%;
  position: relative;
}

.nav-logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  justify-self: center;
}

.nav-logo img {
  height: 24px;
  width: auto;
  filter: brightness(0) invert(1);            /* white over video */
  transition: filter var(--d-med) var(--ease-out);
}

.nav.is-scrolled .nav-logo img {
  filter: none;                                /* original color on light bg */
}

.nav-badge {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.78);
  border: 1px solid rgba(255,255,255,0.30);
  padding: 3px 8px;
  border-radius: 999px;
  transition:
    color var(--d-med) var(--ease-out),
    border-color var(--d-med) var(--ease-out);
}

.nav.is-scrolled .nav-badge {
  color: var(--ink-3);
  border-color: var(--line-strong);
}

/* Left nav links — sit in column 1 of the .nav-inner grid */
.nav-links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  gap: 28px;
  justify-self: start;
}

.nav-links a {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: rgba(255,255,255,0.85);
  padding: 8px 4px;
  position: relative;
  transition: color var(--d-fast) var(--ease-out);
}

.nav-links a::after {
  content: "";
  position: absolute;
  left: 4px;
  right: 4px;
  bottom: 4px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--d-med) var(--ease-out);
}

.nav-links a:hover {
  color: #fff;
}

.nav-links a:hover::after {
  transform: scaleX(1);
}

.nav.is-scrolled .nav-links a {
  color: var(--ink-2);
}

.nav.is-scrolled .nav-links a:hover {
  color: var(--ink);
}

@media (max-width: 880px) {
  /* Phones: drop the middle nav links, collapse the nav to two columns
     so the logo sits hard-left and the CTA hard-right. */
  .nav-links { display: none; }
  .nav-inner { grid-template-columns: auto 1fr; }
  .nav-logo  { justify-self: start; }
}

.nav-cta {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 20px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  border: 1px solid rgba(255,255,255,0.30);
  color: #fff;
  background: rgba(255,255,255,0.06);
  justify-self: end;             /* anchor to the right column of nav-inner */
  transition:
    background var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out),
    border-color var(--d-fast) var(--ease-out);
}

.nav-cta:hover {
  background: #fff;
  color: var(--ink);
  border-color: #fff;
}

.nav.is-scrolled .nav-cta {
  background: var(--teal);
  border-color: var(--teal);
  color: #fff;
}

.nav.is-scrolled .nav-cta:hover {
  background: var(--teal-dark);
  border-color: var(--teal-dark);
}


/* --------------------------------------------------------------------------
   8. HERO
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  isolation: isolate;
  padding: 0;
  background: #000;        /* shows during video load */
}

.hero-video,
.hero-fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.hero-fallback {
  background:
    radial-gradient(ellipse 70% 60% at 30% 70%, rgba(0,118,129,0.40) 0%, transparent 60%),
    radial-gradient(ellipse 50% 50% at 75% 30%, rgba(255,255,255,0.06) 0%, transparent 55%),
    linear-gradient(180deg, #0E1419 0%, #050709 100%);
}

/* Light overlay — just nav legibility at the top.
   The bottom legibility cushion lives in .hero-text-pad below. */
.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg,
      rgba(0,0,0,0.45) 0%,
      rgba(0,0,0,0.20) 8%,
      rgba(0,0,0,0.05) 16%,
      rgba(0,0,0,0.00) 30%,
      rgba(0,0,0,0.00) 100%);
  pointer-events: none;
}

/* Bottom text pad — a band of darkness anchored at the bottom of the hero
   that fades upward into the video. Two stacked gradients:
   (1) a Lupl-teal wash that carries the brand colour into the hero;
   (2) a darker base for guaranteed legibility over bright video frames. */
.hero-text-pad {
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: 70vh;
  z-index: 1;
  /* Pure black-to-transparent gradient — no teal tint. Heavier at the
     bottom for headline legibility, fading cleanly toward the middle of
     the hero. */
  background:
    linear-gradient(180deg,
      rgba(0,0,0,0.00) 0%,
      rgba(0,0,0,0.16) 30%,
      rgba(0,0,0,0.45) 60%,
      rgba(0,0,0,0.72) 90%,
      rgba(0,0,0,0.80) 100%);
  pointer-events: none;
}

.hero-content {
  position: relative;
  z-index: 2;
  min-height: 100svh;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: calc(72px + var(--s-5)) var(--pad-x) clamp(56px, 8vh, 96px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;        /* anchor content to bottom */
  align-items: center;              /* horizontal center */
  text-align: center;
}

.hero-center {
  width: 100%;
  max-width: 1180px;          /* wide enough for the H1 to stay on one line */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-5);
}

.hero-eyebrow {
  margin-bottom: var(--s-4);
}

.hero h1 {
  color: #fff;
  margin: 0;
  max-width: 100%;
  font-family: var(--font-display);
  font-weight: 600;                /* bolder — heavier presence over the video */
  font-size: clamp(34px, 5vw, 72px);
  letter-spacing: -0.034em;
  line-height: 1.02;
  text-shadow:
    0 2px 30px rgba(0,0,0,0.65),
    0 1px 4px rgba(0,0,0,0.45);
}

/* Keep the headline on a single line from tablet up. On narrow phones, allow
   it to wrap naturally — anything else overflows the container. */
@media (min-width: 720px) {
  .hero h1 { white-space: nowrap; }
}

.hero h1 em.accent {
  color: var(--teal);
}

.hero .lede {
  color: rgba(255,255,255,0.94);
  margin: 0;
  max-width: 620px;
  text-shadow: 0 1px 16px rgba(0,0,0,0.45);
}

/* Hero sub-headline (H2) — sits beneath the H1 as the supporting statement. */
.hero-sub {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(20px, 1.9vw, 28px);
  line-height: 1.25;
  letter-spacing: -0.018em;
  color: rgba(255,255,255,0.92);
  margin: 0;
  max-width: 36ch;
  text-shadow: 0 1px 16px rgba(0,0,0,0.5);
}

.hero-actions {
  display: flex;
  gap: var(--s-4);
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  margin-top: var(--s-3);
}

/* Scroll hint is hidden — content now sits at the bottom of the hero,
   which already cues the user that there's more below. */
.hero-scroll-hint { display: none; }

.hero-scroll-hint .line {
  width: 1px;
  height: 28px;
  background: linear-gradient(180deg, rgba(255,255,255,0.0), rgba(255,255,255,0.6));
  animation: scrollHint 2.4s ease-in-out infinite;
}

@keyframes scrollHint {
  0%   { transform: scaleY(0.4); transform-origin: top; opacity: 0.4; }
  50%  { transform: scaleY(1);   transform-origin: top; opacity: 1; }
  100% { transform: scaleY(0.4); transform-origin: bottom; opacity: 0.4; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-video,
  .claim-video { display: none; }
  .hero-scroll-hint .line { animation: none; }
}


/* --------------------------------------------------------------------------
   9. SECTION: GAP STATEMENT + CHECKS
   --------------------------------------------------------------------------
   Two parts:
   (a) The gap STATEMENT — a pinned, side-by-side display where line 1 sits
       on the left and line 2 reveals CHARACTER-BY-CHARACTER on the right as
       the user scrolls. The reveal is tied to scroll progress through the
       outer .gap-scroller wrapper; the .gap-sticky inner pins to the
       viewport while progress advances 0 → 1. JS toggles `.is-on` on each
       <span class="char"> based on that progress.
   (b) The CHECKS — bullets under "What Claude is great at" / "Where Claude
       is blind". Each [data-reveal-step] bullet is tied to scroll position;
       as it crosses the viewport its opacity ramps 0 → 1.
   -------------------------------------------------------------------------- */

.section-gap {
  background: var(--bg);
  overflow-x: clip;          /* huge typography mustn't force horizontal scroll */
  padding: var(--s-7) 0 var(--s-7);   /* tighter top + bottom — was default 160px each */
}

/* ---- (a) pinned gap statement ---- */
.gap-scroller {
  position: relative;
  height: 220vh;             /* drives reveal duration — 120vh of scroll while pinned */
}

.gap-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
}

.gap-sticky-inner {
  width: 100%;
  /* Override the standard container-edge side padding so the now-larger
     typography has more horizontal room before clipping at the gutter. */
  padding: 0 clamp(20px, 3vw, 56px);
}

.gap-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, 3vw, 56px);          /* tighter gutter — was up to 120px */
  align-items: start;
  width: 100%;
}

.gap-line {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(46px, 6vw, 104px);   /* ~30% larger than previous */
  line-height: 1.02;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin: 0;
  max-width: 100%;
}

.gap-line-1 { justify-self: start; }

.gap-line-2 {
  color: var(--ink-3);
  justify-self: end;
  text-align: left;
}

/* Character-by-character reveal — chars start hidden and snap to full
   opacity as scroll progress advances. `display: inline` (not inline-block)
   keeps word integrity at line-break time: the browser only breaks at the
   spaces between words, not between individual character spans. */
.js [data-char-reveal] { visibility: visible; }
.js [data-char-reveal] .char {
  display: inline;
  opacity: 0;
  transition: opacity 90ms linear;
}
.js [data-char-reveal] .char.is-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  [data-char-reveal] .char { opacity: 1 !important; transition: none !important; }
}

/* ---- (b) checks — pinned, scroll-driven char reveal ----
   Both columns sit side-by-side from the moment the section pins. A single
   character queue (split across both columns in DOM order) reveals as the
   user scrolls through .checks-scroller. The right column's first char
   doesn't appear until the left column's last char has rendered, so the
   "follow-up" rhythm comes from the actual content, not from layout tricks.
*/

.checks-scroller {
  position: relative;
  height: 240vh;            /* drives reveal duration — left then right */
  background: #EDF4F4;      /* discreet light teal — distinguishes the section without shouting */
}

.checks-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
}

.checks-sticky > .container-edge { width: 100%; }

.checks {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 clamp(48px, 8vw, 160px);
  padding: var(--s-7) 0 0;
}

/* Centred section heading — sits above both columns. Spans the full grid
   width and reveals as part of the [data-char-reveal-block] queue. */
.checks-heading {
  grid-column: 1 / -1;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(40px, 5.6vw, 80px);
  line-height: 1.02;
  letter-spacing: -0.030em;
  color: var(--ink);
  margin: 0 auto var(--s-8);
  max-width: 22ch;
}

.checks-col-label {
  font-family: var(--font-display);
  font-size: clamp(20px, 1.8vw, 26px);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 var(--s-6);
}

.check-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.check-list li {
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: var(--s-5);
  align-items: baseline;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(20px, 2.1vw, 30px);
  line-height: 1.18;
  letter-spacing: -0.02em;
  color: var(--ink);
  /* No fixed max-width — column governs width so every bullet ("What needs
     to happen next." in particular) can sit on a single line. */
}

.check-list .icon {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  transform: translateY(3px);
  opacity: 0;                /* icons fade in alongside their text */
  transition: opacity 280ms var(--ease-out);
}

.check-list .icon svg { width: 32px; height: 32px; display: block; }

.check-list.is-positive .icon { color: var(--teal); }
.check-list.is-gap      .icon { color: var(--ink-4); }

.check-list.is-gap li { color: var(--ink-3); }

/* When a li has at least one revealed character, light up its icon. The
   :has() selector keeps the wiring in CSS without per-li JS bookkeeping. */
.check-list li:has(.char.is-on) .icon { opacity: 1; }

.checks-col-gap .check-list li { justify-self: end; }

/* Char reveal for the checks block — same engine as the gap/manifesto. */
.js [data-char-reveal-block] .char {
  display: inline;
  opacity: 0;
  transition: opacity 90ms linear;
}
.js [data-char-reveal-block] .char.is-on { opacity: 1; }

/* Column label inherits the char-reveal too, but uses its mono font/size. */
.js [data-char-reveal-block] .checks-col-label .char,
.js [data-char-reveal-block] .check-list .char { display: inline; }

@media (prefers-reduced-motion: reduce) {
  [data-char-reveal-block] .char { opacity: 1 !important; transition: none !important; }
  .check-list .icon { opacity: 1 !important; }
}

@media (max-width: 880px) {
  .gap-scroller { height: 200vh; }
  .gap-split { grid-template-columns: 1fr; gap: 8vh; }
  .gap-line { font-size: clamp(32px, 7vw, 56px); }
  .gap-line-2 { justify-self: start; }
  .checks-scroller { height: 280vh; }
  .checks { grid-template-columns: 1fr; gap: 8vh; padding: var(--s-6) 0 0; }
  .check-list { gap: var(--s-5); }
  .check-list li { font-size: clamp(20px, 5vw, 28px); }
  .checks-col-gap .check-list li { justify-self: start; }
}


/* --------------------------------------------------------------------------
   9c. CLAUDE UI MOCKUP — pinned interactive demo (own section, white bg)
   --------------------------------------------------------------------------
   Pixel-perfect Claude chat interface. The prompt is non-editable; the
   coral send button pulses and is clickable. As the user scrolls through
   the pinned scroller, the chat card scales from small to large (JS sets
   inline transform: scale on .claude-mockup). On click, the response
   streams in word-by-word.
   -------------------------------------------------------------------------- */

.section-claude-ui {
  background: var(--bg);        /* white — sits between the teal band above and the video below */
  padding: 0;
}

/* No pin, no scale. Cards just sit in normal flow at their natural size. */
.ui-mockup-scroller {
  position: relative;
  background: var(--bg);
}

.ui-mockup-sticky {
  /* Reserve a full viewport for the section. Cards stay vertically
     centred via justify-content: center, so when the response expands
     the content stays centred WITHIN the fixed height instead of
     pushing the section taller — the video below never moves. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(40px, 7vh, 96px);   /* air between heading + cards */
  padding:
    clamp(72px, 10vh, 144px) var(--pad-x)
    clamp(140px, 22vh, 280px);
}

/* Heading + subheading above the chat card. Stays constant size while
   the chat card scales beneath it. Both lines are sized + width-freed so
   they sit on a single line on desktop. */
.claude-section-head {
  text-align: center;
  max-width: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-5);              /* more air between heading + subhead */
}

.claude-section-heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(44px, 6vw, 92px);
  line-height: 1.02;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin: 0;
  /* No max-width: let it sit on one line on desktop. Wraps naturally on
     phones where the viewport is too narrow. */
}

.claude-section-sub {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.1vw, 17px);
  line-height: 1.45;
  color: var(--ink-3);
  margin: 0;
  /* Generous max-width so the full sentence sits on one line on desktop. */
  max-width: 96ch;
}

@media (min-width: 1100px) {
  .claude-section-heading,
  .claude-section-sub { white-space: nowrap; }
}

.claude-mockup {
  width: 100%;
  /* Use a system / Inter stack so it reads as Claude's own UI, not the
     Lupl marketing display font. */
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* The comparison wrapper holds both chat cards. A 1px hairline divides
   the two cards — vertical on desktop, horizontal when they stack on
   mobile. Cards display at their natural size — no scroll-driven scale. */
.claude-comparison {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 3.6vw, 64px);
  width: 100%;
  max-width: 1180px;
}

.claude-comparison::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: var(--line);
  pointer-events: none;
}

.cmp-side {
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

/* Plain labels — no pill background, no caps. Just text + the Lupl
   wordmark inline on the With side. */
.cmp-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: clamp(16px, 1.4vw, 20px);
  font-weight: 500;
  letter-spacing: -0.012em;
  margin-bottom: var(--s-4);
  align-self: flex-start;
}

.cmp-label-without { color: var(--ink-3); }

.cmp-label-with    { color: var(--teal); }

/* Differentiate the two sides at a glance. Without Lupl reads as the
   "empty" state — keeps the standard white card but muted response
   text. With Lupl reads as the "powered" state — thicker teal border,
   soft teal tint and a lift. */
.cmp-without .cm-input {
  border-color: rgba(0, 0, 0, 0.08);
}

.cmp-without .cm-response-text {
  color: #6B6B6B;
}

.claude-mockup.with-lupl .cm-input {
  border: 1.5px solid rgba(0, 118, 129, 0.42);
  background:
    linear-gradient(180deg, rgba(0, 118, 129, 0.03), #fff 60%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 1) inset,
    0 10px 32px -10px rgba(0, 118, 129, 0.28);
}

/* Lupl tool pill — sits before the model selector on the With Lupl card,
   signalling that Claude is wired up to the matter operating system. */
.cm-tool-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--teal);
  background: rgba(0, 118, 129, 0.10);
  border: 1px solid rgba(0, 118, 129, 0.30);
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
  user-select: none;
}

.cm-tool-pill-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 0 2px rgba(0, 118, 129, 0.20);
  animation: cm-tool-pulse 2s ease-in-out infinite;
}

@keyframes cm-tool-pulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(0, 118, 129, 0.20); }
  50%      { box-shadow: 0 0 0 5px rgba(0, 118, 129, 0.08); }
}

/* Traffic-light bullets — the structured, visual response on the With
   Lupl side. Each bullet fades in sequentially after the intro text
   finishes streaming (JS adds .is-visible with a stagger). */
.cm-traffic {
  list-style: none;
  padding: 0;
  margin: 14px 0 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.cm-traffic-item {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 12px;
  align-items: baseline;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 320ms var(--ease-out),
    transform 320ms var(--ease-out);
}

.cm-traffic-item.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.cm-traffic-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  transform: translateY(3px);
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.04);
}

.is-green  .cm-traffic-dot { background: #16A34A; box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.18); }
.is-amber  .cm-traffic-dot { background: #F59E0B; box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.20); }
.is-red    .cm-traffic-dot { background: #DC2626; box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.18); }

.cm-traffic-text {
  font-size: 15px;
  line-height: 1.5;
  color: #1F1F1F;
}

.cm-traffic-text strong {
  font-weight: 600;
  color: #1F1F1F;
}

@media (max-width: 880px) {
  .claude-comparison {
    grid-template-columns: 1fr;
    max-width: 560px;
    gap: clamp(28px, 6vw, 48px);
  }
  /* Hide the divider on phones — when cards stack and one expands with
     its response, the 50% midpoint falls inside a card. The natural gap
     between stacked cards is enough separation. */
  .claude-comparison::before { display: none; }
  /* Bigger heading wraps cleanly on phones; tighten its line-height so the
     wrap doesn't blow out the vertical space. */
  .claude-section-heading {
    font-size: clamp(34px, 9vw, 56px);
    line-height: 1.04;
  }
  .claude-section-sub {
    font-size: clamp(14px, 3.4vw, 17px);
    max-width: 38ch;
  }
  /* On phones we don't fix the section to 100vh — the stacked cards
     are usually taller than the viewport anyway. Section sizes to its
     content with a chunky bottom gap before the video. */
  .ui-mockup-sticky {
    min-height: auto;
    padding: var(--s-8) var(--pad-x) var(--s-10);
    gap: var(--s-6);
  }
}

/* ---- Chat input card ---- */
.cm-input {
  background: #fff;
  border: 1px solid rgba(0,0,0,0.10);
  border-radius: 24px;
  padding: 22px 24px 18px;
  box-shadow:
    0 1px 0 rgba(255,255,255,1) inset,
    0 4px 16px -6px rgba(0,0,0,0.08);
}

.cm-prompt {
  font-size: 16px;
  line-height: 1.45;
  color: #1F1F1F;
  font-weight: 400;
  margin: 0 0 28px;
}

.cm-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.cm-plus {
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  color: #5A5A5A;
  border-radius: 8px;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: default;
}

.cm-right {
  display: flex;
  align-items: center;
  gap: 14px;
}

.cm-model {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 14px;
  font-weight: 500;
  color: #5A5A5A;
  white-space: nowrap;
  user-select: none;
}

/* Send button is static now — responses auto-stream when the section
   enters the viewport, so the button no longer needs to attract a
   click. Kept purely as a faithful Claude UI element. */
.cm-send {
  width: 36px;
  height: 36px;
  border: 0;
  background: #D97757;
  color: #fff;
  border-radius: 10px;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: default;
}

.cm-send:disabled,
.cm-send.is-clicked { background: #C16544; }

/* ---- Response ---- */
.cm-response {
  margin-top: 28px;
  padding: 0 6px;
}

.cm-response-text {
  font-size: 16px;
  line-height: 1.6;
  color: #1F1F1F;
  margin: 0 0 14px;
  min-height: 1.6em;
}

/* Streaming cursor — blinks while still being typed. */
.cm-response.is-streaming .cm-response-text::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 0.95em;
  background: currentColor;
  vertical-align: text-bottom;
  margin-left: 3px;
  animation: cm-cursor 1s steps(2, end) infinite;
}

@keyframes cm-cursor {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

.cm-response-actions {
  display: flex;
  gap: 10px;
}

.cm-response-actions button {
  width: 30px;
  height: 30px;
  border: 0;
  background: transparent;
  color: #5A5A5A;
  border-radius: 6px;
  display: grid;
  place-items: center;
  padding: 0;
  cursor: default;
}

@media (max-width: 720px) {
  .cm-prompt { font-size: 15px; }
  .cm-input { padding: 18px 18px 14px; border-radius: 20px; }
  .cm-response { padding: 0 4px; }
  .cm-response-text { font-size: 15px; }
}


/* --------------------------------------------------------------------------
   10. SECTION: CATEGORY CLAIM  —  full-bleed video + overlay headline
   --------------------------------------------------------------------------
   The use-cases video fills the entire section like the hero. A two-stop
   linear-gradient overlay anchors text legibility at the top and bottom
   while keeping the middle of the video clean. The teal Lupl mark, the
   claim headline, and a single caption line sit in the bottom-left corner.
   -------------------------------------------------------------------------- */

.section-claim {
  position: relative;
  min-height: 100vh;
  padding: 0;
  background: #050709;
  overflow: hidden;
  isolation: isolate;
}

.claim-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* Legibility overlay — mirror of the hero pad. Headline sits at the BOTTOM
   of the section, so the dark band is anchored at the bottom; the top
   stays clean so the video reads through. */
.claim-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg,
      rgba(0,0,0,0.00) 0%,
      rgba(0,0,0,0.00) 40%,
      rgba(0,0,0,0.28) 58%,
      rgba(0,0,0,0.62) 78%,
      rgba(0,0,0,0.82) 100%);
  pointer-events: none;
}

.claim-content {
  position: relative;
  z-index: 2;
  min-height: 100vh;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: calc(72px + var(--s-5)) clamp(28px, 5vw, 80px) clamp(56px, 8vh, 96px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;       /* title anchored to BOTTOM */
  align-items: center;             /* centre horizontally */
  text-align: center;
  color: #fff;
}

.claim-statement {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(44px, 6vw, 96px);
  line-height: 1.0;
  letter-spacing: -0.032em;
  color: #fff;
  margin: 0;
  max-width: none;
  text-align: center;
  text-shadow:
    0 2px 36px rgba(0,0,0,0.85),
    0 1px 8px rgba(0,0,0,0.6);
}

/* Keep the claim on a single line from tablet up. On phones we let it wrap
   naturally — the bolder weight + tighter clamp keeps it compact. */
@media (min-width: 720px) {
  .claim-statement { white-space: nowrap; }
}

@media (max-width: 720px) {
  .claim-statement { font-size: clamp(36px, 9vw, 64px); }
}

/* Hide the use-cases video section entirely on mobile — it has no text
   content of its own, and a heavy MP4 background isn't worth the
   bandwidth on phones. */
@media (max-width: 880px) {
  .section-claim { display: none; }
}


/* --------------------------------------------------------------------------
   10b. SECTION: STACK — pinned, scroll-driven build
   --------------------------------------------------------------------------
   A tall .stack-scroller wrapper contains a .stack-sticky inner that pins to
   the viewport for the duration of the scroll-through. The H2 sits at the
   top of the pinned area so the title is visible THROUGHOUT the sequence;
   the stack viz sits in a teal-outlined frame underneath.
   Reveal is top-down (Security → Claude). The JS sorts [data-stack-step]
   ascending and reveals them in order based on scroll progress.
   -------------------------------------------------------------------------- */

.section-stack { background: var(--bg); padding: 0; }

/* Tall scroller — height drives how long the build "takes" while pinned.
   6 steps now → slightly longer scroll. */
.stack-scroller {
  position: relative;
  height: 280vh;
}

.stack-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 96px var(--pad-x) 56px;
  gap: clamp(20px, 3vh, 40px);
}

/* Title pinned at the top of the sticky region — stays visible for the
   entire scroll-through, so the user always sees what they're building. */
.stack-title-pin {
  text-align: center;
  max-width: 800px;
}

.stack-title-pin h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3.8vw, 48px);
  line-height: 1.06;
  letter-spacing: -0.026em;
  color: var(--ink);
  margin: 0 auto;
  max-width: 22ch;
}

.stack-title-pin h2 .accent { color: var(--teal); }

/* Frame around the whole stack — content host. The teal outline itself
   lives on .stack-frame-border so it can animate in independently as the
   final step in the scroll sequence (the bracket clicks shut once the
   blocks have all assembled underneath it). */
.stack-frame {
  position: relative;
  width: 100%;
  max-width: 1024px;          /* ~25% wider than before (was 820px) */
  padding: clamp(16px, 2vw, 32px);
  background: transparent;
}

.stack-frame-border {
  position: absolute;
  inset: 0;
  border: 2px solid var(--teal);
  border-radius: 24px;
  background:
    linear-gradient(180deg, rgba(0,118,129,0.04), rgba(0,118,129,0.02));
  box-shadow:
    0 1px 0 rgba(0,118,129,0.20),
    0 28px 60px -36px rgba(0,118,129,0.30);
  pointer-events: none;
  opacity: 0;
  transform: translateY(0);
  will-change: opacity, transform;
}

.stack-viz {
  width: 100%;
  display: flex;
  flex-direction: column;     /* normal order: DOM top→bottom matches visual */
  gap: 12px;
}

.stack-row {
  display: grid;
  grid-template-columns: 1fr 1.2fr 1fr;
  gap: 12px;
}

/* Each block is intentionally simple and abstract — just a labelled slab. */
.stack-block {
  position: relative;
  border-radius: 14px;
  background: #fff;
  border: 1px solid var(--line);
  height: clamp(60px, 9.5vh, 88px);
  display: grid;
  place-items: center;
  text-align: center;
  /* Scroll-driven inline styles set opacity + transform per step. Start hidden. */
  opacity: 0;
  transform: translateY(28px);
  will-change: opacity, transform;
}

.stack-label-text {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(15px, 1.7vw, 22px);
  letter-spacing: -0.015em;
  color: var(--ink);
  padding: 0 var(--s-4);
}

/* Each block is its own stacking context because the JS reveal applies a
   translate. To stop tooltips getting hidden underneath adjacent blocks
   we lift the hovered block's stacking context. */
.stack-block { z-index: 1; }
.stack-block:hover,
.stack-block:focus-within { z-index: 20; }

/* Tooltip — appears above the block on hover/focus. Dark pill with a small
   downward caret. The block is position: relative so the absolute tooltip
   anchors to it. */
.stack-tooltip {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translate(-50%, 6px);
  padding: 8px 14px;
  background: var(--ink);
  color: #fff;
  border-radius: 8px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 180ms var(--ease-out),
    transform 180ms var(--ease-out);
  z-index: 50;
  box-shadow: 0 10px 24px -10px rgba(0,0,0,0.35);
}

.stack-tooltip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--ink);
}

.stack-block:hover .stack-tooltip,
.stack-block:focus-within .stack-tooltip {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* Top-most block (Security) — the tooltip would shoot up out of the frame.
   Flip it BELOW the block instead so it sits inside the visible area. */
.stack-security .stack-tooltip {
  bottom: auto;
  top: calc(100% + 10px);
  transform: translate(-50%, -6px);
}

.stack-security .stack-tooltip::after {
  top: auto;
  bottom: 100%;
  border-top-color: transparent;
  border-bottom-color: var(--ink);
}

.stack-block:hover.stack-security .stack-tooltip,
.stack-block:focus-within.stack-security .stack-tooltip {
  transform: translate(-50%, 0);
}

/* TOP: Security & Compliance — black slab, the enclosing layer. */
.stack-security {
  background: #0A0A0A;
  border-color: #0A0A0A;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.08),
    0 18px 40px -22px rgba(0,0,0,0.45);
}
.stack-security .stack-label-text { color: #fff; }

/* BASE: Claude — Claude's brand coral. The foundation layer. */
.stack-claude {
  background: #D97757;
  border-color: #C16544;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.18),
    0 18px 40px -22px rgba(217,119,87,0.45);
}
.stack-claude .stack-label-text { color: #fff; }

/* SKILLS — neutral, restrained. */
.stack-skills {
  background: var(--bg-soft);
}

/* Matter Management — starts as a dotted teal placeholder (the missing
   slot Lupl will fill). At step 7 the .stack-mm-fill child fades in over
   it, replacing the placeholder text with the Lupl logo and turning the
   border solid. */
.stack-mm {
  background: rgba(0,118,129,0.04);
  border: 2px dashed var(--teal);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    0 12px 28px -20px rgba(0,118,129,0.30);
  overflow: hidden;
}

.stack-mm .stack-mm-placeholder {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(15px, 1.7vw, 22px);
  letter-spacing: -0.015em;
  color: var(--teal);
  padding: 0 var(--s-4);
  text-align: center;
  position: relative;
  z-index: 1;
}

/* The "fill" sits absolutely on top of the placeholder. JS reveals it at
   step 7 — fading from transparent to opaque, transitioning to a solid
   teal background with the Lupl logo. */
.stack-mm-fill {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--teal);
  border-radius: 12px;
  overflow: hidden;
  z-index: 2;
  pointer-events: none;
}

.stack-mm-fill img {
  display: block;
  width: auto;
  height: auto;
  max-height: 48%;          /* hard cap so the wordmark never overflows the block */
  max-width: 64%;
  object-fit: contain;
  /* Logo is teal on white originally; invert to white for contrast on
     the teal background of the fill. */
  filter: brightness(0) invert(1);
}

@media (max-width: 720px) {
  .stack-scroller { height: 320vh; }
  .stack-row { grid-template-columns: 1fr; }
  .stack-block { height: 56px; }
  .stack-viz { gap: 10px; }
  .stack-frame { padding: 14px; }
}


/* --------------------------------------------------------------------------
   11. SECTION: CAPABILITY BEATS  —  centered coverflow carousel
   --------------------------------------------------------------------------
   Header centred above the controls. The .beats-viewport masks the wide
   .beats-track which is translated horizontally to centre the active tile.
   Tiles are tall and portrait; the active one is taller and fully bright
   while neighbours are slightly shorter and dimmed. JS sets the
   translateX on the track every time the index changes.
   -------------------------------------------------------------------------- */

.section-beats { background: var(--bg-soft); padding: var(--s-7) 0 var(--s-8); }

.beats-head {
  text-align: center;
  margin: 0 auto var(--s-5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
}

/* Match the building-blocks / "Missing Context Layer" heading style for
   cross-section consistency. */
.beats-head h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3.8vw, 48px);
  line-height: 1.06;
  letter-spacing: -0.026em;
  margin: 0;
  max-width: 22ch;
  color: var(--ink);
}

/* Discreet supporting line under the section heading. */
.beats-sub {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.15vw, 18px);
  line-height: 1.5;
  color: var(--ink-3);
  margin: 0;
  max-width: 56ch;
}

.beats-carousel {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-5);
}

/* Arrows sit ABSOLUTELY positioned on the left/right edges of the viewport,
   vertically centred on the active tile. */
.beats-arrow {
  position: absolute;
  top: 50%;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(255,255,255,0.92);
  color: var(--ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  z-index: 3;
  transform: translateY(-50%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition:
    background var(--d-fast) var(--ease-out),
    border-color var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out),
    box-shadow var(--d-fast) var(--ease-out);
}

.beats-prev { left: clamp(12px, 2vw, 36px); }
.beats-next { right: clamp(12px, 2vw, 36px); }

.beats-arrow:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
  box-shadow: 0 8px 20px -8px rgba(0,0,0,0.3);
}

.beats-arrow:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Caption sentence below the active image. Updates per slide via JS. */
.beats-caption {
  margin: var(--s-5) auto 0;
  max-width: 56ch;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(18px, 1.6vw, 24px);
  line-height: 1.35;
  letter-spacing: -0.012em;
  color: var(--ink);
  transition: opacity var(--d-med) var(--ease-out);
}

/* Dots — much more discreet. Small circles below the caption, no pill
   background, low contrast. The active dot grows slightly. */
.beats-dots {
  list-style: none;
  padding: 0;
  margin: var(--s-4) auto 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.beats-dots li { display: inline-flex; }

.beats-dots button {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 0;
  background: rgba(0,0,0,0.18);
  cursor: pointer;
  padding: 0;
  transition:
    background var(--d-fast) var(--ease-out),
    width var(--d-med) var(--ease-out),
    transform var(--d-fast) var(--ease-out);
}

.beats-dots button.is-active {
  background: var(--ink);
  transform: scale(1.35);
}

.beats-dots button:hover { background: rgba(0,0,0,0.45); }
.beats-dots button.is-active:hover { background: var(--ink); }

/* Viewport masks the horizontal overflow; the track is wider than the page
   and gets translated horizontally so the active tile is centred. */
.beats-viewport {
  position: relative;
  overflow: hidden;
  padding: var(--s-4) 0;
}

.beats-track {
  display: flex;
  gap: clamp(16px, 1.6vw, 28px);
  align-items: center;            /* short side tiles centre against the tall one */
  padding: 0 50%;                 /* huge padding so we can centre via translateX */
  transform: translate3d(0,0,0);
  transition: transform 720ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

.beat {
  flex: 0 0 auto;                  /* width follows the tile (height-bound) */
  transition: transform 720ms cubic-bezier(0.16, 1, 0.3, 1);
}

.beat-tile {
  position: relative;
  display: block;
  /* Height-constrained so the active tile always fits between the
     section heading and the caption + dots, even on shorter laptops. */
  height: clamp(260px, 56vh, 680px);
  aspect-ratio: 4 / 3;
  width: auto;
  max-width: 80vw;
  padding: 0;
  border: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #FAFAF7;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.04) inset,
    0 18px 36px -22px rgba(0,0,0,0.30);
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition:
    transform 720ms cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 600ms var(--ease-out),
    filter 600ms var(--ease-out);
  filter: brightness(0.78) saturate(0.85);   /* deeper dim — sides are intentionally background */
  transform-origin: center;
  transform: scale(0.5);                     /* much smaller side peeks so the active tile dominates */
}

/* The active tile is the focused content — disable the "go to me" cursor. */
.beat.is-active .beat-tile { cursor: default; }

.beat-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  display: block;
}

/* Strong gradient + frosted blur at the top of every tile so the overlay
   label reads cleanly even when the screenshot has a white background or
   competing text near the top. */
.beat-tile::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 32%;
  background: linear-gradient(180deg,
    rgba(0,0,0,0.78) 0%,
    rgba(0,0,0,0.62) 35%,
    rgba(0,0,0,0.36) 65%,
    rgba(0,0,0,0.00) 100%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  /* Mask the blur so it fades out alongside the gradient — keeps the
     bottom of the image fully sharp. */
  mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
  pointer-events: none;
  z-index: 1;
}

/* Card label — sits at the top of each image, centred, white. */
.beat-tile-label {
  position: absolute;
  top: clamp(16px, 2.2vw, 28px);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(16px, 1.7vw, 24px);
  letter-spacing: -0.012em;
  color: #fff;
  text-shadow: 0 1px 12px rgba(0,0,0,0.55);
  white-space: nowrap;
  z-index: 2;
  transition: font-size var(--d-med) var(--ease-out);
}

/* Active tile — full size, bright, with a stronger shadow and slightly
   larger label so it reads as the focal card. */
.beat.is-active .beat-tile {
  transform: scale(1);
  filter: brightness(1) saturate(1);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.04) inset,
    0 40px 100px -40px rgba(0,0,0,0.50);
}

.beat.is-active .beat-tile-label {
  font-size: clamp(20px, 2.2vw, 32px);
}

@media (max-width: 880px) {
  /* On phones, size the tile by width (height follows 4:3 aspect) rather
     than by viewport height — vh-bound tiles end up too small on portrait
     phones where 56vh is taller than the viewport's narrow dimension. */
  .beat-tile {
    height: auto;
    width: 86vw;
    max-width: 86vw;
    transform: scale(0.92);
  }
}


/* --------------------------------------------------------------------------
   11b. SECTION: AUDIENCE — Who it's for
   -------------------------------------------------------------------------- */

.section-audience { background: var(--bg); }

.audience-header {
  max-width: 760px;
  margin: 0 auto var(--s-9);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-4);
}

.audience-header h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(32px, 4.6vw, 56px);
  line-height: 1.05;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin: 0;
  max-width: 22ch;
}

.audience-header h2 .accent { color: var(--teal); }

.audience-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-5);
  align-items: stretch;
}

.audience {
  position: relative;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(28px, 3.6vw, 48px);
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  transition:
    border-color var(--d-med) var(--ease-out),
    box-shadow var(--d-med) var(--ease-out),
    transform var(--d-med) var(--ease-out);
}

.audience:hover {
  border-color: var(--line-strong);
  box-shadow: 0 12px 36px -18px rgba(0,0,0,0.12);
}

.audience-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--teal);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}

.audience-tag::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--teal);
}

.audience-head h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(24px, 2.8vw, 34px);
  line-height: 1.1;
  letter-spacing: -0.024em;
  color: var(--ink);
  margin: 0;
  max-width: 22ch;
}

.audience-body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0;
  max-width: 44ch;
}

.audience-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
}

.audience-list li {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 12px;
  align-items: baseline;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}

.audience-list li::before {
  content: "";
  width: 6px; height: 6px;
  background: var(--teal);
  border-radius: 50%;
  margin-top: 8px;
  align-self: start;
}

/* Law firms sub-grid: four roles */
.role-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border-top: 1px solid var(--line);
}

.role {
  padding: var(--s-5) 0;
  border-bottom: 1px solid var(--line);
}

.role:nth-child(odd) {
  padding-right: var(--s-5);
  border-right: 1px solid var(--line);
}
.role:nth-child(even) {
  padding-left: var(--s-5);
}

.role:nth-last-child(-n+2) { border-bottom: 0; }

.role h4 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 18px;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 6px;
}

.role p {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0;
  max-width: 28ch;
}

@media (max-width: 880px) {
  .audience-grid { grid-template-columns: 1fr; }
}

@media (max-width: 600px) {
  .role-grid { grid-template-columns: 1fr; }
  .role,
  .role:nth-child(odd),
  .role:nth-child(even) {
    padding: var(--s-4) 0;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .role:last-child { border-bottom: 0; }
}


/* --------------------------------------------------------------------------
   12. SECTION: MANIFESTO  —  pinned char-by-char reveal
   --------------------------------------------------------------------------
   Lines are tightly stacked (no inflated vertical gaps). The block is
   pinned and scroll progress drives a per-character reveal across the
   entire manifesto — characters get `.is-on` added in order as the user
   scrolls past the .manifesto-scroller wrapper.
   -------------------------------------------------------------------------- */

.section-manifesto {
  background: var(--bg-soft);
  padding: 0;
}

.manifesto-scroller {
  position: relative;
  height: 220vh;
}

.manifesto-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
}

.manifesto-sticky > .container { width: 100%; }

.manifesto-stack {
  max-width: 1000px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);             /* tight spacing — was 28vh+ */
}

.manifesto-line {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 5.4vw, 80px);
  line-height: 1.04;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin: 0;
  max-width: 24ch;
}

.manifesto-line .accent { color: var(--teal); }

.manifesto-line.m-3 { align-self: flex-end; text-align: right; }
.manifesto-line.m-5 { align-self: flex-end; text-align: right; }

.manifesto-sub {
  font-size: clamp(26px, 3.6vw, 48px);
  color: var(--ink-3);
  max-width: 28ch;
}

/* Char-reveal — chars are split by JS, opacity 0 → 1 as scroll progresses. */
.js [data-char-reveal-manifesto] .char {
  display: inline;
  opacity: 0;
  transition: opacity 90ms linear;
}
.js [data-char-reveal-manifesto] .char.is-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  [data-char-reveal-manifesto] .char { opacity: 1 !important; transition: none !important; }
}

@media (max-width: 720px) {
  .manifesto-scroller { height: 180vh; }
  .manifesto-line.m-3 { align-self: flex-start; text-align: left; }
  .manifesto-line.m-5 { align-self: flex-start; text-align: left; }
  .manifesto-stack { gap: var(--s-2); }
}


/* --------------------------------------------------------------------------
   13. SECTION: BRANCHED CTA
   --------------------------------------------------------------------------
   Two parts:
     (a) .section-branch-gate — the question + two large choice cards. Each
         card is an anchor link to a detail panel below.
     (b) .section-path — each detail panel sits in its own anchored section
         so the user lands on it directly. Cards reuse the existing .branch
         card styles for visual continuity.
   -------------------------------------------------------------------------- */

.section-branch-gate { background: var(--bg); }
.section-path { background: var(--bg); scroll-margin-top: 88px; }
.section-path + .section-path { padding-top: 0; }

.branch-question {
  text-align: center;
  margin: 0 auto var(--s-8);
  max-width: 24ch;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 5.2vw, 68px);
  line-height: 1.06;
  letter-spacing: -0.028em;
  color: var(--ink);
}

.branch-gate {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-6);
  max-width: 1280px;        /* ~25% wider to accommodate the larger cards */
  margin: 0 auto;
}

/* Full-width stacked accordion replacing the two side-by-side cards.
   Each <details> handles its own open/close natively. */
.branch-accordion {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  max-width: 1100px;
  margin: 0 auto;
}

.branch-accordion-item {
  position: relative;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--bg);
  overflow: hidden;
  transition: border-color var(--d-med) var(--ease-out);
}

/* 4px stripe across the top of each item — teal for the YES path, ink for
   the NO path. Same visual cue as the previous cards, applied at full
   width. */
.branch-accordion-item::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; height: 4px;
}
.branch-accordion-yes::before { background: linear-gradient(90deg, var(--teal) 0%, var(--teal-dark) 100%); }
.branch-accordion-no::before  { background: linear-gradient(90deg, var(--ink) 0%, var(--ink-3) 100%); }

.branch-accordion-item > summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--s-3) var(--s-5);
  padding: clamp(28px, 3.4vw, 44px) clamp(28px, 3.4vw, 56px);
}

.branch-accordion-item > summary::-webkit-details-marker { display: none; }
.branch-accordion-item > summary::marker { content: ""; }

.ba-headline {
  grid-column: 1;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(28px, 3.4vw, 48px);
  line-height: 1.06;
  letter-spacing: -0.024em;
  color: var(--ink);
}

.ba-meta {
  grid-column: 2;
  font-family: var(--font-body);
  font-size: clamp(15px, 1.2vw, 18px);
  color: var(--ink-3);
  white-space: nowrap;
  justify-self: end;
}

.ba-icon {
  grid-column: 3;
  position: relative;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
}

.ba-icon::before,
.ba-icon::after {
  content: "";
  position: absolute;
  background: var(--ink);
  border-radius: 1px;
  transition: transform var(--d-med) var(--ease-out);
}

.ba-icon::before {
  top: 50%;
  left: 0; right: 0;
  height: 2px;
  transform: translateY(-50%);
}

.ba-icon::after {
  left: 50%;
  top: 0; bottom: 0;
  width: 2px;
  transform: translateX(-50%);
}

.branch-accordion-item[open] .ba-icon::after {
  transform: translateX(-50%) scaleY(0);
}

.branch-accordion-yes:hover { border-color: var(--teal); }
.branch-accordion-no:hover  { border-color: var(--ink); }

.branch-accordion-yes:hover .ba-icon::before,
.branch-accordion-yes:hover .ba-icon::after { background: var(--teal); }
.branch-accordion-no:hover .ba-icon::before,
.branch-accordion-no:hover .ba-icon::after  { background: var(--ink); }

/* Expanded body — instructions, steps, CTAs. */
.ba-body {
  padding: 0 clamp(28px, 3.4vw, 56px) clamp(28px, 3.4vw, 44px);
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
}

.ba-body h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(24px, 2.6vw, 36px);
  line-height: 1.1;
  letter-spacing: -0.022em;
  color: var(--ink);
  margin: var(--s-6) 0 0;
  max-width: 28ch;
}

.ba-body .branch-steps {
  gap: var(--s-4);
}

.ba-body .branch-steps li {
  grid-template-columns: 36px 1fr;
  font-size: clamp(16px, 1.2vw, 18px);
}

.ba-body .branch-actions {
  margin-top: var(--s-3);
}

@media (max-width: 720px) {
  .branch-accordion-item > summary { grid-template-columns: 1fr auto; }
  .ba-meta { grid-column: 1; grid-row: 2; justify-self: start; white-space: normal; }
  .ba-icon { grid-row: 1; grid-column: 2; }
}

/* --------------------------------------------------------------------------
   13. SECTION: BOOK A DEMO  —  brand teal card, image right, single CTA
   -------------------------------------------------------------------------- */

.section-book-demo {
  background: var(--bg);
  padding: var(--s-9) 0;
}

/* Override the standard 1240px container so this card spans wider — the
   video gets more real estate. */
.section-book-demo .container {
  max-width: 1520px;
}

.book-demo-card {
  background: var(--teal);
  color: #fff;
  border-radius: clamp(20px, 2vw, 32px);
  padding: clamp(40px, 4.4vw, 80px) clamp(40px, 4.4vw, 80px);
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.45fr);
  gap: clamp(40px, 4.5vw, 88px);
  align-items: center;
  overflow: hidden;
}

.book-demo-content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-4);
}

.book-demo-headline {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(32px, 4.2vw, 60px);
  line-height: 1.04;
  letter-spacing: -0.026em;
  color: #fff;
  margin: 0;
  max-width: 18ch;
}

.book-demo-copy {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.15vw, 18px);
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.88);
  margin: 0;
  max-width: 52ch;
}

.book-demo-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 10px 20px;
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  margin-top: var(--s-3);
  transition:
    background var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out),
    transform var(--d-fast) var(--ease-out);
}

.book-demo-cta:hover {
  background: var(--ink);
  color: #fff;
  transform: translateY(-1px);
}

.book-demo-cta-arrow {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  transition:
    background var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out),
    transform var(--d-fast) var(--ease-out);
}

.book-demo-cta:hover .book-demo-cta-arrow {
  background: #fff;
  color: var(--ink);
  transform: translateX(2px);
}

.book-demo-visual {
  background: #fff;
  border-radius: clamp(14px, 1.2vw, 20px);
  overflow: hidden;
  aspect-ratio: 16 / 11;        /* wider + slightly taller frame */
  box-shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.35);
}

.book-demo-visual img,
.book-demo-video {
  width: 100%;
  height: 100%;
  /* Show the full video frame — no crop. Any aspect mismatch with the
     16:11 container falls back to the white card background. */
  object-fit: contain;
  display: block;
}

@media (max-width: 880px) {
  .book-demo-card {
    grid-template-columns: 1fr;
    gap: var(--s-6);
    padding: clamp(28px, 5vw, 40px);
  }
  .book-demo-visual { order: -1; }    /* image above text on phones */
}


/* --------------------------------------------------------------------------
   13b. SECTION: THE CASE FOR CLAUDE  —  downloadable PDF
   -------------------------------------------------------------------------- */

.section-case-for-claude {
  background: var(--bg-soft);
  padding: var(--s-9) 0;
}

.case-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
}

.case-visual {
  display: flex;
  align-items: flex-start;
  justify-content: center;
}

.case-visual img {
  width: 100%;
  height: auto;
  max-width: 460px;
  display: block;
  border-radius: var(--r-md);
  box-shadow: 0 28px 60px -28px rgba(0, 0, 0, 0.20);
}

.case-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-4);
}

.case-heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(36px, 4.8vw, 64px);
  line-height: 1.04;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin: 0;
  max-width: 18ch;
}

.case-subhead {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(18px, 1.6vw, 24px);
  line-height: 1.3;
  letter-spacing: -0.016em;
  color: var(--ink);
  margin: 0;
  max-width: 30ch;
}

.case-intro {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.15vw, 17px);
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0;
}

.case-bullets {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.case-bullets li {
  position: relative;
  padding-left: 24px;
  font-family: var(--font-body);
  font-size: clamp(15px, 1.1vw, 17px);
  line-height: 1.5;
  color: var(--ink);
}

.case-bullets li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 12px;
  height: 1.5px;
  background: var(--teal);
  border-radius: 1px;
}

/* HubSpot form container — neutral white card so the embed sits cleanly
   against the off-white section background. Lives inside .case-text now
   so it stacks below the bullets. */
.case-form {
  width: 100%;
  margin-top: var(--s-5);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(24px, 3vw, 40px);
  box-shadow: 0 14px 36px -18px rgba(0, 0, 0, 0.10);
}

/* Light targeting of HubSpot's injected markup so it picks up our font
   stack and looks at home. Anything HubSpot doesn't expose stays at
   their defaults. */
.case-form .hs-form-frame,
.case-form .hs-form-frame * {
  font-family: var(--font-body) !important;
}

.case-form .hs-form-frame input,
.case-form .hs-form-frame textarea,
.case-form .hs-form-frame select {
  font-size: 15px !important;
}

@media (max-width: 880px) {
  .case-grid {
    grid-template-columns: 1fr;
    gap: var(--s-6);
  }
  .case-visual img { max-width: 280px; margin: 0 auto; }
}

/* Each choice card — big serif headline, meta line, and a circular arrow.
   The two cards are visually distinguished:
     .branch-choice-yes  — filled, teal, the "primary" path (ready to go).
     .branch-choice-no   — outlined, ink, the "secondary" path (we'll guide). */
.branch-choice {
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: var(--s-4) var(--s-5);
  padding: clamp(36px, 4.5vw, 60px);     /* ~25% larger interior padding */
  border-radius: var(--r-lg);
  min-height: clamp(300px, 38vh, 400px); /* ~25% larger card height */
  overflow: hidden;
  transition:
    transform var(--d-med) var(--ease-out),
    box-shadow var(--d-med) var(--ease-out);
}

.branch-choice:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 44px -20px rgba(0,0,0,0.25);
}

/* PRIMARY — white card with a discreet teal stripe across the top,
   mirroring the No card's black stripe. */
.branch-choice-yes {
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--line-strong);
}

.branch-choice-yes::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; height: 4px;
  background: linear-gradient(90deg, var(--teal) 0%, var(--teal-dark) 100%);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}

.branch-choice-yes:hover { border-color: var(--teal); }
.branch-choice-yes:hover .branch-choice-arrow {
  background: var(--teal);
  border-color: var(--teal);
  color: #fff;
  transform: translateX(4px);
}

/* SECONDARY — outlined ink on white. The "we'll help you" card. */
.branch-choice-no {
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--line-strong);
}

.branch-choice-no::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; height: 4px;
  background: linear-gradient(90deg, var(--ink) 0%, var(--ink-3) 100%);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}

.branch-choice-no:hover { border-color: var(--ink); }
.branch-choice-no:hover .branch-choice-arrow {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
  transform: translateX(4px);
}

.branch-choice-headline {
  grid-column: 1 / 3;
  grid-row: 1;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(40px, 5vw, 64px);   /* ~25% larger */
  line-height: 1.04;
  letter-spacing: -0.028em;
  color: var(--ink);
  max-width: 16ch;
  align-self: start;
  position: relative;
  z-index: 1;
}

.branch-choice-meta {
  grid-column: 1 / 2;
  grid-row: 2;
  font-family: var(--font-body);
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.45;
  color: var(--ink-3);
  align-self: end;
  position: relative;
  z-index: 1;
}

.branch-choice-arrow {
  grid-column: 2;
  grid-row: 2;
  display: inline-grid;
  place-items: center;
  width: 64px;          /* ~25% larger arrow */
  height: 64px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  background: var(--bg);
  position: relative;
  z-index: 1;
  transition:
    background var(--d-fast) var(--ease-out),
    border-color var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out),
    transform var(--d-fast) var(--ease-out);
}

@media (max-width: 720px) {
  .branch-gate { grid-template-columns: 1fr; }
}

.branch-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-5);
}

/* Minimalist path card — heading, steps, CTA. No image, no eyebrow, no
   body paragraph. Just the instructions, scaled up to read as a serious
   section in its own right. */
.branch-minimal {
  border: 0;
  background: transparent;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-7);
  max-width: 1100px;
  margin: 0 auto;
}

.branch-minimal:hover {
  border-color: transparent;
  box-shadow: none;
  transform: none;
}

.branch-minimal h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(36px, 4.8vw, 68px);
  line-height: 1.04;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin: 0;
  max-width: 24ch;
}

/* Scale up the steps + meta + CTAs inside the minimal card so they match
   the headline's weight. */
.branch-minimal .branch-steps {
  gap: var(--s-5);
}

.branch-minimal .branch-steps li {
  grid-template-columns: 44px 1fr;
  gap: var(--s-5);
  font-size: clamp(18px, 1.5vw, 22px);
  line-height: 1.45;
}

.branch-minimal .branch-steps li::before {
  font-size: 14px;
  letter-spacing: 0.08em;
}

.branch-minimal .branch-steps .step-meta {
  font-size: clamp(14px, 1vw, 16px);
  margin-top: 4px;
}

.branch-minimal .branch-actions {
  margin-top: var(--s-5);
  gap: var(--s-4);
}

.branch-minimal .branch-actions .btn {
  padding: 18px 28px;
  font-size: 17px;
}

/* Detail path with placeholder media — image on one side, content on the
   other. .branch-reverse flips the order so the No path mirrors the Yes
   path. */
.branch-with-media {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 72px);
  align-items: stretch;
  padding: clamp(20px, 2.4vw, 32px);
}

.branch-with-media.branch-reverse {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
}
.branch-with-media.branch-reverse .branch-media     { order: 2; }
.branch-with-media.branch-reverse .branch-body-wrap { order: 1; }

.branch-body-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  justify-content: center;
  padding: clamp(16px, 2vw, 28px) 0;
}

.branch-media {
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  min-height: 360px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(24px, 2.6vw, 40px);
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 28px 60px -34px rgba(0,0,0,0.30);
}

.branch-media-yes {
  background:
    radial-gradient(70% 60% at 10% 0%, rgba(0,118,129,0.55), transparent 55%),
    radial-gradient(60% 60% at 90% 100%, rgba(0,118,129,0.30), transparent 55%),
    linear-gradient(140deg, #0E2A30 0%, #0A1416 100%);
}

.branch-media-no {
  background:
    radial-gradient(70% 60% at 90% 0%, rgba(217,119,87,0.40), transparent 55%),
    radial-gradient(60% 60% at 10% 100%, rgba(0,118,129,0.26), transparent 55%),
    linear-gradient(140deg, #1A1410 0%, #0A0A0A 100%);
}

.branch-media-eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.70);
  margin-bottom: var(--s-3);
}

.branch-media-headline {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(32px, 4vw, 56px);
  line-height: 1.04;
  letter-spacing: -0.026em;
  color: #fff;
  text-shadow: 0 1px 24px rgba(0,0,0,0.4);
  margin-bottom: var(--s-3);
}

.branch-media-meta {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: rgba(255,255,255,0.70);
}

@media (max-width: 880px) {
  .branch-with-media,
  .branch-with-media.branch-reverse {
    grid-template-columns: 1fr;
  }
  .branch-with-media.branch-reverse .branch-media     { order: 0; }
  .branch-with-media.branch-reverse .branch-body-wrap { order: 0; }
  .branch-media { min-height: 220px; }
}

.branch {
  position: relative;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(var(--s-6), 4vw, 56px);
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  transition:
    border-color var(--d-med) var(--ease-out),
    transform var(--d-med) var(--ease-out),
    box-shadow var(--d-med) var(--ease-out);
}

.branch:hover {
  border-color: var(--line-strong);
  transform: translateY(-2px);
  box-shadow: 0 12px 36px -16px rgba(0,0,0,0.12);
}

.branch-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--teal);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.branch-tag .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--teal);
}

.branch h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(26px, 3vw, 38px);
  line-height: 1.1;
  letter-spacing: -0.025em;
  margin: 0;
  color: var(--ink);
  max-width: 16ch;
}

.branch-body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0;
  max-width: 38ch;
}

.branch-steps {
  list-style: none;
  padding: 0;
  margin: var(--s-4) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  counter-reset: step;
}

.branch-steps li {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: var(--s-4);
  align-items: baseline;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
}

.branch-steps li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--teal);
  letter-spacing: 0.06em;
  align-self: center;
  transform: translateY(-1px);
}

.branch-steps .step-meta {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink-3);
  display: block;
  margin-top: 2px;
}

.branch-actions {
  margin-top: var(--s-4);
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
}


/* --------------------------------------------------------------------------
   14. SECTION: SECURITY (inverted, distinctive)
   -------------------------------------------------------------------------- */

.section-security {
  background: var(--bg-inverted);
  color: var(--ink-on-dark);
  padding: var(--s-11) 0;
  position: relative;
  overflow: hidden;
}

.section-security::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 20% 0%, rgba(0,118,129,0.18), transparent 60%),
    radial-gradient(ellipse 60% 50% at 90% 100%, rgba(0,118,129,0.10), transparent 55%);
  pointer-events: none;
}

.section-security .container { position: relative; z-index: 1; }

.security-head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-8);
  align-items: end;
  margin-bottom: var(--s-9);
}

.security-head h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 5vw, 64px);
  line-height: 1.04;
  letter-spacing: -0.028em;
  color: var(--ink-on-dark);
  margin: 0;
  max-width: 18ch;
}

.security-head h2 .accent { color: var(--teal); }

.security-head p {
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-on-dark-2);
  margin: 0;
  max-width: 42ch;
  justify-self: end;
}

.security-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-top: 1px solid var(--line-on-dark);
}

.security-cert {
  padding: var(--s-7) var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  border-right: 1px solid var(--line-on-dark);
}

.security-cert:last-child { border-right: 0; }

/* Badge: subtle white outline on the dark security section. The icon
   itself is rendered as a clean white line drawing (set via stroke on
   the SVG inside each card). */
.security-cert .badge {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.18);
  display: grid;
  place-items: center;
  color: #fff;
}

.security-cert .badge svg {
  width: 22px;
  height: 22px;
  display: block;
}

.security-cert h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 22px;
  letter-spacing: -0.015em;
  color: var(--ink-on-dark);
  margin: 0;
}

.security-cert p {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-on-dark-2);
  margin: 0;
}

.security-cert .status {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--teal);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
}

.security-cert .status .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 0 3px rgba(0,118,129,0.20);
}

.security-foot {
  margin-top: var(--s-7);
  padding-top: var(--s-6);
  border-top: 1px solid var(--line-on-dark);
  display: flex;
  align-items: center;
  justify-content: center;       /* single link sits centred now */
  gap: var(--s-5);
  flex-wrap: wrap;
}


/* --------------------------------------------------------------------------
   14b. SECTION: FINAL CTA — closing call to action
   -------------------------------------------------------------------------- */

.section-final-cta {
  background: var(--bg-soft);
  padding: var(--s-10) 0;
  text-align: center;
}

.final-cta-inner {
  max-width: 760px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-5);
}

.final-cta-headline {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(40px, 6vw, 88px);
  line-height: 1.02;
  letter-spacing: -0.032em;
  color: var(--ink);
  margin: 0;
  max-width: 16ch;
}

.final-cta-headline .accent { color: var(--teal); }
.final-cta-headline em { font-style: normal; }

.final-cta-sub {
  font-family: var(--font-body);
  font-size: clamp(16px, 1.4vw, 20px);
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0;
  max-width: 48ch;
}

.final-cta-actions {
  display: flex;
  gap: var(--s-4);
  flex-wrap: wrap;
  justify-content: center;
  margin-top: var(--s-3);
}


/* --------------------------------------------------------------------------
   14c. SECTION: FAQ — SEO accordion
   -------------------------------------------------------------------------- */

.section-faq {
  background: var(--bg);
  padding: var(--s-9) 0 var(--s-10);
}

.faq-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(28px, 3.6vw, 44px);
  line-height: 1.06;
  letter-spacing: -0.026em;
  color: var(--ink);
  margin: 0 0 var(--s-6);
  text-align: center;
  max-width: 22ch;
  margin-left: auto;
  margin-right: auto;
}

.faq-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
}

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

.faq-item > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-5) 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(18px, 1.7vw, 22px);
  line-height: 1.3;
  letter-spacing: -0.012em;
  color: var(--ink);
}

/* Hide default disclosure markers across browsers. */
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::marker { content: ""; }

.faq-icon {
  position: relative;
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
}

.faq-icon::before,
.faq-icon::after {
  content: "";
  position: absolute;
  background: var(--ink);
  border-radius: 1px;
  transition: transform var(--d-med) var(--ease-out);
}

.faq-icon::before {
  top: 50%;
  left: 0;
  right: 0;
  height: 1.5px;
  transform: translateY(-50%);
}

.faq-icon::after {
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1.5px;
  transform: translateX(-50%);
}

.faq-item[open] .faq-icon::after {
  transform: translateX(-50%) scaleY(0);
}

.faq-item:hover > summary { color: var(--teal); }
.faq-item:hover .faq-icon::before,
.faq-item:hover .faq-icon::after { background: var(--teal); }

.faq-body {
  padding: 0 0 var(--s-5);
  max-width: 64ch;
}

.faq-body p {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.1vw, 17px);
  line-height: 1.6;
  color: var(--ink-2);
  margin: 0 0 var(--s-3);
}

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


/* --------------------------------------------------------------------------
   14d. CONNECT CLAUDE MODAL — native <dialog> for the MCP install steps
   -------------------------------------------------------------------------- */

/* Step-link button styled as a teal inline link inside the .step-meta
   line. Triggers the connect-modal via JS. */
.step-link {
  border: 0;
  background: transparent;
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  font-weight: 600;
  color: var(--teal);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color var(--d-fast) var(--ease-out);
}

.step-link:hover { color: var(--teal-dark); }

/* The dialog itself — reset the browser defaults, position it centred,
   give it room to breathe on phones. */
.connect-modal {
  border: 0;
  padding: 0;
  background: transparent;
  width: min(540px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  border-radius: 18px;
  overflow: visible;
  box-shadow: 0 24px 60px -20px rgba(0,0,0,0.35);
}

.connect-modal::backdrop {
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.connect-modal-inner {
  position: relative;
  background: var(--bg);
  border-radius: 18px;
  padding: clamp(28px, 4vw, 40px);
  max-height: calc(100vh - 32px);
  overflow-y: auto;
}

.connect-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 36px;
  height: 36px;
  border: 0;
  background: transparent;
  color: var(--ink-3);
  border-radius: 8px;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition:
    background var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out);
}

.connect-modal-close:hover {
  background: rgba(0,0,0,0.05);
  color: var(--ink);
}

.connect-modal h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(20px, 2.2vw, 26px);
  line-height: 1.15;
  letter-spacing: -0.020em;
  color: var(--ink);
  margin: 0 0 6px;
  padding-right: 36px;          /* room for the close button */
}

.connect-modal-lede {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-3);
  margin: 0 0 22px;
}

.connect-steps {
  list-style: none;
  padding: 0;
  margin: 0;
  counter-reset: connect-step;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.connect-steps li {
  position: relative;
  padding-left: 38px;            /* 26px counter + 12px gap */
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  counter-increment: connect-step;
}

/* The counter is absolutely positioned so the li's inner text + <strong>
   + .connect-url all flow naturally as block / inline content, without
   getting broken up by grid auto-placement. */
.connect-steps li::before {
  content: counter(connect-step);
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  background: rgba(0, 118, 129, 0.10);
  color: var(--teal);
  border-radius: 50%;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
}

.connect-steps li strong {
  font-weight: 600;
}

/* URL row — code on the left, copy button on the right. */
.connect-url {
  margin-top: 10px;
  display: flex;
  align-items: stretch;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-soft);
}

.connect-url code {
  flex: 1 1 auto;
  min-width: 0;
  padding: 12px 14px;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink);
  overflow-x: auto;
  white-space: nowrap;
  background: transparent;
}

.connect-copy {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  border-left: 1px solid var(--line-strong);
  background: var(--bg);
  color: var(--ink);
  padding: 0 14px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background var(--d-fast) var(--ease-out),
    color var(--d-fast) var(--ease-out);
}

.connect-copy:hover {
  background: var(--teal);
  color: #fff;
}

.connect-copy.is-copied {
  background: var(--teal);
  color: #fff;
}

.connect-modal-done {
  margin-top: 22px;
  width: 100%;
  padding: 14px 20px;
  background: var(--teal);
  color: #fff;
  border: 0;
  border-radius: 10px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  transition: background var(--d-fast) var(--ease-out);
}

.connect-modal-done:hover { background: var(--teal-dark); }


/* --------------------------------------------------------------------------
   15. FOOTER
   -------------------------------------------------------------------------- */

/* Brand teal footer — minimal: logo + 4 links + bottom legal strip. */
footer {
  background: var(--teal);
  color: #fff;
  padding: var(--s-8) 0 var(--s-6);
}

.foot-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s-5);
}

.foot-brand img {
  height: 28px;
  filter: brightness(0) invert(1);   /* white wordmark on teal */
}

.foot-nav {
  display: flex;
  gap: clamp(20px, 3vw, 40px);
  flex-wrap: wrap;
  align-items: center;
}

.foot-nav a {
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.92);
  transition:
    color var(--d-fast) var(--ease-out),
    opacity var(--d-fast) var(--ease-out);
}

.foot-nav a:hover {
  color: #fff;
  opacity: 1;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}

.foot-bottom {
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.72);
}

.foot-bottom a { color: rgba(255, 255, 255, 0.85); }
.foot-bottom a:hover { color: #fff; }


/* --------------------------------------------------------------------------
   16. RESPONSIVE
   -------------------------------------------------------------------------- */

@media (max-width: 960px) {
  .beats-header { grid-template-columns: 1fr; gap: var(--s-5); }
  .beats-header p { justify-self: start; }
  .security-head { grid-template-columns: 1fr; gap: var(--s-5); }
  .security-head p { justify-self: start; }
  .security-grid { grid-template-columns: 1fr; }
  .security-cert { border-right: 0; border-bottom: 1px solid var(--line-on-dark); }
  .security-cert:last-child { border-bottom: 0; }
}

@media (max-width: 880px) {
  .nav-badge { display: none; }
  .checks { grid-template-columns: 1fr; gap: var(--s-7); }
  .beats { grid-template-columns: 1fr; }
  .beat { padding: var(--s-6) 0; }
  .beat:nth-child(odd),
  .beat:nth-child(even) { padding: var(--s-6) 0; border-right: 0; }
  .branch-grid { grid-template-columns: 1fr; }
  .foot-row { flex-direction: column; align-items: flex-start; gap: var(--s-4); }
}

@media (max-width: 600px) {
  .hero-content { padding: calc(72px + var(--s-5)) var(--pad-x) var(--s-8); }
  .hero h1 { max-width: 100%; }
  .hero-actions { width: 100%; }
  .hero-actions .btn { flex: 1 1 auto; justify-content: center; }
  .foot-nav { gap: 14px 20px; }
  .foot-bottom { flex-direction: column; align-items: flex-start; }
  .beat { grid-template-columns: 48px 1fr; gap: var(--s-4); }
}


/* --------------------------------------------------------------------------
   17. MOBILE: disable pinned scrubbing + show full videos
   --------------------------------------------------------------------------
   The pinned/scroll-driven sections (gap, checks, manifesto, stack) all
   assume a 100vh sticky container with content that fits in one viewport.
   On phones the content stacks vertically and is taller than 100vh, so it
   spills beyond the pin. Below 880px we unpin everything: the section
   becomes a normal flow block, the char-reveal/step-reveal effects show
   their final state immediately, and the user just scrolls past.

   Videos: `object-fit: cover` is great on desktop but crops 25–35% of
   either side on portrait phones. Below 880px we switch to `contain` so
   the full video frame is visible. The dark fallback (hero-fallback or
   the .section-claim background) fills the bars cleanly.
   -------------------------------------------------------------------------- */

@media (max-width: 880px) {
  /* Unpin every scroll-driven scroller and let its content flow. */
  .gap-scroller,
  .checks-scroller,
  .manifesto-scroller,
  .stack-scroller {
    height: auto;
  }
  .gap-sticky,
  .checks-sticky,
  .manifesto-sticky,
  .stack-sticky {
    position: static;
    height: auto;
    padding: var(--s-7) var(--pad-x);
  }

  /* Char-reveal targets — show all characters immediately. */
  [data-char-reveal] .char,
  [data-char-reveal-manifesto] .char,
  [data-char-reveal-block] .char {
    opacity: 1 !important;
    transition: none !important;
  }

  /* Bullet icons — drop the :has() gating since we're not driving them
     from the char queue any more. */
  .check-list .icon { opacity: 1 !important; }

  /* Stack blocks + frame — clear inline opacity/transform from JS. */
  .stack-block,
  .stack-frame-border {
    opacity: 1 !important;
    transform: none !important;
  }

  /* Tighten the checks padding so it doesn't dwarf the content. */
  .checks { padding: 0; }

  /* Stack: drop the giant scroller padding from the sticky version. */
  .stack-sticky { gap: var(--s-5); }
  .stack-title-pin { margin-bottom: var(--s-3); }

  /* Carousel arrows tend to overlap the tile content on phones. Make them
     smaller and inset further so they don't punch the screenshot. */
  .beats-arrow {
    width: 38px;
    height: 38px;
  }
  .beats-prev { left: 6px; }
  .beats-next { right: 6px; }

  /* Branch accordion summary: tighten padding so the stack reads on phones. */
  .branch-accordion-item > summary {
    padding: var(--s-5) var(--s-4);
  }
  .ba-meta { font-size: 14px; }
}
