/* ============================================================
   Southgate Strategies — southgatestrategies.com

   Brand kit (July 2026, southgate-brand-kit/brand-guide.html):
   charcoal #2A2D2B · forest #2F5D3F · bone #F6F5F1
   fern #4E8B63 (accents on dark) · stone #6A6E68
   Type: Montserrat (display/labels/buttons) + Libre Franklin (body)

   Layout system (July 2026 direction): near-black canvas, oversized
   light display type, pill controls, large soft-bordered cards, and
   a bone-inverted tail for About → Contact → Footer.
   ============================================================ */

/* ============================================================
   SELF-HOSTED FONTS  (2026-07-25)

   These used to come from fonts.googleapis.com. Three reasons they
   don't any more:

   1. Speed. The old setup cost two chained introductions to servers
      the browser had never met -- googleapis for the stylesheet, then
      gstatic for the font files, each needing DNS + TCP + TLS before a
      byte moved, and the second could not start until the first
      finished. A stylesheet blocks rendering, so that whole chain sat
      in front of the first painted word. Served from our own origin the
      browser reuses the connection it already has.
   2. Privacy. Every visitor's browser was handing their IP address to
      Google. That is the practice a German court ruled against in 2022,
      and removing it takes a third party out of the consent question
      entirely.
   3. Weight. Google served six static files (Montserrat 300/400/500/600,
      Libre Franklin 400/600). These are the VARIABLE versions, so two
      files carry every weight in the range -- 66KB total.

   Only the `latin` subset is shipped. Google splits each family into
   five unicode subsets; the site's text was scanned and uses 80 distinct
   characters, of which the only non-ASCII ones are NBSP, ©, ·, ×, – and
   — , all inside `latin`. If copy ever gains accented characters beyond
   Latin-1 (a client name like "Muñoz" is fine; "Łukasz" is not), add the
   latin-ext files rather than letting them silently fall back to Arial.

   The unicode-range below is copied verbatim from Google's own CSS. The
   font files are pinned versions (Montserrat v31, Libre Franklin v20);
   re-download both if you ever change the weight range.
   ============================================================ */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 300 600;          /* variable axis, not a single weight */
  font-display: swap;
  src: url('../assets/fonts/montserrat-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Libre Franklin';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../assets/fonts/libre-franklin-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* canvas: near-black with the brand's green cast */
  --ink: #0E100F;            /* hero floor, deepest */
  --canvas: #141715;         /* page canvas */
  --raise: #1B1F1C;          /* raised control / secondary pill */
  --card: rgba(0, 0, 0, 0.22);
  --card-raise: rgba(246, 245, 241, 0.035);

  --charcoal: #2A2D2B;
  --charcoal-deep: #222422;
  --charcoal-raise: #33362F;
  --forest: #2F5D3F;
  --bone: #F6F5F1;
  --fern: #4E8B63;
  --fern-bright: #74B08A;
  --stone: #6A6E68;

  --line: rgba(246, 245, 241, 0.10);
  --line-strong: rgba(246, 245, 241, 0.18);
  --hairline: #E2E0D8;
  --hairline-dark: rgba(246, 245, 241, 0.10);

  --fg: #F6F5F1;
  /* Lifted from 0.55 to 0.64 with the type recalibration. At 0.55 this
     measured 5.71:1 -- passing AA on paper -- but WCAG's thresholds are
     calibrated around 16px+ text, and this variable was mostly being used
     on the smallest copy on the site. Small, light-weight and dimmed at
     once is much harder to read than any one of those alone, which is
     what "almost hard to read" was. */
  --fg-mute: rgba(246, 245, 241, 0.64);
  --fg-soft: rgba(246, 245, 241, 0.72);

  --font: 'Libre Franklin', Arial, sans-serif;
  --font-head: 'Montserrat', Arial, sans-serif;

  /* ---- type scale ----------------------------------------------------
     Calibrated for the actual buyer, not for the design reference. The
     giga.ai layout this site borrows from sizes type for a young
     technical audience on good monitors; Southgate sells to HVAC owners
     in NWA who skew 45-65, an age at which focusing up close is
     universally harder. The look is unchanged -- oversized light display
     type, pill controls, the bone tail -- but the numbers underneath it
     assume presbyopic eyes.

     This replaced 18 ad-hoc values scattered across 78 declarations, of
     which 54% rendered under 14px and 34% under 12px, bottoming out at
     9.6px. Pick a step from this scale; do not invent a new number, or
     the drift starts over.

     12px is a HARD FLOOR and it belongs to tracked uppercase micro-labels
     only -- eyebrows, stat labels, section marks. Nothing on the site may
     be smaller. Two deliberate exemptions are marked at their rules:
     .phone-avatar (initials inside a fixed 40px circle) and
     .chart-values text (SVG chart labels), both graphics rather than
     reading text.

     Contrast was measured after this change, not assumed: every
     text/background pair still passes WCAG AA. */
  --text-2xs:  0.75rem;    /* 12px — tracked uppercase micro-labels. FLOOR. */
  --text-xs:   0.8125rem;  /* 13px — dense meta inside the demo mockups */
  --text-sm:   0.875rem;   /* 14px — compact UI: buttons, nav, fine print */
  --text-md:   1rem;       /* 16px — secondary copy */
  --text-base: 1.0625rem;  /* 17px — body copy, the default reading size */
  --text-lg:   1.1875rem;  /* 19px — lede, emphasis, small headings */
  --text-xl:   1.375rem;   /* 22px — sub-headings */

  --container: 1265px;
  --gutter: clamp(20px, 4vw, 32px);
  --section-pad: clamp(4.5rem, 9vw, 7.5rem);

  --radius-card: 16px;
  --radius-lg: 22px;
  --radius-pill: 999px;
  --shadow-soft: 0 1px 2px rgba(14, 16, 15, 0.05), 0 18px 60px -22px rgba(14, 16, 15, 0.30);
  --shadow-card: 0 40px 120px -50px rgba(0, 0, 0, 0.9);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  font-family: var(--font);
  font-size: var(--text-base);
  /* 1.6 rather than 1.55: longer measure at 17px needs a little more
     leading to keep the eye from dropping a line on the return sweep. */
  line-height: 1.6;
  color: var(--fg);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }

::selection { background: var(--fern); color: var(--ink); }

a { color: inherit; text-decoration: none; }

/* Keyboard users land here first and can jump the header nav.
   Off-screen until focused, per WCAG 2.4.1 Bypass Blocks. */
