/* ===========================================================================
   PulseForge — landing page styles
   ---------------------------------------------------------------------------
   Direction follows the ForgeFit sibling site: Poppins throughout with heavy
   display weights and tight tracking, a warm brown-black ink ramp, cream text,
   and the cherry→orange→gold "flame" gradient on the words that matter.

   Plain CSS, no build step. The identity hangs off the tokens in :root.

   Body and small copy are white; the flame gradient is rationed to h1/h2 and
   the big figures, where a glow makes it stand out.

   Contrast (WCAG AA, all against --ink #0A0908):
     --ash-100  #FFFFFF  20.4:1  AAA  (emphasis)
     --ash-200  #F4F4F6  18.9:1  AAA
     --ash-400  #E6E6EA  16.6:1  AAA  (body copy)
     --ash-600  #C4C4CD  11.8:1  AAA  (small print)
     --flame-1  #FF3D5A   5.73:1 AA
     --flame-2  #FFA500  10.05:1 AAA
     --flame-3  #FFCF4D  13.50:1 AAA
     --ash-800  #8F5C24   3.52:1 AA   (large decorative numerals only)
   Every flame stop clears AA, so gradient headings are safe at any size.
   ========================================================================= */

:root {
  /* --- Surfaces: a warm brown-black ladder, matching ForgeFit's ink ramp.
     Deliberately not a neutral grey-black — the warmth is what makes the
     flame palette sit naturally on top of it. --- */
  --ink: #0a0908;
  --ink-sunken: #050403;
  --ink-raised: #110f0c;
  --ink-float: #161310;

  /* --- Text ramp: white. Body and small copy stay white so the flame is
     reserved for the big headings and reads as emphasis, not decoration. --- */
  --ash-100: #ffffff; /* 20.4:1 — emphasis, strong labels */
  --ash-200: #f4f4f6; /* 18.9:1 — figures, table values */
  --ash-400: #e6e6ea; /* 16.6:1 — body copy */
  --ash-600: #c4c4cd; /* 11.8:1 — small print, captions */
  --ash-800: #8f5c24; /*  3.5:1 — ghost numerals, large text only */

  /* Glows. text-shadow works on solid-coloured text; gradient-filled text is
     painted through a clipped background, so that uses --flame-glow's
     drop-shadow filter instead. */
  --glow-orange: 0 0 14px rgba(255, 165, 0, 0.5), 0 0 4px rgba(255, 165, 0, 0.35);
  --glow-white: 0 0 18px rgba(255, 243, 230, 0.3), 0 0 6px rgba(255, 243, 230, 0.2);

  /* Depth for white text over the gradient-lit background (ForgeFit tokens). */
  --text-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
  --text-shadow: 0 2px 10px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.55);

  /* Glow behind the flame headings. drop-shadow, not text-shadow: the glyphs
     are painted by a clipped background, so a text-shadow would show through
     the transparent fill instead of hugging the letterforms. */
  --flame-glow: drop-shadow(0 0 28px rgba(255, 165, 0, 0.38))
    drop-shadow(0 2px 6px rgba(0, 0, 0, 0.55));

  /* --- Flame: cherry → orange → gold. ForgeFit's signature gradient. --- */
  --flame-1: #ff3d5a;
  /* Bright orange. Replaces the darker #ff7a1a everywhere this token is used —
     links, eyebrow rules, icons and the middle of the flame gradient. It is
     also the better contrast: 10.05:1 on --ink versus 7.60:1 before. */
  --flame-2: #ffa500;
  --flame-3: #ffcf4d;
  --flame-grad: linear-gradient(
    92deg,
    var(--flame-1) -20%,
    var(--flame-2) 52%,
    var(--flame-3) 120%
  );

  /* Aliases so existing component rules keep reading naturally. */
  --ember: var(--flame-2);
  --ember-bright: var(--flame-3);
  --ember-deep: var(--flame-1);
  --gold: var(--flame-3);
  --amber: #f0a63e;
  /* Dark brown for text on flame fills — warmer than pure ink. */
  --on-flame: #1a0b02;

  --line: rgba(255, 214, 170, 0.07);
  --line-strong: rgba(255, 214, 170, 0.14);
  --surface: rgba(255, 214, 170, 0.035);
  --surface-hover: rgba(255, 214, 170, 0.07);

  /* --- Type ---
     One family, as on ForgeFit. Hierarchy comes from weight and tracking
     (800/700 display vs 400 body) rather than from a second typeface. */
  --font-display: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body: var(--font-display);

  /* --- Layered, colour-tinted shadows (never a flat drop shadow) --- */
  --shadow-raised:
    0 1px 2px rgba(0, 0, 0, 0.5),
    0 8px 24px -10px rgba(0, 0, 0, 0.65);
  --shadow-float:
    0 2px 4px rgba(0, 0, 0, 0.5),
    0 18px 50px -14px rgba(0, 0, 0, 0.8),
    0 0 48px -24px rgba(255, 165, 0, 0.35);
  --shadow-ember:
    0 10px 40px -12px rgba(255, 165, 0, 0.55),
    0 2px 8px -2px rgba(255, 61, 90, 0.4);

  /* --- Spacing scale: intentional steps, not arbitrary values --- */
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-24: 6rem;

  --container: 1180px;

  /* The fixed header's real height (75px on a phone, 80px on desktop; 5rem is
     the safe upper bound). The hero derives its top padding from this rather
     than hard-coding a number, because the two were tuned independently and
     drifted: a short-viewport rule trimmed the hero to 5rem of top padding
     while the header was still 5rem tall, so the badge rendered *behind* the
     nav. Anything that sits under the fixed header should measure from here. */
  --header-h: 5rem;
  --header-clearance: 2.25rem;
  --radius-sm: 12px;
  --radius: 20px;
  --radius-lg: 28px;

  /* Matching ForgeFit's motion curves. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

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

* {
  margin: 0;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 6.5rem;
  -webkit-text-size-adjust: 100%;

  /* The page scrollbar, in the flame palette. Without this the browser paints
     its default light-grey system chrome, which on a near-black page is the
     brightest thing on screen and the first thing your eye goes to.

     `color-scheme: dark` is what makes the browser render every other piece of
     built-in UI — form controls, the scrollbar's own buttons — in dark form.
     `thin` rather than `auto` because a full-width bar is a lot of orange. */
  color-scheme: dark;
  scrollbar-width: thin;
  scrollbar-color: var(--flame-2) rgba(255, 214, 170, 0.06);

  /* `clip`, not `hidden`: overflow-x:hidden forces the computed overflow-y to
     `auto`, turning the element into a scroll container — double scrollbars and
     broken sticky positioning. `clip` contains overflow without that. */
  overflow-x: clip;
}

body {
  position: relative;
  background: var(--ink);
  color: var(--ash-100);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Subtle depth so white copy sits on the lit background rather than
     floating flat on it. */
  text-shadow: var(--text-shadow-sm);
}

/* Atmosphere: layered radial gradients rather than a solid fill. Fixed, so it
   sits behind the whole scroll rather than repeating per section. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 50% at 15% -5%, rgba(255, 165, 0, 0.13), transparent 60%),
    radial-gradient(ellipse 60% 45% at 95% 15%, rgba(255, 61, 90, 0.10), transparent 65%),
    radial-gradient(ellipse 80% 40% at 50% 105%, rgba(255, 61, 90, 0.1), transparent 70%);
}

/* Film grain. Kills the flat, plasticky digital look at almost no cost. */
body::after {
  content: '';
  position: fixed;
  inset: -50%;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

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

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

ul,
ol {
  list-style: none;
  padding: 0;
}

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

table {
  border-collapse: collapse;
  width: 100%;
}

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 4px;
}

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

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 100;
}

.skip-link:focus {
  left: 1rem;
  top: 1rem;
  padding: var(--space-3) var(--space-6);
  border-radius: 999px;
  background: var(--ember);
  color: var(--ink);
  font-weight: 700;
}

/* --- Layout --------------------------------------------------------------- */
.container {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 1.25rem;
}

.section {
  position: relative;
  /* Mobile-first: 96px of vertical padding is desktop rhythm and wastes a
     phone screen. Scaled back up at the breakpoints below. */
  padding-block: 4.5rem;
  scroll-margin-top: var(--space-24);
}

.bordered {
  border-top: 1px solid var(--line);
}

.section-head {
  max-width: 48rem;
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}

.section-head__desc {
  /* Narrower than the heading it sits under: at the section's full 48rem this
     runs to ~85 characters a line, well past the 60–75 comfortable measure. */
  max-width: 40rem;
  margin-top: var(--space-6);
  font-size: 1.125rem;
  line-height: 1.7;
  color: var(--ash-400);
  text-wrap: pretty;
}

.section-head--center .section-head__desc {
  margin-inline: auto;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: var(--space-6);
  /* Lifted from 0.6875rem: these are the section labels and were reading as
     fine print. Larger, with a soft white halo so they hold their own against
     the flame headings underneath. */
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ash-100);
  text-shadow: var(--glow-white), var(--text-shadow-sm);
}

/* Hairline rule leading out of the eyebrow — editorial detail. */
.eyebrow::before {
  content: '';
  width: 2.25rem;
  height: 2px;
  border-radius: 2px;
  /* Holds full-strength orange for most of its length before fading, so it
     reads as a deliberate orange marker rather than a grey hairline. */
  background: linear-gradient(90deg, var(--flame-2) 0%, var(--flame-2) 55%, transparent);
  box-shadow: var(--glow-orange);
}

/* --- Typography ----------------------------------------------------------- */
/* Weight and tracking carry the hierarchy — matching ForgeFit's scale:
   h1 800/-0.03em, h2 700/-0.02em, h3 600/-0.01em. */
h1,
h2 {
  font-family: var(--font-display);
  font-weight: 700;
  text-wrap: balance;
  letter-spacing: -0.02em;
}

/* h3 and below stay white — these are card titles and questions, not display
   type, and flame here would dilute the effect. */
h3 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-wrap: balance;
  line-height: 1.25;
  color: var(--ash-100);
  text-shadow: var(--text-shadow);
}

.display {
  font-size: clamp(2.75rem, 7.5vw, 4.8rem);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.03em;
}

.section-head h2 {
  font-size: clamp(2rem, 4.4vw, 3.625rem);
  line-height: 1.08;
}

.muted {
  color: var(--ash-600);
}

.lede {
  margin-top: var(--space-8);
  max-width: 34rem;
  font-size: 1.1875rem;
  line-height: 1.7;
  color: var(--ash-400);
  text-wrap: pretty;
}

/* --- Flame headings -------------------------------------------------------
   Big type only (h1/h2). Small copy stays white — the flame reads as emphasis
   because it is rationed. Each section shifts --flame-angle a few degrees so
   the mix varies down the page instead of repeating identically.

   The solid-colour declaration below is the fallback for engines without
   background-clip:text; the gradient is layered on inside @supports. */
h1,
h2,
.accent {
  color: var(--flame-2);
}

