/* ===================== RESET & BASE ===================== */

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

/* Palette matches the real app's own default screen exactly: a barely-
   there warm-grey canvas (--bg) with pure white cards (--surface) —
   cards read as distinct floating surfaces from that color contrast
   alone, the same way the product's own cards do, so most of them carry
   no border or shadow at all (see .value-card, .testimonial-card,
   .feature-frame, .feature-content, .job-card, .program-card-inner).
   Ink text, hairline dividers only where something is actually
   interactive, serif display headlines, and the app's own primary
   accent (blue) in place of the marketing-only clay/orange this site
   used before — --clay is kept as the token name (every component below
   is written against it) but now points at the same blue as --accent,
   everywhere on the site except go/checklist, which doesn't use this
   stylesheet at all. Orange and green survive only where the app itself
   gives them meaning (an alert, a good outcome, a segment page's own
   identity) — never purple, which the app doesn't have. */
:root {
  --bg:        #f5f4f2;
  --bg-alt:    #f6f6f4;
  --surface:   #ffffff;
  --border:    rgba(0,0,0,0.07);
  --border-mid: rgba(0,0,0,0.13);

  --text-primary:   #2E2C27;
  --text-secondary: #6B6A63;
  --text-tertiary:  #B4B3A8;

  --accent:       #0050c8;
  --accent-hover: #0046b0;
  --accent-light: rgba(0,80,200,0.08);

  --clay:       var(--accent);
  --clay-hover: var(--accent-hover);
  --clay-light: var(--accent-light);

  --green:        #1a9e40;
  --green-light:  rgba(26,158,64,0.10);

  --orange:       #b5690a;
  --orange-light: rgba(181,105,10,0.10);

  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 12px;
  --radius-2xl: 20px;
  /* The real app's squircle radius (see CornerKit usage in index.html) —
     a continuous-curvature corner, not a plain border-radius arc. This
     is the CSS border-radius fallback for the instant before/if that
     JS runs; CornerKit's clip-path takes over once it does. */
  --radius-squircle: 30px;

  --shadow-sm: 0 1px 2px rgba(46,44,39,0.06);
  --shadow-md: 0 8px 24px rgba(46,44,39,0.10);

  --font:        -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
  /* Display face for the hero and page-title moments only — a bold,
     faceted geometric sans that echoes the logomark's cut-stone angles
     instead of an editorial serif that had nothing to do with it. */
  --font-display: 'Space Grotesk', var(--font);
  --font-mono:   ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --max-w: 1080px;
  --section-gap: 130px;
}

html { scroll-behavior: smooth; }

/* Flat canvas, matching the real app exactly (see its own styles.css:
   "color used only as a navigational accent, never as decoration") —
   no ambient color glow. The only texture is a barely-there paper grain
   (below), the one finish every section shares instead of a gradient
   that reads as a template default. */
body {
  background: var(--bg);
  font-family: var(--font);
  margin: 0; padding: 0;
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Fixed, full-viewport, painted behind every in-flow element via a
   negative z-index — the standard way to pin a decorative layer without
   it scrolling away or having to sit inside every section. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* A quiet "measurement frame" — four short bracket marks standing just
   outside a block, the same idea as a viewfinder's focus corners. Purely
   decorative (a background image on an unlabelled pseudo-element, so
   screen readers never see it), a recurring on-brand hint that whatever
   sits inside is being watched closely — which is the whole product.
   One shared recipe, tuned per component with custom properties rather
   than redrawn each time. */
.feature-row::before {
  content: "";
  position: absolute;
  pointer-events: none;
  inset: var(--frame-inset, -14px);
  --fc: var(--frame-color, var(--clay));
  --fl: var(--frame-len, 16px);
  opacity: var(--frame-opacity, 0.4);
  background:
    linear-gradient(var(--fc), var(--fc)) 0 0 / var(--fl) 1.5px no-repeat,
    linear-gradient(var(--fc), var(--fc)) 0 0 / 1.5px var(--fl) no-repeat,
    linear-gradient(var(--fc), var(--fc)) 100% 0 / var(--fl) 1.5px no-repeat,
    linear-gradient(var(--fc), var(--fc)) 100% 0 / 1.5px var(--fl) no-repeat,
    linear-gradient(var(--fc), var(--fc)) 0 100% / var(--fl) 1.5px no-repeat,
    linear-gradient(var(--fc), var(--fc)) 0 100% / 1.5px var(--fl) no-repeat,
    linear-gradient(var(--fc), var(--fc)) 100% 100% / var(--fl) 1.5px no-repeat,
    linear-gradient(var(--fc), var(--fc)) 100% 100% / 1.5px var(--fl) no-repeat;
}

.feature-row { --frame-inset: -16px; --frame-len: 18px; --frame-opacity: 0.35; }
.feature-row--orange { --frame-color: var(--orange); }
.feature-row--green  { --frame-color: var(--green); }

/* Same treatment the app uses on its own interactive rows (e.g.
   .now-issue-item:focus-visible) — a plain clay outline, not a box-shadow
   ring, so focus reads identically here and inside the product. */
a:focus-visible,
button:focus-visible,
.btn:focus-visible {
  outline: 2px solid var(--clay);
  outline-offset: 3px;
  border-radius: 3px;
}

/* ===================== SCROLL REVEAL ===================== */
/* A short, one-time fade + rise for headings and body copy as they
   enter view — kept quick (~0.4s) so it reads as polish, not a wait.
   Scoped under html.js (set by an inline script at the top of <head>)
   so content simply renders visible, with no hidden text, if that
   script is ever blocked or JS is off. */

html.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}

html.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

.reveal-delay-1 { transition-delay: 0.08s; }
.reveal-delay-2 { transition-delay: 0.16s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

@media (prefers-reduced-transparency: reduce) {
  .nav { background: var(--bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* ===================== NAV ===================== */
/* A floating pill the width of the page's own content column — not a
   full-bleed bar — inset from the top and sides everywhere, mobile
   included, so it reads as its own separated block sitting on the
   canvas rather than a stripe glued across the viewport. Transparent at
   rest, gains a frosted white glass surface once the page scrolls
   (.is-scrolled, toggled by the small script near the end of body) —
   the same liquid-glass recipe the real app uses for its own floating
   chrome (.empty-screen-card, .deep-dive-header-card: a translucent
   white surface at blur(20px) saturate(160%), separated by a shadow
   rather than a hard border-bottom line). One nav markup, one set of
   rules, shared by every page. */

.nav {
  position: sticky;
  top: 16px;
  z-index: 200;
  /* var(--max-w) plus 96px, matching .nav-inner's own former side
     padding — same content edge as the stats band, case studies and
     footer below. calc(100% - 32px) is the floor: a minimum 16px gap on
     each side even on viewports too narrow for the max-width to bind,
     so it's never flush against the edges. */
  width: calc(100% - 32px);
  max-width: calc(var(--max-w) + 96px);
  margin: 0 auto;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  transition: background 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out);
}

.nav.is-scrolled {
  background: rgba(255, 255, 255, 0.72);
  box-shadow: var(--shadow-sm);
}

.nav-inner {
  padding: 0 48px;
  height: 60px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
}

.nav-logo {
  display: flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: var(--text-primary);
}

.nav-logo-mark {
  display: block;
  flex-shrink: 0;
}

.nav-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 30px;
}

.nav-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-secondary);
  text-decoration: none;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color 0.15s;
}
.nav-link:hover { color: var(--text-primary); }