.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -130%);
  z-index: 999;
  padding: 0.7em 1.4em;
  border-radius: 0 0 var(--radius-pill) var(--radius-pill);
  background: var(--bone);
  color: var(--charcoal);
  font-family: var(--font-head);
  font-size: var(--text-sm);
  font-weight: 500;
  transition: transform 180ms ease;
}
.skip-link:focus { transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

:focus-visible {
  outline: 2px solid var(--fern-bright);
  outline-offset: 3px;
  border-radius: 4px;
}
.on-light :focus-visible { outline-color: var(--forest); }

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

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* ---------- typography ----------
   Display type runs large and light; scale carries the confidence,
   never weight. Body copy stays small and quiet beneath it. */

h1 {
  font-family: var(--font-head);
  font-size: clamp(2.5rem, 5.4vw, 3.7rem);
  font-weight: 300;
  line-height: 1.16;
  letter-spacing: -0.03em;
}

h2 {
  font-family: var(--font-head);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 300;
  line-height: 1.24;
  letter-spacing: -0.025em;
}

h3 {
  font-family: var(--font-head);
  font-size: clamp(1.35rem, 2.1vw, 1.875rem);
  font-weight: 400;
  line-height: 1.32;
  letter-spacing: -0.015em;
}

h4 {
  font-family: var(--font-head);
  font-size: var(--text-lg);
  font-weight: 500;
  line-height: 1.5;
}

/* 52ch, not 68ch, and the number is not arbitrary.

   `ch` is the width of the "0" glyph, and Libre Franklin has wide figures:
   measured in the browser, 1ch = 11.0px at a 16px font size while the
   average character is only 7.2px. So `ch` overstates real line length by
   1.52x here, and the old 68ch cap allowed ~94 actual characters -- which
   is why it was capping nothing at all. Every paragraph on the page was
   being sized by its container instead.

   Comfortable measure tops out near 75 characters, and overlong lines cost
   an older reader more than a younger one: the return sweep to the start of
   the next line is where the eye loses its place. 52ch = 572px = ~79 real
   characters, and it matches the cap already used on .pathway-copy p.

   If the body font ever changes, re-measure the ratio rather than assuming
   this number still means what it meant here. */
p { max-width: 52ch; }

.lede {
  font-size: var(--text-lg);
  line-height: 1.55;
  color: var(--fg-mute);
  max-width: 46ch;
}

/* the small tracked label that opens a section */
/* Small green labels sit on the near-black canvas, where the deep
   forest tone falls under 4.5:1 — the brighter fern carries them. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.75em;
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fern-bright);
  margin-bottom: 1.4rem;
}
.eyebrow::before {
  content: "";
  width: 18px;
  height: 2px;
  background: currentColor;
  opacity: 0.6;
  border-radius: 1px;
  flex: none;
}

.on-light { color: var(--charcoal); }
.on-light .eyebrow { color: var(--forest); }
.on-light .lede { color: var(--stone); }

/* ---------- pill controls ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  min-height: 44px;
  padding: 0.6em 1.35em;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-family: var(--font-head);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.005em;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 200ms ease, border-color 200ms ease,
              color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}

/* primary reads as light-on-dark; it inverts to forest on bone */
.btn-primary {
  background: var(--bone);
  color: var(--ink);
}
.btn-primary:hover {
  background: #FFFFFF;
  transform: translateY(-1px);
  box-shadow: 0 12px 34px -14px rgba(246, 245, 241, 0.4);
}

.btn-ghost {
  background: var(--raise);
  color: var(--fg);
  border-color: var(--line);
}
.btn-ghost:hover {
  border-color: var(--line-strong);
  background: #232724;
  transform: translateY(-1px);
}

.on-light .btn-primary {
  background: var(--forest);
  color: #FFFFFF;
}
.on-light .btn-primary:hover {
  background: var(--fern);
  box-shadow: 0 12px 34px -14px rgba(47, 93, 63, 0.55);
}
.on-light .btn-ghost {
  background: transparent;
  color: var(--charcoal);
  border-color: rgba(42, 45, 43, 0.25);
}
.on-light .btn-ghost:hover {
  border-color: rgba(42, 45, 43, 0.5);
  background: rgba(42, 45, 43, 0.04);
}

.btn .btn-arrow {
  width: 14px;
  height: 14px;
  flex: none;
  transition: transform 220ms ease;
}
.btn:hover .btn-arrow { transform: translateX(3px); }

/* ---------- header ----------
   Floats transparent over the hero, then condenses into a
   translucent pill once the page moves. */

.site-header {
  position: fixed;
  inset: 14px 0 auto 0;
  z-index: 60;
  transition: transform 280ms ease;
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: 56px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  padding-top: 0;
  padding-bottom: 0;
  transition: background-color 300ms ease, border-color 300ms ease,
              backdrop-filter 300ms ease, max-width 300ms ease,
              box-shadow 300ms ease;
}

.site-header.scrolled .container {
  max-width: 1040px;
  background: rgba(20, 23, 21, 0.72);
  border-color: var(--line);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  box-shadow: 0 20px 50px -30px rgba(0, 0, 0, 0.9);
}

.brand-link { display: inline-flex; align-items: center; flex: none; }
.brand-link img { height: 46px; width: auto; }

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.2vw, 2rem);
}

.site-nav a:not(.btn) {
  position: relative;
  font-family: var(--font-head);
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--fg-soft);
  transition: color 200ms ease;
}
.site-nav a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1px;
  background: var(--fern-bright);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 240ms ease;
}
.site-nav a:not(.btn):hover { color: var(--fg); }
.site-nav a:not(.btn):hover::after,
.site-nav a:not(.btn):focus-visible::after { transform: scaleX(1); }

.site-nav .btn { min-height: 38px; padding: 0.45em 1.15em; }

@media (max-width: 760px) {
  .site-nav a:not(.btn) { display: none; }
  .brand-link img { height: 40px; }
}

/* ---------- hero ----------
   Full-height black stage: badge, oversized light headline,
   one quiet line of support, two pills. */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 100vh;
  min-height: 100svh;
  padding-top: clamp(7rem, 14vh, 9.5rem);
  padding-bottom: clamp(5rem, 10vh, 7rem);
  overflow: hidden;
  background: var(--ink);
}

/* The plate is overdrawn well past the frame on every side, so scroll
   parallax and cursor drift can never pull an edge into view. Parallax
   moves .hero-bg and drift moves .hero-media — separate elements, so
   the two effects never fight over one transform. */
.hero-bg {
  position: absolute;
  inset: -14% -5%;
  z-index: 0;
  will-change: transform;
}

