/* ---- Tokens ------------------------------------------------------- */
:root {
  --primary: #0F3D3E;
  --primary-fg: #F6F5F1;
  --bg: #F6F5F1;
  --surface: #FFFFFF;
  --secondary: #2D6A6B;
  --accent: #C4652B;
  --text: #1A1A1A;
  --text-muted: #5B5B54;
  --border: #DDD9D0;

  --serif: "IBM Plex Serif", Georgia, "Times New Roman", serif;
  --sans: "IBM Plex Sans", -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;

  /* Card tilt-on-hover — set by js/animations.js on mousemove, read here so
     no inline style attribute is needed. Default = flat/no-op. */
  --tilt-x: 0deg;
  --tilt-y: 0deg;
  --tilt-s: 1;

  /* Richer, deeper versions of the same brand hues — used for gradients
     and glows so buttons/panels/hover states read as premium rather than
     flat fills, without introducing new colors outside the palette. */
  --primary-deep: #071f20;
  --primary-bright: #14524f;
  --accent-bright: #e07a3b;
  --accent-glow: rgba(196, 101, 43, 0.45);
  --secondary-glow: rgba(45, 106, 107, 0.4);
}

/* ---- Reusable: flowing gradient background --------------------------- */
/* Apply `.gradient-flow` to ANY element for a smooth, continuously
   shifting multi-color background — the "living gradient" look (Gemini's
   UI does this). Technique: a large, multi-stop gradient slowly panned
   via background-position — the standard, GPU-cheap way to animate a
   gradient in pure CSS, no JS, since browsers still can't natively tween
   between colors in a gradient's stops directly.

   Colors/speed are all custom properties, so reusing this elsewhere with
   a different palette or pace never means touching this rule — just set
   --flow-1..--flow-4 / --flow-speed on the element you add the class to:

     <div class="gradient-flow" style="--flow-speed: 10s;">

   `.gradient-flow--soft` is the same effect built from faint tints of
   the brand colors instead of the full-strength ones — for a surface
   that still needs to hold readable text on top of it (this site's
   <body>, below), where the bold default would fight with contrast. */
.gradient-flow {
  --flow-1: var(--primary);
  --flow-2: var(--secondary);
  --flow-3: var(--accent);
  --flow-4: var(--primary-bright, var(--primary));
  --flow-speed: 18s;
  background: linear-gradient(
    115deg,
    var(--flow-1),
    var(--flow-2),
    var(--flow-3),
    var(--flow-4),
    var(--flow-1)
  );
  background-size: 400% 400%;
  animation: gradientFlow var(--flow-speed) ease-in-out infinite;
}
.gradient-flow--soft {
  --flow-1: color-mix(in srgb, var(--primary) 7%, var(--bg));
  --flow-2: color-mix(in srgb, var(--secondary) 9%, var(--bg));
  --flow-3: color-mix(in srgb, var(--accent) 6%, var(--bg));
  --flow-4: color-mix(in srgb, var(--primary) 4%, var(--bg));
  --flow-speed: 22s;
}
@keyframes gradientFlow {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* ---- Reset / base --------------------------------------------------- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--sans);
  color: var(--text);
  background: var(--bg); /* fallback if .gradient-flow--soft (below) isn't applied */
  line-height: 1.55;
}
img { max-width: 100%; display: block; }
h1, h2, h3 { font-family: var(--serif); font-weight: 600; margin: 0 0 0.5em; color: var(--primary); }

/* ---- Eyebrow label ------------------------------------------------- */
/* Small tracked-wide uppercase tag above a heading — introduced in the
   Hero + Product Showcase redesign pass as a reusable convention (other
   sections pick it up in a later step). var(--primary) for the text
   keeps contrast safely high against --bg/--surface; the accent dot is
   purely decorative color, never load-bearing for legibility. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--primary);
  margin: 0 0 14px;
}
.eyebrow::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}
p { margin: 0 0 1em; color: var(--text); }
a { color: var(--secondary); }
ul, ol { margin: 0; padding: 0; list-style: none; }

.wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 20px;
}

section[id] { scroll-margin-top: 84px; }

.section { padding: 72px 0; }
.section h2 { font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2.1rem); letter-spacing: -0.015em; }

/* ---- Buttons --------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  padding: 0.55em 1.1em;
  border-radius: 7px;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.9rem;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease,
    transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.25s ease;
  /* Set by js/animations.js's "magnetic" hover (a small nudge toward the
     cursor) — 0/0 when idle, so buttons with no JS still work fine. */
  transform: translate(var(--mag-x, 0px), var(--mag-y, 0px));
}
.btn-primary {
  background: linear-gradient(135deg, var(--primary-bright), var(--primary));
  color: var(--primary-fg);
  box-shadow: 0 4px 14px -6px rgba(15, 61, 62, 0.5);
}
.btn-primary:hover {
  background: linear-gradient(135deg, var(--primary), var(--primary-deep));
  box-shadow: 0 14px 32px -10px rgba(15, 61, 62, 0.6), 0 0 0 1px rgba(196, 101, 43, 0.25);
}
.btn-primary.pulse-cta { animation: ctaPulse 2.8s ease-in-out infinite; }
@keyframes ctaPulse {
  0%, 100% { box-shadow: 0 4px 14px -6px rgba(15, 61, 62, 0.5), 0 0 0 0 var(--accent-glow); }
  50% { box-shadow: 0 4px 14px -6px rgba(15, 61, 62, 0.5), 0 0 0 12px rgba(196, 101, 43, 0); }
}
.btn-ghost {
  background: transparent;
  color: var(--primary);
  border-color: var(--border);
}
.btn-ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translate(var(--mag-x, 0px), var(--mag-y, 0px)) translateY(-2px);
  box-shadow: 0 8px 20px -12px var(--accent-glow);
}
.btn-lg { padding: 0.75em 1.5em; font-size: 1rem; }

