@charset "UTF-8";
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* ── THEME: "ship green" — code-dark slate + signal green ──
     Deliberately not the reference page's blue/amber. Green is the
     build-passing / deploy-succeeded colour, which is what this page sells.

     CONTRAST RULE: --accent clears 4.5:1 only against the dark slate
     surfaces. Any accent-coloured TEXT sitting on paper must use
     --accent-deep instead. --accent stays for CTA fills, dark-surface
     text, borders, rules and glows. */
  --primary: #0F172A;
  --secondary: #1E293B;
  --accent: #22C55E;
  --accent-deep: #15803D;
  /* Button fills that carry WHITE labels. --accent is too light for that
     (white on it is 2.28:1); these clear AA at 5.02 and 6.08. Kept separate
     from --accent, which paints green TEXT on the dark surfaces and needs to
     stay bright there. */
  --accent-cta: #15803D;
  --accent-cta-hover: #14713A;
  --bg: #F5F9F6;
  --fg: #0D1117;
  --muted: #C9D6CD;
  --border: #DDE7E0;
  /* For cards that sit ON a white section (.step, .faq-item). --bg is only
     ~2% off white, so those cards vanished; these read clearly. Cards on a
     tinted section (.proj-card, .review-card) stay white + --border. */
  --surface: #ECF4EF;
  --surface-border: #D2E2D9;
  /* For the boundary of an interactive control: --border is only 1.16:1
     against the hero wash, which WCAG 1.4.11 wants at 3:1. This is the
     lightest tone on the ramp that clears it (3.45:1). */
  --border-strong: #72897D;
  --white: #FFFFFF;
  --ink-soft: #4A5B54;
  --rule: rgba(15, 23, 42, 0.10);
  /* Both families are taxi-dispatch-software's: its body stack for
     everything, Poppins for the lead modal. That page has no monospace at
     all, so this one no longer has one either. */
  --font-ui: 'Segoe UI', 'Inter', system-ui, -apple-system, sans-serif;
  --font-modal: 'Poppins', sans-serif;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow-md: 0 4px 16px rgba(13,17,23,0.1), 0 2px 6px rgba(13,17,23,0.06);
  --shadow-lg: 0 20px 60px rgba(13,17,23,0.15), 0 8px 24px rgba(13,17,23,0.08);
  --transition: 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

html { scroll-behavior: smooth; }

/* The header is fixed at 65px, so without this an anchor target lands flush
   beneath it: the section's top padding is swallowed and its heading ends up
   9px off the header. */
section[id] { scroll-margin-top: 80px; }

body {
  font-family: var(--font-ui);
  background: var(--bg);
  color: var(--fg);
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* ── UTILITIES ── */
.container {
  max-width: 1600px;
  margin: 0 auto;
  padding: 0 24px;
}

.section-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent-deep);
  background: rgba(34, 197, 94, 0.08);
  border: 1px solid rgba(34, 197, 94, 0.2);
  border-radius: 100px;
  padding: 4px 12px;
  margin-bottom: 12px;
}

.section-label::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-deep);
  animation: pulse-dot 2s ease-in-out infinite;
}

@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.5; transform: scale(0.75); }
}

/* Was 44px against a 62px h1 and a 56px CTA heading — the section headings
   were the quietest type on the page. The extra size is paid for by the
   tighter leading and margins below, not added to the section. */
.section-title {
  font-size: clamp(30px, 4.6vw, 52px);
  font-weight: 700;
  color: var(--primary);
  line-height: 1.08;
  letter-spacing: -0.03em;
}

/* Highlight = same sans as the heading, upright, accent colour. No serif,
   no italic. */
.section-sub {
  font-size: 16px;
  color: #4B5563;
  line-height: 1.65;
  max-width: 540px;
  margin: 14px auto 0;
}

.section-title em {
  font-style: normal;
  color: var(--accent-deep);
}

/* ── HEADER / NAV ── */
header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  background: rgba(245, 249, 246, 0.88);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border);
}

header nav {
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.logo {
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 500;
  color: var(--primary);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 6px;
  letter-spacing: -0.02em;
}

/* ── BRAND LOGO (OnGraph PNG, 1026x242 = 4.24:1) ──
   Sized by height only; width:auto keeps the ratio so the mark never stretches. */
.logo .logo-img {
  display: block;
  height: 36px;
  width: auto;
  max-width: none;
  flex-shrink: 0;
}

@media (max-width: 768px) {
  .logo .logo-img { height: 32px; }
}

@media (max-width: 480px) {
  .logo .logo-img { height: 28px; }
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a {
  font-size: 14px;
  font-weight: 500;
  color: #4B5563;
  text-decoration: none;
  transition: color var(--transition);
  white-space: nowrap;
}

/* 19px of text is not a target. The CTA is already tall enough. */
.nav-links a:not(.nav-cta) {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
}

.nav-links a:hover { color: var(--primary); }

/* Button structure from taxi-dispatch-software: shimmer sweep + arrow chip.
   The trailing arrow is ::after content — never put a literal → in the label. */
.nav-cta {
  position: relative;
  overflow: hidden;
  display: inline-flex !important;
  align-items: center;
  gap: 12px;
  background: var(--accent-cta);
  color: var(--white) !important;
  padding: 8px 8px 8px 18px;
  border-radius: 10px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-decoration: none;
  white-space: nowrap;
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.25s ease;
  box-shadow: 0 4px 14px rgba(34, 197, 94, 0.32);
  isolation: isolate;
}

.nav-cta::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, transparent 20%, rgba(255,255,255,0.55) 50%, transparent 80%);
  transform: translateX(-120%);
  transition: transform 0.6s ease;
  z-index: -1;
}

.nav-cta::after {
  content: '→';
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  background: var(--primary);
  color: var(--white);
  border-radius: 7px;
  font-weight: 700;
  font-size: 12px;
  flex-shrink: 0;
  transition: transform 0.25s ease;
}

.nav-cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(34, 197, 94, 0.5);
}

.nav-cta:hover::before { transform: translateX(120%); }
.nav-cta:hover::after { transform: translateX(3px); }

.nav-cta:active {
  transform: translateY(0) scale(0.97);
  transition-duration: 0.1s;
}

.nav-cta:focus-visible {
  outline: 3px solid rgba(34, 197, 94, 0.55);
  outline-offset: 3px;
}

/* Was 30x24 — the primary mobile nav control sitting on WCAG's bare 24px
   floor. The bars stay put; only the hit area grows. */
.hamburger {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  cursor: pointer;
  padding: 0;
  min-width: 44px;
  min-height: 44px;
  margin-right: -8px;
  background: none;
  border: none;
}

.hamburger span {
  width: 22px;
  height: 2px;
  background: var(--primary);
  border-radius: 2px;
  transition: all 250ms ease;
  display: block;
}