.hero-media {
  position: absolute;
  inset: 0;
  will-change: transform;

  /* Blur-up placeholder: a 24px-wide version of the real plate, inlined
     as ~480 bytes so it costs no request and paints with the HTML. The
     full image lands on top of it, so the hero is never an empty box on
     a slow connection -- it is the right picture, just soft, and then it
     sharpens. Scaled past the edges because blurring samples past them. */
  background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAgABQAEvAAD//gAQTGF2YzYxLjE5LjEwMAD/2wBDAAgQEBMQExYWFhYWFhoYGhsbGxoaGhobGxsdHR0iIiIdHR0bGx0dICAiIiUmJSMjIiMmJigoKDAwLi44ODpFRVP/xABsAAADAQEAAAAAAAAAAAAAAAADBQYIBwEBAQAAAAAAAAAAAAAAAAAAAgMQAAIABAMFCQEAAAAAAAAAAAECAAQDETEhBRIGcpFSgaFhUSITFcLSQREAAwEBAQEAAAAAAAAAAAAAAAFRESFSIv/AABEIAA4AGAMBIgACEQADEQD/2gAMAwEAAhEDEQA/AA0t4a1TEphn6SfteHA1io2SNTLeTKUHNiBGfFaKuW1evLfxH4lzPbF9URD69M6tVn9SpLtMlNV6iBs975wp+bmuqX5D9RB1JkzzXYvfGxN1HDhaAez4w+RA11n/2Q==");
  background-size: cover;
  background-position: 58% 46%;
}
.hero-media::before {
  content: "";
  position: absolute;
  inset: -4%;
  background: inherit;
  background-position: 58% 46%;
  filter: blur(22px);
  transform: scale(1.06);
}

.hero-media img,
.hero-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 58% 46%;
}

/* the footage fades in over the still once it can actually play */
/* The plate fades in over the placeholder. It starts visible so that a
   failed script, or no script at all, still shows the picture; main.js
   only opts in to the fade when the image has not decoded yet. */
.hero-media img {
  transition: opacity 700ms ease;
}
.hero-media img.is-loading { opacity: 0; }

.hero-video {
  opacity: 0;
  transition: opacity 1400ms ease;
}
.hero-video.is-live { opacity: 1; }

/* the plate sits behind the type as atmosphere, not as a picture.
   It stays pinned to the hero while the plate drifts underneath. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Tuned by sampling the real plate pixels behind every hero element:
     this is the lightest scrim that still clears WCAG on all of them
     (headline 4.1:1 against a 3.0 floor), so the fog keeps its depth. */
  background:
    radial-gradient(76% 60% at 50% 46%, rgba(14, 16, 15, 0.60), transparent 74%),
    linear-gradient(to bottom,
      rgba(14, 16, 15, 0.55) 0%,
      rgba(14, 16, 15, 0.24) 30%,
      rgba(14, 16, 15, 0.62) 72%,
      var(--ink) 100%);
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.42;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.16 0 0 0 0 0.18 0 0 0 0 0.17 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* first light: soft shafts from the upper right */
.hero-light {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
}
.hero-light i {
  position: absolute;
  display: block;
  top: -55%;
  height: 165%;
  border-radius: 50%;
  transform: rotate(-26deg);
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(246, 245, 241, 0.08),
    rgba(246, 245, 241, 0.02) 55%,
    transparent 75%);
}
.hero-light i:first-child { right: 2%; width: 36rem; }
.hero-light i:last-child { right: 26%; width: 15rem; transform: rotate(-22deg); }

@media (max-width: 760px) {
  .hero-light { display: none; }
}

.hero-inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 900px;
}

/* the announcement pill above the headline */
.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  padding: 0.45em 0.5em 0.45em 1.1em;
  margin-bottom: clamp(1.6rem, 3vw, 2.2rem);
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: rgba(246, 245, 241, 0.05);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-soft);
  transition: background-color 240ms ease, border-color 240ms ease, color 240ms ease;
}
.hero-badge:hover {
  background: rgba(246, 245, 241, 0.09);
  border-color: var(--line-strong);
  color: var(--fg);
}
.hero-badge .badge-sep {
  width: 1px;
  height: 14px;
  background: var(--line-strong);
  flex: none;
}
.hero-badge .badge-go {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(246, 245, 241, 0.1);
  flex: none;
}
.hero-badge .badge-go svg { width: 11px; height: 11px; }
.hero-badge:hover .badge-go { background: rgba(246, 245, 241, 0.18); }

.hero h1 {
  max-width: 16em;
  font-size: clamp(2.6rem, 6.4vw, 4.6rem);
  font-weight: 300;
  line-height: 1.14;
  letter-spacing: -0.035em;
  color: var(--bone);
  margin-bottom: 1.5rem;
}
.hero h1 .h1-accent { font-weight: 500; }

/* masked line reveal */
.hero h1 .line { display: block; overflow: hidden; }
.hero h1 .line > span { display: inline-block; }

.hero .lede {
  color: var(--fg-soft);
  max-width: 42ch;
  margin-bottom: clamp(2rem, 4vw, 2.6rem);
}

.hero-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: clamp(2.4rem, 5vw, 3.4rem);
}

.hero-trades {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.8rem;
  color: var(--fg-mute);
  font-size: var(--text-md);
}
.hero-trades .fence { display: inline-flex; gap: 4px; }
.hero-trades .fence i {
  width: 2px;
  height: 13px;
  background: var(--fern);
  opacity: 0.85;
  border-radius: 1px;
}

.hero-cue {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  pointer-events: none;
}
.hero-cue span {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  /* 0.45 measured 4.25:1 once this went from 9.6px to the 12px floor --
     the only pair on the page that failed AA after the recalibration.
     0.55 clears it, and this sits over hero footage whose luminance
     varies, so the extra headroom is not decorative. */
  color: rgba(246, 245, 241, 0.55);
}
.hero-cue i {
  width: 1px;
  height: 38px;
  background: linear-gradient(to bottom, transparent, rgba(246, 245, 241, 0.6));
  animation: cue-drop 2.4s infinite ease-in-out;
  transform-origin: top center;
}
@keyframes cue-drop {
  0% { transform: scaleY(0); }
  45% { transform: scaleY(1); transform-origin: top center; }
  46% { transform-origin: bottom center; }
  100% { transform: scaleY(0); transform-origin: bottom center; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-cue i { animation: none; }
}
@media (max-height: 700px), (max-width: 760px) {
  .hero-cue { display: none; }
}

/* ---------- the strip below the hero ----------
   Black dissolves into the canvas; one claim on the left,
   the standard we run on across the right. */

.strip {
  position: relative;
  background: linear-gradient(to bottom, var(--ink) 0%, var(--canvas) 62%);
  padding: clamp(3.5rem, 7vw, 5.5rem) 0 clamp(3rem, 6vw, 4.5rem);
}

.strip-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.35fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

.strip-lead {
  font-size: clamp(1.1875rem, 1.6vw, 1.45rem);
  line-height: 1.5;
  color: var(--fg);
  max-width: 24ch;
  letter-spacing: -0.01em;
}

.strip-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.2rem, 3vw, 2.5rem);
  margin: 0;
}