.nav-dropdown { position: relative; }

.nav-dropdown-trigger svg {
  width: 9px;
  height: 9px;
  transition: transform 0.2s var(--ease-out);
}
.nav-dropdown:hover .nav-dropdown-trigger svg,
.nav-dropdown:focus-within .nav-dropdown-trigger svg {
  transform: rotate(180deg);
}

.nav-dropdown-menu {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  min-width: 190px;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s var(--ease-out), transform 0.15s var(--ease-out), visibility 0.15s;
}

.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}

.nav-dropdown-link {
  display: block;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-secondary);
  text-decoration: none;
  padding: 9px 12px;
  border-radius: var(--radius-md);
  transition: background 0.12s, color 0.12s;
}
.nav-dropdown-link:hover { background: var(--bg); color: var(--text-primary); }

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

/* Below this the 3-column grid plus a 4-item link row plus the dropdown
   starts crowding the bar — dropped in favor of just the logo and
   primary action, same as the existing mobile-only button treatment
   further down. The footer repeats every one of these links anyway. */
@media (max-width: 900px) {
  .nav-links { display: none; }
}

/* Hamburger — three bars morphing into an X (see .nav.is-menu-open),
   hidden until the narrow-viewport rule below shows it in place of the
   Sign in/Get started pair, which doesn't have room to sit comfortably
   in the compact bar at that width any more. Explicitly pinned to the
   grid's 3rd (outer) column: with .nav-links and .nav-actions both
   display:none at this width, the burger is the grid's 2nd visible
   item, and CSS Grid auto-placement would otherwise drop it into the
   2nd (1fr, center) column right next to the logo instead of out at
   the far edge where a menu toggle belongs. */
.nav-burger {
  display: none;
  grid-column: 3;
  position: relative;
  width: 36px;
  height: 36px;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
}
.nav-burger span {
  position: absolute;
  left: 7px;
  right: 7px;
  height: 2px;
  border-radius: 1px;
  background: var(--text-primary);
  transition: transform 0.25s var(--ease-out), opacity 0.2s var(--ease-out), top 0.25s var(--ease-out);
}
.nav-burger span:nth-child(1) { top: 13px; }
.nav-burger span:nth-child(2) { top: 17px; }
.nav-burger span:nth-child(3) { top: 21px; }

.nav.is-menu-open .nav-burger span:nth-child(1) { top: 17px; transform: rotate(45deg); }
.nav.is-menu-open .nav-burger span:nth-child(2) { opacity: 0; }
.nav.is-menu-open .nav-burger span:nth-child(3) { top: 17px; transform: rotate(-45deg); }

/* The slide-out panel itself — collapsed via max-height rather than
   display, so it animates instead of snapping open. Sits solid instead
   of transparent regardless of scroll position, since it would
   otherwise overlap whatever's directly behind the bar at the top of
   the page. */
.nav-mobile-menu {
  display: flex;
  flex-direction: column;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 24px;
  transition: max-height 0.25s var(--ease-out), opacity 0.2s var(--ease-out);
}

.nav.is-menu-open {
  background: rgba(255, 255, 255, 0.85);
  box-shadow: var(--shadow-sm);
}

.nav.is-menu-open .nav-mobile-menu {
  max-height: 480px;
  opacity: 1;
  padding-bottom: 24px;
}

.nav-mobile-link {
  display: block;
  padding: 13px 2px;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-primary);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
}

.nav-mobile-link--sub {
  padding-left: 14px;
  font-size: 14px;
  color: var(--text-secondary);
}

.nav-mobile-group-title {
  display: block;
  padding: 14px 2px 2px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-tertiary);
}

.nav-mobile-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 18px;
}

.nav-mobile-btn { width: 100%; justify-content: center; }

/* ===================== BUTTONS ===================== */
/* Rounded-rect, gradient-filled, with the same hover-lift / press-scale
   the app's real .auth-submit-btn uses — not a pill. */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  padding: 9px 18px;
  border-radius: var(--radius-xl);
  border: none;
  cursor: pointer;
  text-decoration: none;
  /* The same spring ease-out used everywhere else on the page (tag
     hover, tab indicators, modals) — plain "ease" at 0.12-0.15s read as
     a flat, mechanical snap next to those, not a considered motion. */
  transition: opacity 0.2s var(--ease-out), transform 0.2s var(--ease-out), box-shadow 0.25s var(--ease-out), background 0.2s var(--ease-out);
  white-space: nowrap;
}

.btn:active { transform: scale(0.97); transition: transform 0.12s var(--ease-out); }

.btn-primary {
  color: #fff;
  background: linear-gradient(160deg, color-mix(in srgb, var(--clay) 65%, white) 0%, var(--clay) 55%, var(--clay-hover) 100%);
  box-shadow:
    0 1px 2px rgba(46,44,39,0.14),
    0 4px 16px color-mix(in srgb, var(--clay) 32%, transparent),
    inset 0 1px 0 rgba(255,255,255,0.18);
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow:
    0 1px 2px rgba(46,44,39,0.12),
    0 8px 22px color-mix(in srgb, var(--clay) 38%, transparent),
    inset 0 1px 0 rgba(255,255,255,0.18);
}

/* Trailing arrow on primary CTAs, nudging right on hover — a small,
   recognizably "premium SaaS" tell. Scoped to .btn-arrow (used on the
   homepage) rather than every .btn-primary site-wide, so the other
   pages' buttons are untouched. */
.btn-arrow::after {
  content: "\2192";
  display: inline-block;
  transition: transform 0.15s var(--ease-out);
}
.btn-arrow:hover::after { transform: translateX(3px); }

.btn-ghost { background: transparent; color: var(--clay); font-weight: 500; }
.btn-ghost:hover { opacity: 0.75; }

.btn-outline {
  background: var(--surface);
  color: var(--text-primary);
  box-shadow: inset 0 0 0 1px var(--border-mid);
}
.btn-outline:hover { background: var(--bg-alt); }

.btn-lg { font-size: 16px; padding: 15px 26px; }

.btn-full { width: 100%; justify-content: center; padding-top: 13px; padding-bottom: 13px; }

/* ===================== HERO ===================== */
/* Pitch, then get out of the way — one headline, one line of support,
   one action. No secondary CTA competing with it, no social-proof row
   crowding the bottom; the product shot right below carries that weight
   instead of a stack of avatars. */

.hero {
  position: relative;
  text-align: center;
  /* Clears the floating nav's own bottom edge (16px inset + 60px tall)
     with real breathing room instead of crowding right underneath it. */
  margin-top: 112px;
  padding: 24px 24px 88px;
  max-width: 880px;
  margin-left: auto;
  margin-right: auto;
}

.hero-title {
  font-family: var(--font-display);
  font-size: clamp(36px, 5.4vw, 62px);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--text-primary);
  margin: 0 0 20px;
}

/* Selective word-color instead of a solid-color headline — picks out
   the phrase that carries the meaning rather than tinting everything. */