.mobile-menu {
  display: flex;
  position: fixed;
  top: 64px;
  left: 0;
  right: 0;
  background: var(--white);
  border-bottom: 1px solid var(--border);
  padding: 16px 24px;
  z-index: 999;
  flex-direction: column;
  gap: 4px;
  box-shadow: var(--shadow-md);
  /* Closed. It used to toggle display:none <-> flex, which cannot transition.
     It's position:fixed, so staying laid out costs no layout; visibility and
     opacity do the hiding and they animate. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(-10px);
  pointer-events: none;
  transition: opacity 0.25s ease,
              transform 0.28s cubic-bezier(0.22, 1, 0.36, 1),
              visibility 0s 0.28s;
}

.mobile-menu.open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
  transition: opacity 0.2s ease,
              transform 0.28s cubic-bezier(0.22, 1, 0.36, 1),
              visibility 0s;
}

/* The hamburger only exists below 769 — keep the panel out entirely above it. */
@media (min-width: 769px) {
  .mobile-menu { display: none; }
}

.mobile-menu a {
  padding: 12px 0;
  font-size: 16px;
  font-weight: 500;
  color: #4B5563;
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  /* Each link follows the panel in. */
  opacity: 0;
  transform: translateY(-8px);
  transition: color var(--transition),
              opacity 0.3s ease,
              transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.mobile-menu.open a {
  opacity: 1;
  transform: translateY(0);
}

.mobile-menu.open a:nth-child(1) { transition-delay: 0.06s; }
.mobile-menu.open a:nth-child(2) { transition-delay: 0.11s; }
.mobile-menu.open a:nth-child(3) { transition-delay: 0.16s; }
.mobile-menu.open a:nth-child(4) { transition-delay: 0.21s; }
.mobile-menu.open a:nth-child(5) { transition-delay: 0.26s; }

.mobile-menu a:hover { color: var(--primary); }

.mobile-menu a:last-child { border-bottom: none; }

.mobile-menu .nav-cta {
  display: flex !important;
  margin: 20px 0 6px;
  padding: 14px 24px;
  width: 100%;
  justify-content: center;
  align-items: center;
  gap: 14px;
  color: var(--white) !important;
  background: var(--accent-cta);
  border-radius: 999px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.3px;
  text-align: center;
  border-bottom: none;
  min-height: 56px;
  box-shadow: 0 10px 24px rgba(34, 197, 94, 0.38), 0 2px 6px rgba(0, 0, 0, 0.08);
}

.mobile-menu .nav-cta::after {
  position: static;
  transform: none;
  width: 28px;
  height: 28px;
  font-size: 12px;
}

/* ── HERO ──────────────────────────────────────────────────────
   Atmosphere ported from taxi-dispatch-software: layered radial wash +
   tiled pattern + grain + drifting objects. The reference's topographic
   contours read as "maps"; this page sells builds, so the motif is a
   blueprint grid instead. Kept restrained — Swiss Modernism's one
   anti-pattern is excessive decoration.
   ────────────────────────────────────────────────────────────── */
.hero {
  padding: 88px 0 0;
  background:
    radial-gradient(circle at 88% 8%,  rgba(34,197,94,0.16), transparent 45%),
    radial-gradient(circle at 6% 78%,  rgba(15,23,42,0.06), transparent 55%),
    radial-gradient(circle at 95% 95%, rgba(34,197,94,0.08), transparent 50%),
    linear-gradient(180deg, #EDF6F0 0%, #F2F8F4 55%, var(--bg) 100%);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* Blueprint grid — tiled SVG, faded at the edges by a radial mask. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='96' height='96' viewBox='0 0 96 96'><g fill='none' stroke='%2315803D' stroke-opacity='0.11' stroke-width='1'><path d='M96 0H0v96'/></g><circle cx='96' cy='96' r='1.6' fill='%2315803D' fill-opacity='0.18'/></svg>");
  background-size: 96px 96px;
  -webkit-mask-image: radial-gradient(ellipse at center, rgba(0,0,0,0.85) 0%, transparent 75%);
  mask-image: radial-gradient(ellipse at center, rgba(0,0,0,0.85) 0%, transparent 75%);
}

/* Fine grain — SVG turbulence, tactile depth. */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.05  0 0 0 0 0.15  0 0 0 0 0.09  0 0 0 0.05 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* Drifting orbs + dev icons, below the content. */
.hero-objects {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
}

.bg-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(50px);
  will-change: transform;
}

.bg-orb.orb-1 {
  top: 14%;
  left: 4%;
  width: 240px;
  height: 240px;
  background: radial-gradient(circle, rgba(34,197,94,0.26), transparent 70%);
  animation: orbDrift1 14s ease-in-out infinite;
}

.bg-orb.orb-2 {
  top: 46%;
  right: 3%;
  width: 320px;
  height: 320px;
  background: radial-gradient(circle, rgba(21,128,61,0.18), transparent 70%);
  animation: orbDrift2 16s ease-in-out infinite;
}

.bg-orb.orb-3 {
  bottom: 14%;
  left: 34%;
  width: 200px;
  height: 200px;
  background: radial-gradient(circle, rgba(15,23,42,0.10), transparent 70%);
  animation: orbDrift3 18s ease-in-out infinite;
}

@keyframes orbDrift1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(40px, -30px) scale(1.12); }
}

@keyframes orbDrift2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(-36px, 40px) scale(0.92); }
}

@keyframes orbDrift3 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(28px, -44px) scale(1.08); }
}

.bg-icon {
  position: absolute;
  opacity: 0.3;
  fill: none;
  stroke: var(--accent-deep);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  will-change: transform;
}

/* Anchored to the CONTAINER's gutter rather than a viewport percentage:
   .container is max-width 1200, so its edges sit at 50% ± 600px. A viewport
   % put these on the copy at some widths and half off-screen at others. */
.bg-icon.icon-terminal { top: 20%;    right: calc(50% + 604px); width: 32px; height: 32px; animation: iconDrift 9s  ease-in-out infinite; }
.bg-icon.icon-branch   { bottom: 20%; right: calc(50% + 604px); width: 34px; height: 34px; animation: iconDrift 11s ease-in-out infinite 1.2s; stroke: var(--primary); opacity: 0.2; }
.bg-icon.icon-package  { top: 14%;    left:  calc(50% + 604px); width: 32px; height: 32px; animation: iconDrift 10s ease-in-out infinite 0.6s; }

/* Under ~1340px the gutter is too narrow to hold a 32px icon clear of both
   the copy and the window edge, so drop them — the orbs, blueprint grid and
   grain still carry the atmosphere. */
@media (max-width: 1340px) {
  .bg-icon { display: none; }
}

@keyframes iconDrift {
  0%, 100% { transform: translateY(0)     rotate(-6deg); }
  50%      { transform: translateY(-22px) rotate(6deg); }
}

/* The icons clutter a phone-width canvas — keep the orbs only. */
@media (max-width: 640px) {
  .bg-icon { display: none; }
  .bg-orb { filter: blur(40px); opacity: 0.7; }
  .bg-orb.orb-2 { width: 220px; height: 220px; }
  .bg-orb.orb-3 { display: none; }
}