@supports (-webkit-background-clip: text) or (background-clip: text) {
  h1,
  h2,
  .accent {
    background-image: linear-gradient(
      var(--flame-angle, 92deg),
      var(--flame-1) -10%,
      var(--flame-2) 45%,
      var(--flame-3) 100%
    );
    background-size: 200% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    filter: var(--flame-glow);

    /* MUST be none. `body` sets a text-shadow for depth on white copy, and it
       inherits down to here — but these glyphs have a transparent fill, so the
       shadow is painted behind them and then shows straight THROUGH the
       letterforms as a displaced grey ghost. That is what was smearing the
       hero and the section headings. The drop-shadow filter above is the
       correct tool for gradient-filled text; a text-shadow never is. */
    text-shadow: none;
  }

  /* Accent words run gold-dominant, so they lift out of the orange around
     them rather than blending into it. */
  .accent {
    background-image: linear-gradient(
      var(--flame-angle, 92deg),
      var(--flame-3) 0%,
      #ffe27a 35%,
      var(--flame-2) 70%,
      var(--flame-3) 100%
    );
  }

  @media (prefers-reduced-motion: no-preference) {
    h1,
    .accent {
      animation: text-drift 14s var(--ease) infinite;
    }

    /* The big figures drift too, a little slower and out of phase so the page
       never pulses in unison. */
    .grad-num {
      animation: text-drift 18s var(--ease) -6s infinite;
    }
  }
}

/* Per-section variation in the flame mix. */
#problem { --flame-angle: 100deg; }
#how-it-works { --flame-angle: 84deg; }
#what-you-get { --flame-angle: 96deg; }
#revenue { --flame-angle: 88deg; }
#for-creators { --flame-angle: 104deg; }
#technology { --flame-angle: 80deg; }
#faq { --flame-angle: 94deg; }
#apply { --flame-angle: 90deg; }

/* Secondary clause inside a heading: dimmed by opacity, not colour, so it
   stays inside the gradient rather than punching a solid hole in it. */
h1 .muted,
h2 .muted {
  color: inherit;
  opacity: 0.45;
}

@keyframes text-drift {
  0%,
  100% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
}

/* Numerals share the gradient but stay upright — italic numbers read badly. */
.grad-num {
  color: var(--ember);
}

@supports (-webkit-background-clip: text) or (background-clip: text) {
  .grad-num {
    /* Gold-led, so the big figures read as the "money" colour. */
    background-image: linear-gradient(
      140deg,
      #ffe27a 0%,
      var(--flame-3) 30%,
      var(--flame-2) 60%,
      var(--flame-1) 85%,
      var(--flame-3) 100%
    );
    /* Room for the drift to travel through. */
    background-size: 220% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: none; /* see the note on h1/h2/.accent above */
    filter: var(--flame-glow);
  }
}

/* An accent word inside a heading sits inside a parent that is ALREADY running
   the glow filter, so applying it again stacked two drop-shadows on the same
   glyphs — a visible doubled edge. The parent's glow is enough; the child only
   needs to override the gradient. */
h1 .accent,
h2 .accent {
  filter: none;
}

/* --- Surfaces ------------------------------------------------------------- */
.card {
  position: relative;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background:
    linear-gradient(180deg, rgba(255, 214, 170, 0.045), rgba(255, 214, 170, 0.012)),
    var(--ink-raised);
  box-shadow: var(--shadow-raised);
  transition:
    transform 0.28s var(--ease),
    box-shadow 0.28s var(--ease),
    border-color 0.28s var(--ease);
}

/* Hairline highlight along the top edge — light catching a machined edge. */
.card::before {
  content: '';
  position: absolute;
  inset-inline: 1.5rem;
  top: -1px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 207, 77, 0.4), transparent);
}

/* Lift on hover. Transform and shadow only — never `all`. */
@media (hover: hover) {
  .orbit:not([data-orbit-active]) .orbit__item:hover,
  .profiles > .card:hover,
  .tier:hover {
    transform: translateY(-4px);
    border-color: var(--line-strong);
    box-shadow: var(--shadow-float);
  }
}

/* --- Buttons -------------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 2.875rem;
  padding-inline: 1.375rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  cursor: pointer;
  overflow: hidden;
  transition:
    transform 0.3s var(--ease-spring),
    box-shadow 0.3s var(--ease),
    background-color 0.3s var(--ease),
    border-color 0.3s var(--ease),
    color 0.3s var(--ease);
}

.btn svg {
  transition: transform 0.35s var(--ease-spring);
}

/* Dark text on ember: 5.9:1, versus 3.4:1 for white. Also reads hotter. */
.btn--primary {
  background: var(--flame-grad);
  color: var(--on-flame);
  box-shadow: var(--shadow-raised);
}

/* Sheen that sweeps across on hover. */
.btn--primary::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    transparent 20%,
    rgba(255, 214, 170, 0.35) 50%,
    transparent 80%
  );
  transform: translateX(-120%);
  transition: transform 0.7s var(--ease);
}

.btn--primary:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-ember);
}

.btn--primary:hover::after {
  transform: translateX(120%);
}

.btn--primary:hover svg {
  transform: translateX(3px);
}

.btn--primary:active {
  transform: translateY(0);
}

.btn--secondary {
  border-color: var(--line-strong);
  background: var(--surface);
  color: var(--ash-100);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.btn--secondary:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 207, 77, 0.45);
  background: var(--surface-hover);
  color: #fff;
}

.btn--secondary:active {
  transform: translateY(0);
}

.btn--sm {
  height: 2.375rem;
  padding-inline: 1.125rem;
  font-size: 0.875rem;
}

.btn--lg {
  height: 3.625rem;
  padding-inline: 2rem;
  font-size: 1rem;
}

.btn[disabled] {
  opacity: 0.5;
  pointer-events: none;
}

.btn--glow {
  box-shadow: var(--shadow-ember);
}

.link-accent {
  position: relative;
  color: var(--flame-2);
  font-weight: 600;
  text-shadow: var(--glow-orange);
  transition: color 0.3s var(--ease), text-shadow 0.3s var(--ease);
}

.link-accent::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.4s var(--ease);
}

.link-accent:hover {
  color: var(--gold);
}

.link-accent:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* --- Decorative ----------------------------------------------------------- */
/* Atmosphere blobs. These were radial gradients run through filter: blur(100px)
   — a separable convolution at a very large radius, on several big elements,
   redrawn as the page scrolls. Blur cost scales with radius, so 40px is roughly
   a third of the work, and the gradient underneath is widened to keep the same
   spread. will-change puts each one on its own compositor layer, so scrolling
   moves them rather than re-running the blur — and unlike a translateZ(0) hack
   it is not cancelled by the transform these elements set for positioning.

   If they now read as too tight, raise the blur — it is one number. */
.ember-glow {
  position: absolute;
  border-radius: 999px;
  filter: blur(40px);
  pointer-events: none;
  background: radial-gradient(
    circle,
    rgba(255, 165, 0, 0.26) 0%,
    rgba(255, 165, 0, 0.18) 32%,
    rgba(255, 165, 0, 0.07) 58%,
    transparent 78%
  );
  will-change: transform;
}

/* --- Scroll reveal --------------------------------------------------------
   Content is in the DOM at full opacity for crawlers and for anyone with JS
   disabled (see the <noscript> block in index.html). */
.reveal {
  opacity: 0;
  transform: translate3d(0, 20px, 0);
  transition:
    opacity 0.55s var(--ease),
    transform 0.55s var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

.reveal[data-visible='true'] {
  opacity: 1;
  transform: none;
}

/* ===========================================================================
   NAV
   ========================================================================= */
.site-header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid transparent;
  /* backdrop-filter is deliberately NOT transitioned. Animating it re-blurs
     the full width of the page behind the header on every frame for the length
     of the transition, which is the single most expensive thing this page was
     doing at the moment you start scrolling. The colour fade carries it. */
  transition:
    background-color 0.28s var(--ease),
    border-color 0.4s var(--ease);
}

.site-header.is-scrolled {
  border-bottom-color: var(--line);
  background: rgba(8, 8, 10, 0.82);
  /* 12px rather than 20px, and no saturate(): both are per-frame costs on a
     fixed element over scrolling content, and the difference is not visible
     against a background this dark. */
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--space-4) 1.25rem;
}

/* Official wordmark. Source is 600x86 so it stays crisp on 2x displays. */
.logo {
  display: inline-flex;
  align-items: center;
  transition: opacity 0.3s var(--ease);
}

.logo:hover {
  opacity: 0.75;
}

.logo img {
  display: block;
  width: 148px;
  height: auto;
}

/* --- Tubelight nav --------------------------------------------------------
   Vanilla port of the "tubelight-navbar" component. The original animates a
   per-link highlight with Framer Motion's shared-layout (layoutId="lamp"),
   which measures and re-measures every link on each change. Here there is one
   lamp element, positioned out of flow, that slides on a transform — nothing
   in the document reflows when the section changes, which is what keeps it
   free of jank on a phone.

   The original's three stacked blur() divs for the glow are replaced by a
   single radial-gradient. A filter: blur() forces an offscreen raster pass on
   an element that sits in a fixed header over scrolling content; a gradient
   costs nothing.
   ------------------------------------------------------------------------ */
.nav__links {
  display: none;
  position: relative;
  align-items: center;
  gap: 0.125rem;
  padding: 0.25rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  /* Deliberately no backdrop-filter: the header already blurs once it is
     scrolled, and a second blurred layer on top of it is pure cost. */
  background: rgba(255, 214, 170, 0.035);
}

.nav__links a {
  position: relative;
  z-index: 1;
  display: block;
  padding: var(--space-2) 0.875rem;
  border-radius: 999px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ash-400);
  transition: color 0.3s var(--ease);
}

.nav__links a:hover {
  color: var(--ash-100);
}

.nav__links a[aria-current='true'] {
  color: var(--ash-100);
}

.nav__lamp {
  position: absolute;
  top: 0.25rem;
  left: 0;
  bottom: 0.25rem;
  z-index: 0;
  width: var(--lamp-w, 0px);
  border-radius: 999px;
  background: rgba(255, 165, 0, 0.1);
  opacity: 0;
  pointer-events: none;
  transform: translate3d(var(--lamp-x, 0px), 0, 0);
  transition:
    transform 0.42s var(--ease-spring),
    width 0.42s var(--ease-spring),
    opacity 0.28s var(--ease);
}

.nav__links[data-lamp='on'] .nav__lamp {
  opacity: 1;
}

/* The tube itself, sitting on the top edge of the pill. */
.nav__lamp::before {
  content: '';
  position: absolute;
  top: -0.3125rem;
  left: 50%;
  width: 2rem;
  height: 3px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--flame-grad);
  box-shadow: 0 0 10px rgba(255, 165, 0, 0.7);
}