.text-accent { color: var(--clay); }

.hero-sub {
  font-size: clamp(16px, 2vw, 18px);
  font-weight: 400;
  color: var(--text-secondary);
  line-height: 1.55;
  margin: 0 auto 32px;
  max-width: 480px;
  letter-spacing: -0.005em;
}

/* Primary CTA plus a small reassurance line underneath — the "starting
   is free" fact had no home anywhere on the site before this. Reused
   as-is for the closing section's own CTA further down the page. */
.hero-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.hero-cta-note {
  font-size: 13px;
  color: var(--text-tertiary);
  letter-spacing: -0.005em;
}

/* Four small floating cards, one per corner of the headline, styled
   exactly like the real app's own UI (white surface, --shadow-md,
   tabular numerals, the same green/orange/blue semantics) — a peek at
   the actual product instead of a screenshot, since the app's own
   dashboard is too dense to shrink and stay legible. Above 1320px wide,
   positioned outside the hero's own 880px text column, in the margin a
   wide viewport already has either side of it, so they never compete
   with the headline. Below that width there's no margin left to float
   them in, so they pile up at the bottom of the hero instead and
   scatter apart on scroll — see the mobile media query further down.

   The drift animation lives on the inner .hero-float-drift, not on
   .hero-float itself — .hero-float also carries .reveal, whose entrance
   transition animates `transform` once on load, and a running CSS
   animation on the same property would just win outright and swallow
   that transition. Splitting the two onto parent/child lets the reveal
   rise happen once, then the drift take over indefinitely on the child. */
.hero-float {
  position: absolute;
  width: 196px;
}

.hero-float--tl { top: 130px; left: -206px; }
.hero-float--tr { top: 108px; right: -206px; }
.hero-float--bl { top: 330px; left: -206px; }
.hero-float--br { top: 310px; right: -206px; }

.hero-float-drift {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 12px 16px;
  box-shadow: var(--shadow-md), 0 0 0 1px rgba(0,0,0,0.03);
  animation: hero-float-drift 7s ease-in-out infinite;
  animation-delay: var(--float-delay, 0s);
}

@keyframes hero-float-drift {
  0%, 100% { transform: translateY(0) rotate(var(--float-rot, 0deg)); }
  50%      { transform: translateY(-9px) rotate(var(--float-rot, 0deg)); }
}

.hero-float--tl .hero-float-drift { --float-rot: -4deg; --float-delay: 0s; }
.hero-float--tr .hero-float-drift { --float-rot: 3deg; --float-delay: 1.7s; }
.hero-float--bl .hero-float-drift { --float-rot: 3deg; --float-delay: 3.4s; }
.hero-float--br .hero-float-drift {
  --float-rot: -3deg;
  --float-delay: 5.1s;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}