.hero .container {
  position: relative;
  z-index: 3;
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr 420px;
  gap: 60px;
  align-items: start;
}

/* Editorial pre-headline label: live dot + trailing rule (reference page). */
.hero-eyebrow {
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 20px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding-left: 16px;
  position: relative;
}

.hero-eyebrow::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 8px;
  height: 8px;
  background: var(--accent-deep);
  border-radius: 50%;
  transform: translateY(-50%);
  animation: heroLive 1.8s ease-in-out infinite;
}

.hero-eyebrow::after {
  content: '';
  display: inline-block;
  width: 40px;
  height: 1px;
  background: var(--rule);
}

@keyframes heroLive {
  0%, 100% { box-shadow: 0 0 0 0   rgba(21,128,61,0.5); }
  50%      { box-shadow: 0 0 0 6px rgba(21,128,61,0); }
}

h1.hero-heading {
  font-size: clamp(36px, 5vw, 62px);
  font-weight: 700;
  color: var(--primary);
  line-height: 1.08;
  letter-spacing: -0.03em;
  margin-bottom: 12px;
}

/* Highlight = same sans as the heading, upright, accent colour. No serif,
   no italic. */
h1.hero-heading em {
  font-style: normal;
  color: var(--accent-deep);
}

/* Highlighter swipe (ported from taxi-dispatch-software's h1 .marker).
   z-index:-1 resolves inside .hero-left, which .fade-up's transform
   already made a stacking context. */
h1.hero-heading .marker {
  position: relative;
  display: inline-block;
}

h1.hero-heading .marker::after {
  content: '';
  position: absolute;
  left: -0.06em;
  right: -0.06em;
  bottom: 0.05em;
  height: 0.30em;
  background: linear-gradient(90deg, rgba(34,197,94,0.55), rgba(34,197,94,0.12));
  border-radius: 2px;
  z-index: -1;
}

.hero-desc {
  font-size: 17px;
  color: #4B5563;
  line-height: 1.7;
  max-width: 100%;
  margin-bottom: 24px;
}

.hero-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 34px;
}

.btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  color: var(--white);
  background: var(--accent-cta);
  padding: 14px 28px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background var(--transition), transform var(--transition), box-shadow var(--transition);
  border: none;
  cursor: pointer;
}

.btn-primary:hover {
  background: var(--accent-cta-hover);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(34, 197, 94, 0.4);
}

.btn-primary:active { transform: scale(0.96); }

.btn-outline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  color: var(--primary);
  background: var(--white);
  border: 1.5px solid var(--border-strong);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
  padding: 14px 28px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: border-color var(--transition), background var(--transition), transform var(--transition);
  cursor: pointer;
}

.btn-outline:hover {
  border-color: var(--accent-deep);
  background: rgba(34, 197, 94, 0.06);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.1);
  transform: translateY(-1px);
}

/* KPI strip — ruled separators instead of floating divider divs, big
   display numbers, mono uppercase labels (reference page's .tds-hero-stats). */
.hero-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border-top: 1px solid var(--rule);
  padding-top: 24px;
  align-items: start;
}

.hero-stat {
  padding: 0 20px 0 0;
  position: relative;
}

/* A rule that fades at both ends reads as a separator, not a border. */
.hero-stat:not(:last-child)::after {
  content: '';
  position: absolute;
  right: 0;
  top: 2px;
  bottom: 2px;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--rule) 22%, var(--rule) 78%, transparent);
}

.hero-stat:not(:first-child) { padding-left: 20px; }
.hero-stat:last-child { padding-right: 0; }

.hero-stat strong {
  display: block;
  font-weight: 700;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  color: var(--primary);
  letter-spacing: -0.03em;
  line-height: 1;
}

.hero-stat strong em {
  font-style: normal;
  font-family: inherit;
  color: var(--accent-deep);
  font-weight: 700;
  margin-left: 1px;
}

/* The $ leads its number rather than trailing it. */
.hero-stat strong em:first-child {
  margin-left: 0;
  margin-right: 1px;
}

.hero-stat span {
  display: block;
  font-size: 0.67rem;
  font-weight: 700;
  color: #3F4F49;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  margin-top: 8px;
  line-height: 1.35;
}

/* ── HERO VISUAL — double-rule bezel + floating live tags ── */
.hero-visual {
  position: relative;
  padding: 14px;
}

.hero-visual::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid var(--rule);
  border-radius: 28px;
  pointer-events: none;
}

.hero-visual::after {
  content: '';
  position: absolute;
  inset: 6px;
  border: 1px dashed rgba(15,23,42,0.07);
  border-radius: 22px;
  pointer-events: none;
}

.hero-tag {
  position: absolute;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 9px;
  background: rgba(255,255,255,0.94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 9px 13px;
  box-shadow: 0 12px 30px rgba(15,23,42,0.12);
  animation: tagFloat 7s ease-in-out infinite;
}

.hero-tag .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-deep);
  flex-shrink: 0;
  /* Belt and braces: if anything ever writes text in here again, it stays
     invisible instead of spilling across the tag. */
  font-size: 0;
  overflow: hidden;
  animation: heroLive 1.8s ease-in-out infinite;
}

.hero-tag-title {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: var(--primary);
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.hero-tag-sub {
  display: block;
  font-family: var(--font-ui);
  font-size: 10px;
  color: #6B7280;
  margin-top: 2px;
}

.hero-tag-body { transition: opacity 260ms ease; }
.hero-tag.swapping .hero-tag-body { opacity: 0; }

/* Bottom-LEFT, not -right: the WhatsApp FAB is fixed to the viewport's
   bottom-right at z-index 9990 and painted straight over this tag on any
   viewport shorter than ~680px. */
.hero-tag-bl { bottom: -14px; left: -18px; }

@keyframes tagFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}

/* ── HERO TICKER — thin mono build-telemetry strip along the hero's
   bottom edge (reference page's .tds-hero-ticker). Reuses @keyframes
   marquee, so the track content must stay exactly duplicated. ── */
.hero-ticker {
  position: relative;
  z-index: 3;
  margin-top: 40px;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  background: rgba(255,255,255,0.5);
  overflow: hidden;
  padding: 11px 0;
}

.hero-ticker-track {
  display: flex;
  align-items: center;
  width: max-content;
  animation: marquee 42s linear infinite;
}

.hero-ticker-track span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  white-space: nowrap;
  padding: 0 18px;
}

.hero-ticker-track span i {
  font-style: normal;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent-deep);
  flex-shrink: 0;
}

.hero-ticker-track span b { color: var(--primary); font-weight: 700; }
.hero-ticker-track .sep { color: var(--muted); padding: 0; }
/* Pausing is coordinated in js/main.js, not by :hover — hovering this strip
   has to keep it moving and freeze the others instead. */
.hero-ticker-track.is-paused { animation-play-state: paused; }