/* Pill + trailing-arrow variant — reserved for the one or two most
   important CTAs on the page (hero + contact form), not a full button
   system replacement. Same .btn-primary/.btn-ghost color rules apply;
   this only changes the shape and adds the arrow glyph. */
.btn-pill { border-radius: 999px; }
.btn-arrow {
  display: inline-flex;
  width: 14px;
  height: 14px;
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.btn-arrow svg { width: 100%; height: 100%; }
.btn-pill:hover .btn-arrow { transform: translateX(3px); }

/* ---- Header ------------------------------------------------------ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(246, 245, 241, 0.92);
  backdrop-filter: saturate(180%) blur(6px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
/* Toggled by js/animations.js past a small scroll threshold — a border/
   shadow that only appears once there's something to separate from. */
.site-header.scrolled {
  border-bottom-color: var(--border);
  box-shadow: 0 8px 24px -16px rgba(15, 61, 62, 0.25);
}
.header-row {
  display: flex;
  align-items: center;
  gap: 24px;
  height: 68px;
  transition: height 0.25s ease;
}
.site-header.scrolled .header-row { height: 60px; }
.main-nav a {
  position: relative;
}
.main-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 100%;
  bottom: -4px;
  height: 2px;
  background: var(--accent);
  transition: right 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.main-nav a:hover::after { right: 0; }
.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--serif);
  font-weight: 600;
  font-size: 1.15rem;
  color: var(--primary);
  text-decoration: none;
  flex-shrink: 0;
  transition: color 0.2s ease;
}
.brand:hover { color: var(--secondary); }
.brand svg { transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); }
.brand:hover svg { transform: scale(1.08); }
.main-nav {
  display: flex;
  gap: 28px;
  margin: 0 auto 0 40px;
}
.main-nav a {
  color: var(--text);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 500;
}
.main-nav a:hover { color: var(--primary); }
.header-actions { display: flex; gap: 10px; flex-shrink: 0; }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 36px;
  height: 36px;
  background: none;
  border: none;
  cursor: pointer;
  margin-left: auto;
}
.nav-toggle span { display: block; height: 2px; background: var(--primary); border-radius: 1px; }
.mobile-nav {
  display: none;
  flex-direction: column;
  gap: 4px;
  padding: 12px 20px 20px;
  border-top: 1px solid var(--border);
}
.mobile-nav a { padding: 10px 0; color: var(--text); text-decoration: none; font-weight: 500; }
.mobile-nav .btn { margin-top: 6px; width: 100%; }
.site-header.nav-open .mobile-nav { display: flex; }

/* ---- Hero ------------------------------------------------------- */
.hero {
  position: relative;
  /* Pulled back in from 104/120 — that gap read as empty space above the
     fold rather than breathing room, pushing both columns down below
     where the reference design starts them. */
  padding: 56px 0 96px;
  overflow: hidden;
  isolation: isolate;
}
/* A slow-drifting gradient mesh behind everything in the hero — pure CSS,
   no canvas cost. The 3D scene (js/three-hero.js) sits above this, the
   copy/chat-mock above that. Navy/teal-led on purpose (the accent bloom
   is now a faint top glint, not the dominant color) plus a barely-there
   dot grid for a "science/data" texture — still just gradients, no new
   assets or dependencies. */
.hero::before {
  content: "";
  position: absolute;
  inset: -20% -10%;
  z-index: -2;
  background:
    radial-gradient(circle, rgba(15, 61, 62, 0.1) 1px, transparent 1.2px) 0 0 / 30px 30px,
    radial-gradient(44% 52% at 82% 12%, rgba(45, 106, 107, 0.24), transparent 60%),
    radial-gradient(52% 58% at 10% 85%, rgba(15, 61, 62, 0.18), transparent 60%),
    radial-gradient(55% 55% at 50% 0%, rgba(196, 101, 43, 0.08), transparent 65%);
  animation: heroDrift 22s ease-in-out infinite alternate;
}
@keyframes heroDrift {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  100% { transform: translate3d(-2%, 2%, 0) scale(1.06); }
}

/* flex-start, not center: the copy column (headline + CTAs) is taller
   than the visual column's min-height, so centering the row vertically
   centered the visual against that extra copy height and shoved the
   chat card down with a gap above it that the copy column didn't have.
   Starting both columns at the same top keeps them level. */
.hero-row { display: flex; align-items: flex-start; gap: 72px; }
.hero-copy { flex: 1 1 480px; }
/* Appears first, before the headline lines drop in below (lineUp starts
   at --d: 0.05s) — the label announces, then the headline lands. */