.strip-stats .stat-cell dt {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-mute);
  margin-bottom: 0.9rem;
}
.strip-stats .stat-cell dd {
  margin: 0;
  font-family: var(--font-head);
  font-size: clamp(1.9rem, 3.4vw, 2.75rem);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--bone);
}

@media (max-width: 860px) {
  .strip-grid { grid-template-columns: 1fr; }
  .strip-stats { gap: 1.5rem 1rem; }
}
@media (max-width: 560px) {
  .strip-stats { grid-template-columns: 1fr; }
  .strip-stats .stat-cell {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--line);
  }
  .strip-stats .stat-cell dt { margin-bottom: 0; }
}

/* ---------- sections ---------- */

.section { padding-top: var(--section-pad); padding-bottom: var(--section-pad); }
.section.on-dark { background: var(--canvas); }
.section.on-light { background: var(--bone); color: var(--charcoal); }

/* the short intro block that opens each feature: kicker, big
   light title, then a row of three quiet chips */
/* headings get room to run at display size; the paragraph under them
   stays at a readable measure */
.section-head { max-width: 46rem; margin-bottom: clamp(2.4rem, 5vw, 3.5rem); }
.section-head h2 { margin-bottom: 1rem; }
.section-head p { color: var(--fg-mute); max-width: 46ch; }
.on-light .section-head p { color: var(--stone); }

.chips {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.4rem, 3vw, 2rem);
  border-top: 1px solid var(--line);
}
/* h3, not h4: these sit directly under the section h2, and h4 there was a
   heading-order skip. Line-height and tracking are restated because the
   global h3 rule sets both for display type. */
.chip h3 {
  font-family: var(--font-head);
  font-size: var(--text-md);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: normal;
  color: var(--fg);
  margin-bottom: 0.2rem;
}
.chip p {
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--fg-mute);
  max-width: 32ch;
}
.on-light .chips { border-top-color: rgba(42, 45, 43, 0.12); }
.on-light .chip h3 { color: var(--charcoal); }
.on-light .chip p { color: var(--stone); }

@media (max-width: 760px) {
  .chips { grid-template-columns: 1fr; gap: 1.4rem; }
}

/* ---------- how it works: the pinned pathway ----------
   Default (no JS, phones): a plain readable list. When main.js adds
   .is-live the steps stack into one full-height stage and scroll
   advances them one at a time. */

.pathway {
  position: relative;
  background: var(--canvas);
  padding-top: var(--section-pad);
  padding-bottom: var(--section-pad);
}

.pathway-inner { position: relative; }

.pathway-head {
  max-width: 46rem;
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
}
.pathway-head h2 { margin-bottom: 1rem; }
.pathway-head p { color: var(--fg-mute); }

.pathway-steps { list-style: none; }

.pathway-step {
  padding: clamp(1.6rem, 3vw, 2.2rem) 0;
  border-top: 1px solid var(--line);
}
.pathway-step:last-child { border-bottom: 1px solid var(--line); }

.pathway-body {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

/* the stage diagram only appears once the section drives itself */
.pathway-visual { display: none; }

.pathway-num {
  font-family: var(--font-head);
  font-size: clamp(2.2rem, 5vw, 4rem);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--fern-bright);
  font-variant-numeric: tabular-nums;
  opacity: 0.9;
}

.pathway-copy h3 {
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  font-weight: 300;
  letter-spacing: -0.025em;
  margin-bottom: 0.7rem;
  color: var(--bone);
}
.pathway-copy p {
  font-size: clamp(1.0625rem, 1.3vw, 1.1875rem);
  line-height: 1.6;
  color: var(--fg-mute);
  max-width: 52ch;
}

/* the rail only means something once the section drives itself */
.pathway-rail { display: none; }

/* ----- pinned mode ----- */

/* Pinned: the section's own vertical padding is dropped so the stage
   is exactly one viewport tall and its contents sit centred in it.
   Top padding clears the floating header; the small top-heavy bias
   keeps the block optically centred beneath it. */
.pathway.is-live { padding-top: 0; padding-bottom: 0; }

.pathway.is-live .pathway-stage {
  height: 100vh;
  height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: 5.5rem;
  padding-bottom: 3.5rem;
}
/* the stage is a flex container, so the inner rail must be told to
   fill it — otherwise it shrink-wraps to its content */
.pathway.is-live .pathway-inner { width: 100%; }

.pathway.is-live .pathway-head {
  margin-bottom: clamp(1.6rem, 3.4vh, 2.6rem);
}

.pathway.is-live .pathway-steps {
  position: relative;
  min-height: clamp(16rem, 40vh, 26rem);
}

.pathway.is-live .pathway-step {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 26rem);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  padding: 0;
  border: 0;
}
.pathway.is-live .pathway-step:last-child { border-bottom: 0; }

.pathway.is-live .pathway-body { align-items: center; }

.pathway.is-live .pathway-visual {
  display: block;
  justify-self: end;
  width: 100%;
  max-width: 26rem;
}
.pathway.is-live .pathway-visual svg { width: 100%; height: auto; }

/* These carry a real alpha channel, cut in build-pathway-art.py, so the
   object composites straight onto the canvas with no rectangle edge.
   Do NOT reach for mix-blend-mode here: GSAP transforms .pathway-visual,
   a transform creates a stacking context, and a blend mode cannot see
   past its own stacking context -- it rendered as an opaque black box. */
.pathway.is-live .pathway-visual img {
  width: 100%;
  height: auto;
  display: block;
}

@media (max-width: 1150px) {
  .pathway.is-live .pathway-step { grid-template-columns: minmax(0, 1fr) minmax(0, 19rem); }
  .pathway.is-live .pathway-visual { max-width: 19rem; }
}