/* ── PRICE CARD (HERO RIGHT) ── */
.price-card {
  /* Lighter at the top = lit from above, which is what sells the emboss. */
  background: linear-gradient(180deg, #1B2540 0%, var(--primary) 58%);
  border-radius: 20px;
  padding: 26px 28px;
  border: 1px solid rgba(255,255,255,0.09);
  box-shadow:
    0 34px 72px rgba(2, 6, 14, 0.55),        /* deep drop */
    0 12px 28px rgba(2, 6, 14, 0.40),        /* contact shadow */
    0 0 70px rgba(34, 197, 94, 0.10),        /* accent bloom */
    inset 0 -1px 0 rgba(0, 0, 0, 0.5);       /* bottom shade; the matching top
                                                highlight lives on .pc-statusbar,
                                                which covers the card's top edge */
  position: relative;
  overflow: hidden;
}

.price-card::before {
  content: '';
  position: absolute;
  top: -80px;
  right: -80px;
  width: 200px;
  height: 200px;
  background: radial-gradient(circle, rgba(34, 197, 94, 0.12) 0%, transparent 70%);
  pointer-events: none;
}

/* Console chrome. Frames the right column as the surface the agents work
   on — which is what the floating tags and the ticker already claim — and
   absorbs the old "Available Now" pill, so it costs no height.
   The negative margins bleed it to the card's edges; .price-card already
   clips with overflow:hidden + radius. */
.pc-statusbar {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  margin: -26px -28px 22px;
  padding: 11px 16px;
  background: rgba(255,255,255,0.05);
  border-bottom: 1px solid rgba(255,255,255,0.08);
  /* The card's top inner highlight — it has to live here, because this bar
     bleeds over the card's own edge. */
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12);
}

.pc-dots {
  display: flex;
  gap: 5px;
  flex-shrink: 0;
}

.pc-dots i {
  font-style: normal;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255,255,255,0.14);
}

.pc-dots i:last-child { background: rgba(34, 197, 94, 0.5); }

/* The live log line. Cycles via JS; the caret is CSS-generated so it
   survives the textContent swap. */
.pc-activity {
  font-family: var(--font-ui);
  font-size: 10.5px;
  color: rgba(255,255,255,0.5);
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity 260ms ease;
}

.pc-activity::before {
  content: '\203A ';
  color: var(--accent);
}

.pc-statusbar.swapping .pc-activity { opacity: 0; }

.pc-live {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-family: var(--font-ui);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}

.pc-live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse-dot 2s ease-in-out infinite;
}

.price-val {
  font-family: var(--font-ui);
  font-size: 56px;
  font-weight: 700;
  color: var(--white);
  line-height: 1;
  letter-spacing: -0.03em;
  margin-bottom: 6px;
  text-shadow: 0 0 44px rgba(34, 197, 94, 0.4);
}

/* The $ inherits from .price-val, so it needs saying explicitly to stay the
   accent. /mo sets its own colour inline. */
.price-val span {
  font-size: 28px;
  opacity: 0.7;
  color: var(--accent);
}

.price-note {
  font-size: 13px;
  color: rgba(255,255,255,0.62);
  font-family: var(--font-ui);
  margin-bottom: 16px;
}

.price-divider {
  border: none;
  border-top: 1px solid rgba(255,255,255,0.12);
  margin-bottom: 20px;
  padding-top:0px;
}

.price-features {
  list-style: none;
  margin-bottom: 22px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.price-features li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 14px;
  color: rgba(255,255,255,0.9);
  line-height: 1.45;
}

.price-features li::before {
  content: '';
  width: 18px;
  height: 18px;
  min-width: 18px;
  background: rgba(34, 197, 94, 0.2);
  border-radius: 50%;
  border: 1px solid rgba(34, 197, 94, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%2322C55E' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 9px;
}

.compare-table {
  background: rgba(255,255,255,0.03);
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: var(--radius-sm);
  overflow: hidden;
  margin-bottom: 24px;
}

.compare-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 10px 14px;
  font-size: 12.5px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}

.compare-row:last-child { border-bottom: none; }

.compare-row.header {
  background: rgba(34, 197, 94, 0.06);
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
}

.compare-row.ours {
  background: rgba(34, 197, 94, 0.06);
}

.compare-row div { color: rgba(255,255,255,0.7); }
.compare-row.ours div { color: var(--accent); font-weight: 600; }

.price-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 600;
  box-shadow: 0 8px 22px rgba(34, 197, 94, 0.28), inset 0 1px 0 rgba(255,255,255,0.25);
  color: var(--white);
  background: var(--accent-cta);
  padding: 14px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  text-align: center;
  transition: background var(--transition), transform var(--transition), box-shadow var(--transition);
  cursor: pointer;
  width: 100%;
}

.price-cta:hover {
  background: var(--accent-cta-hover);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(34, 197, 94, 0.4);
}

.price-cta:active { transform: scale(0.96); }

/* ── DIVIDER MARQUEE ── */
.divider-marquee {
  background: var(--primary);
  padding: 14px 0;
  overflow: hidden;
  border-top: 1px solid rgba(34, 197, 94, 0.12);
  border-bottom: 1px solid rgba(34, 197, 94, 0.12);
}

.marquee-track {
  display: flex;
  gap: 0;
  animation: marquee 30s linear infinite;
  width: max-content;
}

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

.marquee-text {
  font-family: var(--font-ui);
  font-size: 12px;
  color: rgba(255,255,255,0.5);
  letter-spacing: 0.06em;
  white-space: nowrap;
  padding-right: 40px;
}

.marquee-text span {
  color: var(--accent);
  margin: 0 8px;
}

@keyframes marquee {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

/* ── HOW IT WORKS ── */
.how {
  padding: 72px 0;
  background: var(--white);
}

.how-header {
  text-align: center;
  max-width: 560px;
  margin: 0 auto 36px;
}

.how-header .section-label {
  display: inline-flex;
}

.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  position: relative;
}

/* Flow connector. Runs the full width at the vertical centre of the .step-num
   circles (1px card border + 28px padding + 22px half-row); the cards are opaque and paint
   over it, so it only shows in the 24px gaps — reading as a dashed line
   stepping from 01 through 04. The old rule sat 18px high and spanned only
   25%-75%, so it hung between cards 2 and 3 like an artifact. */
.steps::before {
  content: '';
  position: absolute;
  top: 51px;
  left: 0;
  right: 0;
  height: 1px;
  background: repeating-linear-gradient(90deg, var(--accent-deep) 0 4px, transparent 4px 9px);
  opacity: 0.5;
}

.step {
  background: var(--surface);
  border: 1px solid var(--surface-border);
  border-radius: var(--radius);
  padding: 28px 24px;
  position: relative;
  box-shadow: 0 1px 3px rgba(15,23,42,0.05);
  transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
}

.step:hover {
  border-color: rgba(34, 197, 94, 0.3);
  box-shadow: 0 4px 24px rgba(34, 197, 94, 0.08);
  transform: translateY(-2px);
}