.eyebrow--hero {
  opacity: 0;
  animation: fadeUp 0.6s ease 0s forwards;
}
.hero h1 {
  /* Bigger ceiling than before (was 3.6rem) — the headline is the single
     most important statement on the page and had room to be bolder. */
  font-size: clamp(2.4rem, 1rem + 5.2vw, 4.4rem);
  line-height: 1.08;
  /* Tightened from -0.01em — a deliberately tighter display headline now
     contrasts on purpose with the eyebrow's wide 0.16em tracking above
     it, instead of both sitting at a similarly neutral spacing. */
  letter-spacing: -0.02em;
  /* Solid fallback color — the real gradient-clip paint lives on the leaf
     spans below (see .hero h1 .line > span), not here. Falls back to the
     solid --primary color (set above by the global h1 rule) if
     background-clip: text isn't supported. */
}
/* Each line of the headline is its own inline-block so js/animations.js
   can stagger them in on load without touching the words themselves. */
.hero h1 .line {
  display: block;
  overflow: hidden;
}
.hero h1 .line > span {
  display: inline-block;
  /* Navy -> teal gradient on the headline text — applied on the same
     element that carries the transform/animation below, not on the
     ancestor .hero h1. Putting the gradient-clip and the transform on
     different elements let Chromium composite the transform-animated
     span on its own GPU layer separately from the ancestor's clipped
     background, which silently painted zero text (confirmed: every
     computed style — opacity, background-clip, text-fill-color,
     transform — looked correct, yet nothing rendered). Same element,
     same layer, paints correctly. */
  background: linear-gradient(120deg, var(--primary) 25%, var(--secondary) 80%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  transform: translateY(115%);
  animation: lineUp 0.9s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  animation-delay: var(--d, 0s);
}
@keyframes lineUp {
  to { transform: translateY(0); }
}
.hero .lede {
  font-size: 1.1rem;
  color: var(--text-muted);
  max-width: 46ch;
  opacity: 0;
  animation: fadeUp 0.8s ease 0.5s forwards;
}
.cta-row {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  margin-top: 8px;
  opacity: 0;
  animation: fadeUp 0.8s ease 0.68s forwards;
}
/* Understated on purpose — was a bordered .btn-ghost competing with the
   primary CTA for attention; a plain underlined link keeps "Request a
   demo" as the one unambiguous action in the hero. */
.hero-secondary-link {
  display: inline-flex;
  align-items: center;
  color: var(--text-muted);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.2s ease;
}
.hero-secondary-link:hover { color: var(--primary); }
.watch-demo-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--secondary);
  opacity: 0;
  animation: fadeUp 0.8s ease 0.82s forwards;
}
.watch-demo-link:hover { color: var(--accent); }
.watch-demo-icon {
  display: inline-flex;
  width: 22px; height: 22px;
  color: var(--secondary);
  transition: color 0.2s ease;
}
.watch-demo-link:hover .watch-demo-icon { color: var(--accent); }
.watch-demo-icon svg { width: 100%; height: 100%; }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}

.hero-visual {
  flex: 1 1 420px;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 480px;
}
/* A soft teal halo lifting the 3D pulse + chat mock off the page —
   pure CSS, sits behind both (z-index below .hero-3d's 0 and
   .chat-mock-float's 1). */
.hero-visual::before {
  content: "";
  position: absolute;
  inset: 6%;
  z-index: -1;
  background: radial-gradient(60% 60% at 50% 48%, var(--secondary-glow), transparent 72%);
  filter: blur(8px);
  pointer-events: none;
}
/* The Three.js canvas — an abstract rotating "pulse" object, sized to fill
   the visual column, sitting behind the chat-mock card. Bordered off with
   a radial mask so it fades at the edges instead of hard-clipping. */
