/* Inter (variable, 400-600), self-hosted from Google Fonts v20: latin + latin-ext only. */
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(../fonts/inter-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url(../fonts/inter-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: "Inter", system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
  background: #050607;
  color: #e5e5e5;
  -webkit-font-smoothing: antialiased;
}

.hero { position: relative; width: 100%; height: 100vh; min-height: 640px; overflow: hidden; background: #050607; }
.hero-fade {
  position: absolute; inset: 0; z-index: 55;
  background: #050607; opacity: 0; pointer-events: none;
}
#scene {
  position: absolute;
  display: block;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  /* JS sets exact pixel width/height; this is only the pre-script fallback */
}

/* The spinning logo's own small canvas, always at full screen resolution.
   JS sizes it to the logo and moves it with the scene. */
#logoLayer {
  position: absolute; top: 0; left: 0; display: none;
  pointer-events: none; will-change: transform;
}

/* ---------- Header: edge-to-edge, anchored to the corners ---------- */
header.topbar { position: absolute; top: 0; left: 0; right: 0; z-index: 50; }
/* Side padding is --hero-gutter (see SECTION_PRESETS): one value shared by
   the nav bar, the mobile menu and the headline below, so the logo and the
   headline start on one line. It is separate from the section gutter. */
.topbar-inner { display: flex; align-items: center; justify-content: space-between; padding: 30px var(--hero-gutter); }
.brand { display: flex; align-items: center; gap: 9px; color: #f5f5f5; text-decoration: none; font-weight: 600; font-size: 18px; letter-spacing: -0.01em; }
.brand svg { width: 20px; height: 20px; display: block; }
.brand .dot { color: #e5e5e5; }
nav.menu { display: flex; align-items: center; gap: 30px; }
nav.menu a { color: rgba(229,229,229,0.72); text-decoration: none; font-size: 14px; font-weight: 500; transition: color .15s ease; }
nav.menu a:hover { color: #fff; }
.cta { display: inline-flex; align-items: center; gap: 8px; background: #f5f5f5; color: #0a0a0a; font-size: 14px; font-weight: 600; padding: 9px 16px; border-radius: 10px; text-decoration: none; transition: transform .15s ease, background .15s ease; }
.cta:hover { background: #fff; transform: translateY(-1px); }
.menu-toggle { display: none; }
.menu-toggle .icon-close { display: none; }
.menu-toggle.open .icon-menu { display: none; }
.menu-toggle.open .icon-close { display: block; }

/* ---------- Mobile nav panel (menu-toggle's dropdown) ---------- */
.mobile-menu {
  display: none; flex-direction: column;
  position: absolute; top: 0; left: 0; right: 0; z-index: 45;
  padding: 96px var(--hero-gutter) 24px;
  background: rgba(7,9,8,0.92); backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(255,255,255,0.1);
}
.mobile-menu.open { display: flex; }
.mobile-menu-links { display: flex; flex-direction: column; }
.mobile-menu-links a {
  color: #f5f5f5; text-decoration: none; font-size: 17px; font-weight: 500;
  padding: 14px 2px; border-bottom: 1px solid rgba(255,255,255,0.08);
}
.mobile-menu .cta { justify-content: center; margin-top: 20px; }
@media (min-width: 821px) { .mobile-menu { display: none !important; } }

/* ---------- Headline: anchored to bottom-left corner ---------- */
/* Left/right follow --hero-gutter. The distance up from the bottom edge
   stays the hero's own: it is part of how the scene is composed, not of the
   page's column. */
.tagline { position: absolute; left: 0; bottom: 0; z-index: 40; padding: 0 var(--hero-gutter) 54px; pointer-events: none; }
/* Held back until the load entrance plays; see the hero-enter script in index.html. */
.hero-enter .tagline h1, .hero-enter .tagline p { opacity: 0; }
.tagline h1 {
  margin: 0;
  font-size: clamp(28px, 4.2vw, 52px);
  line-height: 1.04;
  font-weight: 500;
  letter-spacing: -0.025em;
  color: #fafafa;
  max-width: 17ch;
  text-shadow: 0 2px 30px rgba(0,0,0,0.5);
}
.grad {
  background: linear-gradient(90deg, #74e06a 0%, #36c7e0 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.tagline p { margin: 18px 0 0; font-size: clamp(14px, 1.4vw, 17px); line-height: 1.5; font-weight: 400; color: rgba(229,229,229,0.66); max-width: 44ch; }

@media (max-width: 820px) {
  nav.menu, .topbar .cta { display: none; }
  .menu-toggle { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 10px; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.04); color: #f5f5f5; }
}

/* ---------- Control panel ---------- */
#panel {
  position: absolute; top: 122px; right: 18px; z-index: 60;
  width: 248px; max-height: calc(100vh - 150px); overflow-y: auto;
  background: rgba(16,19,18,0.82); backdrop-filter: blur(16px);
  border: 1px solid rgba(255,255,255,0.10); border-radius: 12px;
  padding: 14px 14px 16px; color: #d8dcd8; font-size: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
#panel.hidden { display: none; }
#panel h4 { margin: 14px 0 8px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #9fb89a; }
#panel h4:first-child { margin-top: 0; }
#panel .row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 7px 0; }
#panel .row label { flex: 1; color: rgba(216,220,216,0.85); }
#panel .row .val { width: 30px; text-align: right; color: #fff; font-variant-numeric: tabular-nums; }
#panel input[type=range] { width: 96px; accent-color: #5fc97a; }
#panel input[type=color] { width: 30px; height: 22px; padding: 0; border: 1px solid rgba(255,255,255,0.15); border-radius: 5px; background: none; cursor: pointer; }
#panel input[type=checkbox] { accent-color: #5fc97a; width: 15px; height: 15px; }
#panel .row select[data-cfg] { width: 96px; padding: 2px 4px; border-radius: 5px; }
#panel .btns { display: flex; gap: 7px; margin-top: 12px; }
#panel button { flex: 1; padding: 7px 6px; font-size: 11px; font-weight: 600; border-radius: 7px; cursor: pointer; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.06); color: #e8ece8; }
#panel button:hover { background: rgba(255,255,255,0.12); }
#panel button.primary { background: #5fc97a; color: #08110a; border-color: #5fc97a; }
#panel textarea { width: 100%; height: 54px; margin-top: 10px; resize: vertical; font-family: ui-monospace, Menlo, monospace; font-size: 10px; border-radius: 7px; border: 1px solid rgba(255,255,255,0.12); background: rgba(0,0,0,0.35); color: #cfe; padding: 6px; }
#panel .hint { font-size: 10px; color: rgba(216,220,216,0.45); margin: 4px 0 8px; line-height: 1.4; }
#panel select, #panel input[type=text] {
  width: 100%; padding: 6px 7px; font-size: 11px; border-radius: 7px;
  border: 1px solid rgba(255,255,255,0.14); background: rgba(0,0,0,0.35);
  color: #e8ece8; font-family: inherit;
}
#panel select option, #panel select optgroup { background: #17201a; color: #e8ece8; }
#panel .presets { padding-bottom: 12px; margin-bottom: 4px; border-bottom: 1px solid rgba(255,255,255,0.1); }
#panel .presets .btns { margin-top: 7px; }
#panel button[disabled] { opacity: 0.4; cursor: default; }
#panel button[disabled]:hover { background: rgba(255,255,255,0.06); }

/* ---- Tagline section ---- */
.tagline-section { }
.tagline-track { height: 275vh; position: relative; }
.tagline-sticky {
  /* No z-index on purpose. GSAP pins the sections below this one with
     position:fixed and z-index:auto, so any positive z-index here made this
     box — which is opaque and a full viewport tall — paint over a pinned
     carousel whenever the two overlapped. Left on auto, plain document
     order applies: this paints above the hero before it and below the
     pinned sections after it, which is the order you actually want. */
  position: sticky; top: 0; height: 100vh;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none; background: #050607;
}
.tagline-phrase {
  position: absolute; text-align: center; opacity: 0;
  max-width: 900px; width: 100%; padding: 0 48px; box-sizing: border-box;
}
.tagline-h {
  font-size: clamp(28px, 4.2vw, 52px); font-weight: 500;
  letter-spacing: -0.025em; color: #fafafa; line-height: 1.08; margin: 0 0 18px;
}

/* ---- Sticky reveal section ---- */
.reveals { background: #050607; }
/* No card/tail — just centered text over a plain divider line. The
   divider isn't trying to visually merge into .spine-line below (that
   line only exists once the sticky section engages, a separate
   positioning system entirely); instead .reveals-intro fades out and
   .reveals-spine fades in right at the moment stickiness engages, so
   it's a clean handoff rather than an attempted seamless connection. */
.reveals-intro {
  padding: var(--section-y) var(--gutter) 0;
  opacity: 1;
  transition: opacity 0.4s ease;
}
.reveals-intro.faded { opacity: 0; pointer-events: none; }
.reveals-intro .why-header {
  margin: 0;
  opacity: 0; transform: translateY(28px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveals-intro .why-header.in-view { opacity: 1; transform: translateY(0); }
.reveals-track { height: 600vh; }
.reveals-sticky {
  position: sticky; top: 0; height: 100vh;
  overflow: hidden;
}
/* The scale/dim treatment lives on this inner wrapper, not
   .reveals-sticky itself — a transform on the sticky element changes
   what its own getBoundingClientRect() reports (scale shifts the visual
   box by half the size delta), which broke the top<=0 "is it actually
   stuck" check the scroll handler relies on. Keeping .reveals-sticky
   untransformed keeps that detection accurate. */
.reveals-sticky-inner {
  display: flex; align-items: stretch;
  width: 100%; height: 100%; position: relative;
  border-radius: 4px; overflow: hidden;
  /* --reveal-scale-x is computed in JS from the current viewport width
     so the resulting empty space lands on exactly 80px each side
     (matching .reveals-intro's padding) — a fixed scale() value can't
     do that on its own since it leaves width-proportional space, not a
     fixed px amount, and that proportion changes with viewport width.
     Applied uniformly (one scale() argument) so height shrinks by the
     same factor — proportional, not stretched. */
  transform: scale(var(--reveal-scale-x, 0.95));
  transition: transform 0.4s ease;
  background: black;
}
.reveals-sticky.stuck .reveals-sticky-inner { transform: scale(1); }
/* Dims/mutes the section while it's not yet (or no longer) pinned —
   removed the instant stickiness engages, restored on exit. */
.reveals-sticky-inner::before {
  content: ''; position: absolute; inset: 0; z-index: 1000;
  background: linear-gradient(175deg, rgb(0 20 92 / 61%) 0%, #1482af24 30%, #11241d75 100%);
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.reveals-sticky.stuck .reveals-sticky-inner::before { opacity: 0; }
/* Image on left (order 0), spine in middle (order 1), text on right (order 2) */
.reveals-left {
  width: calc(50% - 1.5px); order: 2;
  display: flex; align-items: center;
  padding: 0 var(--gutter) 0 24px; box-sizing: border-box;
  position: relative;
}
.reveals-spine {
  width: 3px; flex-shrink: 0; position: relative; order: 1;
}
.spine-line {
  position: absolute; left: 50%; top: 64px; bottom: 64px;
  width: 3px; background: rgba(255,255,255,0.12);
  transform: translateX(-50%);
  overflow: hidden;
  border-radius: 1.5px;
}
/* Short glow trail riding behind the dot — travels with it (same `top`),
   sits under it (lower z-index), fades to transparent at both ends. Lives
   inside .spine-line (clipped by its overflow:hidden) so it can never
   poke out past the top/bottom of the track itself, however long it is. */
.spine-trail {
  position: absolute; left: 50%; z-index: 1;
  width: 3px; height: 110px;
  transform: translate(-50%, -50%);
  background: linear-gradient(to bottom, transparent 0%, rgba(96,210,180,0.6) 50%, transparent 100%);
  opacity: 0;
  transition: top 0.45s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease, height 0.2s ease;
  pointer-events: none;
}
.reveals-sticky.stuck .spine-trail { opacity: 1; }
.spine-trail.traveling { height: 60px; }
/* The single dot that actually travels: static markers stay put, one dot
   slides between them via a `top` transition, rather than each marker
   changing size.
   The track (.spine-line) stays visible throughout — only the dot and
   its trail are hidden until stickiness engages. */
.spine-dot {
  position: absolute; left: 50%; z-index: 2;
  width: 20px; height: 20px; border-radius: 50%;
  transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #74e06a 0%, #36c7e0 100%);
  box-shadow: 0 0 10px rgba(96,210,180,0.55);
  font-size: 10px; font-weight: 700; letter-spacing: 0.02em;
  color: #000000; white-space: nowrap;
  font-family: ui-monospace, Menlo, monospace;
  opacity: 0;
  transition: top 0.45s cubic-bezier(0.4, 0, 0.2, 1),
              width 0.2s ease, height 0.2s ease, font-size 0.15s ease, color 0.15s ease,
              opacity 0.4s ease;
}
.reveals-sticky.stuck .spine-dot { opacity: 1; }
/* Tucked in while sliding between steps, expands back with the number
   once it arrives — added/removed off the `top` transition's own
   start/end events, not tied to scroll. */
.spine-dot.traveling {
  width: 10px; height: 10px;
  font-size: 0; color: transparent;
}
.reveals-right {
  width: calc(50% - 1.5px); order: 0;
  position: relative;
}
.reveal-item {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 var(--gutter) 0 64px; box-sizing: border-box;
  opacity: 0; transform: translateY(40px); pointer-events: none;
  transition: opacity 0.6s cubic-bezier(0.4,0,0.2,1),
              transform 0.6s cubic-bezier(0.4,0,0.2,1);
}
.reveal-item.above  { transform: translateY(-30px); opacity: 0; }
.reveal-item.active { opacity: 1; transform: translateY(0); pointer-events: auto; }
.reveal-item h2 {
  font-size: clamp(22px, 2.4vw, 36px); font-weight: 700;
  line-height: 1.2; color: #f0f4ee; margin: 0 0 20px;
}
.reveal-item p {
  font-size: clamp(14px, 1.25vw, 17px); line-height: 1.65;
  color: rgba(210,220,210,0.65); max-width: 44ch; margin: 0;
}
.reveal-visual {
  position: absolute; inset: 0;
  opacity: 0; transform: translateY(40px);
  transition: opacity 1.1s cubic-bezier(0.4,0,0.2,1),
              transform 1.1s cubic-bezier(0.4,0,0.2,1);
}
.reveal-visual.above  { transform: translateY(-30px); opacity: 0; }
.reveal-visual.active { opacity: 1; transform: translateY(0); }
.reveal-placeholder { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.reveal-placeholder img { width: 70%; height: auto; object-fit: contain; }
.reveal-placeholder video { width: 70%; height: auto; object-fit: contain; display: block; }
.reveal-visual[data-i="1"] .reveal-placeholder video { width: 90%; }
/* Stand-in for tiles whose artwork isn't finished yet: layered green
   orb in the same green-to-blue language as the finished tiles. */
.coming-soon {
  position: relative; isolation: isolate;
  width: 70%; aspect-ratio: 1; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; padding: 16%; text-align: center; box-sizing: border-box;
  background:
    radial-gradient(circle at 50% 50%, rgba(5,6,7,0.1) 0 30%, rgba(5,6,7,0.3) 30% 45%, rgba(5,6,7,0.45) 45% 60%, rgba(5,6,7,0.6) 60% 75%, rgba(5,6,7,0.78) 75%),
    linear-gradient(135deg, #2a7a4c 0%, #145a55 40%, #0f3f5c 75%, #0a2440 100%);
  box-shadow: 0 0 120px rgba(63,174,106,0.1), inset 0 0 60px rgba(0,0,0,0.35);
}
.coming-soon::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(116,224,106,0.2), transparent 60%);
  filter: blur(30px); opacity: 0.6;
  animation: coming-soon-pulse 4s ease-in-out infinite;
}
@keyframes coming-soon-pulse { 50% { opacity: 1; transform: scale(1.05); } }
@media (prefers-reduced-motion: reduce) { .coming-soon::before { animation: none; } }
.coming-soon-tag {
  font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: #0a1f14; background: #f2f5f1;
  border-radius: 999px; padding: 8px 16px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.35);
}

/* Step dots — the mobile stand-in for the spine indicator, which needs a
   vertical column of its own that the narrow layout can't spare. */
.reveal-dots { display: none; }

/* Below ~900px the 50/50 image+text split leaves each column too narrow to
   read (padding alone ate most of a phone's width). Instead both columns
   go absolute and stack in Z: the visual runs edge to edge across the top,
   the copy sits over a scrim anchored to the bottom — same shape as the
   .gtm-card treatment, so the two sections read as one visual language. */
@media (max-width: 900px) {
  .reveals-spine { display: none; }
  .reveals-right {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
  }
  /* Percentage insets resolve against the container's own height, so the
     visual holds a fixed share of the screen whatever the device height.
     The artwork is square and the box is portrait, so `contain` always
     leaves slack above and below it — object-position pushes that slack
     upwards so the art sits just above the copy instead of stranding a
     band of dead space between the two. */
  .reveal-placeholder { inset: 0 0 26% 0; }
  .coming-soon { width: min(78%, 46vh); }
  .reveal-placeholder img,
  .reveal-placeholder video,
  .reveal-visual[data-i="1"] .reveal-placeholder video {
    width: 100%; height: 100%; object-fit: contain; object-position: center 74%;
  }
  .reveals-left {
    position: absolute; left: 0; right: 0; bottom: 0; top: auto;
    width: 100%; height: 54%; padding: 0; z-index: 2;
    background: linear-gradient(to top, #050607 0%, rgba(5,6,7,0.94) 42%, rgba(5,6,7,0) 100%);
  }
  /* Horizontal padding follows the shared section gutter (--gutter, set per
     band in SECTION_PRESETS) so the copy lines up with the headings and body
     text of the surrounding sections. The step dots sit exactly one gutter
     up from the bottom edge too, and the copy's bottom padding is gutter +
     32px so it clears the dots by the same amount at every tier. */
  .reveal-item { padding: 0 var(--gutter) calc(var(--gutter) + 32px); justify-content: flex-end; }
  .reveal-item h2 { font-size: clamp(24px, 6.6vw, 32px); margin-bottom: 12px; }
  .reveal-item p { font-size: 15px; line-height: 1.6; color: rgba(210,220,210,0.72); }
  .reveal-dots {
    display: flex; gap: 7px; align-items: center;
    position: absolute; left: var(--gutter); bottom: var(--gutter); z-index: 3;
  }
  .reveal-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: rgba(255,255,255,0.22);
    transition: width 0.4s ease, background 0.4s ease;
  }
  .reveal-dot.on {
    width: 20px; border-radius: 3px;
    background: linear-gradient(90deg, #74e06a 0%, #36c7e0 100%);
  }
}

/* ---- Why section ---- */
/* ---- Why / AI-native section ---- */
.why { background: #050607; }
.why-block { padding: var(--section-y) var(--gutter); }
.why-block > .why-header, .why-block > .why-grid { max-width: 900px; margin-left: auto; margin-right: auto; }
/* ---- Success Stories ---- */
.stories { background: #050607; }
.stories-inner { padding: var(--section-y) var(--gutter); }
.stories-inner .why-header { margin-bottom: var(--header-gap); }
.stories-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px;
}
/* Three-up only while each card stays comfortably wide (~350px+); below
   that the copy wraps too tightly, so drop to two columns / two rows. */
@media (max-width: 1180px) {
  .stories-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .stories-grid { grid-template-columns: minmax(0, 1fr); }
}
.story-card {
  box-sizing: border-box;
  overflow: hidden;
  position: relative;
  /* Portrait at every width: height follows the column width at 4:5, with
     560px as the floor so the copy always has room in narrow columns.
     The explicit width keeps the ratio from deriving width back from that
     floor (560 × 4/5 = 448px), which would overflow narrow columns. */
  width: 100%; aspect-ratio: 4 / 5; min-height: 560px;
  background: #111214;
  border-radius: 4px;
  opacity: 0; transform: translateY(28px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.story-card.in-view { opacity: 1; transform: translateY(0); }
.story-card:nth-child(1) { transition-delay: 0s; }
.story-card:nth-child(2) { transition-delay: 0.18s; }
.story-card:nth-child(3) { transition-delay: 0.36s; }
.story-img {
  position: absolute; top: 0; left: 0; right: 0; height: 80%;
  overflow: hidden;
}
/* Scroll parallax: the image is over-sized vertically by the max travel
   (--story-parallax) on each side and nudged via --py from the scroll
   handler below, so the shift never exposes the card background. The
   travel is tuned for the 415px-wide desktop card; the script scales it
   down per card with its width, halves it again on phones, and rewrites
   --story-parallax to match, so small cards move far less. */
.story-card { --story-parallax: 40px; }
.story-img::after {
  content: ''; position: absolute; bottom: 0; left: 0; right: 0;
  /* Sized as a share of the image (itself 80% of the card) so the fade
     scales with the card: 71% ≈ 320px on the 560px-tall desktop card. */
  height: 71%;
  background: linear-gradient(188deg, transparent 30%, #111214 71%);
}
/* Seam cover. The image is its own GPU layer (will-change below) and the fade
   above is not, so while the card animates in at fractional offsets the two
   round their shared bottom edge differently and a 1px sliver of the photo
   shows as a light line. The fade is already solid there, so a few px of
   the same solid colour over the edge, above the image layer, hides it. */
.story-card::after {
  content: ''; position: absolute; left: 0; right: 0; z-index: 1;
  top: calc(80% - 3px); height: 5px;
  background: #111214; pointer-events: none;
}
.story-card .story-content { z-index: 2; }
.story-img img {
  width: 100%; display: block; object-fit: cover;
  height: calc(100% + var(--story-parallax) * 2);
  margin-top: calc(var(--story-parallax) * -1);
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .story-img img { transform: none; will-change: auto; }
}
.story-img-placeholder {
  width: 100%; height: 100%;
  background: rgba(255,255,255,0.06);
}
.story-overlay { display: none; }
.story-meta-top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  padding: 20px 24px;
}
.story-meta-top-bg {
  position: absolute; inset: 0; height: 120px;
  backdrop-filter: blur(10px);
  background: linear-gradient(to bottom, rgb(0 18 92 / 61%) 0%, rgba(255,255,255,0.01) 100%);
  mask: linear-gradient(to bottom, black 30%, transparent 100%);
}
.story-meta-top .story-meta { position: relative; z-index: 1; margin: 0; }
.gtm-card-bottom {
  position: absolute; bottom: 0; left: 0; right: 0; z-index: 5;
  padding: 28px 36px;
}
.gtm-card-bottom-bg {
  position: absolute; bottom: 0; left: 0; right: 0; height: 180px;
  /* No backdrop-filter, no mask — both removed for scroll performance
     (see .gtm-card .story-meta-top-bg comment below). The "hold solid
     until 30%, then fade" shape the mask used to provide is baked
     straight into the gradient stops instead.
     Grayscale by default; the active card swaps in the tinted version
     below so the colour only shows up on whichever card is highlighted. */
  background: linear-gradient(to top, rgb(22 22 22 / 93%) 0%, rgb(17 17 17 / 79%) 30%, rgba(0, 0, 0, 0) 100%);
}
.gtm-card.active .gtm-card-bottom-bg {
  background: linear-gradient(to top, rgb(7 26 26 / 93%) 0%, rgb(17 17 17 / 79%) 30%, rgba(0, 0, 0, 0) 100%);
}
.gtm-card-bottom-text {
  position: relative; z-index: 1;
  font-size: 16px; font-weight: 500;
  color: rgb(255 255 255 / 77%); margin: 0; line-height: 1.25;
  opacity: 0.55; transition: opacity 0.5s ease;
}
.gtm-card.active .gtm-card-bottom-text { opacity: 1; }
.img-ctrl {
  display: none;
  position: absolute; top: 10px; left: 10px; z-index: 20;
  background: rgba(0,0,0,0.72); backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,0.12);
  padding: 10px 12px; flex-direction: column; gap: 7px;
  border-radius: 6px; min-width: 180px;
}
.img-ctrl-row {
  display: flex; align-items: center; gap: 8px;
}
.img-ctrl-label {
  font-size: 9px; font-weight: 700; letter-spacing: 0.1em;
  color: rgba(255,255,255,0.4); font-family: ui-monospace,Menlo,monospace;
  width: 32px; flex-shrink: 0;
}
.img-ctrl-row input[type=range] {
  flex: 1; accent-color: #74e06a; cursor: pointer;
}
.img-ctrl-val {
  font-size: 9px; color: rgba(255,255,255,0.35);
  font-family: ui-monospace,Menlo,monospace; width: 28px; text-align: right;
}
.img-ctrl-row input[type=checkbox] { accent-color: #74e06a; cursor: pointer; }
.img-ctrl-divider { height: 1px; background: rgba(255,255,255,0.12); margin: 1px 0; }
.img-ctrl-sliders { display: flex; flex-direction: column; gap: 7px; transition: opacity 0.2s ease; }
.img-ctrl.fill-active .img-ctrl-sliders { opacity: 0.35; pointer-events: none; }
/* Debug-only media swap row: load a local video/image into the tile so it
   can be framed with the zoom/left/top sliders below. Client-side only —
   nothing is uploaded and the swap is gone on reload. */
.img-ctrl-btn {
  font-size: 9px; font-weight: 700; letter-spacing: 0.06em;
  font-family: ui-monospace,Menlo,monospace;
  color: rgba(255,255,255,0.75); background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.16); border-radius: 4px;
  padding: 4px 7px; cursor: pointer; line-height: 1;
  max-width: 108px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.img-ctrl-btn:hover { background: rgba(255,255,255,0.16); color: #fff; }
.img-ctrl-btn[hidden] { display: none; }
.img-ctrl.drop-active { border-color: rgba(116,224,106,0.6); box-shadow: 0 0 0 1px rgba(116,224,106,0.35); }
.story-content {
  position: absolute; bottom: 0; left: 0; right: 0;
  padding: 0 40px 40px; box-sizing: border-box;
}
.story-meta {
  display: flex; align-items: center; gap: 12px; margin-bottom: 28px;
}
.story-num {
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  color: #ffffff; font-family: ui-monospace,Menlo,monospace;
}
.story-tag {
  font-size: 12px; font-weight: 600; letter-spacing: 0.08em;
  color: #ffffff; font-family: ui-monospace,Menlo,monospace;
  text-transform: uppercase;
}
.story-title {
  font-size: clamp(24px, 2.4vw, 36px); font-weight: 700;
  color: #f0f4ee; margin: 0 0 20px; line-height: 1.1;
  letter-spacing: -0.02em;
}
.story-result {
  font-size: clamp(16px, 0.5vw + 11px, 18px); font-weight: 700;
  line-height: 1.45; margin: 0 0 20px;
  background: linear-gradient(90deg, #74e06a 0%, #36c7e0 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.story-desc {
  font-size: clamp(15px, 0.35vw + 11px, 16px); line-height: 1.7;
  color: rgba(210,220,210,0.5); margin: 0;
}
.carousel-header {
  padding: 0 var(--gutter); flex-shrink: 0;
}
/* One distance from a section heading to the content under it, shared by
   every section (Results, Why, Services, How we help on mobile, stacked FAQ)
   so they all read the same. Phones get a tighter value below. */
:root { --header-gap: 56px; }
@media (max-width: 640px) { :root { --header-gap: 40px; } }
.why-header {
  font-size: clamp(28px, 4.2vw, 52px); font-weight: 500;
  letter-spacing: -0.025em;
  color: #fafafa; line-height: 1.04; margin: 0 0 18px;
}
.why-header.carousel-header {
  font-size: clamp(24px, 3.6vw, 44px); margin: 0 0 80px;
}
.why-subheader {
  font-size: clamp(16px, 1.6vw, 22px); font-weight: 600;
  line-height: 1.55;
  color: rgba(210,220,210,0.65); max-width: 560px; margin: 0;
}
/* Carousel */
.carousel-track { /* height set by JS */ }
.carousel-sticky {
  /* pinned by GSAP ScrollTrigger (see script), not CSS position:sticky */
  height: 100vh;
  overflow: hidden; display: flex; align-items: center; justify-content: center;
}
.carousel-inner {
  display: flex; flex-direction: column; width: 100%;
}
.carousel-reel {
  display: flex; gap: 24px;
  padding: 0 var(--gutter);
  will-change: transform;
}
.ai-card {
  flex-shrink: 0; width: 500px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.07);
}
.ai-card-body {
  padding: 32px 36px;
  display: flex; flex-direction: row;
  justify-content: space-between; align-items: center;
  gap: 56px; height: 100%; box-sizing: border-box;
}
.ai-card-text { flex: 1; min-width: 0; }
.ai-card-text .why-card-num { margin-bottom: 12px; }
.ai-card-text h3 {
  font-size: clamp(18px, 1.6vw, 24px); font-weight: 700;
  color: #f0f4ee; margin: 0 0 14px; line-height: 1.2;
}
.ai-card-text p {
  font-size: clamp(12px, 1vw, 14px); line-height: 1.7;
  color: rgba(210,220,210,0.5); margin: 0;
}
.ai-card-icon {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  align-self: center;
}
.ai-icon {
  font-size: 64px; display: block; line-height: 1;
  background: linear-gradient(135deg, #74e06a 0%, #36c7e0 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* GTM carousel */
.gtm { background: #050607; }
.gtm-track { }
.gtm-sticky {
  /* pinned by GSAP ScrollTrigger (see script), not CSS position:sticky —
     keeps the pin and the horizontal scrub on the same ticker so there's
     no seam between two independent positioning systems right at the
     moment the section engages/disengages. */
  height: 100vh;
  overflow: hidden; display: flex; align-items: center;
}
/* Same as .svc2-inner: will-change keeps it on its own layer between the
   entry/exit ease tweens instead of being promoted and dropped (a full
   re-raster in Safari) each time. */
.gtm-inner { display: flex; flex-direction: column; width: 100%; will-change: transform; }
.gtm-reel {
  display: flex; gap: 32px; padding: 0 var(--gutter);
  align-items: stretch; will-change: transform;
}
.gtm-header-card {
  flex-shrink: 0; width: 400px; height: 560px;
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 64px 0 0; box-sizing: border-box;
}
.gtm-header-card .why-header { margin: 0 0 20px; }
.gtm-header-mobile, .gtm-intro-mobile { display: none; }
.gtm-intro {
  font-size: clamp(13px, 1.1vw, 16px); line-height: 1.7;
  color: rgba(210,220,210,0.5); margin: 0;
}
.gtm-card {
  flex-shrink: 0; width: 420px; height: 560px;
  background: #000000;
  border-radius: 4px;
  box-sizing: border-box; position: relative; overflow: hidden;
  transition: transform 0.4s ease;
  /* Own layer permanently: otherwise every active-card change promotes the
     card for its scale transition and drops it after, re-rastering the whole
     card (image/video included) both times, mid-scroll. */
  will-change: transform;
}
.gtm-card.active { transform: scale(1.05); z-index: 2; }
.gtm-card-img {
  position: absolute; inset: 0;
}
.gtm-card-placeholder {
  width: 100%; height: 100%; background: rgba(255,255,255,0.05);
}
.gtm-card-dim {
  position: absolute; inset: 0; z-index: 4;
  background: #141414; opacity: 0.8;
  transition: opacity 0.5s ease;
  will-change: opacity; /* fades on the compositor instead of repainting the card each frame */
  pointer-events: none;
}
.gtm-card.active .gtm-card-dim { opacity: 0; }
.gtm-card-img img,
.gtm-card-img video {
  width: 100%; height: 100%; object-fit: cover;
  transform-origin: center; display: block;
  transform: none;
}
.gtm-card .story-content { padding: 0 28px 32px; }
.gtm-card .story-meta {
  display: flex; flex-direction: column; gap: 10px; margin: 0;
  align-items: flex-start; text-align: left;
}
.gtm-card .story-meta-top { padding: 32px 36px; }
.gtm-card .story-meta-top-bg {
  height: 240px;
  /* No backdrop-filter or mask here (unlike the base .story-meta-top-bg)
     — this overlay moves with the horizontally-scrubbed reel, and a live
     backdrop blur has to resample every frame it (or the content behind
     it) moves, which was a major source of scroll jank. A plain gradient
     reads just as legibly without the per-frame cost; the "hold solid
     until 30%, then fade" shape the mask used to provide is baked
     straight into the gradient stops instead. */
  backdrop-filter: none;
  mask: none;
  background: linear-gradient(to bottom, rgb(20 22 20 / 55%) 0%, rgb(20 22 20 / 55%) 30%, rgba(255, 255, 255, 0) 100%);
}
.gtm-card.active .story-meta-top-bg {
  background: linear-gradient(to bottom, rgb(0 14 70 / 80%) 0%, rgb(0 14 70 / 80%) 30%, rgba(255,255,255,0) 100%);
}
.gtm-card-title {
  font-size: clamp(26px, 2.6vw, 36px); font-weight: 700;
  color: #f0f4ee; margin: 0; line-height: 1.1;
  letter-spacing: -0.025em;
  opacity: 0.55; transition: opacity 0.5s ease;
}
.gtm-card.active .gtm-card-title { opacity: 1; }
.gtm-card-subtitle {
  font-size: clamp(15px, 1.35vw, 18px); font-weight: 400;
  color: rgba(255,255,255,0.4); margin: 0; line-height: 1.4;
}
/* Benefits grid */
.why-grid {
  display: flex; flex-direction: column;
  gap: 16px; margin-top: var(--header-gap);
}
.why-card {
  background: linear-gradient(53deg, #ffffff0a 60%, #ffffff0a 100%);
  padding: 36px var(--why-card-pad-right, 130px) 40px 40px;
  border-radius: 4px;
  box-sizing: border-box;
  position: relative;
  opacity: 0.45; transition: opacity 0.4s ease, transform 0.4s ease, background 0.4s ease;
}
.why-card.open {
  opacity: 1; transform: scale(1.05); z-index: 1;
  background: linear-gradient(53deg, #3556d642 0%, #358bd624 30%, #35d6af1c 49%, transparent 80%, transparent 100%);
}
.why-card-icon-wrap {
  position: absolute; top: 50%; right: 18px;
  width: 136px; height: 136px;
  margin-top: -65px; /* half of height — centers vertically regardless of card height */
  pointer-events: none;
  z-index: 2;
  /* isolate so .why-card-icon-tint's mix-blend-mode only blends against
     the icon image inside this box, not the card background/text behind
     it — see makeCenterHighlighter's onChange callback for .why-card,
     which GSAP-animates this wrap (position/scale) and the .why-card-icon
     img (filter) together. Base values here are the JS defaults
     (window.whyIconAnimConfig) restated as plain CSS so the pre-JS/
     first-paint look matches. */
  isolation: isolate;
  transform: scale(0.38);
}
.why-card-icon {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  filter: grayscale(100%) brightness(0%) contrast(60%);
}
/* Optional colour-tint test (toggled from the why-icon debug panel): a
   gradient masked to the icon's own alpha shape, mix-blend-mode'd onto
   just the icon pixels rather than tinting the whole wrap as a square.
   mix-blend-mode: color keeps the BACKDROP's luminance and only takes
   hue/saturation from this layer — against the inactive icon's own
   brightness(0%) filter (pure black, 0 luminance) that blends to black
   regardless of tint colour, so .why-card-icon-tint-backer sits between
   the img and the tint purely to guarantee some non-zero luminance for
   the blend to show against, whatever state the icon filter is in. */
.why-card-icon-tint-backer {
  position: absolute; inset: 0;
  background: rgba(255,255,255,0.55);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.why-card-icon-tint {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, #74e06a 0%, #36c7e0 100%);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  mix-blend-mode: color;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.why-icon-tint-on .why-card-icon-tint-backer,
.why-icon-tint-on .why-card-icon-tint { opacity: 1; }
.why-card-num {
  font-size: 16px; font-weight: 700; letter-spacing: 0.12em;
  color: rgba(255,255,255,0.25); margin-bottom: 16px;
  font-family: ui-monospace, Menlo, monospace;
}
.why-card h3 {
  font-size: clamp(17px, 1.6vw, 24px); font-weight: 700;
  color: #f0f4ee; margin: 0 0 14px; line-height: 1.2;
}
.why-card p {
  font-size: clamp(13px, 1.05vw, 15px); line-height: 1.7;
  color: rgba(210,220,210,0.5); margin: 0;
}
@media (max-width: 640px) {
  .why-card { padding: 32px 24px 32px; }
  /* Icon tucked into the top-right corner instead of stacked above the
     text, so it doesn't add a row of height to every card. The heading
     keeps clear of it; the paragraph below runs full width. */
  .why-card-icon-wrap { top: 8px; right: 8px; width: 88px; height: 88px; margin-top: 0; }
  .why-card h3 { padding-right: 72px; }
}
/* ---- Why icon-animation debug panel (dev tool — see script at the
   bottom for makeCenterHighlighter's why-card wiring). Toggle button
   appears fixed top-right while .why-block is in the viewport. ---- */
.why-debug-toggle {
  position: fixed; top: 20px; right: 20px; z-index: 9999;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(20,22,24,0.9); border: 1px solid rgba(255,255,255,0.15);
  color: #f0f4ee; font-size: 18px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; transform: translateY(-8px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  backdrop-filter: blur(6px);
}
.why-debug-toggle.visible { opacity: 1; pointer-events: auto; transform: translateY(0); }
.why-debug-toggle:hover { background: rgba(255,255,255,0.1); }
.why-debug-panel {
  position: fixed; top: 72px; right: 20px; z-index: 9999;
  width: 300px; max-height: calc(100vh - 100px); overflow-y: auto;
  background: rgba(14,15,17,0.97); border: 1px solid rgba(255,255,255,0.12);
  border-radius: 8px; padding: 16px;
  font-family: ui-monospace, Menlo, monospace; font-size: 11px;
  color: rgba(220,225,220,0.85);
  box-shadow: 0 20px 50px rgba(0,0,0,0.5);
  opacity: 0; pointer-events: none; transform: translateY(-8px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.why-debug-panel.open { opacity: 1; pointer-events: auto; transform: translateY(0); }
.why-debug-panel h4 {
  margin: 16px 0 8px; font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: #74e06a;
}
.why-debug-panel h4:first-child { margin-top: 0; }
.why-debug-row {
  display: flex; align-items: center; gap: 8px; margin-bottom: 6px;
}
.why-debug-row label { flex: 0 0 78px; color: rgba(220,225,220,0.55); }
.why-debug-row input[type="range"] { flex: 1; min-width: 0; }
.why-debug-row input[type="number"] {
  width: 52px; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12);
  color: #f0f4ee; border-radius: 3px; padding: 2px 4px; font: inherit;
}
.why-debug-row select {
  flex: 1; min-width: 0; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.12);
  color: #f0f4ee; border-radius: 3px; padding: 3px 4px; font: inherit;
}
.why-debug-actions { display: flex; gap: 8px; margin-top: 16px; }
.why-debug-actions button {
  flex: 1; padding: 8px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.15);
  background: rgba(255,255,255,0.06); color: #f0f4ee; font: inherit; cursor: pointer;
}
.why-debug-actions button:hover { background: rgba(255,255,255,0.12); }
.why-debug-actions button.primary { background: rgba(116,224,106,0.18); border-color: rgba(116,224,106,0.4); color: #74e06a; }
/* ---- Services section ---- */
.services { background: #050607; }
/* ---- Services section v2 (redesign draft: pinned horizontal carousel, same
   mechanism as .gtm-track/.carousel-track — see makeReelScrollTrigger) ---- */
.svc2-section { background: #050607; }
.svc2-track { }
.svc2-sticky {
  /* pinned by GSAP ScrollTrigger (see script), not CSS position:sticky */
  height: 100vh;
  overflow: hidden; display: flex; align-items: center;
}
/* will-change keeps it on its own layer between entry/exit ease tweens,
   instead of being promoted and dropped (a full re-raster in Safari) each time. */
.svc2-inner { display: flex; flex-direction: column; width: 100%; will-change: transform; }
/* Inert on desktop — it only becomes a sticky bar on narrow screens. */
.svc2-head { display: contents; }
.svc2-head-sentinel { display: none; }
.svc2-header { padding: 0 var(--gutter); box-sizing: border-box; margin-bottom: var(--header-gap); }
.svc2-header .why-header { margin: 0; }
.svc2-tabs {
  /* Sized by viewport, not shrunk to fit. The row is allowed to run off the
     edge; the page scroll slides it along in step with the reel. */
  margin-bottom: 12px; overflow: hidden;
}
/* The row moves by transform on this rail, not by scrollLeft on .svc2-tabs.
   Writing scrollLeft every frame is a synchronous scroll update, which iOS
   Safari in particular handles badly; a transform on its own layer is the
   same cheap compositor move the card reel uses. */
.svc2-tabs-rail {
  display: flex; flex-wrap: nowrap; gap: 8px;
  padding: 0 var(--gutter); width: max-content; box-sizing: border-box;
  position: relative; /* anchors .svc2-tab-bar */
  will-change: transform;
}
.svc2-tab {
  /* Label size is fixed. Shrinking it only ever existed to cram all six
     tabs onto one line; now that the row is allowed to overflow and scroll,
     a smaller label buys nothing and just costs legibility. Only the padding
     gives a little on narrow screens, so more of the next tab peeks in. */
  font-family: inherit; font-size: 15px; font-weight: 600;
  display: flex; align-items: center; gap: 9px;
  flex-shrink: 0; white-space: nowrap;
  padding: clamp(13px, 1.1vw, 16px) clamp(20px, 2.1vw, 28px);
  border-radius: 4px; box-sizing: border-box;
  border: none; background: rgba(255,255,255,0.03);
  color: rgba(210,220,210,0.55);
  cursor: pointer; transition: background 0.2s, color 0.2s;
}
.svc2-tab-icon { font-size: 17px; line-height: 1; color: rgba(210,220,210,0.4); transition: color 0.2s; }
.svc2-tab:hover { background: rgba(255,255,255,0.07); color: #e8ede8; }
.svc2-tab:hover .svc2-tab-icon { color: #e8ede8; }
.svc2-tab.active {
  /* same subtle wash as the active card's ::before, not a solid fill */
  background: linear-gradient(135deg, rgba(116,224,106,0.09) 0%, rgba(54,199,224,0.09) 100%);
  color: #eafaf0;
}
.svc2-tab.active .svc2-tab-icon { color: #74e06a; }
/* Single indicator that slides/resizes to the active tab, mirroring
   .svc2-active-bar on the cards below — bottom-aligned here instead of
   top. Positioned via offsetLeft/offsetWidth (see positionSvcTabBar), so it
   tracks correctly whether the tab shrank to fit or the row scrolled. */
.svc2-tab-bar {
  position: absolute; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, #74e06a 0%, #36c7e0 100%);
  opacity: 0; pointer-events: none;
  transition: left 0.4s ease, top 0.4s ease, width 0.4s ease, opacity 0.4s ease;
}
.svc2-reel {
  display: flex; gap: 12px; padding: 0 var(--gutter);
  align-items: stretch; will-change: transform;
  position: relative; /* anchors .svc2-active-bar to reel coordinates */
}
/* One bar spanning every active card, instead of each card drawing its
   own top border — so the gradient sweeps once across the whole active
   group rather than restarting green→cyan at every card boundary. */
.svc2-active-bar {
  display: none; /* hidden for now — remove this line to bring the sweeping bar back */
  position: absolute; top: 0; height: 3px;
  background: linear-gradient(90deg, #74e06a 0%, #36c7e0 100%);
  opacity: 0; pointer-events: none;
  transition: left 0.5s ease, width 0.5s ease, opacity 0.5s ease;
}
.svc2-card {
  flex-shrink: 0; width: 340px; min-height: 380px; box-sizing: border-box;
  padding: 36px; border-radius: 4px;
  display: flex; flex-direction: column;
  background: linear-gradient(45deg, #ffffff0a, #ffffff05);
  position: relative; overflow: hidden; /* clips the ::after top bar to the rounded corners */
}
/* The highlight wash is a separate full-cover layer whose opacity fades,
   rather than swapping the background gradient itself — gradients can't
   be interpolated by a CSS transition, only crossfaded via opacity, which
   is what makes the active/trail change feel like a fade instead of a cut. */
.svc2-card::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; z-index: -1;
  background: linear-gradient(135deg, #74e06a 0%, #36c7e0 100%);
  opacity: 0; transition: opacity 0.5s ease; pointer-events: none;
}
.svc2-card.active::before  { opacity: 0.09; }
.svc2-card.trail-1::before { opacity: 0.07; }
.svc2-card.trail-2::before { opacity: 0.05; }
.svc2-card.trail-3::before { opacity: 0.035; }
.svc2-card.trail-4::before { opacity: 0.02; }
.svc2-cat {
  display: block;
  font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(210,220,210,0.4);
  margin: 0 0 10px;
}
.svc2-card-head {
  display: flex; align-items: flex-start; gap: 16px;
  margin: 0 0 20px;
}
.svc2-icon {
  margin-left: auto; flex-shrink: 0;
  font-size: 22px; color: rgba(255,255,255,0.18); line-height: 1;
  transition: color 0.5s ease;
}
.svc2-card.active .svc2-icon { color: #74e06a; }
.svc2-title {
  flex: 1; min-width: 0;
  font-size: clamp(18px, 1.4vw, 21px); font-weight: 700; color: #e8ede8;
  margin: 0; line-height: 1.2;
}
.svc2-desc {
  font-size: 15px; line-height: 1.65; color: rgba(210,220,210,0.6);
  margin: auto 0 0;
}
/* ---- FAQ section ----
   Normal document flow — no pin, no scroll-jacking, no scroll-tied
   height. Intro sits beside the list again (a plain position:sticky
   sidebar, like before), but the list itself is capped at 650px instead
   of stretching to fill the rest of the row, and the whole intro+list
   pair is centered as a unit within the section (.faq-block's
   justify-content) rather than the list eating all remaining width.
   The extra gap between categories (see .faq-categories below) is what
   gives scrolling through the list a slightly slower, more deliberate
   feel, purely from the section being taller — nothing hijacks the
   actual scroll input. Which category is "active" is decided by the FAQ
   script via IntersectionObserver: whichever category is currently
   crossing the vertical center of the viewport gets .open (see the
   script for the rootMargin trick that does that). */
.faq { background: #050607; }
.faq-block {
  box-sizing: border-box;
  /* Side padding is the shared gutter. Top/bottom is the one value this
     section keeps to itself (--faq-y): it closes the page, so it carries
     more air than the sections above it. Both come from Section framing. */
  padding: var(--faq-y) var(--gutter);
  display: flex; align-items: flex-start; justify-content: center;
  gap: 64px;
}
.faq-intro { flex-shrink: 0; width: 380px; position: sticky; top: 120px; }
.faq-intro .why-header { margin: 0 0 20px; }
/* Only earns its keep in the stacked layout, where the heading has the full
   900px measure and would otherwise leave "yes!" stranded on its own line.
   In the 380px sidebar the line wraps three times regardless. */
.faq-hdr-br { display: none; }
.faq-intro .why-subheader { font-size: 15px; max-width: none; }
.faq-cta-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 24px; padding-right: 24px; }
/* Stacked layout only. In the desktop sidebar the subheader ("Don't see
   yours below? Ask us directly.") sits directly above these buttons and
   already does this job; it's only once the CTA row moves below the cards
   that the buttons arrive with no lead-in. */
.faq-cta-head {
  display: none;
  font-size: 20px; font-weight: 700; line-height: 1.3;
  color: #f0f4ee; margin: 0;
}
.faq-cta-btn {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-radius: 10px;
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);
  color: #f0f4ee; font-size: 14px; font-weight: 600; text-decoration: none;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}
.faq-cta-btn:hover { background: rgba(255,255,255,0.09); border-color: rgba(255,255,255,0.2); transform: translateY(-2px); }
.faq-cta-btn i { font-size: 17px; color: #74e06a; }
.faq-cta-primary { width: 100%; padding: 12px 16px; font-size: 14px; }
.faq-cta-primary i { font-size: 17px; }
.faq-cta-primary:hover { transform: translateY(-2px); }
.faq-categories {
  /* Shrinkable (flex-shrink: 1) rather than a hard 650px. The row needs
     380 + 64 + 650 + 160 of gutter = 1254px to fit; between the stacking
     breakpoint below and that number the cards give up the difference
     instead of running off the right edge. */
  flex: 0 1 650px; max-width: 100%; min-width: 0;
  display: flex; flex-direction: column; gap: 28px;
}
.faq-category {
  flex-shrink: 0;
  background: rgba(255,255,255,0.03);
  border-radius: 4px;
  position: relative; overflow: hidden;
  opacity: 0.45; transition: opacity 0.4s ease, transform 0.4s ease;
}
.faq-category.open { opacity: 1; transform: translateX(10px); }
.faq-category::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: rgba(255,255,255,0.025);
  opacity: 0; transition: opacity 0.4s ease; pointer-events: none;
}
.faq-category.open::before { opacity: 1; }
.faq-category-header {
  position: relative; z-index: 1;
  width: 100%; display: flex; align-items: center; gap: 18px;
  padding: 28px 32px; margin: 0; border: none; background: none;
  font-family: inherit; text-align: left; cursor: pointer;
  color: inherit;
}
.faq-cat-icon {
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  font-size: 24px; color: #f0f4ee; opacity: 0.6;
}
.faq-category-title {
  flex: 1; min-width: 0;
  font-size: clamp(16px, 1.5vw, 19px); font-weight: 700; color: #f0f4ee;
  margin: 0; line-height: 1.3;
}
.faq-category-body-wrap { position: relative; z-index: 1; }
.faq-list { list-style: none; margin: 0; padding: 0 32px 8px; }
.faq-item {
  display: flex; align-items: center; gap: 16px;
  padding: 16px 0; border-top: 1px solid rgba(255,255,255,0.06);
}
.faq-bullet {
  flex-shrink: 0; width: 6px; height: 6px; border-radius: 50%;
  background: rgba(210,220,210,0.35);
}
.faq-q {
  flex: 1; min-width: 0;
  font-size: 16px; line-height: 1.5; color: white;
  font-weight: 500;
}
.faq-yes {
  flex-shrink: 0; display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  background: rgba(255,255,255,0.06);
  white-space: nowrap;
  font-size: 12px; font-weight: 800; letter-spacing: 0.02em;
  color: rgba(210,220,210,0.5);
  transition: background 0.4s ease, color 0.4s ease;
}
.faq-category.open .faq-yes {
  background: linear-gradient(135deg, rgba(116,224,106,0.14) 0%, rgba(54,199,224,0.14) 100%);
  color: #74e06a;
}
/* Stacked layout. Raised from 980px to 1180px because the side-by-side row
   can't fit under 1254px (see .faq-categories) — 980 left a ~200px band
   where the cards were clipped off screen.

   Once stacked the intro, the cards and the CTA row share one 900px measure,
   the same one .why-block uses, so this section reads like the Why section
   at these widths. The intro text is left-aligned and inset by 32px — the
   card header's own horizontal padding — so the heading starts on the same
   line as the card titles rather than on the cards' outer edge.

   The CTA row moves below the cards: stacked, buttons above the list push
   the questions themselves off screen, and "ask us directly" makes more
   sense after you've read the list than before it. Reordering it needs
   .faq-intro to be display:contents so the heading, subheader and CTA row
   become flex items of .faq-block and can be ordered around
   .faq-categories, which is their sibling, not their cousin. */
@media (max-width: 1180px) {
  .faq-block {
    flex-direction: column; align-items: stretch;
    gap: 0;
  }
  .faq-intro { display: contents; }
  /* Note these are .faq-intro > children, not .faq-block > children:
     display:contents flattens the box tree, not the DOM the selectors
     match against. */
  .faq-intro > .why-header,
  .faq-intro > .why-subheader,
  .faq-block > .faq-categories,
  .faq-intro > .faq-cta-head,
  .faq-intro > .faq-cta-row {
    box-sizing: border-box;
    width: 100%; max-width: 900px;
    margin-left: auto; margin-right: auto;
  }
  .faq-hdr-br { display: inline; }
  /* No horizontal inset: the heading and subheader sit flush with the
     cards' outer edge, so all three share one left edge and one measure.
     (Insetting them by the card's own 32px header padding instead lines
     the copy up with the card titles, but then the cards visibly overhang
     the text on both sides.) */
  .faq-intro > .why-header {
    order: 1; text-align: left;
    margin-bottom: 16px;
  }
  .faq-intro > .why-subheader {
    order: 2; text-align: left;
    margin-bottom: var(--header-gap); /* heading + subheading act as one heading block here */
    font-size: 17px; line-height: 1.6;
  }
  .faq-block > .faq-categories { order: 3; flex: none; }
  .faq-intro > .faq-cta-head {
    order: 4; display: block;
    margin-top: 48px; margin-bottom: 16px;
  }
  .faq-intro > .faq-cta-row {
    order: 5; margin-top: 0; padding: 0;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
  }
  /* The 10px nudge reads as "this one stepped forward" only while the list
     sits beside the intro. Once the intro stacks above it the cards span the
     full width, and the same nudge just looks like a misaligned card. */
  .faq-category.open { transform: none; }
  /* Full-width buttons: left-aligned label plus icon leaves a lake of empty
     space once each button is ~200px wide, so centre the pair and give them
     the taller padding the extra width can carry. translateX on hover was
     the sidebar's nudge; centred it has nothing to nudge away from. */
  .faq-cta-btn, .faq-cta-primary {
    justify-content: center;
    padding: 15px 18px;
  }
}
@media (max-width: 640px) {
  .faq-category-header { padding: 20px; gap: 12px; }
  .faq-list { padding: 0 20px 4px; }

  .faq-item { flex-wrap: wrap; row-gap: 4px; }
  .faq-yes { margin-left: 22px; }
}

/* ---------------------------------------------------------------------
   Mobile pass — gutters and card sizing.

   The desktop layout is built on an 80px gutter and card widths in fixed
   px (420px gtm, 340px services). On a 375px phone that gutter alone ate
   43% of the screen, and every reel card was wider than the viewport, so
   no card could ever be framed whole — you only ever saw a slice of one.
   Below, the gutter drops to a single value (--gutter) shared by every section
   so they line up down the page, and the reel cards switch to
   viewport-relative widths: one card fills the screen minus the gutter
   and a deliberate peek of the next, which is what signals "swipe".
   min() keeps the desktop px width as a ceiling so nothing grows on
   tablets that are already comfortable.
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* Intermediate gutter tier. Without it the page jumped straight from the
     80px desktop gutter to 20px at 640px, while the reveals section had
     already switched to its narrow layout up here at 900 — so tablets and
     open foldables sat in a mismatched in-between state. */
  /* The tier values themselves now live in SECTION_PRESETS (the Section
     framing script in the head), which writes --gutter / --section-y /
     --faq-y per width band. Sections read those directly, so nothing has
     to be restated here. The tagline is the exception: it keeps its own
     48px on desktop and only joins the shared gutter from here down. */
  .tagline-phrase { padding: 0 var(--gutter); }

  /* Peek = gutter (20) + gap + a sliver of the next card. */
  /* Card height drops from 66vh to make room for the heading now stacked
     above it — both have to fit inside the 100vh pinned viewport, which is
     overflow:hidden. Dropping the intro below frees this back up to 66vh. */
  .gtm-card { width: min(420px, calc(100vw - 76px)); height: min(560px, 60vh); }
  .gtm-header-card { display: none; }
  .gtm-header-mobile {
    /* + the 2.5% of card height the active card's scale(1.05) reaches up
       into the gap, so the visible distance is the shared --header-gap. */
    display: block; padding: 0 var(--gutter) calc(var(--header-gap) + min(560px, 60vh) * 0.025); box-sizing: border-box;
  }
  .gtm-header-mobile .why-header { margin: 0; }
  .gtm-intro-mobile { display: block; padding: 36px var(--gutter) 0; box-sizing: border-box; }
  .gtm-intro-mobile .gtm-intro { margin: 0; }
  .gtm-reel { gap: 24px; }
  .gtm-card .story-meta-top { padding: 24px 22px; }
  .gtm-card .story-content { padding: 0 22px 24px; }
  .gtm-card-bottom { padding: 22px 22px; }
  /* Two rows, still the pinned horizontal scrub. Stacking the cards two
     deep halves how far the reel has to travel and lets each card be
     narrower, without giving up the scrub that the wide layout uses.
     Applies all the way down to phones — there is no vertical list mode. */
  .svc2-reel {
    display: grid; grid-auto-flow: column;
    grid-template-rows: repeat(2, auto);
    gap: 12px; align-items: stretch;
  }
  .svc2-card { width: min(320px, calc(100vw - 96px)); min-height: 0; padding: 24px 22px; }
  /* Half the desktop fade — the highlight reads as arriving late at 0.5s. */
  .svc2-card::before { transition: opacity 0.25s ease; }
}

/* Not enough vertical room for heading + card + intro inside the pinned
   100vh, so the intro is dropped rather than letting the card be clipped. */
@media (max-width: 900px) and (max-height: 730px) {
  .gtm-intro-mobile { display: none; }
}

@media (max-width: 640px) {
  /* Hero */
  .topbar-inner { padding: 20px var(--hero-gutter); }
  .mobile-menu { padding: 88px var(--hero-gutter) 22px; }
  .tagline { padding: 0 var(--hero-gutter) 44px; }

  /* Section gutters — one shared value so every section's left edge lines
     up, instead of each one carrying its own desktop-era padding. That
     value is --gutter (set per band in SECTION_PRESETS); only the
     rules that add something of their own are left here. */
  .svc2-reel { padding: 0 var(--gutter) 8px; }  /* no top padding: tabs→cards gap = the 12px card gap */
  /* Phone cards sized like the Results cards (full content width, ~560px
     tall), minus 20px so the next card still peeks in at the right edge.
     Height is capped by viewport so heading + card + intro still fit the
     pinned 100vh. */
  .gtm-reel { gap: 16px; }
  .gtm-card { width: calc(100vw - var(--gutter) * 2 - 20px); height: min(560px, 68vh); }
  /* No zoom on the active card here — the dim/undim alone marks it. */
  .gtm-card.active { transform: none; }
  /* No scale here, so the shared heading gap applies as-is. The intro keeps
     its tighter 16px: it is a caption to the cards, not a section heading. */
  .gtm-header-mobile { padding: 0 var(--gutter) var(--header-gap); }
  .gtm-intro-mobile { padding: 16px var(--gutter) 0; }

  /* Headings were still sized off the desktop ramp; the vw term collapses
     to the clamp floor on a phone, so set the floor where it should land.
     One size for every section heading, the hero headline included. */
  .tagline h1, .tagline-h, .why-header, .why-header.carousel-header { font-size: clamp(28px, 8vw, 52px); }
  .story-card { min-height: min(560px, 74vh); }
  .story-content { padding: 0 24px 28px; }
  .gtm-card-title { font-size: clamp(22px, 6.2vw, 36px); }
  .gtm-card-bottom-text { font-size: 14px; }
  .svc2-desc { font-size: 14px; }
  .faq-q { font-size: 15px; }
}
/* ---------- Footer ----------
   Deliberately quiet: the FAQ CTA row above already does the selling, so
   this is just orientation — who we are, where things are, how to reach
   us. A faint white wash, edge to edge, sets it apart from the page, with
   the .why-card.open blue-to-teal glow at half strength over it. */
/* Reveal: the page content is an opaque layer that scrolls up and away,
   while the footer waits underneath, pinned to the bottom of the viewport
   (sticky, so it keeps its place in the flow and needs no height sync).
   The .is-tall class (set below) drops the pin when the footer doesn't fit
   the viewport, so it can never be cut off. */
.page-content { position: relative; z-index: 1; background: #050607; }
.site-footer { position: sticky; bottom: 0; z-index: 0; }
.site-footer.is-tall { position: relative; }
/* The footer starts out dimmed and brightens as it is revealed: a dark
   veil over it whose strength follows --reveal-dim, which goes 1 → 0 as the
   footer comes into view (set on the footer by the script at the footer). */
.site-footer::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: #050607; opacity: calc(0.75 * var(--reveal-dim, 0));
}
.site-footer {
  background:
    linear-gradient(53deg, #3556d621 0%, #358bd612 30%, #35d6af0e 49%, transparent 80%),
    rgba(255,255,255,0.03);
}
/* 1094px of content = the FAQ row (380 + 64 + 650), so the footer edges
   line up with the section directly above it. The gutter is added on top
   of that, so the content stays 1094px whatever the gutter is set to. */
.footer-inner { max-width: calc(1094px + 2 * var(--gutter)); margin: 0 auto; padding: 72px var(--gutter) 36px; }
.footer-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 48px; }
.footer-brand .brand { font-size: 17px; }
.footer-tagline { margin: 14px 0 0; max-width: 32ch; font-size: 14px; line-height: 1.55; color: rgba(229,229,229,0.5); }
.footer-cols { display: flex; gap: 88px; }
.footer-col { display: flex; flex-direction: column; gap: 12px; }
.footer-col h4 {
  margin: 0 0 4px; font-size: 12px; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(229,229,229,0.38);
}
.footer-col a, .footer-top-link {
  display: inline-flex; align-items: center; gap: 4px;
  color: rgba(229,229,229,0.72); text-decoration: none; font-size: 14px; font-weight: 500;
  transition: color .15s ease;
}
.footer-col a:hover, .footer-top-link:hover { color: #fff; }
.footer-col a i { font-size: 16px; color: #74e06a; }
.footer-col a:has(i) { gap: 10px; }
.footer-bottom {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  margin-top: 64px; padding-top: 24px; border-top: 1px solid rgba(255,255,255,0.07);
  font-size: 13px; color: rgba(229,229,229,0.4);
}
.footer-top-link { font-size: 13px; color: rgba(229,229,229,0.5); }
.footer-top-link i { font-size: 14px; transition: transform .2s ease; }
.footer-top-link:hover i { transform: translateY(-2px); }

@media (max-width: 820px) {
  .footer-top { flex-direction: column; gap: 40px; }
  .footer-cols { gap: 64px; }
}
@media (max-width: 640px) {
  .footer-inner { padding: 56px var(--gutter) 28px; }
  .footer-cols { gap: 48px; }
  .footer-bottom { margin-top: 48px; }
}

.contact-qr-overlay {
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(0,0,0,0.9);
  opacity: 0; visibility: hidden;
  transition: opacity 0.22s ease, visibility 0s linear 0.22s;
}
.contact-qr-overlay.open { opacity: 1; visibility: visible; transition: opacity 0.22s ease; }
.contact-qr-card {
  position: relative; width: 100%; max-width: 360px; overflow: hidden;
  padding: 28px 28px 22px; border-radius: 8px; text-align: center;
  background:
    radial-gradient(110% 55% at 0% 0%, rgba(116,224,106,0.15), transparent 70%),
    #0c0f10;
  color: #f0f4ee; font-family: "Inter", system-ui, -apple-system, sans-serif;
  transform: translateY(10px) scale(0.97);
  transition: transform 0.28s cubic-bezier(.2,.9,.3,1.2);
}
.contact-qr-overlay.open .contact-qr-card { transform: none; }
.contact-qr-badge {
  flex-shrink: 0; width: 48px; height: 48px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(116,224,106,0.12);
}
.contact-qr-badge i { font-size: 24px; color: #74e06a; }
.contact-qr-head {
  display: flex; align-items: center; gap: 14px;
  margin: 0 0 24px; padding-right: 32px; /* clear the close button */
}
.contact-qr-card h4 { margin: 0 0 3px; font-size: 21px; font-weight: 700; letter-spacing: -0.01em; text-align: left; }
.contact-qr-hint { margin: 0; font-size: 13.5px; line-height: 1.5; text-align: left; color: rgba(240,244,238,0.55); }
/* Same width and surface as the number row below, so the two read as a pair. */
.contact-qr-well {
  display: flex; justify-content: center; margin: 0 0 14px; padding: 22px;
  border-radius: 6px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1);
}
.contact-qr-frame { position: relative; padding: 12px; border-radius: 6px; background: #fff; }
.contact-qr-code img, .contact-qr-code canvas { display: block; width: 168px; height: 168px; }
.contact-qr-center {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 40px; height: 40px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  background: #0c0f10; box-shadow: 0 0 0 4px #fff;
}
.contact-qr-center i { font-size: 27px; color: #ffffff; }
.contact-qr-or {
  margin: 0 0 14px; line-height: 1;
  font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: rgba(240,244,238,0.38);
}
.contact-qr-number {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 14px 13px 18px; border-radius: 6px; cursor: pointer;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1);
  color: #f0f4ee; font: inherit; text-align: left;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.contact-qr-number:hover { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.2); }
.contact-qr-number-text { font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
.contact-qr-copy {
  display: inline-flex; align-items: center; gap: 5px; padding: 5px 9px; border-radius: 4px;
  background: rgba(255,255,255,0.06); font-size: 12px; font-weight: 600; color: rgba(240,244,238,0.65);
  transition: background 0.2s ease, color 0.2s ease;
}
.contact-qr-copy i { font-size: 14px; }
.contact-qr-number.copied .contact-qr-copy { background: rgba(116,224,106,0.15); color: #74e06a; }
.contact-qr-direct {
  display: inline-block; margin-top: 14px; font-size: 12.5px; color: rgba(240,244,238,0.45);
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(240,244,238,0.2);
}
.contact-qr-direct:hover { color: #74e06a; text-decoration-color: currentColor; }
.contact-qr-close {
  position: absolute; top: 12px; right: 12px; width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 5px; background: rgba(255,255,255,0.06); border: none;
  color: rgba(240,244,238,0.7); font-size: 16px; cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.contact-qr-close:hover { background: rgba(255,255,255,0.14); color: #fff; }
@media (prefers-reduced-motion: reduce) {
  .contact-qr-overlay, .contact-qr-card { transition: none; }
}

/* Off-phone these lose their href (see the QR script), and with it the
   default pointer cursor. */
[data-contact-qr] { cursor: pointer; }
.plan-call-options { display: flex; flex-direction: column; gap: 10px; }
.plan-call-option {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px; border-radius: 6px; text-align: left; text-decoration: none;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1);
  color: #f0f4ee; transition: background 0.2s ease, border-color 0.2s ease;
}
.plan-call-option:hover { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.2); }
.plan-call-option-icon {
  flex-shrink: 0; width: 38px; height: 38px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(116,224,106,0.12); color: #74e06a; font-size: 19px;
}
.plan-call-option-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.plan-call-option-text strong { font-size: 15px; font-weight: 600; }
.plan-call-option-text span { font-size: 13px; color: rgba(240,244,238,0.55); font-variant-numeric: tabular-nums; }
.plan-call-option-arrow { font-size: 18px; color: rgba(240,244,238,0.45); transition: transform 0.2s ease, color 0.2s ease; }
.plan-call-option:hover .plan-call-option-arrow { transform: translateX(3px); color: #74e06a; }