/* Number and icon share one row — stacked they burned ~116px of card height
   on two badges before the title even started. */
.step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}

.step-num {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--primary);
  border: 2px solid rgba(34, 197, 94, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}

.step-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  background: rgba(34, 197, 94, 0.08);
  border: 1px solid rgba(34, 197, 94, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--accent-deep);
}

.step-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--primary);
  margin-bottom: 10px;
  letter-spacing: -0.01em;
}

.step-desc {
  font-size: 14px;
  color: #6B7280;
  line-height: 1.6;
}

/* The $999 chip. Lives in the Process section rather than the hero — see
   .how-footer. Named .price-mark, not .hero-*, since it's no longer a hero
   element. */
.price-mark {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  background: linear-gradient(180deg, #1B2540 0%, var(--primary) 60%);
  border-radius: 10px;
  padding: 9px 17px;
  flex-shrink: 0;
  box-shadow:
    0 6px 18px rgba(2, 6, 14, 0.28),
    inset 0 1px 0 rgba(255,255,255,0.12);
}

.pm-dollar {
  font-family: var(--font-ui);
  font-size: 19px;
  font-weight: 500;
  color: var(--accent);
}

.pm-num {
  font-family: var(--font-ui);
  font-size: 30px;
  font-weight: 500;
  color: var(--white);
  line-height: 1;
}

.pm-period {
  font-family: var(--font-ui);
  font-size: 19px;
  color: rgba(255,255,255,0.4);
}

/* Closes the Process section: ruled top edge to match the hero KPI strip,
   then price + one line of copy + the ask. */
/* The offer band that closes the Process section. */
.how-footer {
  /* 860 vs the container's 1318: content needs 809, so full-bleed left 285px
     of dead air each side. */
  max-width: 860px;
  margin: 44px auto 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 26px;
  flex-wrap: wrap;
  padding: 26px 32px;
  background: var(--surface);
  border: 1px solid rgba(34, 197, 94, 0.28);
  border-radius: 18px;
  position: relative;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.05), 0 0 44px rgba(34, 197, 94, 0.07);
}

/* Ambient sweep. Animates background-position rather than a transform so the
   band needs no overflow:hidden — which would clip the CTA's hover shadow. */
.how-footer::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(100deg, transparent 34%, rgba(34, 197, 94, 0.18) 50%, transparent 66%);
  background-size: 260% 100%;
  background-position: 200% 0;
  animation: bandSweep 5.5s ease-in-out infinite;
}

/* ::before is positioned, so it would paint over the content without this. */
.how-footer > * {
  position: relative;
  z-index: 1;
}

@keyframes bandSweep {
  0%   { background-position: 200% 0; }
  55%  { background-position: -110% 0; }
  100% { background-position: -110% 0; }   /* rest between passes */
}

.how-footer-copy {
  font-size: 15px;
  color: #374151;
  line-height: 1.55;
  max-width: 330px;
  padding-left: 26px;
  border-left: 1px solid var(--surface-border);
}

.how-footer-copy strong {
  color: var(--primary);
  font-weight: 700;
}

@media (max-width: 768px) {
  .how-footer {
    flex-direction: column;
    text-align: center;
    gap: 18px;
    margin: 36px auto 0;
    padding: 24px 18px;
  }
  /* The spine only works across a row. */
  .how-footer-copy { max-width: 420px; padding-left: 0; border-left: none; }
  .how-footer .btn-primary { width: 100%; justify-content: center; }
}

/* ── PROJECTS ── */
/* 80 + the carousel's own 20px scrollbar gutter = the 100px every other
   section uses. */
.projects {
  padding: 72px 0 54px;
  background: var(--bg);
}

/* Matches .how-header / .pricing-header / .reviews-header / .faq-header.
   The old flex+space-between was only there to push the carousel arrows
   right; without them it just stranded the title on the left. */
.projects-header {
  text-align: center;
  max-width: 560px;
  margin: 0 auto 32px;
}

/* No visible controls by design — the carousel auto-advances, and drag /
   trackpad / arrow keys all still work. */

/* ── SHARED CAROUSEL (projects + reviews) ── */
.carousel-outer {
  overflow-x: auto;
  /* Not 0: overflow-x:auto clips the y-axis too, and .proj-card:hover lifts
     3px under a 16px-blur shadow — zero padding shears the hover off. */
  padding-bottom: 18px;
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* old Edge */
  cursor: grab;
  user-select: none;
  /* One card at a time. NOT scroll-behavior:smooth here — that would also
     animate the drag handler's direct scrollLeft writes and make dragging
     lag; the arrows/autoplay pass behavior:'smooth' per call instead. */
  scroll-snap-type: x mandatory;
  /* Inset the snapport by the same gutter the track is padded with. Without
     this, scroll-snap-align:start aligns cards to the container's padding
     edge and scrolls the track's 107px gutter away — which both undoes the
     card-1/heading alignment and offsets every snap position (scrollLeft
     rests at 107 instead of 0). */
  scroll-padding-left: max(24px, calc((100% - 1200px) / 2 + 24px));
}

/* Mandatory snap fights a drag that writes scrollLeft every mousemove. */
.carousel-outer.dragging { scroll-snap-type: none; }

/* tabindex="0" makes this focusable for the arrow keys, which brings the UA's
   black focus ring with it — restyle it to the theme. */
.carousel-outer:focus { outline: none; }

.carousel-outer:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: -2px;
  border-radius: 6px;
}

.carousel-outer:active { cursor: grabbing; }

.carousel-outer::-webkit-scrollbar { display: none; }

/* Pad to the container's content edge so card 1 lines up with the section
   heading (it was starting at x=2 against a heading at x=107). Percentages
   resolve against .carousel-outer's width, i.e. the client width — using vw
   here would be off by the scrollbar. */
.carousel-track {
  display: flex;
  gap: 20px;
  width: max-content;
  padding: 4px max(24px, calc((100% - 1200px) / 2 + 24px));
  align-items: stretch;
}

/* Every direct child is a snap target, whatever kind of card it is. */
.carousel-track > * { scroll-snap-align: start; }

.proj-card {
  width: 320px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}

.proj-card:hover {
  border-color: rgba(34, 197, 94, 0.3);
  box-shadow: var(--shadow-md);
  transform: translateY(-3px);
}

/* Project screenshot header — 16:9 to match the 640x360 images in images/. */
.proj-visual {
  aspect-ratio: 16 / 9;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}

/* Sized by the box, not by the width/height attributes, so it never stretches. */
.proj-visual img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  -webkit-user-drag: none;
  user-select: none;
}

.proj-card:hover .proj-visual img { transform: scale(1.04); }

/* Solid pill: it now sits on light and dark screenshots alike. */
.proj-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--accent-deep);
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid rgba(21, 128, 61, 0.18);
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.14);
  border-radius: 100px;
  padding: 3px 9px;
  z-index: 2;
}