.hero-3d {
  position: absolute;
  inset: -10%;
  z-index: 0;
  -webkit-mask-image: radial-gradient(closest-side, #000 65%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 65%, transparent 100%);
}
.hero-3d canvas { display: block; width: 100%; height: 100%; }
/* No WebGL / reduced motion / JS not run yet: keep the mesh gradient only,
   never an empty gap. */
.hero-3d[hidden] { display: none; }

/* Two nested elements on purpose: the outer .chat-mock-float owns the
   entrance + infinite bob (an @keyframes animation, which fully owns
   `transform` for as long as it runs); the inner .chat-mock owns the
   pointer-tilt (a plain rule reading --tilt-* custom properties, written
   by js/animations.js). Keyframes and a static transform rule can't
   safely share one element's `transform` — nesting them is what lets
   both effects show at once instead of one silently overriding the other. */
.chat-mock-float {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 380px;
  opacity: 0;
  animation:
    chatIn 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.35s forwards,
    chatFloat 6s ease-in-out 1.3s infinite;
}
@keyframes chatIn {
  from { opacity: 0; transform: translateY(28px) scale(0.94); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes chatFloat {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 -10px; }
}
.chat-mock {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  overflow: hidden;
  /* Depth shadow plus a faint teal glow ring — reads as a premium,
     lit-from-within card rather than a flat screenshot. */
  box-shadow:
    0 24px 48px -24px rgba(15, 61, 62, 0.35),
    0 10px 36px -14px var(--secondary-glow);
  transform-style: preserve-3d;
  will-change: transform;
}
.chat-mock.tilt {
  transform: perspective(900px) rotateX(var(--tilt-y)) rotateY(var(--tilt-x)) scale(var(--tilt-s));
  transition: transform 0.15s ease-out;
}
.chat-mock-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 16px;
  background: var(--primary);
  color: var(--primary-fg);
  font-weight: 500;
  font-size: 0.9rem;
}
.chat-dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: #6FCF97; }
/* A subtle "AI receptionist is live" ping ring — purely decorative,
   neutralized by the global prefers-reduced-motion rule below like every
   other animation on the page. */
.chat-dot::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid #6FCF97;
  opacity: 0.7;
  animation: chatDotPing 2.2s ease-out infinite;
}
@keyframes chatDotPing {
  0% { transform: scale(0.6); opacity: 0.7; }
  75%, 100% { transform: scale(2); opacity: 0; }
}
.chat-mock-body { padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.bubble { max-width: 85%; padding: 9px 12px; border-radius: 12px; font-size: 0.85rem; line-height: 1.4; }
.bubble.in { align-self: flex-start; background: #EFEDE7; color: var(--text); border-bottom-left-radius: 3px; }
.bubble.out { align-self: flex-end; background: var(--secondary); color: #fff; border-bottom-right-radius: 3px; }

/* ---- Problem ------------------------------------------------------ */
/* Translucent, not opaque var(--surface) — lets <body>'s .gradient-flow
   show through faintly here too, so the whole page reads as one
   continuous "living" background instead of the effect stopping dead at
   every white-card section. Individual cards inside (review-card,
   plan-col, chat-mock, etc.) stay fully opaque — only the section
   wrapper's own background is translucent, so text contrast on actual
   content is never affected, just the space around it. */
/* Deliberate full-width "statement" break — no card background, no
   divider lines between items, generous padding. Was a translucent
   banded row of three bordered columns; the content is unchanged, only
   the composition (more air, bigger numerals, no visual chrome). */
.problem { padding: 108px 0; }
.problem-row { display: flex; gap: 64px; }
.problem-item { flex: 1; }
.problem-mark {
  display: block;
  font-family: var(--serif);
  font-size: 2.75rem;
  font-weight: 500;
  line-height: 1;
  /* Muted, not full --text/--primary black — quiet relative to the
     heading below it, but still clearly legible (unlike a near-white
     "ghost" tone, which measured too low-contrast against --bg to read
     as deliberate rather than a rendering mistake). */
  color: var(--text-muted);
  opacity: 0.75;
  margin-bottom: 20px;
}
.problem-item h3 { font-size: 1.2rem; margin-bottom: 10px; }
.problem-item p { color: var(--text-muted); font-size: 0.96rem; margin: 0; max-width: 32ch; }

/* ---- How it works ------------------------------------------------- */
.how-head { max-width: 62ch; }
.how-head h2 { margin-bottom: 8px; }
.how-lede { color: var(--text-muted); font-size: 1.05rem; }

.how-visual { display: flex; flex-direction: column; align-items: center; margin-top: 32px; }
.demo-video-frame {
  position: relative;
  width: 100%;
  max-width: 780px;
  /* Tighter than the hero's soft .chat-mock (16px) on purpose — a
     deliberate, slightly more structural frame for the showcase video,
     not just a uniform radius repeated everywhere. */
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid var(--border);
  /* Depth shadow plus a faint teal glow ring — same premium treatment
     as the hero's .chat-mock (Phase 2 Step 1), so the showcase reads as
     one consistent design system with the hero. */
  box-shadow:
    0 40px 80px -32px rgba(15, 61, 62, 0.4),
    0 10px 40px -14px var(--secondary-glow);
  background: var(--surface);
}
.demo-video { display: block; width: 100%; height: auto; }
.demo-video-toggle {
  position: absolute;
  right: 16px;
  bottom: 16px;
  width: 38px; height: 38px;
  border-radius: 50%;
  border: none;
  background: rgba(15, 61, 62, 0.72);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(3px);
  transition: background 0.2s ease, transform 0.2s ease;
}
.demo-video-toggle:hover { background: var(--primary); transform: scale(1.06); }
.demo-video-toggle svg { width: 16px; height: 16px; }
.demo-video-toggle .icon-play { margin-left: 2px; }
.demo-video-caption {
  margin-top: 16px;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.88rem;
  max-width: 52ch;
}
/* Three labeled callouts naming what the recording actually shows —
   plain text pills, directly matching the video's own aria-label/
   caption above (no invented features). Inherits visibility from the
   parent .how-visual.reveal — no extra scroll-reveal wiring needed. */
.showcase-tags {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}
.showcase-tags li {
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--secondary);
  font-size: 0.82rem;
  font-weight: 500;
}

.steps { display: flex; flex-direction: column; gap: 0; margin-top: 36px; position: relative; }
.steps li {
  display: flex;
  gap: 20px;
  padding: 22px 0;
  border-top: 1px solid var(--border);
}
.steps li:last-child { border-bottom: 1px solid var(--border); }
.steps-grid {
  margin-top: 56px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0 40px;
}
/* No card chrome (was background+border+radius) — the circular step-num
   below is already enough visual structure; the workflow reads clearer
   as plain, evenly-spaced columns than four more bordered boxes. */
.steps-grid li { flex-direction: column; gap: 14px; border-top: none; padding: 0; }
.steps-grid li:last-child { border-bottom: none; }
.step-num {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1.5px solid var(--primary);
  color: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--serif);
  font-weight: 600;
}
.steps h3 { font-size: 1.05rem; margin-bottom: 4px; }
.steps p { color: var(--text-muted); margin: 0; font-size: 0.94rem; }

/* ---- Features ------------------------------------------------------ */
/* Solid --bg (warm cream), not the translucent rgba(255,255,255,0.82)
   band .problem/.reviews use — distinct from that repeated treatment,
   but still a different color than the fully-white .features-list li
   cards sitting on top (pure var(--surface) on pure var(--surface)
   would have had zero background contrast, relying on the 1px border
   alone to read as "a card"). */
.features { background: var(--bg); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.features-row { display: flex; gap: 56px; align-items: flex-start; }
.features-head { flex: 1 1 300px; position: sticky; top: 100px; }
.features-head p { color: var(--text-muted); }
.features-list { flex: 1.4 1 420px; display: flex; flex-direction: column; }
/* Back to a plain divided list (was a bordered card with a left accent
   bar per item) — a thin top rule and generous padding carry the
   hierarchy instead of four stacked boxes. */
.features-list li { padding: 26px 0; border-top: 1px solid var(--border); }
.features-list li:last-child { border-bottom: 1px solid var(--border); }
.features-list h3 { font-size: 1.1rem; margin-bottom: 6px; }
.features-list p { color: var(--text-muted); margin: 0; font-size: 0.96rem; max-width: 46ch; }

/* ---- About ------------------------------------------------------- */
/* No card (was bordered/shadowed with a left accent bar) — a plain,
   generously-spaced text block reads more like a confident statement
   than a floating panel, and this section has no competing elements to
   separate itself from. */
.about { padding: 96px 0; }
.about-row { max-width: 62ch; }
.about p { color: var(--text-muted); font-size: 1.02rem; }
.about p:first-of-type { color: var(--text); font-size: 1.2rem; line-height: 1.5; }

/* ---- Pricing ------------------------------------------------------- */
/* A deeper, warmer destination for the decision-moment section — a soft
   teal tint instead of the plain translucent band reused elsewhere, same
   reasoning as Features above: distinct composition, not another copy
   of the same card-on-band pattern. */
.pricing {
  background: linear-gradient(180deg, var(--surface), color-mix(in srgb, var(--secondary) 7%, var(--surface)));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.pricing-lede { color: var(--text-muted); max-width: 56ch; }
.pricing-state { color: var(--text-muted); margin-top: 24px; }

/* One connected panel — plans are columns divided by borders, not
   separate gapped cards, so the recommended plan can visually sit "inside"
   the same shape as the others while still standing out. */
.pricing-panel {
  margin-top: 40px;
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: rgba(246, 245, 241, 0.6); /* translucent --bg — same reasoning as .problem/.features/.pricing above */
}
.plan-col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 32px 26px;
  position: relative;
  overflow: hidden;
  transition: background-color 0.25s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.35s ease, border-radius 0.35s ease;
}
/* A gradient bar that sweeps in from the left on hover — the one bit of
   "this column is highlighted" feedback that still works when columns
   share borders (a pointer tilt would visibly break at those seams, so
   this gets a plainer, bolder lift instead of the .tilt-card treatment
   used elsewhere on the page). */
.plan-col::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--accent), var(--secondary));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s ease;
}
/* Touchscreens fire :hover on tap and never un-hover it (no mouseleave
   equivalent) — a fine-pointer-only guard here, so a tapped card stays
   still instead of permanently lifting/scaling up and overlapping the
   card stacked right below it on mobile, which was hiding that card's
   price and features under the "hovered" one. */