/* Its spill of light. A gradient, not a stack of blurred boxes. */
.nav__lamp::after {
  content: '';
  position: absolute;
  top: -0.75rem;
  left: 50%;
  width: 4rem;
  height: 2.25rem;
  transform: translateX(-50%);
  border-radius: 999px;
  background: radial-gradient(
    ellipse at top,
    rgba(255, 165, 0, 0.4),
    rgba(255, 165, 0, 0.12) 45%,
    transparent 72%
  );
}

/* Nothing to slide to and from before the first measurement, and no reason to
   animate a lamp for someone who asked for less movement. */
@media (prefers-reduced-motion: reduce) {
  .nav__lamp {
    transition-duration: 0.001s;
  }
}

.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.nav__cta {
  display: none;
}

.nav__toggle {
  display: grid;
  place-items: center;
  width: 2.625rem;
  height: 2.625rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  transition:
    border-color 0.3s var(--ease),
    background-color 0.3s var(--ease),
    transform 0.3s var(--ease-spring);
}

.nav__toggle:hover {
  border-color: rgba(255, 207, 77, 0.45);
  background: var(--surface-hover);
}

.nav__toggle:active {
  transform: scale(0.94);
}

.nav__toggle-close {
  display: none;
}

.nav__toggle[aria-expanded='true'] .nav__toggle-open {
  display: none;
}

.nav__toggle[aria-expanded='true'] .nav__toggle-close {
  display: block;
}

.mobile-menu {
  border-top: 1px solid var(--line);
  background: rgba(8, 8, 10, 0.96);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  animation: menu-in 0.35s var(--ease);
}

@keyframes menu-in {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
}

.mobile-menu ul {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--space-3) 1.25rem var(--space-4);
}

.mobile-menu a {
  display: block;
  padding: var(--space-3) var(--space-2);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ash-200);
  transition: color 0.25s var(--ease);
}

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

.mobile-menu__cta {
  width: 100%;
  margin-top: var(--space-2);
  color: var(--ink);
}

/* ===========================================================================
   HERO
   ========================================================================= */
/* ===========================================================================
   HERO — animated shader background, centred content
   ---------------------------------------------------------------------------
   Ported from the React animated-shader-hero component. The original was a
   full-height black panel with Tailwind utilities and a framer-motion-free
   CSS stagger; this keeps the composition and the stagger and rebuilds it on
   this site's own tokens, buttons and type scale.

   min-height uses svh, not vh. On a phone 100vh is the height with the address
   bar hidden, so a full-height hero is always taller than the screen on first
   paint and the CTAs sit below the fold until you scroll. 100svh is the
   smallest stable height; the 100vh line above it is the fallback for browsers
   that do not support svh, and the bare rem the fallback for both.
   ========================================================================= */
.hero {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  min-height: 44rem;
  min-height: min(100vh, 52rem);
  min-height: min(100svh, 52rem);
  /* max(), not a bare value. Every tier below sets its own top padding, and
     the only hard requirement is that the first element clears the fixed
     header — so the floor is expressed once, here, and no tier can undercut
     it however aggressively it trims. */
  padding-block: max(7.5rem, calc(var(--header-h) + var(--header-clearance)))
    var(--space-12);
  text-align: center;
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* The shader is atmosphere, not a backdrop competing with the headline, so it
   is held back and faded out toward the bottom where the section meets the
   next one. */
.hero__canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0.62;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 97%);
  mask-image: linear-gradient(180deg, #000 0%, #000 55%, transparent 97%);
}

.hero__glow {
  top: -18rem;
  left: 50%;
  width: 48rem;
  height: 38rem;
  transform: translateX(-50%);
  opacity: 0.55;
}

/* The shader's brightest orbs drift through the middle of the frame, which is
   exactly where the sub-headline sits. A radial scrim keeps body copy at its
   contrast ratio without dimming the whole image. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    62% 46% at 50% 52%,
    rgba(10, 9, 8, 0.72) 0%,
    rgba(10, 9, 8, 0.45) 45%,
    transparent 100%
  );
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 56rem;
}

/* --- Entrance ---------------------------------------------------------------
   The React version used framer-motion's staggerChildren. There is no runtime
   here to stagger with, so the same effect is four animation-delays — which is
   cheaper anyway, runs off the main thread, and needs no JavaScript at all.

   The "backwards" fill mode matters: without it each element is fully visible
   for its share of the delay, then snaps back to the start of its own
   animation — a flicker on every element, staggered.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .hero__badge,
  .hero__headline .hero__title-line,
  .hero__sub,
  .hero__ctas {
    animation: hero-rise 0.75s var(--ease) backwards;
  }

  .hero__badge {
    animation-name: hero-drop;
  }
  .hero__headline .hero__title-line:first-child {
    animation-delay: 0.12s;
  }
  .hero__headline .hero__title-line:last-child {
    animation-delay: 0.24s;
  }
  .hero__sub {
    animation-delay: 0.4s;
  }
  .hero__ctas {
    animation-delay: 0.56s;
  }
}

@keyframes hero-rise {
  from {
    opacity: 0;
    transform: translate3d(0, 1.75rem, 0);
  }
}

@keyframes hero-drop {
  from {
    opacity: 0;
    transform: translate3d(0, -1.25rem, 0);
  }
}

/* --- Trust badge ----------------------------------------------------------- */
.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 var(--space-6);
  padding: 0.5rem 1.1rem;
  border: 1px solid rgba(255, 165, 0, 0.28);
  border-radius: 999px;
  background: rgba(255, 165, 0, 0.09);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--flame-3);
}

.hero__badge svg {
  flex: none;
  color: var(--flame-2);
}

/* --- Headline --------------------------------------------------------------
   Two lines, the second in the flame gradient via the site's existing .accent.
   Kept as separate blocks rather than a <br> so each can carry its own
   animation delay and so the line break survives a wrap on narrow screens.
   -------------------------------------------------------------------------- */
.hero__headline {
  margin: 0;
  /* .display bottoms out at 2.75rem, so every phone got the same 44px no
     matter how much room it had — the hero read smaller than the section
     headings further down the page, which is backwards. A higher floor and a
     steeper vw slope make it the largest type on the site at every width. */
  font-size: clamp(3.125rem, 13vw, 5.25rem);
  /* 1.02 is a display line-height meant for one or two words. At four lines on
     a phone it packed them into a solid block with the descenders of one line
     almost touching the caps of the next. */
  line-height: 1.1;
  letter-spacing: -0.025em;
  /* NOT 20ch. `ch` scales with font-size, so at the hero's 77px this resolved
     to ~1009px — wider than the container, so it did nothing on desktop while
     still forcing awkward breaks elsewhere. A fixed max-width is what was
     actually wanted: a comfortable two-line measure. */
  max-width: 15em;
  text-wrap: balance;

  /* The @supports block up top gives every h1 a clipped gradient and
     `color: transparent`. `color` INHERITS, so the plain first line inherited a
     transparent fill with no background of its own behind it and rendered
     completely invisible — the missing half of the headline. The gradient
     belongs to .accent here, not to the h1, so take it off the h1 entirely. */
  background-image: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
  color: var(--ash-100);
  filter: none;
  text-shadow: var(--text-shadow);
}

/* h1 .accent is set to `filter: none` globally, to stop the glow being applied
   twice when the h1 also carried one. The h1 no longer does, so the accent line
   needs its own back. */
.hero__headline .accent {
  filter: var(--flame-glow);
  text-shadow: none;
}

.hero__title-line {
  display: block;
}

/* A visible beat between the white statement and the flame one, so they read
   as two lines of a claim rather than one dense block of type. */
.hero__title-line + .hero__title-line {
  margin-top: 0.12em;
}

.hero__sub {
  margin: var(--space-6) auto 0;
  max-width: 44ch;
  font-size: clamp(1.0625rem, 0.95rem + 0.6vw, 1.3125rem);
  line-height: 1.6;
  color: var(--text-soft, rgba(255, 255, 255, 0.78));
  text-wrap: pretty;
}

/* Row on anything wider than a phone, stacked below it — the original's
   "flex-col sm:flex-row". Full-width buttons on a narrow screen are the more
   tappable arrangement, so the stacked case stretches rather than centring. */
.hero__ctas {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  gap: var(--space-3);
  /* --space-10 is not in the scale. It silently computed to 0, which is why
     the buttons sat hard against the sub-headline with no gap at all. */
  margin-top: var(--space-12);
}

@media (min-width: 30rem) {
  .hero__ctas {
    flex-direction: row;
    align-self: auto;
    justify-content: center;
    gap: var(--space-4);
  }
}


   PROBLEM
   ========================================================================= */
.problem-grid {
  display: grid;
  gap: 1px;
  margin-top: var(--space-16);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--line);
  box-shadow: var(--shadow-raised);
}

.problem-grid > li {
  padding: var(--space-8);
  background: var(--ink-raised);
  transition: background-color 0.28s var(--ease);
}

.problem-grid > li:hover {
  background: var(--ink-float);
}

.problem-grid .num {
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-style: italic;
  color: var(--ember);
}

.problem-grid h3 {
  margin-top: var(--space-4);
  font-size: 1.1875rem;
}

.problem-grid p {
  margin-top: var(--space-3);
  color: var(--ash-400);
  line-height: 1.7;
  text-wrap: pretty;
}

/* ===========================================================================
   HOW IT WORKS — scroll-driven flame lines
   ---------------------------------------------------------------------------
   Adapted from jh3yy's "you can scroll" scroll-driven type demo. Two changes
   of substance from the original:

   1. The original sweeps --hue across the whole 0-360 colour wheel. That would
      throw every hue on the wheel at a page built around one deliberate
      palette, so the sweep is clamped to the flame's own arc, expressed in
      OKLCH: cherry (h 18) → orange (h 64) → gold (h 88), with lightness and
      chroma travelling alongside. It is --flame-grad unrolled down the scroll
      instead of across a heading.
   2. The original's Tweakpane panel is gone. It is a tool for tuning the
      effect in development, not something to float over a client-facing page.

   Two mechanisms drive it, and only ever one at a time:
     - Browsers with scroll-driven animations (Chrome/Edge): pure CSS, below.
     - Everything else (Safari, Firefox — i.e. most phones): initFlameSteps()
       in script.js, which opts in by setting data-flame-steps="on".
   ========================================================================= */

/* Registered so they interpolate. Unregistered custom properties animate
   discretely — the sweep would jump between keyframes rather than travel. */
@property --flame-hue {
  syntax: '<number>';
  inherits: true;
  initial-value: 64;
}
@property --flame-chroma {
  syntax: '<number>';
  inherits: true;
  initial-value: 0.17;
}
@property --flame-light {
  syntax: '<percentage>';
  inherits: true;
  initial-value: 77%;
}

.flame-steps {
  margin-top: var(--space-16);

  /* Declared as well as registered. Without @property support the registration
     is ignored, and an unresolvable var() in the oklch() below would make the
     whole `color` declaration invalid at computed-value time — which inherits
     rather than falling back to the previous declaration. These guarantee a
     value either way. */
  --flame-hue: 64;
  --flame-chroma: 0.17;
  --flame-light: 77%;
}