.proj-body {
  padding: 20px;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.proj-category {
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #9CA3AF;
  margin-bottom: 8px;
}

.proj-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--primary);
  margin-bottom: 8px;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.proj-desc {
  font-size: 13px;
  color: #6B7280;
  line-height: 1.55;
  margin-bottom: 14px;
}

.proj-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}

.proj-tag {
  font-family: var(--font-ui);
  font-size: 10px;
  color: var(--secondary);
  background: rgba(30, 41, 59, 0.06);
  border: 1px solid rgba(30, 41, 59, 0.12);
  border-radius: 4px;
  padding: 2px 7px;
  font-weight: 500;
}

/* Pinned to the card's bottom so the numbers line up across every card
   regardless of how many lines a description wraps to. */
.proj-meta {
  display: flex;
  gap: 0;
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.proj-stat {
  flex: 1;
  padding-right: 12px;
  min-width: 0;
}

.proj-stat + .proj-stat {
  padding-left: 14px;
  border-left: 1px solid var(--border);
}

.proj-stat-num {
  font-family: var(--font-ui);
  font-size: 19px;
  font-weight: 700;
  color: var(--accent-deep);
  letter-spacing: -0.02em;
  line-height: 1;
}

.proj-stat-label {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: #9CA3AF;
  margin-top: 6px;
}

/* ── PRICING SECTION ── */
.pricing {
  padding: 72px 0;
  background: var(--white);
}

.pricing-header {
  text-align: center;
  max-width: 560px;
  margin: 0 auto 32px;
}

.pricing-header .section-label {
  display: inline-flex;
}

.pricing-card-wrap {
  max-width: 100%;
  margin: 0 auto;
}

/* Pitch left, decision panel right. z-index lifts it over the card's two
   ::before/::after glow layers. */
.pricing-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: 44px;
  /* The panel is taller than the pitch, so `start` left a dead void under
     the feature list. Centring balances the two columns. */
  align-items: center;
  position: relative;
  z-index: 1;
}

.pricing-panel {
  background: rgba(255,255,255,0.045);
  border: 1px solid rgba(255,255,255,0.09);
  border-radius: 16px;
  padding: 26px;
}

.pricing-main-card {
  background: var(--primary);
  border-radius: 24px;
  padding: 40px;
  border: 1px solid rgba(34, 197, 94, 0.2);
  box-shadow: var(--shadow-lg), 0 0 80px rgba(34, 197, 94, 0.08);
  position: relative;
  overflow: hidden;
}

.pricing-main-card::before {
  content: '';
  position: absolute;
  top: -100px;
  right: -100px;
  width: 300px;
  height: 300px;
  background: radial-gradient(circle, rgba(34, 197, 94, 0.1) 0%, transparent 70%);
  pointer-events: none;
}

.pricing-main-card::after {
  content: '';
  position: absolute;
  bottom: -80px;
  left: -80px;
  width: 240px;
  height: 240px;
  background: radial-gradient(circle, rgba(20, 83, 45, 0.55) 0%, transparent 70%);
  pointer-events: none;
}

.pricing-plan-name {
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.pricing-plan-name::before {
  content: '';
  display: inline-block;
  width: 8px;
  height: 8px;
  background: var(--accent);
  border-radius: 50%;
  animation: pulse-dot 2s ease-in-out infinite;
}

.pricing-headline {
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 700;
  color: var(--white);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 8px;
}

/* Highlight = same sans as the heading, upright, accent colour. No serif,
   no italic. */
.pricing-headline em {
  font-style: normal;
  color: var(--accent);
}

.pricing-sub {
  font-size: 15px;
  color: rgba(255,255,255,0.55);
  margin-bottom: 36px;
  line-height: 1.5;
}

.pricing-amounts {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  margin-bottom: 20px;
  text-align: center;
}

.pricing-amount-block {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-sm);
  padding: 26px 20px;
}

.pricing-amount-label {
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  margin-bottom: 8px;
}

.pricing-amount-val {
  font-family: var(--font-ui);
  font-size: 50px;
  font-weight: 500;
  color: var(--accent);
  line-height: 1;
  letter-spacing: -0.03em;
}

.pricing-amount-val small {
  font-size: 24px;
  opacity: 0.7;
}

.pricing-amount-note {
  font-size: 12px;
  color: rgba(255,255,255,0.4);
  margin-top: 6px;
  font-family: var(--font-ui);
}

.pricing-features-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 0;
}

.pricing-feature-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  color: rgba(255,255,255,0.75);
  line-height: 1.4;
}

.pfi-icon {
  width: 20px;
  height: 20px;
  min-width: 20px;
  border-radius: 50%;
  background: rgba(34, 197, 94, 0.12);
  border: 1px solid rgba(34, 197, 94, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
}

.pfi-icon svg {
  width: 11px;
  height: 11px;
  color: var(--accent);
}

.pricing-compare-label {
  font-family: var(--font-ui);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  margin-bottom: 10px;
}

.pricing-cta-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
}

.pricing-cta-btn {
  /* NOT flex:1 — in a column that makes the basis a HEIGHT. */
  flex: none;
  width: 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 500;
  color: var(--white);
  background: var(--accent-cta);
  padding: 16px 32px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background var(--transition), transform var(--transition), box-shadow var(--transition);
  cursor: pointer;
  border: none;
}

.pricing-cta-btn:hover {
  background: var(--accent-cta-hover);
  transform: translateY(-2px);
  box-shadow: 0 8px 32px rgba(34, 197, 94, 0.45);
}

.pricing-cta-btn:active { transform: scale(0.96); }

.pricing-trust-note {
  font-size: 12px;
  color: rgba(255,255,255,0.35);
  font-family: var(--font-ui);
  line-height: 1.5;
  text-align: center;
}

/* ── REVIEWS ── */
.reviews {
  padding: 72px 0;
  background: var(--bg);
}

.reviews-header {
  text-align: center;
  max-width: 560px;
  margin: 0 auto 32px;
}

.reviews-header .section-label {
  display: inline-flex;
}

.stars-overall {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 16px;
}

.stars {
  display: flex;
  gap: 3px;
}

.star {
  width: 18px;
  height: 18px;
  color: #F59E0B;
  fill: #F59E0B;
}

.rating-score {
  font-family: var(--font-ui);
  font-size: 22px;
  font-weight: 500;
  color: var(--primary);
}

.rating-count {
  font-size: 13px;
  color: #9CA3AF;
}



.review-card {
  width: 360px;
  flex-shrink: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px;
  display: flex;
  flex-direction: column;
  transition: border-color var(--transition), box-shadow var(--transition), transform var(--transition);
}