@media (hover: hover) and (pointer: fine) {
  .plan-col:hover::before { transform: scaleX(1); }
  .plan-col:hover {
    transform: translateY(-10px) scale(1.03);
    z-index: 2;
    border-radius: 16px;
    box-shadow: 0 28px 56px -20px var(--accent-glow), 0 12px 28px -12px rgba(15, 61, 62, 0.35);
  }
  .plan-col:not(.plan-col--elevated):hover { background: var(--surface); }
  .plan-col--elevated:hover {
    background: linear-gradient(160deg, var(--primary-bright), var(--primary-deep));
    box-shadow: 0 32px 64px -18px var(--accent-glow), 0 14px 32px -12px rgba(15, 61, 62, 0.55);
  }
}
.plan-col:not(:first-child) { border-left: 1px solid var(--border); }
.plan-col--elevated {
  background: linear-gradient(160deg, var(--primary), var(--primary-deep));
  color: var(--primary-fg);
  padding-top: 46px;
}
.plan-col--elevated.plan-col:not(:first-child) { border-left-color: rgba(246, 245, 241, 0.15); }
.plan-col--elevated .plan-name { color: var(--primary-fg); }
.plan-col--elevated .plan-price-yearly,
.plan-col--elevated .plan-meta { color: rgba(246, 245, 241, 0.75); }
.plan-col--elevated .plan-features li { color: var(--primary-fg); }
.plan-col--elevated .plan-features li::before { color: #E0A15C; }

.plan-ribbon {
  position: absolute;
  top: 14px;
  left: 26px;
  background: linear-gradient(120deg, var(--accent-bright), var(--accent));
  box-shadow: 0 4px 12px -4px var(--accent-glow);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 3px 10px;
  border-radius: 999px;
  z-index: 1;
}

/* The name/price row is a <button> so it can drive the mobile accordion,
   but on desktop it must look and behave exactly like plain text — no
   button chrome, not clickable-looking. .plan-col-details is its own
   flex column so .plan-cta's margin-top: auto still pins the button to
   the card's bottom, same as when these were both direct children of
   .plan-col. */
.plan-col-toggle {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: default;
}
.plan-col-chevron { display: none; }
.plan-col-details { display: flex; flex-direction: column; flex: 1; }

.plan-name { font-size: 1.05rem; margin-bottom: 10px; }
.plan-price-main { font-family: var(--serif); font-weight: 600; font-size: 1.6rem; color: inherit; }
.plan-price-main span { font-family: var(--sans); font-weight: 400; font-size: 0.82rem; color: var(--text-muted); }
.plan-col--elevated .plan-price-main span { color: rgba(246, 245, 241, 0.75); }
.plan-price-yearly { color: var(--text-muted); font-size: 0.85rem; margin-bottom: 16px; }
.plan-meta { color: var(--text-muted); font-size: 0.85rem; margin-bottom: 4px; }
.plan-features { margin: 14px 0 20px; display: flex; flex-direction: column; gap: 6px; }
.plan-features li { font-size: 0.88rem; padding-left: 1.2em; position: relative; }
.plan-features li::before { content: "✓"; position: absolute; left: 0; color: var(--secondary); font-weight: 600; }
.plan-cta { margin-top: auto; align-self: stretch; }
.plan-col--elevated .plan-cta.btn-ghost { background: var(--primary-fg); color: var(--primary); border-color: var(--primary-fg); }
.plan-col--elevated .plan-cta.btn-ghost:hover { background: #fff; }

/* ---- Reviews ------------------------------------------------------- */
/* The translucent band .problem originated — safe to reuse here since
   How/Features/About/Pricing all sit between the two, so it never reads
   as back-to-back repetition on the page. */
.reviews { background: rgba(255, 255, 255, 0.82); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.reviews-state { color: var(--text-muted); margin-top: 24px; }
.reviews-grid {
  margin-top: 40px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
}
.review-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 24px;
}
.review-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.review-logo { width: 40px; height: 40px; border-radius: 8px; object-fit: contain; border: 1px solid var(--border); background: #fff; }
.review-logo-fallback {
  width: 40px; height: 40px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: var(--primary); color: var(--primary-fg);
  font-family: var(--serif); font-weight: 600; font-size: 0.9rem;
}
.review-hospital { font-weight: 600; font-size: 0.94rem; }
.review-stars { color: var(--accent); letter-spacing: 1px; font-size: 0.95rem; }
.review-message { color: var(--text); font-size: 0.92rem; margin: 0; }

/* ---- FAQ ------------------------------------------------------------ */
/* Native <details>/<summary> — a real accordion with zero JS: keyboard
   and screen-reader support come from the browser for free, and nothing
   here depends on js/animations.js or js/main.js running. */
.faq-list { margin-top: 36px; display: flex; flex-direction: column; gap: 12px; max-width: 74ch; }
.faq-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0 26px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.faq-item[open] { border-color: var(--secondary); box-shadow: 0 16px 36px -22px var(--secondary-glow); }
.faq-item summary {
  cursor: pointer;
  list-style: none;
  padding: 18px 30px 18px 0;
  position: relative;
  font-weight: 500;
  color: var(--text);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "";
  position: absolute;
  right: 2px;
  top: 50%;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--secondary);
  border-bottom: 2px solid var(--secondary);
  transform: translateY(-65%) rotate(45deg);
  transition: transform 0.25s ease;
}
.faq-item[open] summary::after { transform: translateY(-35%) rotate(225deg); }
.faq-item p { color: var(--text-muted); margin: 0 0 20px; font-size: 0.94rem; }

/* ---- Contact ------------------------------------------------------- */
.contact-row { display: flex; gap: 56px; }
.contact-copy { flex: 1 1 340px; }
.contact-copy p { color: var(--text-muted); }
.demo-form {
  flex: 1 1 380px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 28px;
  box-shadow: 0 30px 60px -36px rgba(15, 61, 62, 0.3), 0 10px 32px -16px var(--secondary-glow);
}
.demo-form label { display: flex; flex-direction: column; gap: 6px; font-size: 0.88rem; font-weight: 500; }
.optional { color: var(--text-muted); font-weight: 400; }
.demo-form input, .demo-form textarea {
  font-family: var(--sans);
  font-size: 0.95rem;
  padding: 0.6em 0.8em;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  resize: vertical;
}
.demo-form input:focus, .demo-form textarea:focus { outline: none; border-color: var(--primary); }
.field-error { color: var(--accent); font-size: 0.8rem; font-weight: 400; }
.form-consent { color: var(--text-muted); font-size: 0.8rem; margin: -6px 0 2px; }
.form-consent a { color: var(--secondary); }
.demo-form button { align-self: flex-start; margin-top: 4px; }
.form-status { font-size: 0.9rem; margin: 0; }
.form-status.ok { color: var(--secondary); }
.form-status.error { color: var(--accent); }

/* ---- Scroll reveal --------------------------------------------------- */
/* js/animations.js adds .reveal to sections/cards on load and .visible
   once each one crosses into the viewport (IntersectionObserver, one-shot
   per element). Nothing but opacity/transform — safe to animate. */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--reveal-d, 0s);
}
.reveal.visible { opacity: 1; transform: translateY(0); }