.flame-step {
  padding-block: clamp(1.75rem, 4vw, 3rem);
  border-top: 1px solid var(--line);
}

.flame-step__num {
  display: block;
  margin-bottom: var(--space-3);
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  color: var(--ash-600);
  font-variant-numeric: tabular-nums;
}

.flame-step__line {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.25rem, 8vw, 4.5rem);
  line-height: 1.02;
  letter-spacing: -0.035em;
}

.flame-step__lead {
  color: var(--ash-100);
  text-shadow: var(--text-shadow-sm);
}

.flame-step__verb {
  /* Solid-colour fallback first: engines without oklch() drop the next
     declaration at parse time and keep this one. */
  color: var(--flame-2);
  text-shadow: var(--glow-orange), var(--text-shadow-sm);

  color: oklch(var(--flame-light) var(--flame-chroma) var(--flame-hue));
  /* The glow travels with the colour rather than sitting at a fixed orange. */
  text-shadow:
    0 0 32px oklch(var(--flame-light) var(--flame-chroma) var(--flame-hue) / 0.4),
    0 0 8px oklch(var(--flame-light) var(--flame-chroma) var(--flame-hue) / 0.3),
    0 2px 6px rgba(0, 0, 0, 0.55);
}

.flame-step__note {
  margin-top: var(--space-4);
  max-width: 48ch;
  color: var(--ash-400);
  line-height: 1.7;
  text-wrap: pretty;
}

/* --- The sweep: pure CSS where scroll-driven animations exist ------------- */
@keyframes pf-flame-travel {
  0% {
    --flame-hue: 18;
    --flame-chroma: 0.21;
    --flame-light: 66%;
  }
  50% {
    --flame-hue: 64;
    --flame-chroma: 0.17;
    --flame-light: 77%;
  }
  100% {
    --flame-hue: 88;
    --flame-chroma: 0.15;
    --flame-light: 86%;
  }
}

/* The line does not just brighten, it lifts and grows a little as it arrives,
   so a single notch of the wheel produces visible movement rather than a
   barely-perceptible change in opacity. Only opacity and transform, so it stays
   on the compositor. */
@keyframes pf-step-focus {
  0% {
    opacity: 0.42;
    transform: translate3d(0, 1.25rem, 0) scale(0.965);
  }
  46%,
  54% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0.42;
    transform: translate3d(0, -1.25rem, 0) scale(0.965);
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .flame-steps {
      animation: pf-flame-travel linear both;
      animation-timeline: view();
      /* `contain`, not `entry`/`exit`: the list is usually taller than the
         viewport, and contain is the stretch during which it fills the screen —
         exactly the time the reader spends inside it. */
      animation-range: contain;
    }

    .flame-step {
      animation: pf-step-focus linear both;
      animation-timeline: view();
      /* Tightened from `entry 85% exit 15%`. That spread the arrival across
         nearly the whole pass, so a small scroll moved it almost not at all —
         which is what made it feel hidden. Over a narrower band the same
         scroll distance produces a much larger change. */
      animation-range: entry 100% exit 0%;
      transform-origin: left center;
    }
  }
}

/* --- The sweep: JS path. Opt-in, so no-JS readers get plain, full-opacity
   text and never depend on a scroll handler running. -------------------- */
[data-flame-steps='on'] .flame-step {
  opacity: var(--step-opacity, 1);
  transform: translate3d(0, var(--step-lift, 0px), 0) scale(var(--step-scale, 1));
  transform-origin: left center;
  /* Short: this tracks the scroll, so a long transition reads as lag rather
     than as smoothing. */
  transition:
    opacity 0.22s linear,
    transform 0.22s linear;
}

@media (prefers-reduced-motion: reduce) {
  [data-flame-steps='on'] .flame-step {
    opacity: 1 !important;
  }
}

.callout {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  margin-top: var(--space-16);
  padding: var(--space-8);
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background:
    linear-gradient(135deg, rgba(255, 165, 0, 0.07), rgba(255, 214, 170, 0.012)),
    var(--ink-raised);
  box-shadow: var(--shadow-raised);
}

.callout__main {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

.callout__icon {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  border-radius: 999px;
  border: 1px solid rgba(255, 207, 77, 0.28);
  background: rgba(255, 165, 0, 0.12);
}

.callout__title {
  font-family: var(--font-display);
  font-size: 1.375rem;
}

.callout__body {
  margin-top: 0.375rem;
  color: var(--ash-400);
  line-height: 1.6;
}

/* ===========================================================================
   WHAT YOU GET / PROFILES
   ========================================================================= */
.profiles {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-16);
}

.profiles > li {
  padding: var(--space-6);
}

.profiles p {
  margin-top: var(--space-3);
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--ash-400);
  text-wrap: pretty;
}

.profiles h3 {
  font-size: 1.0625rem;
}

/* ===========================================================================
   ASSISTANT WIDGET
   ========================================================================= */
.agent {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 80;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-3);
}

.agent__launcher {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 3rem;
  padding-inline: 1.25rem;
  border: 0;
  border-radius: 999px;
  background: var(--flame-grad);
  color: var(--on-flame);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: var(--shadow-ember);
  transition: transform 0.28s var(--ease-spring), box-shadow 0.28s var(--ease);
}

.agent__launcher:hover {
  transform: translateY(-2px);
}

/* Retire the launcher once the panel is open. Otherwise it stacks under the
   panel and, on a short viewport, collides with the header's Apply button. */
.agent[data-open='true'] .agent__launcher {
  display: none;
}

/* Narrow or short viewports: drop to a circular icon. The full pill is 222px
   wide — 59% of a 375px screen — and on a short screen it drifts up into the
   fixed header's CTA. */
@media (max-width: 30rem), (max-height: 34rem) {
  .agent__launcher {
    width: 3.25rem;
    height: 3.25rem;
    padding: 0;
    border-radius: 50%;
    justify-content: center;
  }

  .agent__launcher span {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }
}

.agent__launcher:active {
  transform: translateY(0);
}

/* `display: flex` below is an author rule and therefore beats the UA
   stylesheet's `[hidden] { display: none }`. Without this guard the panel can
   never be hidden — the close button sets the attribute and nothing happens.
   Any element that carries `hidden` AND has an author `display` needs this. */
.agent__panel[hidden] {
  display: none;
}

.agent__panel {
  display: flex;
  flex-direction: column;
  width: min(23rem, calc(100vw - 2.5rem));
  height: min(30rem, calc(100vh - 8rem));
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: rgba(17, 15, 12, 0.97);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: var(--shadow-float);
  overflow: hidden;
  animation: faq-reveal 0.3s var(--ease) both;
}

.agent__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4);
  border-bottom: 1px solid var(--line);
}

.agent__title {
  font-size: 0.875rem;
  font-weight: 700;
}

.agent__close {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: none;
  color: var(--ash-400);
  cursor: pointer;
  transition: color 0.28s var(--ease), border-color 0.28s var(--ease);
}

.agent__close:hover {
  color: var(--ash-100);
  border-color: rgba(255, 207, 77, 0.45);
}

.agent__log {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);

  /* The default scrollbar is a light-grey system chrome sitting on near-black,
     which is the brightest thing in the panel. Standard properties first —
     Chrome 121+, Firefox and Safari 18.2+ all honour these, and where they are
     honoured the ::-webkit- rules below are ignored entirely. */
  scrollbar-width: thin;
  scrollbar-color: var(--flame-2) rgba(255, 214, 170, 0.08);
}

/* Older WebKit/Chrome only, so the two never fight. Gets the full flame
   gradient, which scrollbar-color cannot express. */
@supports not (scrollbar-color: red) {
  html::-webkit-scrollbar {
    width: 12px;
  }

  html::-webkit-scrollbar-track {
    background: var(--ink-sunken);
  }

  html::-webkit-scrollbar-thumb {
    border: 3px solid transparent;
    border-radius: 999px;
    background: var(--flame-grad);
    background-clip: padding-box;
  }

  .agent__log::-webkit-scrollbar {
    width: 10px;
  }

  .agent__log::-webkit-scrollbar-track {
    background: rgba(255, 214, 170, 0.06);
    border-radius: 999px;
  }

  .agent__log::-webkit-scrollbar-thumb {
    border: 2px solid transparent;
    border-radius: 999px;
    background: linear-gradient(
      180deg,
      var(--flame-1),
      var(--flame-2) 55%,
      var(--flame-3)
    );
    background-clip: padding-box;
  }

  .agent__log::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, var(--flame-2), var(--flame-3));
    background-clip: padding-box;
  }
}

.agent__msg p {
  padding: 0.625rem 0.875rem;
  border-radius: 0.875rem;
  font-size: 0.875rem;
  line-height: 1.6;
  white-space: pre-wrap;
}

.agent__msg--assistant p {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ash-200);
  border-top-left-radius: 0.25rem;
}

.agent__msg--user {
  align-self: flex-end;
  max-width: 85%;
}

.agent__msg--user p {
  background: var(--flame-grad);
  color: var(--on-flame);
  font-weight: 500;
  border-bottom-right-radius: 0.25rem;
}

.agent__typing {
  padding: 0 var(--space-4) var(--space-2);
  font-size: 0.75rem;
  color: var(--ash-600);
}

.agent__form {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--line);
}

.agent__input {
  flex: 1;
  min-width: 0;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--line-strong);
  border-radius: 0.75rem;
  background: rgba(5, 4, 3, 0.6);
  font-size: 0.875rem;
  color: var(--ash-100);
}

.agent__input::placeholder {
  color: var(--ash-600);
}

.agent__input:focus {
  border-color: var(--flame-2);
  outline: none;
}

.agent__send {
  display: grid;
  place-items: center;
  width: 2.5rem;
  flex-shrink: 0;
  border: 0;
  border-radius: 0.75rem;
  background: var(--flame-grad);
  color: var(--on-flame);
  cursor: pointer;
}

.agent__send[disabled],
.agent__input[disabled] {
  opacity: 0.55;
  pointer-events: none;
}

.agent__note {
  padding: 0 var(--space-4) var(--space-3);
  font-size: 0.6875rem;
  line-height: 1.5;
  color: var(--ash-600);
}

/* Touch targets on coarse pointers. */
@media (pointer: coarse) {
  .agent__launcher { height: 3.25rem; }
  .agent__close { width: 44px; height: 44px; }
  .agent__send { width: 44px; }
  .agent__input { min-height: 44px; }
}

/* ===========================================================================
   RADIAL ORBITAL — "What you get"
   ---------------------------------------------------------------------------
   Two layouts from one set of markup.

   Default (mobile, and any browser without JS): a plain card grid — every
   benefit visible, nothing behind an interaction. This is the fallback that
   matters, because these are the page's value propositions.

   Orbit mode: orbit.js adds [data-orbit-active] from 64rem up and positions
   the nodes around a rotating ring via --x/--y set inline per node.
   ========================================================================= */
.orbit {
  margin-top: var(--space-16);
}

.orbit__list {
  display: grid;
  gap: var(--space-4);
}