/* diagram ink */
.pv-ring, .pv-ticks, .pv-line, .pv-edge {
  stroke: rgba(246, 245, 241, 0.22);
  stroke-width: 2;
}
.pv-edge { stroke-width: 2.2; }
.pv-line { stroke-linecap: round; }
.pv-ticks {
  stroke: rgba(246, 245, 241, 0.30);
  stroke-width: 6;
  stroke-dasharray: 3 24.2;
  stroke-linecap: round;
}
.pv-core { fill: var(--fern-bright); }
.pv-mark { fill: rgba(246, 245, 241, 0.55); }
.pv-link {
  stroke: var(--fern-bright);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-dasharray: 6 7;
}
.pv-fill { fill: rgba(246, 245, 241, 0.72); }
.pv-soft { fill: rgba(246, 245, 241, 0.20); }
.pv-solid { fill: rgba(116, 176, 138, 0.22); stroke: var(--fern-bright); stroke-width: 1.6; }
.pv-onsolid { fill: rgba(246, 245, 241, 0.80); }
.pv-onsolid.pv-dim { fill: rgba(246, 245, 241, 0.45); }
.pv-tick, .pv-tick-lg {
  stroke: var(--ink);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pv-tick-lg { stroke: var(--fern-bright); stroke-width: 3; }
.pv-arc {
  stroke: var(--fern-bright);
  stroke-width: 3;
  stroke-linecap: round;
}
.pv-arc-fast { stroke: var(--fern-bright); stroke-width: 3.5; stroke-linecap: round; }
.pv-hand { fill: rgba(116, 176, 138, 0.20); stroke: var(--fern-bright); stroke-width: 2; }
.pv-hand-tick {
  stroke: var(--fern-bright);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pv-stars path { fill: rgba(116, 176, 138, 0.55); }

.pathway.is-live .pathway-num {
  font-size: clamp(3.4rem, 7.5vw, 6.5rem);
  opacity: 0.28;
}

/* the number's column is narrower here so the copy keeps a workable
   measure beside the diagram */
.pathway.is-live .pathway-body { gap: clamp(1.2rem, 2.6vw, 2.2rem); }

.pathway.is-live .pathway-copy h3 {
  font-size: clamp(1.9rem, 3.6vw, 2.9rem);
  line-height: 1.12;
}
.pathway.is-live .pathway-copy p {
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  color: var(--fg-soft);
}

.pathway.is-live .pathway-rail {
  display: block;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}

.pathway-track {
  display: block;
  height: 2px;
  border-radius: 1px;
  background: var(--line);
  overflow: hidden;
}
.pathway-track i {
  display: block;
  height: 100%;
  background: var(--fern-bright);
  transform: scaleX(0);
  transform-origin: left center;
}

.pathway-ticks {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  list-style: none;
  margin-top: 0.9rem;
}
.pathway-ticks li {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(246, 245, 241, 0.56);
  transition: color 300ms ease;
}
.pathway-ticks li.is-on { color: var(--fern-bright); }

/* ---------- what we handle ---------- */

.services { position: relative; }

.service-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.service {
  background: var(--canvas);
  padding: clamp(1.6rem, 3vw, 2.4rem) clamp(1.4rem, 2.4vw, 1.9rem) clamp(2rem, 3.4vw, 2.6rem);
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  transition: background-color 350ms ease;
}
.service:hover { background: #191D1A; }

.service-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  border: 1px solid rgba(116, 176, 138, 0.28);
  background: rgba(116, 176, 138, 0.08);
  color: var(--fern-bright);
  margin-bottom: 0.5rem;
  transition: background-color 350ms ease, border-color 350ms ease, transform 350ms ease;
}
.service-icon svg { width: 30px; height: 30px; }
.service:hover .service-icon {
  background: rgba(116, 176, 138, 0.14);
  border-color: rgba(116, 176, 138, 0.45);
  transform: translateY(-2px);
}

.service h3 {
  font-size: clamp(1.1875rem, 1.5vw, 1.375rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--fg);
}
.service p {
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--fg-mute);
}

@media (max-width: 1000px) {
  .service-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .service-grid { grid-template-columns: 1fr; }
}

/* ---------- the big feature card ---------- */

.feature {
  position: relative;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--card);
  padding: clamp(1.5rem, 3vw, 2.2rem);
  overflow: hidden;
}

.feature-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 3rem);
  margin-bottom: clamp(2rem, 4vw, 2.8rem);
  flex-wrap: wrap;
}
.feature-head h3 { margin-bottom: 0.7rem; }
.feature-head p {
  font-size: var(--text-base);
  color: var(--fg-mute);
  max-width: 52ch;
}
.feature-head > div { flex: 1 1 24rem; }

/* numbered path inside the card */
.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow: hidden;
}

.step {
  background: var(--canvas);
  padding: clamp(1.2rem, 2.4vw, 1.6rem);
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  transition: background-color 300ms ease;
}
.step:hover { background: #191D1A; }

.step-num {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  color: var(--fern-bright);
  font-variant-numeric: tabular-nums;
}

.step h4 {
  font-size: var(--text-lg);
  font-weight: 500;
  color: var(--fg);
}

.step p {
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--fg-mute);
}

@media (max-width: 900px) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .steps { grid-template-columns: 1fr; }
}

/* ---------- demo teaser feature ---------- */

.demo { position: relative; overflow: hidden; background: var(--canvas); }
.demo::before {
  content: "";
  position: absolute;
  top: -14%;
  right: -6%;
  width: 54%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(78, 139, 99, 0.12), transparent 62%);
  pointer-events: none;
}
.demo > .container { position: relative; }

.demo-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 900px) {
  .demo-grid { grid-template-columns: 1fr; }
}

.sim-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fern-bright);
  border: 1px solid rgba(116, 176, 138, 0.4);
  border-radius: var(--radius-pill);
  padding: 0.4em 1em;
  margin-bottom: 1.4rem;
}

.demo-note {
  font-size: var(--text-md);
  color: var(--fg-mute);
  max-width: 42ch;
  margin-top: 1.4rem;
}

/* ---------- phone ----------
   A believable handset: machined edge, status bar, and a soft glow
   from the screen. Everything inside is clearly labelled simulated. */