/* ---- Card tilt --------------------------------------------------- */
/* js/animations.js applies this to problem/step/feature/plan/review cards
   and drives --tilt-x/--tilt-y/--tilt-s on pointermove — the same
   mechanism as .chat-mock.tilt above, just a shallower angle since these
   sit in a normal document flow, not a hero. */
.tilt-card {
  transform: perspective(900px) rotateX(var(--tilt-y, 0deg)) rotateY(var(--tilt-x, 0deg)) scale(var(--tilt-s, 1));
  transition: transform 0.2s ease-out, box-shadow 0.25s ease-out, border-color 0.25s ease-out;
  will-change: transform;
}
.tilt-card:hover {
  box-shadow: 0 24px 56px -20px var(--accent-glow), 0 10px 28px -14px rgba(15, 61, 62, 0.4);
}

/* Review cards specifically get a border-color pop + a diagonal light
   sweep on hover — bounded boxes with their own background, unlike
   problem-item (a borderless column in a row), so the extra flourish
   actually reads as "this card" instead of floating free. */
.review-card {
  position: relative;
  overflow: hidden;
  transition: border-color 0.25s ease-out;
}
.review-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.55) 50%, transparent 65%);
  transform: translateX(-130%);
  transition: transform 0.65s ease;
  pointer-events: none;
}
.review-card:hover { border-color: var(--accent); }
.review-card:hover::after { transform: translateX(130%); }
.review-stars { transition: transform 0.25s ease, color 0.25s ease; display: inline-block; }
.review-card:hover .review-stars { color: var(--accent-bright); transform: scale(1.08); }