.orbit__item {
  padding: var(--space-6);
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 214, 170, 0.045), rgba(255, 214, 170, 0.012)),
    var(--ink-raised);
  box-shadow: var(--shadow-raised);
}

.orbit__heading {
  font-size: 1.0625rem;
}

/* The node is a real <button> inside the heading — keyboard-operable and
   announced correctly, unlike the original's div-with-onClick. */
.orbit__node {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.orbit__icon {
  display: grid;
  place-items: center;
  width: 2.875rem;
  height: 2.875rem;
  flex-shrink: 0;
  border: 1px solid rgba(255, 207, 77, 0.25);
  border-radius: 0.875rem;
  background: linear-gradient(150deg, rgba(255, 207, 77, 0.16), rgba(255, 165, 0, 0.05));
  color: var(--flame-2);
  transition: transform 0.3s var(--ease-spring), border-color 0.28s var(--ease);
}

.orbit__title {
  font-weight: 600;
  letter-spacing: -0.01em;
}

.orbit__panel {
  margin-top: var(--space-3);
}

.orbit__panel p {
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--ash-400);
  text-wrap: pretty;
}

/* Decorative chrome — only drawn in orbit mode. */
.orbit__ring,
.orbit__core,
.orbit__hint {
  display: none;
}

/* --- Orbit mode ---------------------------------------------------------- */
[data-orbit-active] .orbit__stage {
  position: relative;
  height: 40rem;
  display: grid;
  place-items: center;
}

[data-orbit-active] .orbit__list {
  display: block;
  position: absolute;
  inset: 0;
}

[data-orbit-active] .orbit__ring {
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--orbit-radius, 15rem) * 2);
  height: calc(var(--orbit-radius, 15rem) * 2);
  transform: translate(-50%, -50%);
  border: 1px solid var(--line);
  border-radius: 50%;
}

[data-orbit-active] .orbit__ring--inner {
  width: calc(var(--orbit-radius, 15rem) * 1.1);
  height: calc(var(--orbit-radius, 15rem) * 1.1);
  border-style: dashed;
  border-color: rgba(255, 214, 170, 0.05);
}

[data-orbit-active] .orbit__core {
  display: grid;
  place-items: center;
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4.5rem;
  height: 4.5rem;
  /* --orbit-lift is set by orbit.js and is 0 except in compact mode, where the
     ring is raised to make room for the card beneath it. The core is centred by
     the stage, so without this it stayed at the stage's centre while the ring
     moved up around it — leaving the glowing middle visibly low. */
  transform: translate(-50%, -50%) translateY(var(--orbit-lift, 0px));
  border-radius: 50%;
  background: var(--flame-grad);
  box-shadow: var(--shadow-ember);
}

.orbit__core-dot {
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: rgba(255, 243, 230, 0.9);
}

/* Expanding halo. Purely decorative, and silenced under reduced motion by the
   global animation rule. */
.orbit__core-pulse {
  position: absolute;
  inset: -0.75rem;
  border: 1px solid rgba(255, 207, 77, 0.35);
  border-radius: 50%;
  animation: orbit-ping 2.6s cubic-bezier(0, 0, 0.2, 1) infinite;
}

@keyframes orbit-ping {
  0% {
    transform: scale(0.9);
    opacity: 0.7;
  }
  75%,
  100% {
    transform: scale(1.9);
    opacity: 0;
  }
}

[data-orbit-active] .orbit__item {
  position: absolute;
  top: 50%;
  left: 50%;
  width: auto;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;

  /* transform, opacity and z-index are written directly as inline styles by
     orbit.js. They used to be read from custom properties, which cost far more
     than it looks: a custom property inherits, so setting one invalidates
     style for the item AND everything inside it (button, icon, title, panel),
     six times over, sixty times a second. Writing the real properties keeps
     the invalidation on the element itself.

     There is deliberately no `transition: opacity` here either. The value is
     rewritten every frame, so a transition just leaves the browser
     continuously retargeting an animation that never gets to finish. */
  will-change: transform;
}

[data-orbit-active] .orbit__node {
  flex-direction: column;
  gap: 0.625rem;
  width: 9rem;
  align-items: center;
  text-align: center;
}

[data-orbit-active] .orbit__icon {
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  background: var(--ink-raised);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-raised);
}

[data-orbit-active] .orbit__node:hover .orbit__icon {
  transform: scale(1.08);
  border-color: rgba(255, 207, 77, 0.5);
}

[data-orbit-active] .orbit__title {
  font-size: 0.8125rem;
  color: var(--ash-200);
  text-shadow: var(--text-shadow);
}

/* Selected node: flame fill, scaled up, lifted above its neighbours. */
[data-orbit-active] .orbit__item[data-open='true'] {
  z-index: 60;
  opacity: 1;
}

[data-orbit-active] [aria-expanded='true'] .orbit__icon {
  transform: scale(1.15);
  border-color: transparent;
  background: var(--flame-grad);
  color: var(--on-flame);
  box-shadow: var(--shadow-ember);
}

[data-orbit-active] [aria-expanded='true'] .orbit__title {
  color: var(--ash-100);
}

/* The detail card, tethered to its node. */
[data-orbit-active] .orbit__panel {
  position: absolute;
  top: calc(100% + 0.875rem);
  left: 50%;
  width: 17rem;
  margin-top: 0;
  transform: translateX(-50%);
  padding: var(--space-4) var(--space-6) var(--space-6);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: rgba(17, 15, 12, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-float);
  /* Opacity only — never transform. These cards are POSITIONED with
     transform (translate(-50%) on desktop, plus the --x/--y cancellation in
     compact mode), so an animation touching transform overrides that and the
     card lands off-centre for the duration.
     The delay is deliberate: on desktop the selected node glides to the top of
     the ring first, and opening the card immediately would render it below a
     node still sitting at the bottom, spilling past the stage. */
  animation: orbit-card-in 0.3s var(--ease) 0.26s both;
}

/* Hairline connecting the card to its node. */
[data-orbit-active] .orbit__panel::before {
  content: '';
  position: absolute;
  top: -0.875rem;
  left: 50%;
  width: 1px;
  height: 0.875rem;
  background: linear-gradient(180deg, transparent, rgba(255, 207, 77, 0.5));
}

[data-orbit-active] .orbit__panel[hidden] {
  display: none;
}

/* Same author-vs-UA precedence trap as .agent__panel — keep `hidden` winning
   over the display rule below. */
.orbit__hint[hidden] {
  display: none;
}

/* ---------------------------------------------------------------------------
   Compact orbit (below 48rem)
   Same component, arranged for a narrow screen: icons only, and the card
   centred inside the ring rather than hanging off the selected node. A 17rem
   card tethered to a node simply cannot fit next to a ring on a 375px screen.
   --------------------------------------------------------------------------- */
[data-orbit-compact='true'] .orbit__stage {
  height: 25rem;
}

/* Compact now mirrors the desktop arrangement: icon with its label beneath,
   and the glowing core left visible in the middle of the ring. It previously
   hid every label and auto-opened a card over the centre, which meant the
   phone showed a ring of unexplained icons around a covered core — a different
   component from the one on the laptop. Smaller, but the same thing. */
[data-orbit-compact='true'] .orbit__node {
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  width: 5.5rem;
  text-align: center;
}

[data-orbit-compact='true'] .orbit__icon {
  width: 2.5rem;
  height: 2.5rem;
}

[data-orbit-compact='true'] .orbit__title {
  font-size: 0.625rem;
  line-height: 1.25;
  letter-spacing: 0;
}

[data-orbit-compact='true'] .orbit__panel {
  position: absolute;
  top: 50%;
  left: 50%;
  /* The card is no longer inside the ring. Shrinking it to fit there was the
     wrong fix pursued three times — 15rem, 11rem, 9rem — because the problem
     was never the width. A card in the middle of the ring covers the only part
     of the section that moves, so the orbit reads as broken, and whatever is
     left of the card is squeezed into a box too small to read comfortably.
     It now sits below a ring that JS lifts off centre, so it can be as wide as
     the screen allows and set at a readable size. */
  width: min(19rem, calc(100vw - 3rem));
  padding: 0.75rem 0.9rem 0.85rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  /* The card's offset parent is its node, which sits out on the ring — so
     `left: 50%` alone centres it on the node, not the stage. Cancelling the
     node's own --x/--y (custom properties inherit) lands it on the stage centre
     and keeps it there as the ring turns; the last translate then drops it
     clear of the ring's lowest node. --orbit-radius is set on the stage. */
  transform: translate(-50%, -50%)
    translate(calc(var(--x, 0px) * -1), calc(var(--y, 0px) * -1))
    translateY(calc(var(--orbit-radius, 104px) + 1.5rem));
  z-index: 70;
  text-align: center;
}

/* The card sits over the core, so the connector line makes no sense here. */
[data-orbit-compact='true'] .orbit__panel {
  animation-delay: 0s;
}

@keyframes orbit-card-in {
  from {
    opacity: 0;
  }
}

[data-orbit-compact='true'] .orbit__panel::before {
  display: none;
}

/* The ring shows its own labels again, so repeating the title on the card just
   said the same word twice, one inch apart. */

[data-orbit-compact='true'] .orbit__panel {
  display: flex;
  flex-direction: column;
}

/* The core stays put. It was hidden because the open card used to sit on top
   of it; the card now sits below the ring, so the glowing centre is visible on
   a phone exactly as it is on a laptop. */

[data-orbit-active] .orbit__core {
  transition: opacity 0.3s var(--ease);
}

[data-orbit-active] .orbit__hint {
  display: block;
  margin-top: var(--space-6);
  text-align: center;
  font-size: 0.8125rem;
  color: var(--ash-600);
}

/* ===========================================================================
   REVENUE MODEL
   ========================================================================= */
.tiers {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-16);
}

.tier {
  padding: var(--space-8);
}

.tier--featured {
  border-color: rgba(255, 207, 77, 0.25);
  background:
    linear-gradient(180deg, rgba(255, 165, 0, 0.07), rgba(255, 214, 170, 0.012)),
    var(--ink-raised);
}

.tier__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}

.tier__head h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.75rem;
}

.tier__head span {
  font-size: 0.8125rem;
  color: var(--ash-600);
}

.tier__pct {
  margin-top: var(--space-6);
  font-family: var(--font-display);
  font-size: 3.75rem;
  line-height: 1;
  letter-spacing: -0.02em;
}

.tier__sub {
  margin-top: var(--space-2);
  font-size: 0.9375rem;
  color: var(--ash-400);
}

.tier__split {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line);
}

.tier__split > div {
  display: flex;
  justify-content: space-between;
  margin-bottom: var(--space-3);
  font-size: 0.9375rem;
}

.tier__split > div:last-child {
  margin-bottom: 0;
}

.tier__split dt {
  color: var(--ash-400);
}

.tier__split dd {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ash-200);
}

.calc-intro {
  margin-top: var(--space-24);
}