.phone {
  position: relative;
  background: linear-gradient(160deg, #34383A 0%, #1B1E1F 32%, #14171A 70%, #2B2F31 100%);
  border-radius: 44px;
  padding: 11px;
  box-shadow:
    0 0 0 1px rgba(246, 245, 241, 0.10),
    inset 0 0 0 1px rgba(246, 245, 241, 0.06),
    0 50px 130px -40px rgba(0, 0, 0, 0.95),
    0 12px 40px -18px rgba(0, 0, 0, 0.7);
  max-width: 384px;
  margin: 0 auto;
  width: 100%;
}

/* the pill cutout at the top of the screen */
.phone-island {
  position: absolute;
  z-index: 3;
  top: 22px;
  left: 50%;
  transform: translateX(-50%);
  width: 84px;
  height: 24px;
  border-radius: 999px;
  background: #0A0C0C;
}

a.phone-tease {
  display: block;
  color: inherit;
  transform: perspective(1400px) rotateY(-6deg) rotateX(2deg);
  transition: transform 550ms cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 550ms ease, border-color 550ms ease;
}
a.phone-tease:hover,
a.phone-tease:focus-visible {
  transform: perspective(1400px) rotateY(0deg) rotateX(0deg) translateY(-6px);
  box-shadow: 0 60px 140px -50px rgba(0, 0, 0, 0.95);
  border-color: rgba(78, 139, 99, 0.45);
}
.phone-tease .phone-screen { min-height: 0; }
.phone-tease .phone-open {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.85rem 1.2rem 0.95rem;
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fern-bright);
  border-top: 1px solid var(--line);
}
.phone-tease .phone-open svg { width: 12px; height: 12px; transition: transform 220ms ease; }
.phone-tease:hover .phone-open svg { transform: translateX(3px); }

.phone-screen {
  position: relative;
  background: #101312;
  border-radius: 34px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 560px;
}

/* status bar */
.phone-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem 1.5rem 0.35rem;
  font-family: var(--font-head);
  color: var(--fg);
}
.status-time {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.01em;
  padding-left: 0.2rem;
}
.status-icons {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--fg);
}
.status-icons svg { display: block; }
.ico-signal { width: 17px; height: 11px; }
.ico-wifi { width: 15px; height: 11px; }
.ico-batt { width: 25px; height: 11px; }

.phone-top {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: 0.7rem 1.2rem 0.85rem;
  border-bottom: 1px solid rgba(246, 245, 241, 0.08);
  background: rgba(246, 245, 241, 0.035);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  text-align: center;
}
.phone-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: linear-gradient(150deg, var(--fern) 0%, var(--forest) 100%);
  color: #FFFFFF;
  font-family: var(--font-head);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.phone-top strong {
  display: block;
  font-family: var(--font-head);
  color: var(--fg);
  font-size: var(--text-md);
  font-weight: 500;
}
.phone-top .phone-sub {
  display: block;
  color: var(--fern-bright);
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* composer bar, inert by design */
.phone-input {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem 1.1rem;
  border-top: 1px solid rgba(246, 245, 241, 0.08);
}
.input-field {
  flex: 1;
  padding: 0.55em 1em;
  border-radius: 999px;
  border: 1px solid rgba(246, 245, 241, 0.14);
  color: rgba(246, 245, 241, 0.58);
  font-size: var(--text-md);
}
.input-send {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--fern);
  color: #FFFFFF;
  flex: none;
}
.input-send svg { width: 15px; height: 15px; }

.chat {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.1rem;
}

/* bubbles carry a drawn tail, the way a real thread does */
.msg {
  position: relative;
  max-width: 78%;
  padding: 0.62em 0.95em;
  border-radius: 19px;
  font-size: var(--text-md);
  line-height: 1.45;
}
.msg::after {
  content: "";
  position: absolute;
  bottom: 0;
  width: 14px;
  height: 16px;
  pointer-events: none;
}

.msg.in {
  align-self: flex-start;
  background: #262B29;
  color: var(--fg);
  border-bottom-left-radius: 6px;
}
.msg.in::after {
  left: -6px;
  background: #262B29;
  -webkit-mask-image: radial-gradient(14px 16px at 14px 0, transparent 13.5px, #000 14px);
  mask-image: radial-gradient(14px 16px at 14px 0, transparent 13.5px, #000 14px);
  border-bottom-left-radius: 10px;
}

.msg.out {
  align-self: flex-end;
  background: linear-gradient(160deg, #55966D 0%, var(--fern) 55%, #427A57 100%);
  color: #FFFFFF;
  border-bottom-right-radius: 6px;
}
.msg.out::after {
  right: -6px;
  background: #427A57;
  -webkit-mask-image: radial-gradient(14px 16px at 0 0, transparent 13.5px, #000 14px);
  mask-image: radial-gradient(14px 16px at 0 0, transparent 13.5px, #000 14px);
  border-bottom-right-radius: 10px;
}

/* day divider and delivery receipts */
.msg-day {
  align-self: center;
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.1em;
  color: rgba(246, 245, 241, 0.62);
  padding: 0.5rem 0 0.2rem;
}
.msg-receipt {
  align-self: flex-start;
  font-size: var(--text-2xs);
  letter-spacing: 0.04em;
  color: rgba(246, 245, 241, 0.60);
  margin-top: -0.35rem;
  padding-left: 0.3rem;
}
.msg-receipt.read {
  align-self: flex-end;
  padding-left: 0;
  padding-right: 0.3rem;
}

.msg-meta {
  align-self: center;
  font-size: var(--text-2xs);
  letter-spacing: 0.06em;
  color: var(--fg-mute);
  padding: 0.2rem 0;
}
.msg-meta.booked {
  color: var(--fern-bright);
  font-family: var(--font-head);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}
.msg-meta.booked svg { width: 13px; height: 13px; }

/* the quiet marker: what triggered the sequence, not the payoff */
.msg-meta.step {
  color: var(--fg-soft);
  font-family: var(--font-head);
  font-weight: 500;
  font-size: var(--text-2xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}
.msg-meta.step svg { width: 12px; height: 12px; opacity: 0.7; }

/* the posted review, shown as a card rather than a bubble — it is a
   receipt of something that landed elsewhere, not part of the thread */
.review-card {
  align-self: flex-end;
  max-width: 88%;
  padding: 0.8rem 0.9rem 0.75rem;
  background: rgba(246, 245, 241, 0.055);
  border: 1px solid var(--line);
  border-radius: 14px;
}
.review-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.review-stars {
  display: inline-flex;
  gap: 2px;
  color: var(--fern-bright);
}
.review-stars svg { width: 13px; height: 13px; fill: currentColor; display: block; }
.review-where {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(246, 245, 241, 0.62);
}
.review-text {
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--fg-soft);
  margin-bottom: 0.45rem;
}
.review-who {
  font-size: var(--text-2xs);
  letter-spacing: 0.04em;
  color: rgba(246, 245, 241, 0.62);
}

.typing {
  align-self: flex-start;
  display: inline-flex;
  gap: 5px;
  padding: 0.7em 0.95em;
  background: rgba(246, 245, 241, 0.09);
  border-radius: 16px;
  border-bottom-left-radius: 5px;
}
.typing i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(246, 245, 241, 0.6);
  animation: typing-dot 1s infinite ease-in-out;
}
.typing i:nth-child(2) { animation-delay: 0.15s; }
.typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes typing-dot {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.5; }
  30% { transform: translateY(-4px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .typing i { animation: none; }
}

/* ---------- example dashboard (fabricated data) ---------- */

.dash {
  margin-top: clamp(2rem, 4vw, 3rem);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.2rem);
}

.dash-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.8rem;
}
.dash-head .sim-chip { margin-bottom: 0; }

.dash-title strong {
  display: block;
  font-family: var(--font-head);
  font-weight: 500;
  font-size: var(--text-base);
  color: var(--fg);
}
.dash-title span {
  display: block;
  font-size: var(--text-sm);
  color: var(--fg-mute);
  margin-top: 3px;
}

.dash-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 0 0 12px;
}
@media (max-width: 860px) {
  .dash-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.stat {
  background: var(--card-raise);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 1.1rem 1.2rem;
}
.stat dt {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-mute);
  margin-bottom: 0.6rem;
}
.stat dd {
  display: flex;
  align-items: baseline;
  gap: 0.25em;
  margin: 0;
}
.stat-val {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(1.7rem, 3vw, 2.2rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.stat-unit {
  font-family: var(--font-head);
  font-weight: 500;
  font-size: var(--text-md);
  color: var(--fern-bright);
}

.dash-chart {
  background: var(--card-raise);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 1.2rem 1.3rem 1rem;
}

.chart-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.2rem;
}
.chart-title {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-mute);
}
.chart-legend {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: var(--text-xs);
  color: var(--fg-mute);
}
.chart-legend i {
  width: 18px;
  height: 2.5px;
  border-radius: 2px;
  background: var(--fern-bright);
}

.chart-plot { position: relative; }

.chart-svg {
  width: 100%;
  height: auto;
  overflow: visible;
}
.chart-grid line {
  stroke: rgba(246, 245, 241, 0.09);
  stroke-width: 1;
}
.chart-line {
  stroke-linejoin: round;
  filter: drop-shadow(0 6px 14px rgba(116, 176, 138, 0.28));
}
.chart-dots circle {
  fill: #101312;
  stroke: var(--fern-bright);
  stroke-width: 2.5;
}
.chart-values text {
  font-family: var(--font-head);
  font-size: 15px;
  font-weight: 500;
  fill: var(--fg-soft);
  text-anchor: middle;
}

.chart-xaxis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: 0.5rem;
}
.chart-xaxis span {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--fg-mute);
}