.review-card:hover {
  border-color: rgba(34, 197, 94, 0.25);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.review-stars {
  display: flex;
  gap: 3px;
  margin-bottom: 14px;
}

.review-text {
  font-size: 14.5px;
  color: #374151;
  line-height: 1.7;
  margin-bottom: 18px;
}

/* Pinned to the card's bottom behind a rule: the quotes are different
   lengths, so as a plain block the author rows sat 23px apart. */
.review-author {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.review-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--primary);
  border: 1px solid rgba(34, 197, 94, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
  flex-shrink: 0;
}

.review-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--primary);
  line-height: 1.2;
}

.review-role {
  font-size: 12px;
  color: #9CA3AF;
  font-family: var(--font-ui);
}

/* ── FAQ ── */
.faq {
  padding: 72px 0;
  background: var(--white);
}

.faq-header {
  text-align: center;
  max-width: 560px;
  margin: 0 auto 32px;
}

.faq-header .section-label {
  display: inline-flex;
}

/* Two columns of native <details>, ported from taxi-dispatch-software.
   .faq-col (not a single grid) so a long answer only pushes its own column. */
.faq-listing {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: 16px;
  max-width: 100%;
  margin: 0 auto;
}

.faq-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.faq-item {
  background: var(--surface);
  border: 1px solid var(--surface-border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(15,23,42,0.05);
  transition: box-shadow var(--transition), border-color var(--transition), transform var(--transition);
}

.faq-item:hover {
  border-color: rgba(34, 197, 94, 0.35);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 18px 20px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--primary);
  line-height: 1.5;
  cursor: pointer;
  user-select: none;
  list-style: none;
}

/* Kill the default disclosure triangle — the chevron replaces it. */
.faq-item summary::-webkit-details-marker,
.faq-item summary::marker { display: none; }

.faq-item summary:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: -2px;
}

.faq-item summary span:first-child { min-width: 0; }

.faq-chevron {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  fill: var(--accent-deep);
  transition: transform 0.3s ease;
}

.faq-item[open] {
  border-color: rgba(34, 197, 94, 0.35);
  box-shadow: var(--shadow-md);
}

.faq-item[open] .faq-chevron { transform: rotate(180deg); }

.faq-answer {
  padding: 0 20px 18px;
  border-top: 1px solid var(--surface-border);
  padding-top: 14px;
  margin-top: 2px;
}

.faq-answer p {
  font-size: 13.5px;
  color: #6B7280;
  line-height: 1.7;
  margin: 0;
}

/* ── CTA SECTION ── */
#cta.cta-section {
  padding: 72px 0;
  background: var(--primary);
  position: relative;
  overflow: hidden;
}

#cta.cta-section::before {
  content: '';
  position: absolute;
  top: -150px;
  left: 50%;
  transform: translateX(-50%);
  width: 600px;
  height: 600px;
  background: radial-gradient(circle, rgba(34, 197, 94, 0.1) 0%, transparent 65%);
  pointer-events: none;
}

/* Pitch + buttons left, social proof right — mirrors .pricing-grid so the
   page's two dark sections share a shape. */
.cta-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: 56px;
  align-items: center;
  text-align: left;
  position: relative;
  z-index: 1;
}

.cta-slots {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: rgba(34, 197, 94, 0.08);
  border: 1px solid rgba(34, 197, 94, 0.25);
  border-radius: 100px;
  padding: 8px 18px;
  margin-bottom: 28px;
  font-family: var(--font-ui);
  font-size: 12px;
  color: rgba(255,255,255,0.7);
  letter-spacing: 0.05em;
}

.cta-slots-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
  animation: pulse-dot 2s ease-in-out infinite;
}

.cta-proof {
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 16px;
  padding: 26px 28px;
}

/* The guarantees, promoted out of the 12px throwaway line under the buttons. */
.cta-proof-list {
  list-style: none;
  margin: 18px 0 0;
  padding: 18px 0 0;
  border-top: 1px solid rgba(255,255,255,0.1);
  display: flex;
  flex-direction: column;
  gap: 11px;
}

.cta-proof-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  color: rgba(255,255,255,0.75);
  line-height: 1.4;
}

.cta-proof-list li::before {
  content: '';
  width: 18px;
  height: 18px;
  min-width: 18px;
  border-radius: 50%;
  background: rgba(34, 197, 94, 0.12);
  border: 1px solid rgba(34, 197, 94, 0.35);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%2322C55E' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 9px;
}

.cta-proof-stars {
  display: flex;
  gap: 3px;
}

.cta-proof-rating {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
}

.cta-proof-score {
  font-family: var(--font-ui);
  font-size: 22px;
  font-weight: 700;
  color: var(--white);
  line-height: 1;
}

.cta-proof-count {
  font-family: var(--font-ui);
  font-size: 12px;
  color: rgba(255,255,255,0.4);
}

/* Same shape as the hero KPI strip. */
.cta-proof-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.cta-proof-stat { padding-right: 16px; }

.cta-proof-stat + .cta-proof-stat {
  padding-right: 0;
  padding-left: 16px;
  border-left: 1px solid rgba(255,255,255,0.1);
}

.cta-proof-stat strong {
  display: block;
  font-size: 26px;
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.02em;
  line-height: 1;
}

.cta-proof-stat strong em {
  font-style: normal;
  font-family: inherit;
  color: var(--accent);
  font-weight: 700;
}

.cta-proof-stat span {
  display: block;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  margin-top: 8px;
  line-height: 1.35;
}

.cta-eyebrow {
  font-family: var(--font-ui);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.cta-heading {
  font-size: clamp(32px, 5vw, 56px);
  font-weight: 700;
  color: var(--white);
  line-height: 1.1;
  letter-spacing: -0.03em;
  margin-bottom: 20px;
}

/* Highlight = same sans as the heading, upright, accent colour. No serif,
   no italic. */
.cta-heading em {
  font-style: normal;
  color: var(--accent);
}

.cta-sub {
  font-size: 17px;
  color: rgba(255,255,255,0.55);
  max-width: 100%;
  margin: 0 0 26px;
  line-height: 1.6;
}

.cta-actions {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 0;
}

.cta-btn-main {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 16px;
  font-weight: 500;
  color: var(--white);
  background: var(--accent-cta);
  padding: 16px 40px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: background var(--transition), transform var(--transition), box-shadow var(--transition);
  cursor: pointer;
  border: none;
}

.cta-btn-main:hover {
  background: var(--accent-cta-hover);
  transform: translateY(-2px);
  box-shadow: 0 12px 36px rgba(34, 197, 94, 0.4);
}

.cta-btn-main:active { transform: scale(0.96); }

.cta-btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 500;
  color: rgba(255,255,255,0.75);
  background: transparent;
  border: 1.5px solid rgba(255,255,255,0.15);
  padding: 16px 32px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: border-color var(--transition), color var(--transition), transform var(--transition);
  cursor: pointer;
}

.cta-btn-ghost:hover {
  border-color: rgba(255,255,255,0.4);
  color: var(--white);
  transform: translateY(-1px);
}

/* ── FOOTER (minimal: copyright + legal, per taxi-dispatch-software) ── */
.footer-min {
  background: var(--white);
  border-top: 1px solid var(--border);
  padding: 20px 0;
  color: #6B7280;
  font-size: 13.5px;
}