/* ---- Section dividers ------------------------------------------------ */
/* A couple of strategic wave dividers (not on every section — that would
   be busy) mark the biggest tonal shifts: into the hero's gradient mesh,
   and into the dark footer. Pure inline SVG, currentColor'd off the
   section it leads into so it stays in sync with any palette tweak. */
.divider {
  display: block;
  width: 100%;
  height: 64px;
  margin-bottom: -1px; /* sit flush against the border below it */
}
.divider--into-surface { color: var(--surface); }
.divider--into-footer { color: var(--primary); }

/* ---- Reduced motion ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .hero h1 .line > span { transform: none; }
  .reveal { opacity: 1; transform: none; }
  .chat-mock.tilt, .tilt-card { transform: none !important; }
  .hero-3d { display: none; }
}

/* ---- Footer -------------------------------------------------------- */
/* A gradient instead of a flat fill (same primary -> primary-deep pairing
   .plan-col--elevated already uses) plus a faint echo of the hero's dot
   grid — ties the very bottom of the page back to the hero at the top
   with the same "science/data" texture, at a much lower opacity since
   there's no colored mesh underneath it here to balance against. */
.site-footer {
  position: relative;
  background: linear-gradient(165deg, var(--primary), var(--primary-deep));
  color: var(--primary-fg);
  padding: 40px 0 0;
  margin-top: 40px;
  overflow: hidden;
}
.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(circle, rgba(246, 245, 241, 0.05) 1px, transparent 1.2px) 0 0 / 30px 30px;
  pointer-events: none;
}
.footer-row { position: relative; z-index: 1; display: flex; align-items: center; flex-wrap: wrap; gap: 20px; justify-content: space-between; }
.brand-light { color: var(--primary-fg); }
.brand-light:hover { color: #fff; }
.footer-nav { display: flex; gap: 20px; flex-wrap: wrap; }
.footer-nav a { color: rgba(246, 245, 241, 0.85); text-decoration: none; font-size: 0.9rem; }
.footer-nav a:hover { color: #fff; }

.footer-social { display: flex; gap: 12px; }
.footer-social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: rgba(246, 245, 241, 0.85);
  border: 1px solid rgba(246, 245, 241, 0.25);
  transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease, transform 0.2s ease;
}
.footer-social a:hover {
  color: var(--primary);
  background: var(--accent);
  border-color: var(--accent);
  transform: translateY(-3px);
}
/* Instagram/Facebook are placeholder links until the real pages exist —
   visibly present but clearly inert, not styled as a broken/dead link. */
.footer-social a[aria-disabled="true"] { cursor: default; }
.footer-social a[aria-disabled="true"]:hover {
  color: rgba(246, 245, 241, 0.85);
  background: transparent;
  border-color: rgba(246, 245, 241, 0.25);
  transform: none;
}
.footer-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; font-size: 0.82rem; color: rgba(246, 245, 241, 0.7); text-align: right; }
.footer-meta a { color: rgba(246, 245, 241, 0.85); }

/* Closing brand moment — MediBook's own name, not PIXORA's wordmark
   copied: the brand's own serif, a teal-tinted fill (not a plain pale
   gray) so it reads as "this site's own navy/teal identity," huge and
   quiet rather than a functional element. .site-footer's overflow:
   hidden (above) clips it safely at any width — no horizontal scroll
   risk even if the text is wider than the viewport. */