.hero-float-icon {
  width: 26px;
  height: 26px;
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.hero-float-icon svg { width: 14px; height: 14px; }
.hero-float-icon--orange { background: var(--orange-light); color: var(--orange); }
.hero-float-icon--blue   { background: var(--accent-light); color: var(--accent); }
.hero-float-icon--green  { background: var(--green-light);  color: var(--green); }

.hero-float-body { display: flex; flex-direction: column; gap: 1px; text-align: left; min-width: 0; }
.hero-float-title { font-size: 13px; font-weight: 700; letter-spacing: -0.005em; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.hero-float-sub { font-size: 11.5px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The two "proof" cards, styled as a tiny Slack message preview instead
   of an app-UI chip — a teammate's own words carry differently than
   another metric, even at this small a scale. Same avatar assets as the
   testimonials wall further down (Sam Rivera and Chris Delgado both
   reappear there), so it reads as one person's real reaction, not a
   generic quote. */
.hero-float-slack { flex-direction: column; align-items: stretch; gap: 6px; }

.hero-float-slack-head { display: flex; align-items: center; gap: 7px; }
.hero-float-slack-avatar { width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0; }
.hero-float-slack-name { font-size: 12.5px; font-weight: 700; color: var(--text-primary); }
.hero-float-slack-time { font-size: 10.5px; color: var(--text-tertiary); margin-left: auto; }
.hero-float-slack-msg { margin: 0; font-size: 12px; line-height: 1.45; color: var(--text-secondary); text-align: left; }

.hero-float-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hero-float-label { font-size: 12px; font-weight: 600; color: var(--text-secondary); }
.hero-float-value {
  display: flex;
  align-items: center;
  gap: 3px;
  font-size: 12px;
  font-weight: 700;
  color: var(--green);
}
.hero-float-value svg { width: 9px; height: 9px; }
.hero-float-spark { width: 100%; height: 26px; }

/* Below the desktop breakpoint there's no side margin left to float
   these in, so instead they pile up, slightly overlapping and rotated,
   at the bottom of the hero — and scatter outward as that hero scrolls
   out of view (see the scroll listener in index.html, which drives
   --scatter from 0 to 1 on each .hero-float and this block turns into
   motion). The gentle desktop bob (.hero-float-drift's own animation)
   is redundant next to that motion, so it's switched off here in favor
   of a plain calc()'d transform: pile position at rest, sliding toward
   --scatter-d* as --scatter climbs, fading out at the same rate. */
@media (max-width: 1320px) {
  /* The scattered cards fly well past the hero's own edges at high
     --scatter values — clipped here rather than via overflow-x:hidden
     on html/body, which stops the horizontal bleed just as well but
     without breaking .nav's position:sticky (an overflow value other
     than visible on any ancestor up to the viewport does that). Scoped
     to this same breakpoint so it never touches the desktop layout,
     where floats are meant to bleed into the page's own side margins. */
  .hero { overflow-x: hidden; }

  .hero-float {
    top: auto;
    left: 50%;
    right: auto;
    bottom: 60px;
    width: 150px;
    margin-left: -75px;
  }

  .hero-float--tl { z-index: 4; }
  .hero-float--tr { z-index: 3; }
  .hero-float--bl { z-index: 2; }
  .hero-float--br { z-index: 1; }

  .hero-float-drift {
    animation: none;
    transition: opacity 0.2s linear;
    transform:
      translate(
        calc(var(--pile-x, 0px) + var(--scatter, 0) * var(--scatter-dx, 0px)),
        calc(var(--pile-y, 0px) + var(--scatter, 0) * var(--scatter-dy, 0px))
      )
      rotate(calc(var(--pile-r, 0deg) + var(--scatter, 0) * var(--scatter-dr, 0deg)));
    opacity: calc(1 - var(--scatter, 0));
  }

  .hero-float--tl .hero-float-drift {
    --pile-x: -56px; --pile-y: -18px; --pile-r: -8deg;
    --scatter-dx: -170px; --scatter-dy: -120px; --scatter-dr: -50deg;
  }
  .hero-float--tr .hero-float-drift {
    --pile-x: 44px; --pile-y: -26px; --pile-r: 7deg;
    --scatter-dx: 170px; --scatter-dy: -140px; --scatter-dr: 45deg;
  }
  .hero-float--bl .hero-float-drift {
    --pile-x: -40px; --pile-y: 8px; --pile-r: 5deg;
    --scatter-dx: -190px; --scatter-dy: 90px; --scatter-dr: 40deg;
  }
  .hero-float--br .hero-float-drift {
    --pile-x: 36px; --pile-y: 2px; --pile-r: -6deg;
    --scatter-dx: 190px; --scatter-dy: 110px; --scatter-dr: -45deg;
  }

  /* Room for the pile below the CTA — it would otherwise sit on top of
     the button, since the hero's default bottom padding was only ever
     sized for the "Free to start" note beneath it. */
  .hero { padding-bottom: 250px; }
}

@media (max-width: 460px) {
  .hero-float { width: 128px; }
}

/* ===================== STATS ===================== */
/* Three self-contained cards, same white-surface-on-canvas language as
   the case-study cards and feature rows, instead of three columns
   sharing one strip with hairline dividers between them. One accent
   color throughout (no per-card rotation — this row makes one quiet
   claim three times, not three different claims), and the number reads
   as part of the sentence around it rather than a giant standalone
   figure with a caption underneath: "38% fewer status-update messages"
   is one thought, not a number and a label that happen to be stacked. */
.stats {
  padding: 56px 24px;
  margin-top: 96px;
}

.stats-grid {
  max-width: var(--max-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.stat {
  text-align: center;
  background: var(--surface);
  border-radius: var(--radius-squircle);
  padding: 32px 28px;
}

.stat-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 16px;
  background: var(--accent-light);
  color: var(--accent);
}
.stat-icon svg { width: 20px; height: 20px; }

.stat-text {
  font-size: 18px;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.45;
  letter-spacing: -0.005em;
  max-width: 260px;
  margin: 0 auto;
}

.stat-number {
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent);
}

/* ===================== FEATURES ===================== */
/* Four rows, each pinned in turn as you scroll through it, taking over
   almost the full screen — not four flat blocks going by in normal
   flow. Each .feature-row sits inside a tall .feature-sticky wrapper
   (position: sticky needs that extra height to have somewhere to hold
   the row while you scroll); once the wrapper's own height runs out,
   the row unpins and the next .feature-sticky's row — already sitting
   right below in normal flow — slides up and, being later in paint
   order, covers it. No JS: this is the standard sticky-stack recipe,
   the same mechanism the nav's own position: sticky uses, just given
   room to "hold" instead of sticking at a single point. */

.features {
  /* Was a wider, one-off 1240px — pulled the feature rows' outer edges
     past every other section's content edge. Same fix as .nav-inner and
     .case-studies: var(--max-w) plus this section's own 24px padding, so
     the cards line up with the nav, stats band, case studies and footer
     above and below them instead of overhanging. */
  max-width: calc(var(--max-w) + 48px);
  margin: 0 auto;
  padding: 96px 24px 0;
}

/* Extra height beyond the row's own — the difference is how long the
   row stays pinned before the next one starts covering it. 180vh held
   for nearly a full extra screen of scrolling with nothing visibly
   happening; cut down so covering the card takes a shorter, snappier
   scroll instead of feeling stuck. */
.feature-sticky {
  position: relative;
  height: 132vh;
}

.feature-row {
  position: sticky;
  /* Clears the now-floating nav's own bottom edge (16px top inset + 60px
     tall, so ~76px) with real breathing room, in px rather than vh so it
     holds steady regardless of viewport height — a vh value here would
     drift the row under/over the nav as that height changes. */
  top: 108px;
  display: flex;
  align-items: stretch;
  /* No gap — the text card and the video sit flush, reading as one
     block instead of two. Each keeps a rounded outer edge only; the
     seam between them is square (see .feature-content/.feature-frame). */
  gap: 0;
  min-height: 80vh;
  box-shadow: 0 28px 56px -16px rgba(46, 44, 39, 0.22);
}

.feature-sticky:nth-of-type(1) .feature-row { z-index: 1; }
.feature-sticky:nth-of-type(2) .feature-row { z-index: 2; }
.feature-sticky:nth-of-type(3) .feature-row { z-index: 3; }
.feature-sticky:nth-of-type(4) .feature-row { z-index: 4; }

/* A real gap, not just a different sticky offset: staggering each row's
   own `top` doesn't actually separate them, because by the time a later
   row reaches its sticky point the one before it has already unstuck
   and scrolled away — there's a whole stretch in between where both are
   just in normal flow, one directly under the other with nothing to
   keep them apart. This margin is what shows during exactly that
   stretch, so the cards never actually touch as the next climbs up over
   the last. */
.feature-sticky:not(:first-of-type) .feature-row {
  margin-top: 32px;
}

.feature-row--reverse { flex-direction: row-reverse; }

.feature-content {
  /* flex-grow ratio, not a percentage width — stays exactly 2:3 against
     .feature-media regardless of the row's gap. */
  flex: 2 1 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--surface);
  /* Rounded on the outer side only — the seam against .feature-media
     stays square. Flipped for reversed rows, where content sits on the
     right instead of the left. */
  border-radius: var(--radius-squircle) 0 0 var(--radius-squircle);
  padding: 48px 44px;
}

.feature-row--reverse .feature-content {
  border-radius: 0 var(--radius-squircle) var(--radius-squircle) 0;
}

.feature-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-lg);
  background: var(--feature-accent-light, var(--accent-light));
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
}
.feature-icon svg { width: 22px; height: 22px; color: var(--feature-accent, var(--accent)); }

/* The exact icon hover-nudge the real app uses on its nav tabs: a single
   quick rotate-and-settle, not a loop, on the icon glyph itself rather
   than a size change on the tile around it. Fires when hovering
   anywhere on the card (not just the icon), and again on each small tag
   glyph when hovering that specific tag. */
@keyframes icon-nudge {
  0%   { transform: rotate(0deg); }
  50%  { transform: rotate(-10deg); }
  100% { transform: rotate(0deg); }
}

.feature-content:hover .feature-icon svg,
.feature-tag:hover svg {
  animation: icon-nudge 0.3s var(--ease-out) 1;
}

.feature-title {
  font-family: var(--font);
  font-size: clamp(24px, 2.4vw, 30px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--text-primary);
  margin: 0 0 12px;
}

.feature-desc {
  font-size: 15.5px;
  font-weight: 400;
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0;
  letter-spacing: -0.005em;
}

.feature-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
}
.feature-tag {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text-primary);
  /* Now sitting on .feature-content's own white card instead of the
     page canvas, so the tag needs the canvas's grey to read as a tag
     rather than disappear into the card behind it. */
  background: var(--bg);
  padding: 6px 11px 6px 8px;
  border-radius: 999px;
  white-space: nowrap;
  cursor: default;
}
.feature-tag svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--feature-accent, var(--accent)); }

/* A small preview popover on each tag — makes good on the claim right
   there instead of asking the visitor to trust three words. Floating
   overlay, not a resting card, so unlike the rest of the page's cards
   this one earns a real shadow: it needs to read as sitting above the
   page, the one place on this page that's actually true. */
.feature-tag-preview {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: 250px;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 14px 16px;
  text-align: left;
  white-space: normal;
  font-weight: 400;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s var(--ease-out), transform 0.15s var(--ease-out), visibility 0.15s;
  z-index: 20;
}

.feature-tag-preview::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 10px;
  height: 10px;
  background: var(--surface);
  border-radius: 0 0 2px 0;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}