.dash-note {
  margin-top: 1.3rem;
  font-size: var(--text-sm);
  color: var(--fg-mute);
}

/* ---------- bone tail: about ---------- */

.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
@media (max-width: 800px) {
  .about-grid { grid-template-columns: 1fr; }
}

.about-body p { color: var(--stone); max-width: 40ch; }
.about-body p + p { margin-top: 1.1rem; }
.about-body strong { color: var(--charcoal); font-weight: 600; }

.about-card {
  background: #FFFFFF;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  padding: clamp(1.5rem, 3vw, 2.2rem);
}
.about-card h3 {
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--forest);
  margin-bottom: 1.2rem;
}
.about-card ul { list-style: none; }
.about-card li {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--hairline);
  font-size: var(--text-base);
  font-weight: 500;
}
.about-card li:last-child { border-bottom: none; }
.about-card li i {
  width: 2px;
  height: 15px;
  background: var(--forest);
  opacity: 0.6;
  border-radius: 1px;
  flex: none;
}

/* the mark, in full colour, on the one background built for it */
.about-mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.6rem;
  padding: clamp(2rem, 4vw, 3rem) clamp(1.5rem, 3vw, 2.5rem);
  border-left: 1px solid var(--hairline);
}
.about-mark img {
  width: clamp(190px, 20vw, 260px);
  height: auto;
}
.about-mark-line {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--forest);
  text-align: center;
}

@media (max-width: 800px) {
  .about-mark {
    border-left: 0;
    border-top: 1px solid var(--hairline);
    padding-top: clamp(2.5rem, 6vw, 3.5rem);
    margin-top: 1rem;
  }
}

/* ---------- bone tail: contact ---------- */

.contact-wrap { max-width: 780px; margin: 0 auto; text-align: center; }
.contact-wrap .section-head {
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 2.2rem;
  max-width: 34ch;
}
.contact-wrap .section-head p { margin-left: auto; margin-right: auto; }
.contact-wrap .eyebrow { justify-content: center; }

.contact-card {
  background: #FFFFFF;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  padding: clamp(1.8rem, 4vw, 2.6rem);
  text-align: left;
}

.contact-rows { border-top: 1px solid var(--hairline); margin-top: 0.3rem; }
.contact-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--hairline);
}
.contact-row dt {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--forest);
}
.contact-row dd { color: var(--stone); font-size: var(--text-lg); }

.contact-note {
  margin-top: 1.3rem;
  font-size: var(--text-md);
  color: var(--stone);
}

/* dark variant kept for the demo page */
.on-dark .contact-card {
  background: var(--card);
  border-color: var(--line);
  box-shadow: var(--shadow-card);
}
.on-dark .contact-rows { border-top-color: var(--line); }
.on-dark .contact-row { border-bottom-color: var(--line); }
.on-dark .contact-row dt { color: var(--fern-bright); }
.on-dark .contact-row dd { color: var(--fg-soft); }
.on-dark .contact-note { color: var(--fg-mute); }

/* ---------- demo page ---------- */

.page-hero {
  padding-top: clamp(8.5rem, 18vh, 11rem);
  padding-bottom: clamp(2rem, 4vw, 3rem);
  background: linear-gradient(to bottom, var(--ink), var(--canvas));
}
.page-hero h1 { max-width: 18ch; margin-bottom: 1.1rem; }
.page-hero .lede { color: var(--fg-soft); max-width: 54ch; }

.convo-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
/* second act runs the other way round, so two scenes of the same
   component don't read as the same slide twice */
.convo-grid.flip { grid-template-columns: minmax(0, 400px) minmax(0, 1fr); }