.calc-intro h3 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.75rem, 3vw, 2.5rem);
}

/* --- Calculator ----------------------------------------------------------- */
.calc {
  margin-top: var(--space-8);
  padding: var(--space-8);
}

.calc__grid {
  display: grid;
  gap: var(--space-12);
}

.calc__inputs {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}

.calc__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.calc__row label {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ash-200);
}

#subsOut {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-variant-numeric: tabular-nums;
}

.calc__scale {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--ash-600);
}

.calc__presets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.calc__presets button {
  padding: 0.4375rem 0.8125rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  font-size: 0.75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ash-400);
  cursor: pointer;
  transition:
    border-color 0.3s var(--ease),
    color 0.3s var(--ease),
    background-color 0.3s var(--ease),
    transform 0.3s var(--ease-spring);
}

.calc__presets button:hover {
  border-color: rgba(255, 207, 77, 0.45);
  color: var(--ash-100);
}

.calc__presets button:active {
  transform: scale(0.94);
}

.calc__presets button[aria-pressed='true'] {
  border-color: rgba(255, 207, 77, 0.55);
  background: rgba(255, 165, 0, 0.14);
  color: var(--ember-bright);
}

.calc__prices {
  border: 0;
  padding: 0;
}

.calc__prices legend {
  margin-bottom: var(--space-3);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ash-200);
}

.calc__prices [role='radiogroup'] {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
}

.calc__prices button {
  padding: 0.875rem 0;
  border: 1px solid var(--line-strong);
  border-radius: 0.875rem;
  background: var(--surface);
  font-size: 0.9375rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ash-200);
  cursor: pointer;
  transition:
    border-color 0.3s var(--ease),
    background 0.3s var(--ease),
    color 0.3s var(--ease),
    transform 0.3s var(--ease-spring),
    box-shadow 0.3s var(--ease);
}

.calc__prices button:hover {
  border-color: rgba(255, 207, 77, 0.45);
  transform: translateY(-2px);
}

.calc__prices button:active {
  transform: translateY(0);
}

.calc__prices button[aria-checked='true'] {
  border-color: transparent;
  background: var(--flame-grad);
  color: var(--on-flame);
  box-shadow: var(--shadow-ember);
}

.calc__disclaimer {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line);
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--ash-600);
}

/* Range input — track fill driven by --progress, set from JS. */
.range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 2.25rem;
  margin-top: var(--space-2);
  background: transparent;
  cursor: pointer;
}

.range::-webkit-slider-runnable-track {
  height: 0.5rem;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    var(--ember-deep) 0%,
    var(--gold) var(--progress, 0%),
    rgba(255, 214, 170, 0.1) var(--progress, 0%),
    rgba(255, 214, 170, 0.1) 100%
  );
}

.range::-moz-range-track {
  height: 0.5rem;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    var(--ember-deep) 0%,
    var(--gold) var(--progress, 0%),
    rgba(255, 214, 170, 0.1) var(--progress, 0%),
    rgba(255, 214, 170, 0.1) 100%
  );
}

.range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: -0.5rem;
  border: 3px solid var(--ink);
  border-radius: 999px;
  background: var(--ash-100);
  box-shadow:
    0 0 0 1px rgba(255, 214, 170, 0.3),
    0 4px 14px -2px rgba(255, 165, 0, 0.6);
  transition: transform 0.25s var(--ease-spring);
}

.range:hover::-webkit-slider-thumb,
.range:active::-webkit-slider-thumb {
  transform: scale(1.12);
}

.range::-moz-range-thumb {
  width: 1.5rem;
  height: 1.5rem;
  border: 3px solid var(--ink);
  border-radius: 999px;
  background: var(--ash-100);
  box-shadow:
    0 0 0 1px rgba(255, 214, 170, 0.3),
    0 4px 14px -2px rgba(255, 165, 0, 0.6);
}

.calc__tier {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.625rem;
}

.tier-badge {
  padding: 0.3125rem 0.8125rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 207, 77, 0.3);
  background: rgba(255, 165, 0, 0.12);
  color: var(--ember-bright);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.calc__tier-note {
  font-size: 0.75rem;
  color: var(--ash-600);
}

.calc__label {
  margin-top: var(--space-8);
  font-size: 0.875rem;
  color: var(--ash-400);
}

.calc__big {
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(3.25rem, 8vw, 4.75rem);
  line-height: 1;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}

.calc__meta {
  margin-top: var(--space-3);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ash-400);
}

.split-bar {
  display: flex;
  height: 0.75rem;
  margin-top: var(--space-8);
  overflow: hidden;
  border-radius: 999px;
  background: rgba(255, 214, 170, 0.07);
}

.split-bar i {
  width: var(--w);
  transition: width 0.6s var(--ease);
}

.split-bar__creator,
.dot--creator {
  background: var(--flame-grad);
}

.split-bar__pf,
.dot--pf {
  background: var(--ash-800);
}

.legend {
  margin-top: var(--space-6);
}

.legend li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: 0.625rem;
  font-size: 0.875rem;
}

.dot {
  width: 0.625rem;
  height: 0.625rem;
  flex-shrink: 0;
  border-radius: 999px;
}

.legend__name {
  flex: 1;
  color: var(--ash-400);
}

.legend__pct {
  font-variant-numeric: tabular-nums;
  color: var(--ash-600);
}

.legend__amt {
  width: 5rem;
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ash-200);
}

.calc__tiernote {
  margin-top: var(--space-6);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: 0.875rem;
  background: var(--surface);
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--ash-400);
}

/* ===========================================================================
   NICHES
   ========================================================================= */
.niches {
  margin-top: var(--space-4);
  padding: var(--space-8);
}

.niches h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.75rem;
}

.niches > p {
  margin-top: var(--space-3);
  max-width: 42rem;
  color: var(--ash-400);
  line-height: 1.7;
  text-wrap: pretty;
}

.niche-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-8);
}

.niche-tags li {
  padding: 0.4375rem 0.9375rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ash-400);
  transition:
    border-color 0.3s var(--ease),
    color 0.3s var(--ease);
}

.niche-tags li:hover {
  border-color: rgba(255, 207, 77, 0.4);
  color: var(--ash-100);
}

.niche-tags .is-active {
  border-color: rgba(255, 207, 77, 0.45);
  background: rgba(255, 165, 0, 0.12);
  color: var(--ember-bright);
}

.niche-tags .is-active span {
  margin-left: var(--space-2);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.85;
}

/* ===========================================================================
   TECHNOLOGY & TRUST
   ========================================================================= */
/* --- Energy-meter comparison ----------------------------------------------
   Vanilla port of the "energy-meter" component, rebuilt around what this
   section actually has to say.

   Three changes of substance from the original:

   1. Its colour is chosen by threshold — red under 30, amber under 60, primary
      above. That is wrong here: the colour has to say WHO, not how much. A
      full bar and an empty bar both belong to the same comparison, so the
      cherry/flame split runs by row, not by value.
   2. Its fill is a setInterval that ticks one segment every 60ms, per meter.
      Eight meters would be eight timers. The stagger is done with per-segment
      transition-delays instead, so it costs one class toggle and the browser
      handles the rest.
   3. Its animated "%" readout is dropped. A percentage is meaningless for
      "engineers to hire"; the real figure sits beside the bar instead.

   The corner brackets and the faint scanline are kept — they are the character
   of the original, and neither costs anything.
   ------------------------------------------------------------------------ */
.meters {
  position: relative;
  margin-top: var(--space-12);
  padding: var(--space-8);
  overflow: hidden;
}

/* Scanline. The original uses black lines, which are invisible on a dark
   surface; this is a warm light one at very low strength. */
.meters::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 2px,
    rgba(255, 214, 170, 0.014) 2px,
    rgba(255, 214, 170, 0.014) 4px
  );
}

.meters__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--line);
}

.meters__title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ash-200);
}

.meters__key {
  display: flex;
  gap: var(--space-4);
  font-size: 0.75rem;
  color: var(--ash-600);
}

.meters__key li {
  display: flex;
  align-items: center;
  gap: 0.4375rem;
}

.meters__swatch {
  width: 0.875rem;
  height: 0.5rem;
  border-radius: 2px;
}

.meters__swatch--alone {
  background: var(--flame-1);
}

.meters__swatch--us {
  background: var(--flame-grad);
}

.meters__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  margin-top: var(--space-8);
}

.meter-group__title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ash-100);
}

/* Explicit areas rather than auto-placement. The track spans the full width on
   a phone, and auto-placement pushed the value onto a third row of its own
   because the spanning item came between them in source order. */
.meter {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    'who value'
    'track track';
  align-items: center;
  gap: 0.375rem 0.75rem;
  margin-top: 0.75rem;
}

.meter__who {
  grid-area: who;
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  color: var(--ash-600);
}

.meter__value {
  grid-area: value;
  font-size: 0.875rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--ash-200);
}

.meter--us .meter__value {
  color: var(--flame-3);
  text-shadow: var(--glow-orange);
}

.meter__track {
  grid-area: track;
  display: flex;
  gap: 3px;
}

.meter__track i {
  flex: 1;
  height: 0.875rem;
  border-radius: 3px;
  /* Empty slots stay clearly visible, so a row with nothing lit reads as
     "none of this" rather than as a bar that failed to render. */
  background: rgba(255, 214, 170, 0.07);
  box-shadow: inset 0 0 0 1px rgba(255, 214, 170, 0.06);
}

/* --- The fill, staggered ---------------------------------------------------
   Lit segments start collapsed and grow in once the card is revealed. The
   delay comes from nth-child rather than from a timer per segment. */
.meter__track i.is-lit {
  background: var(--flame-1);
  box-shadow: 0 0 8px rgba(255, 61, 90, 0.45);
}

.meter--us .meter__track i.is-lit {
  background: var(--flame-grad);
  box-shadow: 0 0 10px rgba(255, 165, 0, 0.55);
}

@media (prefers-reduced-motion: no-preference) {
  .meter__track i.is-lit {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.5s var(--ease);
    /* Composed rather than a single value, so the row offset and the
       per-segment step do not overwrite each other. The previous version set a
       flat delay on .meter--us, which out-specified the nth-child rules and
       silently flattened that row's stagger. */
    transition-delay: calc(
      var(--row-delay, 0ms) + var(--step, 0) * var(--cadence, 95ms)
    );
  }

  .reveal[data-visible='true'] .meter__track i.is-lit {
    transform: none;
  }

  /* Slow enough to read as a sweep travelling to the right — ~850ms to cross
     ten segments. The point of the section is that this bar takes a long time
     to fill and the one under it barely starts. */
  .meter__track i:nth-child(1) { --step: 0; }
  .meter__track i:nth-child(2) { --step: 1; }
  .meter__track i:nth-child(3) { --step: 2; }
  .meter__track i:nth-child(4) { --step: 3; }
  .meter__track i:nth-child(5) { --step: 4; }
  .meter__track i:nth-child(6) { --step: 5; }
  .meter__track i:nth-child(7) { --step: 6; }
  .meter__track i:nth-child(8) { --step: 7; }
  .meter__track i:nth-child(9) { --step: 8; }
  .meter__track i:nth-child(10) { --step: 9; }

  /* The PulseForge row starts only once the row above has finished crossing,
     so the pair reads top-then-bottom: a long haul, then almost nothing. Its
     single segment gets a longer, more deliberate ease — with one bar to fill
     there is no stagger to carry it, so the duration has to. */
  .meter--us .meter__track {
    --row-delay: 1000ms;
    --cadence: 150ms;
  }

  .meter--us .meter__track i.is-lit {
    transition-duration: 0.8s;
  }
}