.feature-tag:hover .feature-tag-preview {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}

.feature-tag-preview-desc {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.feature-tag-preview-notif {
  display: flex;
  align-items: flex-start;
  gap: 9px;
}
.feature-tag-preview-notif svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; color: var(--feature-accent, var(--accent)); }
.feature-tag-preview-notif span {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--text-primary);
}

.feature-tag-preview-quote {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--text-primary);
}

.feature-tag-preview-person {
  display: flex;
  align-items: center;
  gap: 9px;
}
.feature-tag-preview-person img { width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; }
.feature-tag-preview-person span { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.feature-tag-preview-name { font-size: 12px; font-weight: 600; color: var(--text-primary); }
.feature-tag-preview-role { font-size: 11px; color: var(--text-tertiary); }

.feature-media {
  flex: 3 1 0;
  display: flex;
}

.feature-frame {
  position: relative;
  width: 100%;
  /* Fills the row's full height (see .feature-row's min-height) rather
     than sizing itself off the video's own aspect ratio — at this
     height an aspect-ratio box would end up far short of the row,
     leaving the frame looking small inside its own card. object-fit:
     cover on the video crops to fill whatever height that ends up
     being. */
  height: 100%;
  background: var(--surface);
  /* Rounded on the outer side only, mirroring .feature-content, so the
     two meet with a flush, square seam instead of two separate rounded
     rectangles with a gap between them. Plain CSS radius rather than
     CornerKit here (no .squircle class) — its clip-path is uniform on
     all four corners, so it can't produce this two-sided treatment. */
  border-radius: 0 var(--radius-squircle) var(--radius-squircle) 0;
  overflow: hidden;
}

.feature-row--reverse .feature-frame {
  border-radius: var(--radius-squircle) 0 0 var(--radius-squircle);
}

.feature-video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Orange only marks the one panel about something needing attention;
   green only the one panel about a good outcome. Every other feature
   stays on the page's own default accent, blue. */
.feature-row--orange { --feature-accent: var(--orange); --feature-accent-light: var(--orange-light); }
.feature-row--green  { --feature-accent: var(--green);  --feature-accent-light: var(--green-light); }

.feature-deepdive {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 24px 0 0;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--feature-accent, var(--accent));
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}
.feature-deepdive svg { width: 14px; height: 14px; transition: transform 0.2s var(--ease-out); }
.feature-deepdive:hover svg { transform: translateX(3px); }

/* ===================== DEEP DIVE MODAL ===================== */
/* One shared dialog for all four feature rows. Opening it copies the
   row's own --feature-accent onto the overlay (see index.html script),
   so the icon tint and active tab match whichever block was opened.
   Content per tag comes straight from that tag's own markup — icon,
   label, and data-deep-body — so there is nothing to keep in sync. */

.deepdive-overlay {
  position: fixed;
  inset: 0;
  background: rgba(30, 26, 20, 0.44);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 200;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s var(--ease-out), visibility 0.25s;
}

.deepdive-overlay.is-open {
  opacity: 1;
  visibility: visible;
}

.deepdive-modal {
  position: relative;
  width: 100%;
  max-width: 460px;
  /* Fixed height regardless of which tag's body copy is showing, so
     switching tabs never resizes the card — only the body text scrolls
     internally on the rare copy long enough to need it. */
  height: min(480px, calc(100vh - 48px));
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--radius-squircle);
  box-shadow: 0 24px 60px rgba(20,18,14,0.22);
  padding: 40px 32px 24px;
  transform: translateY(12px) scale(0.98);
  transition: transform 0.25s var(--ease-out);
}

.deepdive-overlay.is-open .deepdive-modal {
  transform: translateY(0) scale(1);
}

.deepdive-close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: var(--bg);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.deepdive-close svg { width: 14px; height: 14px; }
.deepdive-close:hover { background: var(--border-mid); color: var(--text-primary); }

/* The scrollable, sliding region — icon, title and body swap together as
   one unit, travelling the same direction the tab indicator just did
   (see the JS): sliding out toward the newly-picked tab, swapping text,
   then sliding back in from the opposite side — instead of just fading
   in place out of sync with the indicator's horizontal motion. */
.deepdive-content {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  transition: opacity 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}

.deepdive-content.is-exit-forward { opacity: 0; transform: translateX(-16px); }
.deepdive-content.is-exit-back    { opacity: 0; transform: translateX(16px); }

/* Snapped into the entry position with no transition, then that class is
   removed a frame later (see showTab) so the element animates back to
   rest via the base transition above — a slide-in rather than a fade. */
.deepdive-content.is-enter-forward { opacity: 0; transform: translateX(16px); transition: none; }
.deepdive-content.is-enter-back    { opacity: 0; transform: translateX(-16px); transition: none; }

.deepdive-icon {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--radius-lg);
  background: var(--feature-accent-light, var(--accent-light));
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 20px;
}
.deepdive-icon svg { width: 24px; height: 24px; color: var(--feature-accent, var(--accent)); }

.deepdive-title {
  flex-shrink: 0;
  font-family: var(--font);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.25;
  color: var(--text-primary);
  margin: 0 0 12px;
}

.deepdive-body {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: -0.005em;
  color: var(--text-secondary);
  margin: 0;
}

@media (prefers-reduced-motion: reduce) {
  .deepdive-content { transition: opacity 0.15s ease; }
  .deepdive-content.is-exit-forward,
  .deepdive-content.is-exit-back,
  .deepdive-content.is-enter-forward,
  .deepdive-content.is-enter-back { transform: none; }
}

/* One bar, one shared highlight sliding behind whichever tab is active —
   the same pattern the real app's own sidebar uses (updateMenuTabIndicator
   in its app.js, positioned via inline transform/width instead of each
   button drawing its own flat background). */
.deepdive-tabs {
  position: relative;
  flex-shrink: 0;
  display: flex;
  gap: 2px;
  margin-top: 18px;
  padding: 4px;
  background: var(--bg);
  border-radius: var(--radius-lg);
}

.deepdive-tab-indicator {
  position: absolute;
  top: 4px;
  left: 0;
  height: calc(100% - 8px);
  width: 0;
  border-radius: var(--radius-md);
  background: var(--feature-accent, var(--accent));
  opacity: 0;
  z-index: 0;
  pointer-events: none;
  transition: transform 0.45s var(--ease-out), width 0.45s var(--ease-out), opacity 0.25s ease;
}

.deepdive-tab {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 4px;
  border-radius: var(--radius-md);
  border: none;
  background: none;
  color: var(--text-tertiary);
  cursor: pointer;
  transition: color 0.3s var(--ease-out);
}
.deepdive-tab svg { width: 18px; height: 18px; }
.deepdive-tab span {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  text-align: center;
  line-height: 1.25;
}
.deepdive-tab:hover { color: var(--text-primary); }
.deepdive-tab.is-active { color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .deepdive-tab-indicator { transition: opacity 0.2s ease; }
}

/* ===================== CASE STUDIES ===================== */
/* A deeper, one-story-per-client version of the same proof already
   given lightly in the testimonials wall below — same three people,
   this time with the metric they moved and how. */