@media (max-width: 900px) {
  .convo-grid,
  .convo-grid.flip { grid-template-columns: 1fr; }
  /* stacked, the copy still introduces the phone */
  .convo-grid.flip .phone { order: 2; }
  .convo-grid.flip .demo-copy { order: 1; }
}

.anno { list-style: none; border-top: 1px solid var(--line); }
.anno li {
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 1rem;
  padding: 1.4rem 0;
  border-bottom: 1px solid var(--line);
}
.anno .anno-num {
  font-family: var(--font-head);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--fern-bright);
  font-variant-numeric: tabular-nums;
  padding-top: 0.2rem;
}
.anno h3 { font-size: var(--text-lg); font-weight: 500; margin-bottom: 0.3rem; }
.anno p { font-size: var(--text-md); color: var(--fg-mute); max-width: 42ch; }

/* ---------- FAQ ----------
   Built on native <details>, so it works with JS off and reads as plain
   question-and-answer text to a crawler. The height animation in
   js/main.js is an enhancement on top, never the mechanism. */

.faq-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
}
@media (max-width: 900px) {
  .faq-grid { grid-template-columns: 1fr; }
}

/* the heading holds its place while the answers scroll past it */
@media (min-width: 901px) {
  .faq-head { position: sticky; top: 132px; }
}

.faq-list { border-top: 1px solid var(--hairline); }

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

.faq-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.35rem 0;
  cursor: pointer;
  list-style: none;
  transition: color 200ms ease;
}
/* the default disclosure triangle, gone in every engine */
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::marker { content: ""; }

.faq-q {
  font-family: var(--font-head);
  font-size: clamp(1.0625rem, 1.5vw, 1.1875rem);
  font-weight: 500;
  line-height: 1.4;
  color: var(--charcoal);
  transition: color 200ms ease;
}
.faq-item > summary:hover .faq-q,
.faq-item[open] > summary .faq-q { color: var(--forest); }

.faq-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid rgba(42, 45, 43, 0.18);
  color: var(--forest);
  transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1),
              background-color 200ms ease, border-color 200ms ease;
}
.faq-icon svg { width: 14px; height: 14px; display: block; }
.faq-item > summary:hover .faq-icon {
  background: rgba(47, 93, 63, 0.07);
  border-color: rgba(47, 93, 63, 0.32);
}
/* the plus becomes a close mark */
.faq-item[open] > summary .faq-icon { transform: rotate(45deg); }

.faq-answer > div { padding: 0 0 1.5rem; }
.faq-answer p {
  font-size: var(--text-base);
  line-height: 1.68;
  color: var(--stone);
  max-width: 64ch;
}

.faq-head .btn { margin-top: 0.4rem; }

@media (prefers-reduced-motion: reduce) {
  .faq-icon { transition: none; }
}

.demo-cta { text-align: center; padding-top: 0; }
.demo-cta .section-head { margin-left: auto; margin-right: auto; }
.demo-cta .section-head p { margin-left: auto; margin-right: auto; }

/* ---------- footer ---------- */

.site-footer {
  background: var(--ink);
  color: var(--fg);
  border-top: 1px solid var(--line);
  padding: clamp(3rem, 6vw, 4.5rem) 0 2.2rem;
}

.site-footer.on-light {
  background: var(--bone);
  color: var(--charcoal);
  border-top-color: var(--hairline);
}

.footer-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 2.5rem;
  flex-wrap: wrap;
  padding-bottom: 2.2rem;
  border-bottom: 1px solid var(--line);
}
.site-footer.on-light .footer-top { border-bottom-color: var(--hairline); }

.footer-top img { height: 50px; width: auto; }

.footer-tag {
  margin-top: 1rem;
  color: var(--fg-mute);
  font-size: var(--text-md);
  max-width: 28ch;
}
.site-footer.on-light .footer-tag { color: var(--stone); }

.footer-nav { display: flex; gap: clamp(2rem, 5vw, 4.5rem); flex-wrap: wrap; }
/* h2, not h4: these are the top-level headings inside the footer
   landmark, and h4 straight after a section h2 was a heading-order skip.
   Every visual property is restated so the global h2 scale can't leak in. */
.footer-nav h2 {
  font-family: var(--font-head);
  font-size: var(--text-2xs);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--fern-bright);
  margin-bottom: 0.9rem;
}
.site-footer.on-light .footer-nav h2 { color: var(--forest); }
.footer-nav ul { list-style: none; }
.footer-nav li { margin-bottom: 0.5rem; }
.footer-nav a { color: var(--fg-soft); font-size: var(--text-md); transition: color 180ms ease; }
.footer-nav a:hover { color: var(--fg); }
.site-footer.on-light .footer-nav a { color: var(--stone); }
.site-footer.on-light .footer-nav a:hover { color: var(--charcoal); }

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-top: 1.6rem;
  font-size: var(--text-sm);
  color: var(--fg-mute);
}
.site-footer.on-light .footer-bottom { color: var(--stone); }

/* ---------- legal pages ---------- */

.legal-main {
  padding-top: clamp(8rem, 16vh, 10rem);
  padding-bottom: var(--section-pad);
  background: var(--canvas);
}
.legal { max-width: 68ch; }
.legal h1 { font-size: clamp(1.9rem, 4vw, 2.7rem); margin-bottom: 0.5rem; }
.legal .updated { color: var(--fg-mute); font-size: var(--text-sm); margin-bottom: 2.6rem; }
.legal h2 {
  font-size: clamp(1.25rem, 2vw, 1.5rem);
  font-weight: 400;
  margin-top: 2.4rem;
  margin-bottom: 0.7rem;
}
/* max-width repeated here because the global measure cap is on `p` alone,
   and these pages carry a lot of their content in <li>. Without it the
   list items ran to 87 characters while the paragraphs beside them sat at
   79 -- and these are the pages an A2P reviewer actually reads. */
.legal p, .legal li { color: var(--fg-soft); font-size: var(--text-base); max-width: 52ch; }
.legal p + p { margin-top: 0.85rem; }
.legal strong { color: var(--fg); font-weight: 600; }
.legal a {
  color: var(--fern-bright);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.legal a:hover { color: var(--bone); }
.legal ul { padding-left: 1.3em; margin: 0.8rem 0; }
.legal li { margin-bottom: 0.4rem; }
.legal .placeholder {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 0.9rem 1.2rem;
  color: var(--fg-mute);
  font-size: var(--text-md);
  margin-top: 0.8rem;
}

/* ---------- reveal defaults ----------
   Content is visible by default; JS only sets hidden states when
   motion is allowed, so nothing is lost without JS. */
.reveal { will-change: transform; }