/* Corner brackets, straight from the original. */
.meters::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(var(--flame-2), var(--flame-2)) 0 0 / 0.875rem 2px no-repeat,
    linear-gradient(var(--flame-2), var(--flame-2)) 0 0 / 2px 0.875rem no-repeat,
    linear-gradient(var(--flame-2), var(--flame-2)) 100% 0 / 0.875rem 2px no-repeat,
    linear-gradient(var(--flame-2), var(--flame-2)) 100% 0 / 2px 0.875rem no-repeat,
    linear-gradient(var(--flame-2), var(--flame-2)) 0 100% / 0.875rem 2px no-repeat,
    linear-gradient(var(--flame-2), var(--flame-2)) 0 100% / 2px 0.875rem no-repeat,
    linear-gradient(var(--flame-2), var(--flame-2)) 100% 100% / 0.875rem 2px no-repeat,
    linear-gradient(var(--flame-2), var(--flame-2)) 100% 100% / 2px 0.875rem no-repeat;
  opacity: 0.5;
}

.meters__note {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line);
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--ash-600);
}

/* ===========================================================================
   FAQ — native <details>, keyboard-operable and works without JS
   ========================================================================= */
.faq-layout {
  display: grid;
  gap: var(--space-12);
}

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

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

.faq summary {
  display: flex;
  align-items: flex-start;
  gap: var(--space-6);
  padding-block: var(--space-6);
  cursor: pointer;
  list-style: none;
  transition: color 0.3s var(--ease);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::marker {
  content: '';
}

.faq__num {
  margin-top: 0.3125rem;
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-style: italic;
  color: var(--ash-800);
  transition: color 0.35s var(--ease);
}

.faq[open] .faq__num,
.faq summary:hover .faq__num {
  color: var(--ember);
}

.faq summary h3 {
  flex: 1;
  font-size: 1.0625rem;
  font-weight: 500;
  transition: color 0.3s var(--ease);
}

.faq summary:hover h3 {
  color: #fff;
}

.faq__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 1.875rem;
  height: 1.875rem;
  margin-top: 0.0625rem;
  flex-shrink: 0;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  transition:
    transform 0.4s var(--ease-spring),
    border-color 0.3s var(--ease),
    background-color 0.3s var(--ease);
}

.faq__icon::before,
.faq__icon::after {
  content: '';
  position: absolute;
  background: var(--ash-400);
  transition: background-color 0.3s var(--ease);
}

.faq__icon::before {
  width: 0.625rem;
  height: 1.6px;
}

.faq__icon::after {
  width: 1.6px;
  height: 0.625rem;
}

.faq summary:hover .faq__icon {
  border-color: rgba(255, 207, 77, 0.45);
  background: rgba(255, 165, 0, 0.1);
}

.faq[open] .faq__icon {
  transform: rotate(135deg);
  border-color: rgba(255, 207, 77, 0.5);
}

.faq[open] .faq__icon::before,
.faq[open] .faq__icon::after {
  background: var(--ember-bright);
}

/* No indent on mobile — aligning under the number gutter costs ~96px of a
   phone's width and drops the answer to ~28 characters per line. The indent
   comes back at 48rem where there's room for it. */
.faq > p {
  padding: 0 0 var(--space-6);
  color: var(--ash-400);
  line-height: 1.75;
  text-wrap: pretty;
}

/* Height snaps open; the answer fades in, which reads as deliberate and avoids
   interpolating height (fragile, and broken when the panel clips overflow). */
.faq[open] > p {
  animation: faq-reveal 0.4s var(--ease) both;
}

@keyframes faq-reveal {
  from {
    opacity: 0;
    transform: translate3d(0, -8px, 0);
  }
}

/* ===========================================================================
   APPLY / FORM
   ========================================================================= */
.apply__glow {
  top: -8rem;
  left: 50%;
  width: 44rem;
  height: 32rem;
  transform: translateX(-50%);
  opacity: 0.6;
}

.form-wrap {
  max-width: 48rem;
  margin: var(--space-12) auto 0;
}

.apply-form {
  padding: var(--space-8);
}

.apply-form__grid {
  display: grid;
  gap: var(--space-6);
}

.field label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ash-600);
}

/* Required marker. The `required` attribute carries this for screen readers,
   so the glyph is aria-hidden and purely visual. */
.req {
  margin-left: 0.25rem;
  color: var(--ember);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.8125rem var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: 0.875rem;
  background: rgba(5, 5, 6, 0.6);
  font-size: 0.9375rem;
  color: var(--ash-100);
  transition:
    border-color 0.3s var(--ease),
    background-color 0.3s var(--ease),
    box-shadow 0.3s var(--ease);
}

.field textarea {
  resize: vertical;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--ash-600);
}

.field input:hover,
.field select:hover,
.field textarea:hover {
  border-color: rgba(255, 214, 170, 0.22);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--ember);
  background: rgba(5, 5, 6, 0.85);
  box-shadow: 0 0 0 4px rgba(255, 165, 0, 0.12);
  outline: none;
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.field select option {
  background: var(--ink-raised);
}

.field.has-error input,
.field.has-error select,
.field.has-error textarea {
  border-color: var(--ember);
}

.honeypot {
  position: absolute;
  left: -9999px;
}

.apply-form__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-8);
}

.apply-form__note {
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--ash-600);
}

.form-error {
  margin-top: var(--space-4);
  font-size: 0.875rem;
  color: var(--ember-bright);
}

.form-error:empty {
  margin-top: 0;
}

.form-success {
  padding: var(--space-12);
  text-align: center;
  animation: faq-reveal 0.5s var(--ease) both;
}

.form-success__icon {
  display: grid;
  place-items: center;
  width: 3.75rem;
  height: 3.75rem;
  margin: 0 auto;
  border-radius: 999px;
  border: 1px solid rgba(255, 207, 77, 0.3);
  background: rgba(255, 165, 0, 0.12);
}

.form-success h3 {
  margin-top: var(--space-6);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.875rem;
}

.form-success p {
  max-width: 28rem;
  margin: var(--space-3) auto 0;
  color: var(--ash-400);
  line-height: 1.7;
  text-wrap: pretty;
}

/* ===========================================================================
   FOOTER
   ========================================================================= */
.site-footer {
  position: relative;
  z-index: 2;
  padding-block: var(--space-16);
  border-top: 1px solid var(--line);
}

.site-footer__top {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}

.site-footer__brand {
  max-width: 20rem;
}

.site-footer__brand p {
  margin-top: var(--space-4);
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--ash-400);
}

.site-footer__brand .link-accent {
  display: inline-block;
  margin-top: var(--space-4);
  font-size: 0.9375rem;
}

.site-footer__cols {
  display: flex;
  gap: 3.5rem;
}

.site-footer__cols h2 {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash-600);
}

.site-footer__cols ul {
  margin-top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.site-footer__cols a {
  font-size: 0.9375rem;
  color: var(--ash-400);
  transition:
    color 0.3s var(--ease),
    transform 0.3s var(--ease);
}

.site-footer__cols a:hover {
  color: var(--ash-100);
  transform: translateX(3px);
  display: inline-block;
}

.site-footer__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-16);
  padding-top: var(--space-8);
  border-top: 1px solid var(--line);
  font-size: 0.75rem;
  color: var(--ash-600);
}


/* ===========================================================================
   GRID SHRINK GUARD
   ---------------------------------------------------------------------------
   Grid and flex items default to `min-width: auto`, which refuses to shrink
   below their min-content width — so one long word or a wide table pushes the
   whole column past the viewport. At 320px this was clipping the Technology
   section by 7px. `min-width: 0` lets the tracks size honestly.
   ========================================================================= */
.hero__inner > *,
.meter,
.meter > *,
.calc__grid > *,
.faq-layout > *,
.flame-step,
.flame-step > *,
.callout__main > *,
.site-footer__top > * {
  min-width: 0;
}

/* Last-resort safety net: a single unbreakable word in a heading can still
   exceed a narrow column. Break it rather than let it clip. */
h1,
h2,
h3 {
  overflow-wrap: break-word;
}

/* ===========================================================================
   TOUCH TARGETS
   ---------------------------------------------------------------------------
   Minimum 44x44 on coarse pointers (Apple HIG / Material 48dp). Scoped to
   `pointer: coarse` so mouse-driven layouts keep their tighter rhythm rather
   than being padded out for a finger that isn't there.
   ========================================================================= */
@media (pointer: coarse) {
  .nav__links a,
  .mobile-menu a,
  .site-footer__cols a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }

  .btn--sm {
    height: 44px;
  }

  .calc__presets button {
    min-height: 44px;
    min-width: 44px;
  }

  .phone__tab {
    min-height: 44px;
    justify-content: center;
    padding-inline: 0.75rem;
  }

  .calc__prices button {
    min-height: 44px;
  }

  .faq summary {
    min-height: 44px;
  }
}

/* ===========================================================================
   RESPONSIVE
   ========================================================================= */