.case-studies {
  /* Same content-edge fix as .nav-inner above — this section's own 24px
     side padding would otherwise pull its cards 24px in from the stats
     band and footer's content edge. */
  max-width: calc(var(--max-w) + 48px);
  margin: 0 auto;
  padding: 128px 24px 0;
}

.case-studies-head {
  max-width: 560px;
  margin: 0 auto 48px;
  text-align: center;
}

.case-studies-title {
  font-family: var(--font);
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--text-primary);
  margin: 0;
}

.case-studies-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.case-study-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: none;
  border-radius: var(--radius-squircle);
  padding: 34px 30px 30px;
  font-family: inherit;
  cursor: pointer;
  transition: transform 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out);
}

.case-study-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}

/* Every other card on the page (feature rows, stats) pairs its number
   with a colored icon badge — this was the one card type with nothing
   but text, which is most of why it read as plain next to them. Same
   badge language here, rotating blue/green/orange like the feature
   rows do, tying the metric's color through the icon, the number and
   nothing else. */
.case-study-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-light);
  color: var(--accent);
  margin-bottom: 18px;
}
.case-study-icon svg { width: 19px; height: 19px; }

.case-study-card--green .case-study-icon   { background: var(--green-light);  color: var(--green); }
.case-study-card--orange .case-study-icon  { background: var(--orange-light); color: var(--orange); }

/* A quiet byline now that the icon carries the card's top-of-frame
   weight, not a bold label competing with the metric right below it. */
.case-study-logo {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 10px;
}

/* Same idea as .stat-text: the number reads as part of the sentence
   around it — "−38% status-update messages" is one claim, not a big
   standalone figure sitting over an unrelated-looking caption. */
.case-study-metric {
  font-size: 17px;
  font-weight: 500;
  color: var(--text-primary);
  line-height: 1.4;
  letter-spacing: -0.005em;
  margin-bottom: 20px;
}

.case-study-metric-value {
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent);
}

.case-study-card--green .case-study-metric-value  { color: var(--green); }
.case-study-card--orange .case-study-metric-value { color: var(--orange); }

/* A hairline rather than just margin — separates the headline metric
   from the supporting sentence instead of letting the two runs of grey
   text blur into each other. */
.case-study-divider {
  display: block;
  width: 100%;
  height: 1px;
  background: var(--border);
  margin: 0 0 20px;
}

.case-study-teaser {
  font-size: 14.5px;
  color: var(--text-secondary);
  line-height: 1.55;
  margin-bottom: 24px;
}

.case-study-cta {
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
}
.case-study-card--green .case-study-cta  { color: var(--green); }
.case-study-card--orange .case-study-cta { color: var(--orange); }
.case-study-cta svg { width: 14px; height: 14px; transition: transform 0.2s var(--ease-out); }
.case-study-card:hover .case-study-cta svg { transform: translateX(3px); }

/* ===================== CASE STUDY MODAL ===================== */

.case-study-overlay {
  position: fixed;
  inset: 0;
  background: rgba(30, 26, 20, 0.44);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 200;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s var(--ease-out), visibility 0.25s;
}

.case-study-overlay.is-open {
  opacity: 1;
  visibility: visible;
}

.case-study-modal {
  position: relative;
  width: 100%;
  max-width: 520px;
  /* Fixed height regardless of which case's copy is showing (bodies and
     quotes vary in length) — only the content area scrolls internally,
     so switching tabs never resizes the card. Same approach as the
     deep-dive modal. */
  height: min(600px, calc(100vh - 48px));
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--radius-squircle);
  box-shadow: 0 24px 60px rgba(20,18,14,0.22);
  padding: 44px 40px 36px;
  transform: translateY(12px) scale(0.98);
  transition: transform 0.25s var(--ease-out);
}

.case-study-overlay.is-open .case-study-modal {
  transform: translateY(0) scale(1);
}

.case-study-close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: var(--bg);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.case-study-close svg { width: 14px; height: 14px; }
.case-study-close:hover { background: var(--border-mid); color: var(--text-primary); }

/* The scrollable, sliding region — logo, metric, body and quote swap
   together as one unit, travelling the same direction the tab
   indicator below just did (see the JS), the same cross-fade-and-slide
   treatment the deep-dive modal uses for its own tab switches. */
.case-study-modal-content {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  transition: opacity 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}

.case-study-modal-content.is-exit-forward { opacity: 0; transform: translateX(-16px); }
.case-study-modal-content.is-exit-back    { opacity: 0; transform: translateX(16px); }
.case-study-modal-content.is-enter-forward { opacity: 0; transform: translateX(16px); transition: none; }
.case-study-modal-content.is-enter-back    { opacity: 0; transform: translateX(-16px); transition: none; }

@media (prefers-reduced-motion: reduce) {
  .case-study-modal-content { transition: opacity 0.15s ease; }
  .case-study-modal-content.is-exit-forward,
  .case-study-modal-content.is-exit-back,
  .case-study-modal-content.is-enter-forward,
  .case-study-modal-content.is-enter-back { transform: none; }
}

.case-study-modal-logo {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text-tertiary);
  margin-bottom: 20px;
}

.case-study-modal-metric {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}

.case-study-modal-metric-value {
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
  font-size: clamp(34px, 4vw, 44px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent);
}

.case-study-modal-metric-label {
  font-size: 14px;
  color: var(--text-secondary);
  max-width: 220px;
  line-height: 1.4;
}

.case-study-modal-body {
  font-size: 15px;
  line-height: 1.65;
  color: var(--text-secondary);
  letter-spacing: -0.005em;
  margin: 0 0 28px;
}

/* A real pull-quote instead of a grey box with typed quotation marks
   lost inside the paragraph: one oversized quote glyph as a watermark,
   set behind the text rather than inline with it, does the job of
   marking "this is a quote" far more clearly than a pair of small "
   characters ever could at this size. */
.case-study-modal-quote {
  position: relative;
  background: var(--bg);
  border-radius: var(--radius-lg);
  padding: 34px 24px 22px;
  overflow: hidden;
}

.case-study-modal-quote::before {
  content: "\201C";
  position: absolute;
  top: -20px;
  left: 14px;
  font-family: var(--font-display);
  font-size: 92px;
  font-weight: 700;
  line-height: 1;
  color: var(--accent);
  opacity: 0.13;
  pointer-events: none;
}

.case-study-modal-quote-text {
  position: relative;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.55;
  color: var(--text-primary);
  letter-spacing: -0.005em;
  margin: 0 0 16px;
}