.footer-wordmark {
  position: relative;
  z-index: 1;
  margin-top: 36px;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(4rem, 2rem + 14vw, 11rem);
  line-height: 0.82;
  letter-spacing: -0.02em;
  text-align: center;
  white-space: nowrap;
  color: transparent;
  -webkit-text-stroke: 1px rgba(246, 245, 241, 0.18);
  background: linear-gradient(180deg, rgba(45, 106, 107, 0.16), rgba(246, 245, 241, 0.05));
  -webkit-background-clip: text;
  background-clip: text;
  pointer-events: none;
  user-select: none;
}
.footer-address { font-style: normal; line-height: 1.5; margin: 0; }
.footer-legal-links { font-size: 0.78rem; }
.footer-legal-links a { color: rgba(246, 245, 241, 0.7); text-decoration: underline; text-underline-offset: 2px; }
.footer-legal-links a:hover { color: #fff; }

/* ---- Legal pages (privacy.html, terms.html) ------------------------- */
.legal-page { padding: 48px 0 80px; }
.legal-page .wrap { max-width: 780px; }
.legal-page h1 { font-size: clamp(1.7rem, 1.3rem + 1.5vw, 2.3rem); margin-bottom: 6px; }
.legal-updated { color: var(--text-muted); font-size: 0.85rem; margin-bottom: 32px; }
.legal-page h2 { font-size: 1.2rem; margin-top: 2.2em; }
.legal-page h3 { font-size: 1rem; font-family: var(--sans); font-weight: 600; margin-top: 1.4em; }
.legal-page p, .legal-page li { color: var(--text-muted); font-size: 0.95rem; }
.legal-page strong { color: var(--text); }
.legal-page ul, .legal-page ol { list-style: disc; padding-left: 1.4em; margin-bottom: 1em; }
.legal-page ol { list-style: decimal; }
.legal-page li { margin-bottom: 0.4em; }
.legal-page a { text-decoration: underline; text-underline-offset: 2px; }
.legal-note {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  padding: 14px 16px;
  margin: 28px 0;
  font-size: 0.88rem;
}
.legal-note p:last-child { margin-bottom: 0; }
.legal-toc { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 16px 20px; margin-bottom: 8px; }
.legal-toc p { margin-bottom: 0.5em; font-weight: 600; color: var(--text); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.03em; }
.legal-toc ol { margin-bottom: 0; columns: 2; column-gap: 24px; }
.legal-toc li { font-size: 0.88rem; break-inside: avoid; }
@media (max-width: 560px) {
  .legal-toc ol { columns: 1; }
}

/* ---- Responsive ------------------------------------------------------ */
@media (max-width: 860px) {
  .features-row { flex-direction: column; gap: 24px; }
  .features-head { position: static; }
  .steps-grid { grid-template-columns: repeat(2, 1fr); gap: 28px 32px; }
  .contact-row { flex-direction: column; }
  /* Same issue as .plan-col below: flex-basis (340px/380px) was sized for
     the desktop side-by-side columns. Once the row stacks, that basis
     becomes a forced height instead of a width, leaving a tall empty gap
     under the short intro text before the form starts. */
  .contact-copy, .demo-form { flex: none; }
  .pricing-panel { flex-direction: column; }
  /* flex: 1 1 0 (the desktop rule) divides height equally once the panel
     stacks into a column — each card got squeezed to a sliver and its
     price/features/CTA were clipped by overflow: hidden. In a column
     layout each card should just size to its own content instead. */
  .plan-col { flex: none; }
  .plan-col:not(:first-child) { border-left: none; border-top: 1px solid var(--border); }
  .plan-col--elevated.plan-col:not(:first-child) { border-top-color: rgba(246, 245, 241, 0.15); }

  /* Accordion: five full cards stacked is a very long scroll before
     you've even compared them, so only one is expanded at a time —
     the recommended plan by default (data-open set in main.js),
     whichever one you tap after that. A max-height transition (not
     grid-template-rows: 0fr) because .plan-col-details has several
     direct children, not one — the grid collapse trick only animates
     cleanly with a single child owning the whole row. */
  .plan-col-toggle { cursor: pointer; }
  .plan-col-chevron { display: block; width: 20px; height: 20px; flex: none; margin-top: 2px; transition: transform 0.25s ease; }
  .plan-col[data-open="true"] .plan-col-chevron { transform: rotate(180deg); }
  .plan-col-details {
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    margin-top: 0;
    transition: max-height 0.35s ease, opacity 0.25s ease, margin-top 0.3s ease;
  }
  .plan-col[data-open="true"] .plan-col-details {
    max-height: 900px;
    opacity: 1;
    margin-top: 16px;
  }
}

@media (max-width: 720px) {
  .main-nav, .header-actions { display: none; }
  .nav-toggle { display: flex; }
  .hero-row { flex-direction: column; }
  .hero-visual { order: -1; }
  .steps-grid { grid-template-columns: 1fr; gap: 22px; }
  .problem-row { flex-direction: column; gap: 32px; }
  .footer-row { flex-direction: column; align-items: flex-start; }
  .footer-meta { align-items: flex-start; text-align: left; }
}