@media (min-width: 40rem) {
  .container,
  .nav,
  .mobile-menu ul {
    padding-inline: var(--space-8);
  }

  .nav__cta {
    display: inline-flex;
  }

  .mobile-menu__cta {
    display: none;
  }

  .hero__ctas {
    flex-direction: row;
    align-items: center;
  }

  .orbit__list,
  .profiles {
    grid-template-columns: repeat(2, 1fr);
  }

  .apply-form__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .field--full {
    grid-column: 1 / -1;
  }

  .apply-form__foot {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .site-footer__bottom {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .calc,
  .apply-form,
  .meters,
  .callout,
  .niches,
  .tier {
    padding: var(--space-12);
  }

  .section {
    padding-block: var(--space-24);
  }

  .orbit__item,
  .profiles > li {
    padding: var(--space-8);
  }
}

@media (min-width: 48rem) {
  .section {
    padding-block: 7.5rem;
  }

  .hero {
    /* 11rem, down from 12rem. The fixed header is 80px, so this leaves a 96px
       breath under the nav rather than the 274px the old padding plus centring
       produced together. */
    padding-block: 11rem 7rem;
  }

  .problem-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .profiles {
    grid-template-columns: repeat(3, 1fr);
  }

  /* From tablet up the note sits beside the line rather than under it, so the
     five statements stay a single vertical column the eye can run down. */
  .flame-step {
    display: grid;
    grid-template-columns: 1fr minmax(0, 22rem);
    align-items: baseline;
    column-gap: var(--space-12);
  }

  .flame-step__num {
    grid-column: 1 / -1;
  }

  .flame-step__note {
    margin-top: 0;
  }

  .callout {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  /* Two tier cards sit comfortably side by side from tablet up. */
  .tiers {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Room for the number gutter again. */
  .faq > p {
    padding: 0 3.25rem var(--space-8) 2.75rem;
  }

  .site-footer__top {
    flex-direction: row;
    justify-content: space-between;
  }

  .faq summary h3 {
    font-size: 1.1875rem;
  }
}

@media (min-width: 64rem) {
  .nav__links {
    display: flex;
  }

  .nav__toggle {
    display: none;
  }

  .orbit__list {
    grid-template-columns: repeat(3, 1fr);
  }

  .calc__grid {
    grid-template-columns: 1fr 1.05fr;
    gap: 4rem;
  }

  .tiers {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Wide enough for a single row: who | bar | value. */
  .meter {
    grid-template-columns: 7.5rem 1fr 7.5rem;
    grid-template-areas: 'who track value';
  }

  .faq-layout {
    grid-template-columns: 0.85fr 1.15fr;
    gap: 4rem;
  }
}

/* ===========================================================================
   REDUCED MOTION
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}


/* ===========================================================================
   SHORT VIEWPORTS - must stay LAST in this file
   ---------------------------------------------------------------------------
   These blocks override .hero padding set by the width-based responsive rules
   above, in particular the min-width:48rem rule that sets padding-block to
   11rem 7rem. Media queries add no specificity, so which one wins is decided
   purely by source order: sitting earlier in the file, these were silently
   discarded on every screen wider than 768px - which is every phone held
   sideways, the exact case they exist to handle.

   If you add width-based .hero rules later, put them ABOVE this banner.
   ========================================================================= */
/* --- Short viewports --------------------------------------------------------
   Landscape phones, 1366×768-class laptops and small phones. The hero is a
   full-height composition sized off viewport WIDTH, which says nothing about
   how much vertical room there is: at 844×390 the top padding alone was a
   third of the screen and the headline rendered at 63px, putting the buttons
   573px down a 390px-tall viewport. Below this height the composition is
   scaled to the height available instead, so the call to action stays on
   screen — which is the entire job of a hero.
   -------------------------------------------------------------------------- */
@media (max-height: 50rem) {
  .hero {
    min-height: 0;
    padding-block: max(7rem, calc(var(--header-h) + var(--header-clearance)))
      var(--space-8);
  }

  /* Overrides .display, which is width-derived (7.5vw) and equal in
     specificity — this wins on source order, being later in the file.

     Threshold raised from 46rem to 50rem, and the scale loosened from 5.2vh to
     7vh. At 46rem a 1366x768 laptop missed the tier entirely and rendered the
     full 84px headline into 768px of height, putting the buttons 14px below
     the fold; meanwhile 5.2vh made the hero SMALLER than the section headings
     further down the page on a 640-tall phone, which is backwards. 7vh keeps
     it the largest type on the page while still answering to the height. */
  .hero__headline {
    font-size: clamp(2rem, 5.8vh, 4rem);
  }

  .hero__badge {
    margin-bottom: var(--space-4);
    padding: 0.375rem 0.875rem;
    font-size: 0.8125rem;
  }

  .hero__sub {
    margin-top: var(--space-4);
    font-size: 1rem;
  }

  .hero__ctas {
    margin-top: var(--space-8);
  }

  /* Section headings are width-derived (4.4vw), so on a short screen they kept
     their full size while the hero shrank to fit the height — leaving the hero
     SMALLER than the headings below it. Scale them to the height as well, so
     the hero stays the largest type on the page at every viewport. */
  .section-head h2 {
    font-size: clamp(1.5rem, 4.6vh, 2.75rem);
  }
}

/* Wide but short — a 1366x768 or 1280x720 laptop. These matched the tier above
   and were shrunk as if they were phones, despite having 300px of unused space
   below the buttons. Width is the signal that there is room. */
@media (max-height: 50rem) and (min-width: 48rem) {
  .hero {
    padding-block: max(9rem, calc(var(--header-h) + var(--header-clearance)))
      var(--space-12);
  }

  .hero__headline {
    font-size: clamp(2.5rem, 7vh, 4.5rem);
  }

  .section-head h2 {
    font-size: clamp(1.75rem, 5.2vh, 3rem);
  }
}

/* Very short viewports — a phone held sideways, ~390px tall with a fixed
   header eating the top of it. There is no arrangement of five stacked
   elements that fits comfortably, so the decorative one goes: the badge is a
   trust chip, while the headline and the button are the reason the page
   exists. Everything else tightens around them.
   Must follow the 46rem block — equal specificity, so source order wins. */
@media (max-height: 30rem) {
  .hero {
    /* Even here the header must be cleared; below this the nav would sit on
       top of the headline. */
    padding-block: calc(var(--header-h) + 1.25rem) var(--space-4);
  }

  .hero__badge {
    display: none;
  }

  .hero__headline {
    font-size: clamp(1.5rem, 6.4vh, 2rem);
  }

  .hero__sub {
    margin-top: var(--space-3);
    max-width: 58ch;
    font-size: 0.9375rem;
  }

  .hero__ctas {
    margin-top: var(--space-4);
  }

  .hero__ctas .btn {
    padding-block: 0.625rem;
  }

  .section-head h2 {
    font-size: clamp(1.375rem, 5vh, 2rem);
  }
}

/* Smallest phones still in use. The badge copy wraps to two lines inside the
   pill at this width, reading as a broken chip rather than a badge. Sits after
   the short-viewport tiers on purpose: those reset badge sizing for height,
   and at 320x568 both match - the width constraint is the binding one. */
@media (max-width: 21.5rem) {
  .hero__badge {
    padding: 0.4375rem 0.75rem;
    font-size: 0.75rem;
  }

  /* A 320x568 screen is short AND narrow, so the headline runs to four lines.
     The larger type and looser leading that make the hero work on a modern
     phone push the buttons off the bottom here; this claws back the ~28px
     needed, without touching any screen big enough not to care. */
  .hero__headline {
    font-size: 1.75rem;
    line-height: 1.06;
  }

  .hero__title-line + .hero__title-line {
    margin-top: 0.05em;
  }

  .hero__ctas {
    margin-top: var(--space-4);
  }

  .section-head h2 {
    font-size: 1.625rem;
  }

  /* 320x568 is both the narrowest and one of the shortest screens still in
     use, so the headline runs to four lines AND the header clearance is
     non-negotiable. The remaining pixels come out of the supporting copy and
     the buttons, which can afford it, rather than the headline or the gap
     under the nav, which cannot. */
  .hero__sub {
    margin-top: var(--space-3);
    font-size: 0.9375rem;
  }

  .hero__ctas .btn {
    padding-block: 0.625rem;
  }
}
/* --- Footer social icons ---------------------------------------------------
   Icon plus label rather than icon alone: a bare glyph is a guessing game for
   anyone who does not recognise it, and the label is what a screen reader and
   a search engine both read. The aria-label on the anchor names the
   destination, so the visible text can stay short.
   -------------------------------------------------------------------------- */
.social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.social a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.7rem 0.4rem 0.5rem;
  border: 1px solid var(--line, rgba(255, 255, 255, 0.12));
  border-radius: 999px;
  transition:
    border-color 0.25s var(--ease),
    color 0.25s var(--ease),
    transform 0.25s var(--ease);
}

.social a:hover,
.social a:focus-visible {
  border-color: rgba(255, 165, 0, 0.5);
  color: var(--flame-3);
  transform: translateY(-1px);
}

.social svg {
  flex: none;
}

@media (prefers-reduced-motion: reduce) {
  .social a {
    transition: none;
  }
  .social a:hover,
  .social a:focus-visible {
    transform: none;
  }
}

/* ===========================================================================
   LEGAL PAGES — privacy, terms, cookies
   ---------------------------------------------------------------------------
   Long-form reading, so this deliberately breaks from the landing page's
   centred, high-contrast rhythm: left-aligned, a measure capped near 70
   characters, and generous leading. Nobody reads a privacy policy centred.
   ========================================================================= */
.legal-header {
  position: static;
  background: var(--ink);
  border-bottom: 1px solid var(--line, rgba(255, 255, 255, 0.1));
}

.legal {
  padding-block: var(--space-16) var(--space-24);
}

.legal__inner {
  max-width: 48rem;
}

.legal__inner h1 {
  margin: 0 0 var(--space-3);
  font-size: clamp(2.25rem, 5vw, 3.25rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.legal__meta {
  margin: 0 0 var(--space-8);
  color: var(--ash-600);
  font-size: 0.9375rem;
}

.legal__inner h2 {
  margin: var(--space-12) 0 var(--space-4);
  font-size: 1.375rem;
  line-height: 1.25;
}

.legal__inner h3 {
  margin: var(--space-8) 0 var(--space-3);
  font-size: 1.0625rem;
  color: var(--ash-100);
}

.legal__inner p,
.legal__inner li {
  color: var(--ash-400);
  line-height: 1.75;
}

.legal__inner p {
  margin: 0 0 var(--space-4);
}

.legal__inner ul {
  margin: 0 0 var(--space-4);
  padding-left: 1.25rem;
}

.legal__inner li {
  margin-bottom: 0.5rem;
}

.legal__inner strong {
  color: var(--ash-100);
}

.legal__inner code {
  padding: 0.1em 0.35em;
  border-radius: 0.25rem;
  background: var(--ink-raised);
  font-size: 0.9em;
}

/* The "get a solicitor to read this" callout. Amber rather than red: it is a
   caution, not an error. */
.legal__notice {
  margin: 0 0 var(--space-10);
  padding: var(--space-4) var(--space-6);
  border: 1px solid rgba(255, 165, 0, 0.3);
  border-left-width: 3px;
  border-radius: var(--radius, 0.75rem);
  background: rgba(255, 165, 0, 0.07);
  color: var(--ash-400);
  line-height: 1.7;
}

.legal__notice--good {
  border-color: rgba(255, 207, 77, 0.4);
  background: rgba(255, 207, 77, 0.08);
}

/* Tables must scroll inside their own box: at 320px a three-column table is
   wider than the screen, and the page itself must never scroll sideways. */
.legal__table-wrap {
  overflow-x: auto;
  margin: 0 0 var(--space-6);
  -webkit-overflow-scrolling: touch;
}

.legal__table {
  width: 100%;
  min-width: 32rem;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.legal__table th,
.legal__table td {
  padding: 0.75rem 0.9rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--line, rgba(255, 255, 255, 0.1));
}

.legal__table th {
  color: var(--ash-100);
  font-weight: 600;
  white-space: nowrap;
}

.legal__table td {
  color: var(--ash-400);
  line-height: 1.6;
}

.site-footer__bottom a {
  color: var(--ash-600);
}

.site-footer__bottom a:hover {
  color: var(--flame-3);
}