.case-study-modal-person {
  display: flex;
  align-items: center;
  gap: 12px;
}
.case-study-modal-avatar { width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; }
.case-study-modal-person span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.case-study-modal-name { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.case-study-modal-role { font-size: 12.5px; color: var(--text-secondary); }

/* One bar, one shared highlight sliding behind whichever case is
   active — lets a visitor flip through all three stories without
   closing and reopening the modal. Same sliding-indicator pattern as
   the deep-dive modal's own tab bar. */
.case-study-tabs {
  position: relative;
  flex-shrink: 0;
  display: flex;
  gap: 2px;
  margin-top: 22px;
  padding: 4px;
  background: var(--bg);
  border-radius: var(--radius-lg);
}

.case-study-tab-indicator {
  position: absolute;
  top: 4px;
  left: 0;
  height: calc(100% - 8px);
  width: 0;
  border-radius: var(--radius-md);
  background: var(--accent);
  opacity: 0;
  z-index: 0;
  pointer-events: none;
  transition: transform 0.45s var(--ease-out), width 0.45s var(--ease-out), opacity 0.25s ease;
}

.case-study-tab {
  position: relative;
  z-index: 1;
  flex: 1;
  min-width: 0;
  padding: 10px 6px;
  border-radius: var(--radius-md);
  border: none;
  background: none;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text-tertiary);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.3s var(--ease-out);
}
.case-study-tab:hover { color: var(--text-primary); }
.case-study-tab.is-active { color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .case-study-tab-indicator { transition: opacity 0.2s ease; }
}

/* ===================== TESTIMONIALS ===================== */

.testimonials {
  margin-top: 140px;
  padding: var(--section-gap) 24px;
}

.testimonials-head {
  max-width: 560px;
  margin: 0 auto 48px;
  text-align: center;
}

.section-tag {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--clay);
  margin: 0 0 16px;
}

.testimonials-title {
  font-family: var(--font);
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--text-primary);
  margin: 0;
}

/* Two rows of cards scrolling in opposite directions, each a doubled
   track (see index.html — the second half is aria-hidden) so the loop
   is seamless: at -50% translateX the track is back where it started,
   pixel for pixel. Row 2 is nudged half a card left so the two rows
   read as a staggered checkerboard rather than two aligned columns. */
.testimonials-marquee {
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
}

.testimonials-track {
  display: flex;
  gap: 20px;
  width: max-content;
  animation: testimonials-scroll 56s linear infinite;
}

.testimonials-track--row2 {
  animation-direction: reverse;
  margin-left: -200px;
}

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

@keyframes testimonials-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .testimonials-track { animation: none; }
  .testimonials-marquee { overflow-x: auto; }
}

.testimonial-card {
  margin: 0;
  flex: 0 0 380px;
  width: 380px;
  background: var(--surface);
  border-radius: var(--radius-squircle);
  padding: 36px 32px;
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.testimonial-quote {
  font-size: 15.5px;
  font-weight: 500;
  line-height: 1.55;
  letter-spacing: -0.005em;
  color: var(--text-primary);
  margin: 0;
}

.testimonial-person {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: auto;
}

.testimonial-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px var(--border);
}

.testimonial-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.testimonial-name { font-size: 14px; font-weight: 600; color: var(--text-primary); letter-spacing: -0.005em; }
.testimonial-role { font-size: 12.5px; color: var(--text-secondary); }

/* ===================== CLOSING CTA ===================== */

/* The one deliberately inverted block on the page — a rounded dark card
   inset in the same content column as the nav/stats/footer (--max-w),
   not a full-bleed band. A gradient fade from the warm canvas into ink
   was tried here first and reliably came out muddy — interpolating
   between those two hex values crosses a dirty olive-brown midtone no
   matter how it's tuned, since they're a warm light and a warm dark with
   nothing clean between them. Rounded corners + a shadow sidestep that
   completely: no blended color at all, just the same card language
   already used everywhere else on the page (feature rows, case studies,
   value cards), inverted. Homepage-only: the inner pages don't repeat
   this closing pitch — the nav's own Sign in/Get started stays the one
   conversion path there, rather than a second copy of it per page. */
.closing {
  position: relative;
  text-align: center;
  max-width: var(--max-w);
  margin: 96px auto 0;
  padding: var(--section-gap) 24px;
  background: var(--text-primary);
  border-radius: 40px;
  box-shadow: var(--shadow-md);
}

/* Same words as the hero, so it gets the hero's own display face too —
   a deliberate bookend rather than the plain sans every other heading
   below the hero uses. */
.closing-title {
  font-family: var(--font-display);
  font-size: clamp(28px, 4vw, 46px);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.15;
  color: #fff;
  margin: 0 auto 16px;
  max-width: 680px;
}

.closing-title .text-accent { color: color-mix(in srgb, var(--clay) 55%, white); }

.closing-sub {
  font-size: clamp(15px, 1.8vw, 17px);
  font-weight: 400;
  color: rgba(255,255,255,0.66);
  line-height: 1.55;
  margin: 0 auto 32px;
  max-width: 460px;
  letter-spacing: -0.005em;
}

.closing .hero-cta-note { color: rgba(255,255,255,0.4); }

.hero-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* ===================== FOOTER ===================== */
/* Bigger logo, more columns, and a huge, barely-there mark bleeding off
   the edge — the kind of quiet weight a footer needs to read as a real,
   established company instead of a thin sign-off strip. */

/* No top border — .closing's own gradient already fades into this exact
   --bg-alt right above it, so the seam is the color itself, not a line. */
.footer {
  position: relative;
  overflow: hidden;
  background: var(--bg-alt);
  padding: 104px 48px 40px;
}

.footer-watermark {
  position: absolute;
  top: 50%;
  right: -60px;
  transform: translateY(-50%);
  width: 420px;
  height: auto;
  opacity: 0.035;
  pointer-events: none;
  user-select: none;
}

.footer-top {
  position: relative;
  display: flex;
  justify-content: space-between;
  gap: 48px;
  flex-wrap: wrap;
  padding-bottom: 56px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 32px;
  max-width: var(--max-w);
  margin-left: auto;
  margin-right: auto;
}

.footer-brand { max-width: 300px; flex-shrink: 0; }

.footer-logo { display: block; }
.footer-logo-mark { display: block; }

.footer-tagline {
  font-size: 14.5px;
  color: var(--text-secondary);
  line-height: 1.6;
  letter-spacing: -0.005em;
  margin: 22px 0 0;
}

.footer-cols { display: flex; gap: 56px; flex-wrap: wrap; }

.footer-col { display: flex; flex-direction: column; gap: 13px; min-width: 130px; }

.footer-col-title {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-tertiary);
  margin: 0 0 3px;
}

.footer-link { font-size: 14px; font-weight: 400; color: var(--text-secondary); text-decoration: none; letter-spacing: -0.005em; transition: color 0.12s; }
.footer-link:hover { color: var(--clay); }

.footer-bottom {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  max-width: var(--max-w);
  margin: 0 auto;
}

.footer-copy { font-size: 12px; color: var(--text-tertiary); margin: 0; }

@media (max-width: 680px) {
  /* .nav's own floating-pill treatment already applies at every width;
     just a tighter shadow and inner padding at phone width, where the
     16px floor from .nav's width calc is snugger against the edges. */
  .nav.is-scrolled { box-shadow: var(--shadow-md); }

  .nav-inner { padding: 0 16px; }
  /* Sign in + Get started don't have room to sit comfortably in the
     compact bar at this width — replaced by a single hamburger button
     that opens .nav-mobile-menu, which carries both of them again
     (full-width, at the bottom of the panel) plus the full link list. */
  .nav-actions { display: none; }
  .nav-burger { display: block; }
  .footer { padding: 72px 24px 28px; }
  .footer-watermark { width: 220px; right: -70px; opacity: 0.03; }
  .footer-top { flex-direction: column; gap: 32px; }
  .footer-cols { gap: 32px; }
}