.footer-min .footer-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}

.footer-copy {
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: #6B7280;
  letter-spacing: 0.2px;
}

.footer-copy span {
  color: var(--accent-deep);
  font-weight: 600;
}

.footer-links {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.footer-links a {
  font-size: 13.5px;
  color: var(--primary);
  text-decoration: none;
  transition: color var(--transition);
  display: inline-flex;
  align-items: center;
  min-height: 32px;
}

.footer-links a:hover { color: var(--accent-deep); }

.footer-links .sep {
  color: var(--muted);
  user-select: none;
}

@media (max-width: 768px) {
  .footer-min .footer-row { flex-direction: column; gap: 12px; text-align: center; }
  /* The 3 links wrap at phone widths; centre them and drop the pipes so a
     separator never dangles at the end of a wrapped line. */
  .footer-links { justify-content: center; gap: 8px 18px; }
  .footer-links .sep { display: none; }
}

/* ── ANIMATIONS ── */
@keyframes fade-up {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

.fade-up {
  animation: fade-up 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
}

.delay-1 { animation-delay: 0.1s; }
.delay-2 { animation-delay: 0.2s; }
.delay-3 { animation-delay: 0.3s; }

@media (prefers-reduced-motion: reduce) {
  /* `*` does not match pseudo-elements, so ::before/::after must be named
     explicitly — otherwise the pulsing dots and the offer band's sweep keep
     animating for users who asked them not to. */
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
}

/* ── RESPONSIVE ── */
@media (max-width: 1024px) {
  .hero { padding: 72px 0 0; }
  .hero-grid { grid-template-columns: 1fr; gap: 28px; }
  /* Was max-width:480 — a hangover from the 2-column layout. Once the hero
     stacks, that pinned the card narrow and pushed its 7 features into 7 rows
     beside 315px of dead space. */
  .hero-visual { max-width: none; }
  .price-features { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 24px; }
  .hero-ticker { margin-top: 24px; }
  /* Below this the panel can't hold the comparison table's three columns
     next to a readable feature list. minmax(0,…) not a bare 1fr: 1fr floors
     at min-content and blows the card open at 320px. */
  .pricing-grid { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .cta-grid { grid-template-columns: minmax(0, 1fr); gap: 36px; }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .steps::before { display: none; }
}

@media (max-width: 768px) {
  /* Scope to the nav bar: an unscoped .nav-cta rule also hid the CTA inside
     .mobile-menu, which is exactly where it's needed. */
  header nav > .nav-links { display: none; }
  .hamburger { display: flex; }
  /* This block is after the 1024 one, so these must not re-loosen what it
     tightened. */
  .hero-actions { flex-direction: column; }
  .hero-actions a { width: 100%; justify-content: center; }
  .hero-tag-bl { bottom: -10px; left: -6px; }
  .cta-actions { flex-direction: column; align-items: stretch; }
  .cta-btn-main, .cta-btn-ghost { width: 100%; justify-content: center; }
  .cta-proof { padding: 20px 18px; }
  .pricing-main-card { padding: 28px 20px; }
  .pricing-features-grid { grid-template-columns: 1fr; }
  .pricing-panel { padding: 20px 16px; }
  .review-card { width: 300px; }
  /* Two columns of FAQ don't fit a phone — one column, one flow. */
  .faq-listing { grid-template-columns: 1fr; gap: 12px; }
  .faq-col { gap: 12px; }
  .faq-item summary { padding: 16px; font-size: 14px; }
  .faq-answer { padding: 12px 16px 16px; }
}

/* The 4-col KPI strip holds down to ~700: at 768/720 only the last label
   wraps and the strip is 86px, vs 140px once it stacks. Below 700 every label
   goes two-line, so 2x2 wins. */
@media (max-width: 700px) {
  .hero-stats { grid-template-columns: repeat(2, 1fr); gap: 22px 0; }
  .hero-stat:nth-child(2n)::after { display: none; }
  .hero-stat:nth-child(2n) { padding-right: 0; }
  .hero-stat:nth-child(2n+1) { padding-left: 0; }
}

@media (max-width: 600px) {
  /* Below this the 2-col grid can no longer fit its min-content width and
     blows out the page; stack instead. */
  .steps { grid-template-columns: 1fr; }
  /* Two feature columns would put the longest one on three lines here. */
  .price-features { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
  .container { padding: 0 16px; }
  .mobile-menu { padding: 16px; }
  .pricing-cta-btn { padding: 16px 18px; }
  .pricing-panel { padding: 18px 12px; }
  .compare-row { padding: 9px 8px; font-size: 11px; }
  .compare-row.header { font-size: 9px; }
  h1.hero-heading { font-size: 32px; }
}

.openCalendly { cursor: pointer; }

/* The shared js/whatsapp-float.js hardcodes a system-ui/Segoe UI/Roboto
   stack on its tooltip. That file is loaded by every landing page, so pull
   the label onto this page's font here instead of editing it there. */
.aw-label { font-family: var(--font-ui) !important; }

/* ── FOCUS STATES ── */
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent-deep);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── Extracted inline styles (moved out of index.html markup) ── */

/* Hero price card "/mo" suffix: smaller + dimmer than the "$" span.
   `.price-val .price-val-mo` is deeper than `.price-val span`, so it wins
   that rule's font-size/color while still inheriting its opacity:0.7. */
.price-val .price-val-mo { font-size: 20px; color: rgba(34, 197, 94, 0.6); }

/* A review row's unfilled 5th star (the 4.5-star cards). Compound selector
   out-specifies `.star`, so the grey wins regardless of source order. */
.star.star-empty { fill: #E5E7EB; color: #E5E7EB; }

/* ── TEXT WRAPPING ──
   Keeps a lone word off the last line of body copy. Browsers without
   text-wrap:pretty just wrap as before; the short one-liners that matter most
   also carry an &nbsp; between their last two words in index.html. */
.hero-desc,
.section-sub,
.step-desc,
.proj-desc,
.review-text,
.faq-item summary > span,
.faq-answer p,
.cta-sub,
.pricing-sub,
.how-footer-copy,
.price-features li,
.pricing-feature-item,
.cta-proof-list li,
.lead-modal-left p {
  text-wrap: pretty;
}

/* A phrase that must not split across two lines ("AI agents",
   "1 already taken", the three parts of the modal note). */
.nowrap { white-space: nowrap; }

/* "Stop waiting. Start / shipping." — the accent half moves down as one. */
.cta-heading em { white-space: nowrap; }

@media (max-width: 420px) {
  /* Full-width CTA: 40px side padding pushed "— $999/mo" onto a second line. */
  .cta-btn-main { padding: 16px 18px; font-size: 15px; }
}

@media (max-width: 380px) {
  /* The trailing rule is decoration; without it the eyebrow fits one line. */
  .hero-eyebrow::after { display: none; }
}