@media (max-width: 680px) {
  .hero { padding: 56px 24px 250px; }

  .stats { margin-top: 64px; padding: 40px 24px; }
  .stats-grid { grid-template-columns: 1fr; gap: 16px; }

  .features { padding: 64px 24px 0; gap: 56px; }
  .feature-row,
  .feature-row--reverse { flex-direction: column; gap: 16px; min-height: 0; }
  /* Stacked with a real gap again (see .feature-row above), so both
     pieces go back to being fully rounded on their own instead of the
     desktop's flush, one-sided treatment. */
  .feature-content { flex: none; width: 100%; padding: 32px 28px; }
  /* Same specificity as the desktop-only .feature-row--reverse selectors
     (two classes each) so these actually win at this breakpoint instead
     of losing to them on the cascade despite coming later in the file. */
  .feature-content,
  .feature-row--reverse .feature-content { border-radius: var(--radius-2xl); }
  .feature-media { flex: none; width: 100%; }
  /* Stacked, .feature-row no longer has a 75vh floor to stretch against,
     so the frame goes back to sizing off the video's own aspect ratio
     instead of a now-undefined 100% of its parent's height. */
  .feature-frame,
  .feature-row--reverse .feature-frame { height: auto; aspect-ratio: 2200 / 1078; border-radius: var(--radius-2xl); }
  /* Hover has no real equivalent on touch, and there's not enough
     horizontal room to float a 250px card off a wrapped tag row anyway. */
  .feature-tag-preview { display: none; }

  .deepdive-modal { height: min(440px, calc(100vh - 48px)); padding: 32px 22px 20px; border-radius: var(--radius-2xl); }
  .deepdive-tabs { gap: 2px; }
  .deepdive-tab span { font-size: 10px; }

  .case-studies { padding: 88px 24px 0; }
  .case-studies-head { margin-bottom: 32px; }
  .case-studies-grid { grid-template-columns: 1fr; gap: 16px; }
  .case-study-card { padding: 28px 26px; border-radius: var(--radius-2xl); }
  .case-study-modal { height: min(560px, calc(100vh - 48px)); padding: 32px 26px 28px; border-radius: var(--radius-2xl); }
  .case-study-tab { font-size: 11.5px; }

  .testimonials { margin-top: 72px; padding: 64px 24px; }
  .testimonials-head { margin-bottom: 32px; }
  .testimonials-marquee { gap: 14px; }
  .testimonials-track { gap: 14px; }
  .testimonials-track--row2 { margin-left: -140px; }
  .testimonial-card { flex-basis: 270px; width: 270px; border-radius: var(--radius-2xl); padding: 26px 24px; }
}
/* ===================== INNER PAGES ===================== */
/* Shared building blocks for the standalone pages (About, Careers,
   Terms, Privacy, and the three "for X" segment pages) — same tokens
   and rhythm as the homepage, without the video-heavy hero. */

.page-hero {
  text-align: center;
  padding: 96px 24px 64px;
  max-width: 760px;
  margin: 0 auto;
}

.page-title {
  font-family: var(--font-display);
  font-size: clamp(36px, 5.2vw, 60px);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.1;
  color: var(--text-primary);
  margin: 0 0 20px;
}

.page-sub {
  font-size: clamp(16px, 2vw, 19px);
  font-weight: 400;
  color: var(--text-secondary);
  line-height: 1.55;
  max-width: 600px;
  margin: 0 auto;
  letter-spacing: -0.005em;
}

.section-tag--blue   { color: var(--accent); }
.section-tag--green  { color: var(--green); }
.section-tag--orange { color: var(--orange); }

/* Legal-page prose */
.prose { max-width: 700px; margin: 0 auto; padding: 0 24px 120px; }
.prose-meta { font-size: 13px; color: var(--text-tertiary); margin: -32px 0 44px; text-align: center; }
.prose h2 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  margin: 44px 0 14px;
}
.prose h2:first-of-type { margin-top: 0; }
.prose p { font-size: 15.5px; line-height: 1.7; color: var(--text-secondary); margin: 0 0 16px; letter-spacing: -0.003em; }
.prose ul { margin: 0 0 16px; padding-left: 22px; }
.prose li { font-size: 15.5px; line-height: 1.7; color: var(--text-secondary); margin-bottom: 8px; }
.prose strong { color: var(--text-primary); font-weight: 600; }

/* Value / benefit cards — About, Careers culture blurbs, segment pages */
.value-grid {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 24px 110px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.value-card {
  background: var(--surface);
  border-radius: var(--radius-squircle);
  padding: 32px 28px;
}

.value-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--clay-light);
  color: var(--clay);
  margin-bottom: 20px;
}
.value-icon svg { width: 20px; height: 20px; }

.value-icon--blue   { background: var(--accent-light); color: var(--accent); }
.value-icon--green  { background: var(--green-light);  color: var(--green); }
.value-icon--orange { background: var(--orange-light); color: var(--orange); }

.value-title { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; color: var(--text-primary); margin: 0 0 8px; }
.value-desc { font-size: 14.5px; line-height: 1.6; color: var(--text-secondary); margin: 0; }

/* Careers: open positions list */
.jobs-section { max-width: 760px; margin: 0 auto; padding: 0 24px 110px; }

.jobs-title {
  font-family: var(--font-display);
  font-size: clamp(24px, 3vw, 32px);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  text-align: center;
  margin: 0 0 32px;
}

.jobs-list { display: flex; flex-direction: column; gap: 12px; }

.job-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  background: var(--surface);
  /* Flat, no border, like every other card — the transparent 1px border
     just reserves the same box a hover state's real border would take,
     so nothing shifts when it appears. */
  border: 1px solid transparent;
  border-radius: var(--radius-2xl);
  padding: 22px 26px;
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.job-card:hover { border-color: var(--border-mid); box-shadow: var(--shadow-sm); }

.job-info { display: flex; flex-direction: column; gap: 5px; }
.job-title { font-size: 16px; font-weight: 600; color: var(--text-primary); letter-spacing: -0.01em; }
.job-meta { font-size: 13.5px; color: var(--text-secondary); }

.job-apply { font-size: 13.5px; font-weight: 600; color: var(--clay); white-space: nowrap; }

/* Segment "program" highlight card — startup/nonprofit/enterprise pages */
.program-card {
  max-width: 720px;
  margin: 0 auto 110px;
  padding: 40px 24px;
}

.program-card-inner {
  background: var(--surface);
  border-radius: var(--radius-squircle);
  padding: 40px;
  text-align: center;
}

.program-title { font-size: 20px; font-weight: 600; color: var(--text-primary); margin: 0 0 10px; letter-spacing: -0.01em; }
.program-desc { font-size: 15px; line-height: 1.6; color: var(--text-secondary); margin: 0 0 24px; max-width: 460px; margin-left: auto; margin-right: auto; }

@media (max-width: 900px) {
  .value-grid { grid-template-columns: 1fr; max-width: 460px; }
}

@media (max-width: 680px) {
  .page-hero { padding: 72px 24px 48px; }
  .job-card { flex-direction: column; align-items: flex-start; gap: 12px; }
  .program-card-inner { padding: 28px; }
}
