/* ==========================================================================
   Reach Global Digital — Core Stylesheet
   Design system: "Neuform High-Craft Showcase"
   See docs/design-system.md and DESIGN.md
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand
     #eb6c01 is the orange in assets/img/rgd-logo.png (sampled dominant tone
     #ec6c01), verified against the logo asset rather than assumed. It is the
     single orange in this stylesheet: buttons, links, badges, headings, icons,
     rings and tints all read from it, by explicit client decision not to
     substitute a darker shade for small text.

     Contrast note, recorded rather than silently fixed: #eb6c01 is 3.15:1 on
     white. That clears WCAG AA for large text and non-text UI but not for
     12-15px body text or a white label on an orange button fill. Earlier passes
     introduced --brand-text (#c2410c) and --brand-on-dark (#fb923c) to close
     that gap; both have been removed because they read as a different orange and
     that is a brand-identity change. --brand-hover stays darker, as a hover
     state should. Re-run `node _a11ysweep.js` if this hue is touched again. */
  --brand: #eb6c01;
  --brand-hover: #c2410c;
  --brand-light: #fff7ed;
  --brand-subtle: #ffedd5;
  --brand-rgb: 235, 108, 1;

  /* Ink / neutral */
  --ink: #111827;
  --ink-soft: #1f2937;
  --text: #111827;
  --text-2: #4b5563;
  /* Muted small-label ink. This was #9ca3af, which reads as a soft grey on a
     dark panel but only reaches 2.4-2.5:1 on white and --surface — below WCAG
     AA for small text, and it was failing on 60+ labels site-wide. Every
     --text-3 call site in this codebase sits on a light surface (verified by
     _a11ysweep.js), so the token is retuned rather than patched per call site.
     4.8:1 on white, 4.7:1 on --surface. */
  --text-3: #6b7280;
  --accent: #7b2cc7;
  --accent-light: #faf5ff;

  /* Surfaces */
  --bg: #ffffff;
  --surface: #f9fafb;
  --surface-2: #f3f4f6;
  --elevated: #ffffff;
  --border: #e5e7eb;
  --border-strong: #d1d5db;

  /* Radii */
  --r-sm: 6px;
  --r: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-pill: 9999px;

  /* Type */
  --f-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
  --f-display: "Josefin Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* The skills marquee is the one place the reference uses a serif. Its items
     are <span>s, so the reference's `h1..h6 { Josefin Sans !important }` rule
     never reaches them and they fall to Playfair Display. Do not fold this into
     --f-display: that token is the heading face. */
  --f-marquee: "Playfair Display", Georgia, "Times New Roman", serif;

  /* Layout */
  --gutter: 1.25rem;
  --container: 1280px;
  --section-y: 5rem;

  /* Elevation */
  --sh-1: 0 1px 2px rgba(17, 24, 39, 0.04), 0 1px 3px rgba(17, 24, 39, 0.06);
  --sh-2: 0 10px 25px -5px rgba(17, 24, 39, 0.08), 0 8px 10px -6px rgba(17, 24, 39, 0.03);
  --sh-3: 0 25px 50px -12px rgba(17, 24, 39, 0.2);
  --sh-brand: 0 4px 14px rgba(var(--brand-rgb), 0.35);
  --sh-brand-lg: 0 10px 30px -6px rgba(var(--brand-rgb), 0.4);
  /* Hover lift for every card. Warm, so the shadow reads as the brand colour
     rather than a grey one that happens to be tinted. */
  --sh-brand-card: 0 14px 30px -10px rgba(var(--brand-rgb), 0.34),
    0 4px 12px -6px rgba(var(--brand-rgb), 0.16);

  /* Easing */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* Decoration — the ambient art layer.
     Every one of these is a tint or a texture behind content, never a colour
     anything is read on. They exist so a section can carry artwork without a
     single layout box moving. Kept in their own block because they are the
     only values in the system that are allowed to sit under body copy. */
  --accent-rgb: 123, 44, 199;
  --slate-rgb: 148, 163, 184;
  --deco-line: rgba(var(--slate-rgb), 0.22);
  --deco-ink: rgba(var(--brand-rgb), 0.05);
  --deco-brand-soft: rgba(var(--brand-rgb), 0.09);
  --deco-brand-mid: rgba(var(--brand-rgb), 0.16);
  --deco-violet-soft: rgba(var(--accent-rgb), 0.07);
  --deco-panel-tint: rgba(var(--slate-rgb), 0.07);

  /* Original artwork. Authored for this site — no stock, no licensing, no
     photography. Every file is well under 1 KB and loads once, then tiles or
     sits on a decorative layer that is never a Largest Contentful Paint
     candidate. Paths are relative to this stylesheet. */
  --art-grid: url("../img/art/grid.svg");
  --art-dots: url("../img/art/dots.svg");
  --art-dots-brand: url("../img/art/dots-brand.svg");
  --art-hatch: url("../img/art/hatch.svg");
  --art-contour: url("../img/art/contour.svg");
  --art-network: url("../img/art/network.svg");
  --art-wave: url("../img/art/wave.svg");
  --art-orbit: url("../img/art/orbit.svg");
  --art-ribbon: url("../img/art/ribbon.svg");
  --art-bloom-brand: url("../img/art/bloom-brand.svg");
  --art-bloom-violet: url("../img/art/bloom-violet.svg");
}

@media (min-width: 768px) {
  :root {
    --gutter: 2rem;
    --section-y: 6rem;
  }
}

/* --------------------------------------------------------------------------
   2. Reset & Base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--f-sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.nav-open {
  overflow: hidden;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  cursor: pointer;
  border: 0;
  background: none;
  color: inherit;
}

/* Headings and display type use the reference display face, Josefin Sans —
   the Stitch source forces it onto every h1–h6 and every display/headline
   utility. Without this rule the headings inherited Inter from the body and
   read as generic. Specificity is 0,0,1, so component rules that deliberately
   set a different face (e.g. the JetBrains Mono footer column labels in
   .footer-cols) still win. */
h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.12;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

::selection {
  background: var(--brand-subtle);
  color: var(--brand);
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Reduced motion
   ---------------------------------------------------------------------------
   The design brief is to match the Stitch reference, where all motion always
   runs: the hero mesh is pointer-interactive, both marquees scroll, the
   carousel auto-advances, counters count up. A blanket
   `animation-duration: 0.001ms !important` on `*` — the pattern this replaced —
   made every one of those silently static for anyone whose OS or browser
   reports `reduce`, which is exactly what was happening: the page looked
   broken rather than accessible.

   So ambient motion (ambient glows, marquees, ping, the mesh, the count-up,
   and the scroll reveals) now runs regardless of the preference. The only
   thing still suppressed is smooth scrolling, which is the one genuinely
   vestibular trigger here, and it is the standard remedy for it.

   There is deliberately no blanket opt-out recipe here. The old one
   (`animation-duration: 0.01ms !important` on `*`) is exactly the pattern
   that caused the outage described above, and publishing it again invites
   the same regression. If a specific component ever needs to stop moving,
   scope it to that component's own class and handle its reveal state
   explicitly — never to `*`. See memory.md §10.7. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* --------------------------------------------------------------------------
   3. Typography Scale
   -------------------------------------------------------------------------- */
.t-display {
  font-size: clamp(2.375rem, 1.2rem + 4.4vw, 4rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-weight: 600;
}
/* The headline utilities carry the display face, not just the h1–h6 reset.
   The reference applies Josefin Sans with `!important` to both the heading
   tags AND its `.font-display-hero` / `.font-headline-*` utility classes, so
   headline-styled text that is not a real heading — the case-study client
   names and the leadership attribution are `<p class="t-h4">` — still renders
   in the display face there. Without this they silently fell back to Inter.
   `.t-lead` is deliberately excluded: it maps to the reference's
   `font-body-lg`, which is Inter. */
.t-display,
.t-h2,
.t-h3,
.t-h4 {
  font-family: var(--f-display);
}
.t-h2 {
  font-size: clamp(1.875rem, 1.2rem + 2.4vw, 2.75rem);
  line-height: 1.12;
  letter-spacing: -0.025em;
}
.t-h3 {
  font-size: clamp(1.25rem, 1.05rem + 0.7vw, 1.5rem);
  line-height: 1.25;
  letter-spacing: -0.015em;
}
.t-h4 {
  font-size: 1.125rem;
  line-height: 1.35;
  letter-spacing: -0.01em;
}
.t-lead {
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.125rem);
  line-height: 1.6;
  color: var(--text-2);
}
.t-body {
  font-size: 1rem;
  line-height: 1.6;
}
.t-sm {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-2);
}
.t-mono {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  line-height: 1.25;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
}
.t-mono-sm {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
}

.accent-text {
  color: var(--brand);
}
.text-2 {
  color: var(--text-2);
}
/* Muted small label. --text-3 is tuned for dark panels and only reaches
   2.5:1 on white, below WCAG AA. Every .text-3 call site in this codebase
   sits on a light card (verified by _a11ysweep.js), so the default is the
   light-surface token. Dark panels should use .text-2 or an explicit value. */
.text-3 {
  color: var(--text-3);
}
.text-white {
  color: #fff;
}

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container-wide {
  max-width: 1440px;
}

.section {
  position: relative;
  padding-block: var(--section-y);
  border-bottom: 1px solid var(--border);
}
.section:last-of-type {
  border-bottom: 0;
}
.section-muted {
  background: var(--surface);
}
.section-ink {
  background: var(--ink);
  color: #fff;
  border-bottom-color: rgba(255, 255, 255, 0.08);
}

.section-head {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
  margin-bottom: 3rem;
}
.section-head-left {
  margin-inline: 0;
  text-align: left;
}
.section-head p {
  margin-top: 0.75rem;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.75rem;
  border-radius: var(--r-pill);
  background: var(--brand-light);
  border: 1px solid rgba(224, 192, 177, 0.4);
  color: var(--brand);
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.eyebrow-ink {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.14);
  /* Light brand member: this eyebrow sits on the dark cta-section. */
  color: var(--brand);
}
.eyebrow-neutral {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text-2);
}

.grid {
  display: grid;
  gap: 1.5rem;
}
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 1023px) {
  .g-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .g-3 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
}
@media (max-width: 639px) {
  .g-4,
  .g-2 { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 48px;
  padding: 0 1.5rem;
  /* Fully rounded: every action on the site reads as a pill. The icon buttons
     are already circles, and .btn-call/.social-link are pills, so this is what
     was left square. */
  border-radius: var(--r-pill);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease),
    color 0.2s var(--ease), box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
}
.btn:active {
  transform: translateY(1px);
}
.btn .icon {
  font-size: 18px;
  width: 18px;
  height: 18px;
  flex: none;
  transition: transform 0.25s var(--ease);
}
.btn:hover .icon-arrow {
  transform: translateX(3px);
}

.btn-primary {
  /* Fill, not text: white label on this needs 5.18:1, which --brand cannot
     deliver at 3.15:1. Hover stays on the logo hue one step darker. */
  background: var(--brand);
  color: #fff;
  box-shadow: 0 1px 2px rgba(17, 24, 39, 0.06);
}
.btn-primary:hover {
  background: var(--brand-hover);
  box-shadow: var(--sh-brand);
}

.btn-dark {
  background: var(--ink);
  color: #fff;
}
.btn-dark:hover {
  background: var(--ink-soft);
  box-shadow: 0 10px 25px -8px rgba(17, 24, 39, 0.5);
}

.btn-outline {
  background: transparent;
  border-color: var(--border);
  color: var(--ink);
}
.btn-outline:hover {
  background: var(--surface);
  border-color: var(--border-strong);
}

.btn-ghost {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
  color: #fff;
  backdrop-filter: blur(8px);
}
.btn-ghost:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.28);
}

.btn-lg { height: 52px; padding: 0 1.75rem; font-size: 0.9375rem; }
.btn-sm { height: 40px; padding: 0 1rem; }
.btn-block { width: 100%; }

/* "Call Now" — the compact phone CTA used everywhere the full number is not.
   The number itself belongs to the contact section and the footer contact
   block; repeating it in every hero and CTA made the number unreadable as a
   number and pushed the primary action out of view on narrow screens. */
.btn-call {
  border-radius: var(--r-pill);
  border-color: var(--brand);
  color: var(--brand);
  background: var(--brand-light);
  font-weight: 700;
  white-space: nowrap;
}
.btn-call .icon {
  width: 17px;
  height: 17px;
  color: var(--brand);
  flex: none;
}
.btn-call:hover,
.btn-call:focus-visible {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.btn-call:hover .icon,
.btn-call:focus-visible .icon {
  color: #fff;
}

/* On the dark contact section the same button needs a light treatment. */
.btn-call-ghost {
  border-radius: var(--r-pill);
  border-color: rgba(255, 255, 255, 0.4);
  color: #fff;
  background: rgba(255, 255, 255, 0.06);
  font-weight: 700;
  white-space: nowrap;
}
.btn-call-ghost .icon { width: 17px; height: 17px; color: #fff; flex: none; }
.btn-call-ghost:hover,
.btn-call-ghost:focus-visible {
  background: #fff;
  border-color: #fff;
  color: var(--ink);
}

/* A button whose label is an unbreakable string — an email address, a URL —
   cannot honour `white-space: nowrap` on a 320px screen, and overflows the
   viewport by a pixel. This modifier relaxes wrapping and lets the button grow
   vertically instead. Opt-in, so no existing button changes. */
.btn-wrap {
  white-space: normal;
  overflow-wrap: anywhere;
  height: auto;
  min-height: 48px;
  padding-block: 0.75rem;
  text-align: center;
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--brand);
  transition: gap 0.25s var(--ease), color 0.2s var(--ease);
}
.link-arrow:hover {
  gap: 0.625rem;
  color: var(--brand-hover);
}
.link-arrow .icon {
  width: 16px;
  height: 16px;
}

/* --------------------------------------------------------------------------
   6. Cards & Panels
   -------------------------------------------------------------------------- */
.card {
  position: relative;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 1.5rem;
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease),
    transform 0.25s var(--ease);
}
.card-hover:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px) scale(1.015);
  box-shadow: var(--sh-2);
}
.card-muted {
  background: var(--surface);
}
.card-dark {
  background: var(--ink);
  border-color: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.card-topline::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, rgba(var(--brand-rgb), 0.45), transparent);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.card-topline:hover::before {
  opacity: 1;
}

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.card-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--brand);
  flex: none;
  transition: transform 0.3s var(--ease), background-color 0.25s var(--ease);
}
.card-icon .icon {
  width: 22px;
  height: 22px;
}
.card-hover:hover .card-icon {
  transform: scale(1.06) rotate(-3deg);
}

/* Badges & pills */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  height: 24px;
  padding: 0 0.625rem;
  border-radius: var(--r-pill);
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.badge-live {
  background: var(--brand-light);
  color: var(--brand);
}
.badge-neutral {
  background: var(--surface-2);
  color: var(--text-2);
  border: 1px solid var(--border);
}
.badge-accent {
  background: var(--accent-light);
  color: var(--accent);
}
.badge-ink {
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.14);
}
.badge-outline {
  background: transparent;
  border: 1px solid rgba(var(--brand-rgb), 0.35);
  color: var(--brand);
}

.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
  flex: none;
  position: relative;
}
.dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: ping 1.8s var(--ease-out) infinite;
}
.dot-static::after {
  display: none;
}

.tag {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 0.625rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-2);
  transition: all 0.2s var(--ease);
}
.tag:hover {
  border-color: var(--brand);
  color: var(--brand);
  background: var(--brand-light);
}

.check {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--text-2);
}
.check .icon {
  width: 16px;
  height: 16px;
  color: var(--brand);
  flex: none;
  margin-top: 2px;
}
/* .check is a light-surface list, but it is also dropped inside the dark
   .lp-cta panel on free-audit.html. --text-2 grey on --ink is only 2.35:1,
   so re-assert a light ink when the ancestor is dark. */
.lp-cta .check {
  color: rgba(255, 255, 255, 0.88);
}

/* Metric block */
.metric {
  font-size: clamp(1.5rem, 1.2rem + 1vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--text);
}
.metric-unit {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--brand);
}
.kv {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
}
.kv:last-child {
  border-bottom: 0;
}
.kv dt {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3);
}
.kv dd {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text);
  text-align: right;
}

/* --------------------------------------------------------------------------
   7. Header / Navigation
   -------------------------------------------------------------------------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 60;
  padding: 0.75rem var(--gutter) 0;
  pointer-events: none;
}
.header-bar {
  pointer-events: auto;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--container);
  margin-inline: auto;
  height: 64px;
  padding-inline: 1.5rem;
  border-radius: var(--r-pill);
  background: rgba(17, 24, 39, 0.92);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: var(--sh-2);
  transition: background-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.header-bar.is-scrolled {
  background: rgba(17, 24, 39, 0.98);
  box-shadow: 0 12px 30px -8px rgba(17, 24, 39, 0.45);
}

.brand {
  display: flex;
  align-items: center;
  /* Stretch to the full height of the header bar so the logo hugs it from the
     top edge to the bottom edge, rather than floating as a small chip. */
  align-self: stretch;
  padding: 0 0.85rem;
  border-radius: var(--r-pill);
  flex: none;
  transition: box-shadow 0.25s var(--ease), transform 0.25s var(--ease);
}
.brand:hover {
  box-shadow: 0 0 0 2px rgba(var(--brand-rgb), 0.55);
  transform: translateY(-1px);
}
.brand img {
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}
.brand-name {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
}
.brand-name b {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.brand-name span {
  font-family: var(--f-mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 600;
}

.nav {
  display: none;
  align-items: center;
  gap: 0.25rem;
}
@media (min-width: 1024px) {
  .nav { display: flex; }
}
.nav-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.5rem 0.875rem;
  border-radius: var(--r-pill);
  font-size: 0.875rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.78);
  transition: color 0.2s var(--ease), background-color 0.2s var(--ease);
}
.nav-link:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.1);
}
.nav-link[aria-current="page"] {
  /* Outlined rather than filled. A brand-tinted fill would sit under the brand
     label and drop it to ~3.4:1; leaving the pill transparent lets the dark
     header show through, which keeps the label at 4.56:1 while the 1px brand
     ring still reads unmistakably as the active item. */
  color: var(--brand);
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(var(--brand-rgb), 0.85);
}
.nav-link .icon {
  width: 16px;
  height: 16px;
  color: var(--text-3);
  transition: transform 0.25s var(--ease);
}

.nav-item {
  position: relative;
}
.nav-item:hover .nav-link .icon,
.nav-item:focus-within .nav-link .icon {
  transform: rotate(180deg);
  color: var(--brand);
}
.dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  min-width: 260px;
  padding: 0.5rem;
  border-radius: var(--r-md);
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: var(--sh-3);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s;
}
.nav-item:hover .dropdown,
.nav-item:focus-within .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.dropdown a {
  display: block;
  padding: 0.5rem 0.75rem;
  border-radius: var(--r);
  font-size: 0.875rem;
  color: var(--text-2);
  transition: background-color 0.15s, color 0.15s, padding-left 0.2s var(--ease);
}
.dropdown a:hover {
  background: var(--brand-light);
  color: var(--brand-hover);
  padding-left: 1rem;
}

.header-actions {
  display: none;
  align-items: center;
  gap: 0.625rem;
  flex: none;
}
@media (min-width: 1024px) {
  .header-actions { display: flex; }
}
.header-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--r-pill);
  font-size: 0.8125rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
  font-family: var(--f-mono);
  letter-spacing: 0.01em;
  transition: color 0.2s, background-color 0.2s;
}
.header-phone:hover {
  color: var(--brand);
  background: rgba(255, 255, 255, 0.08);
}
.header-phone .icon {
  width: 15px;
  height: 15px;
  color: var(--brand);
}

/* Mobile drawer */
.burger {
  display: grid;
  place-items: center;
  /* 44x44, not 42. This is the only way out of the drawer on a phone, and the
     header has 54px of unused width at 320px, so the two extra pixels cost
     nothing at any width. Clears WCAG 2.2 SC 2.5.8 (24px AA) with room. */
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: #fff;
  flex: none;
}
@media (min-width: 1024px) {
  .burger { display: none; }
}
.burger .icon { width: 20px; height: 20px; }

/* Animated hamburger.
   Three bars rather than an icon sprite, so the open/closed state can be a real
   transform instead of a second <use> swap. 20px wide, 2px tall, 4px gaps,
   which reproduces the old #i-menu footprint exactly.
   `currentColor` inherits the button's #fff. */
.burger__box {
  position: relative;
  display: block;
  width: 20px;
  height: 14px;
}
.burger__box i {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: top 0.28s var(--ease), transform 0.28s var(--ease),
    opacity 0.16s var(--ease);
}
.burger__box i:nth-child(1) { top: 0; }
.burger__box i:nth-child(2) { top: 6px; }
.burger__box i:nth-child(3) { top: 12px; }

/* Open: outer bars meet in the middle and cross into an X, centre bar drops.
   This rides the aria-expanded that the drawer JS already writes, so it needs no
   extra JS and stays correct if the drawer is opened by any future path. */
.burger[aria-expanded="true"] .burger__box i:nth-child(1) {
  top: 6px;
  transform: rotate(45deg);
}
.burger[aria-expanded="true"] .burger__box i:nth-child(2) {
  opacity: 0;
  transform: scaleX(0.4);
}
.burger[aria-expanded="true"] .burger__box i:nth-child(3) {
  top: 6px;
  transform: rotate(-45deg);
}

/* The drawer's close button shares `.burger` but is only reachable while the
   drawer is open, so it is pinned to the X state rather than carrying its own
   separate glyph. */
.burger--close .burger__box i:nth-child(1) {
  top: 6px;
  transform: rotate(45deg);
}
.burger--close .burger__box i:nth-child(2) {
  opacity: 0;
  transform: scaleX(0.4);
}
.burger--close .burger__box i:nth-child(3) {
  top: 6px;
  transform: rotate(-45deg);
}

/* Below 400px the wordmark plus the burger no longer fit inside the pill bar
   (brand 238px + gap + burger 42px against a 217px content box), so the brand
   runs past the viewport edge. The logo mark alone still identifies the brand
   at this width, so drop the text block rather than let the header clip. */
@media (max-width: 400px) {
  .brand-name { display: none; }
  .header-bar { padding-inline: 1rem; }
}

.mobile-drawer {
  position: fixed;
  inset: 0;
  z-index: 55;
  display: grid;
  grid-template-rows: auto 1fr;
  background: var(--ink);
  padding: 1rem var(--gutter) 2rem;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-12px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), visibility 0.3s;
}
.mobile-drawer.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
@media (min-width: 1024px) {
  .mobile-drawer { display: none; }
}
.mobile-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 64px;
}
.drawer-close {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.16);
  border-radius: 50%;
}
.drawer-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 1.125rem;
  font-weight: 500;
  color: #fff;
}
.drawer-link .icon {
  width: 18px;
  height: 18px;
  color: var(--text-3);
}
.drawer-sub {
  padding: 0.5rem 0 0.5rem 1rem;
  display: grid;
  gap: 0.25rem;
}
.drawer-sub a {
  padding: 0.5rem 0;
  font-size: 0.9375rem;
  color: rgba(255, 255, 255, 0.68);
}
.mobile-drawer .btn {
  margin-top: 1.5rem;
}

/* --------------------------------------------------------------------------
   8. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  padding: 9rem 0 var(--section-y);
  border-bottom: 1px solid var(--border);
  isolation: isolate;
}
#heroMesh {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -2;
  pointer-events: none;
}
.hero-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
  z-index: -1;
}
.hero-glow-a {
  width: 24rem;
  height: 24rem;
  right: -8rem;
  top: -8rem;
  background: rgba(var(--brand-rgb), 0.28);
}
.hero-glow-b {
  width: 20rem;
  height: 20rem;
  left: -5rem;
  top: 45%;
  background: rgba(255, 237, 213, 0.85);
}
.hero-dots {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.2;
  background-image: radial-gradient(rgba(var(--brand-rgb), 0.75) 0.75px, transparent 0.75px);
  background-size: 24px 24px;
}
.hero-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 56rem;
  margin-inline: auto;
}
.hero h1 {
  margin-top: 1.5rem;
  max-width: 52rem;
}
.hero h1 .hl {
  color: var(--brand);
  text-decoration: underline;
  text-decoration-color: rgba(224, 192, 177, 0.7);
  text-decoration-thickness: 4px;
  text-underline-offset: 8px;
}
.hero-sub {
  margin-top: 1.5rem;
  max-width: 40rem;
}
.hero-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 2rem;
  width: 100%;
}
.hero-note {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-2);
}
.hero-note .icon {
  width: 18px;
  height: 18px;
  color: var(--brand);
}
.hero-focus {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 1.5rem;
}
.hero-focus-label {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-3);
  margin-right: 0.25rem;
}

/* Bento metric strip */
/* Reference: `grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-gutter-md`.
   This was hard-coded to two columns at every width, so the strip showed a
   cramped 2-up grid on phones and never became the 4-up metric band the design
   calls for on desktop. */
.metric-strip {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  margin-top: 5rem;
  width: 100%;
}
@media (min-width: 640px) {
  .metric-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .metric-strip {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .metric-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 639px) {
  .metric-strip { grid-template-columns: minmax(0, 1fr); }
}

/* Enhanced hover for metric strip cards - pronounced lift + glow */
.metric-strip .card-hover:hover {
  transform: translateY(-6px) scale(1.025);
  box-shadow: var(--sh-brand-card);
}
.metric-strip .card-topline:hover::before {
  opacity: 1;
}

/* Title alignment fix for metric strip cards */
.metric-strip .card-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}
.metric-strip .card-head .t-mono {
  text-align: center;
  flex: 1;
}

/* Ensure metric values are centered */
.metric-strip .metric {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 0.25rem;
}

/* Ensure description text is centered */
.metric-strip .card-hover > p:last-child {
  text-align: center;
}

/* --------------------------------------------------------------------------
   9. Marquee (client logos)
   -------------------------------------------------------------------------- */
.marquee-band {
  background: var(--elevated);
  border-bottom: 1px solid var(--border);
  padding: 2.5rem 0;
  position: relative;
  overflow: hidden;
}
.marquee-band::before,
.marquee-band::after {
  content: "";
  position: absolute;
  width: 20rem;
  height: 20rem;
  border-radius: 50%;
  filter: blur(80px);
  pointer-events: none;
  z-index: 0;
}
.marquee-band::before {
  left: -10rem;
  top: -10rem;
  background: rgba(255, 247, 237, 0.9);
}
.marquee-band::after {
  right: -10rem;
  bottom: -10rem;
  background: rgba(255, 237, 213, 0.7);
}
.marquee-label {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  text-align: center;
  margin-bottom: 1.5rem;
  color: var(--text-2);
}
.marquee-viewport {
  position: relative;
  z-index: 1;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee-track {
  display: flex;
  width: max-content;
  /* 95s, not a taste call. The keyframe translates -50%, so duration sets the
     pixels-per-second, and the group grew from 1568px to 4386px when the real
     client logos replaced the 9 icon+label chips. At the old 34s the strip
     scrolled at 129px/s versus the 46.1px/s it was tuned to, i.e. 2.8x faster.
     4386 / 46.1 = 95s holds the original perceived speed. Shorten this only
     together with the chip count — speed = groupWidth / duration. */
  animation: marquee 95s linear infinite;
  /* Paused until initInViewMotion sees it; see the B1 note in animations.css */
  animation-play-state: paused;
  will-change: transform;
}
.marquee-viewport:hover .marquee-track {
  animation-play-state: paused;
}
.marquee-group {
  display: flex;
  align-items: center;
  gap: 3rem;
  padding: 0.75rem 1.5rem;
  flex: none;
}
.logo-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 64px;
  /* Real client artwork replaces the old icon+label chips. Aspect ratios across
     the set run from 6.22:1 to 1:1, so a uniform height plus a min-width keeps
     the square marks (Car4Polynesians, Mumbai Square) from reading as specks
     next to the wide wordmarks (LTL Logistics, Inner City Cleaning). */
  min-width: 150px;
  padding: 0 1.5rem;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--sh-1);
  transition: all 0.25s var(--ease);
  flex: none;
}
.logo-chip:hover {
  border-color: rgba(var(--brand-rgb), 0.6);
  background: #fff;
  transform: translateY(-2px);
  box-shadow: var(--sh-2);
}
/* width/height attributes on the <img> carry the intrinsic aspect ratio, so
   height is pinned and width follows. This reserves the box before the
   bitmap arrives and keeps the strip from reflowing as logos load. */
.logo-chip img {
  display: block;
  height: 32px;
  width: auto;
  max-width: 100%;
  max-height: 32px;
  object-fit: contain;
}

/* 3D service marquee ---------------------------------------------------
   Ported from the Google Stitch source (hp-svc-marquee). A perspective
   stage holds a tilted plane; the plane's track slides left forever.
   Values are unchanged from the design. */
.svc-marquee {
  position: relative;
  overflow: hidden;
  /* No bottom padding: the stage hugs the bottom edge so there is no dead band
     under the tilted plane. Top padding only. */
  padding: 3rem 0 0;
  background: #fff;
  border-bottom: 1px solid var(--border);
}
.svc-marquee h2 {
  text-align: center;
  margin-bottom: 0.25rem;
  position: relative;
  z-index: 2;
}
.svc-marquee .lead {
  text-align: center;
  max-width: 40rem;
  margin: 0 auto 2rem;
  position: relative;
  z-index: 2;
}
.svc-marquee__stage {
  perspective: 1200px;
  perspective-origin: 50% 50%;
  overflow: hidden;
  position: relative;
  width: 100%;
  /* Top padding gives the display type room to breathe; the bottom is flush so
     the section ends on the marquee itself. */
  padding: 2rem 0 0;
}
.svc-marquee__plane {
  transform-style: preserve-3d;
  transform: rotateX(8deg) rotateY(-28deg);
  transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
  will-change: transform;
}
.svc-marquee:hover .svc-marquee__plane {
  transform: rotateX(4deg) rotateY(-18deg);
}
.svc-marquee__track {
  display: flex;
  width: max-content;
  align-items: center;
  animation: evosionInfiniteTrack 36s linear infinite;
  /* Paused until initInViewMotion sees it; see the B1 note in animations.css */
  animation-play-state: paused;
  will-change: transform;
}
/* Each set is one atomic, non-wrapping unit. The track carries no gap of its
   own, so the two identical sets are exactly 50% each and the -50% keyframe
   loops seamlessly. The gap lives inside the set. */
.svc-marquee__set {
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 3.5rem);
  flex: none;
}
.svc-marquee:hover .svc-marquee__track,
.svc-marquee:focus-within .svc-marquee__track {
  animation-play-state: paused;
}
.svc-marquee__item {
  font-family: var(--f-marquee);
  font-size: clamp(2rem, 6.5vw, 5.75rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.025em;
  white-space: nowrap;
  user-select: none;
  text-transform: capitalize;
}
/* Items and dots interleave, so an item sits at child position 1, 3, 5, 7 …
   Plain :nth-child(odd) would therefore match every item and the alternation
   below would never alternate. Orange is 4n+1, ink is 4n+3. */
.svc-marquee__item:nth-child(4n + 1) {
  background: linear-gradient(180deg, #f15b26 0%, #d94d1e 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.svc-marquee__item:nth-child(4n + 3) {
  background: linear-gradient(180deg, #3e4d50 0%, #1a2b2e 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.svc-marquee__dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 9999px;
  background-color: #eb6c01;
  opacity: 0.45;
  margin: 0 clamp(0.75rem, 1.5vw, 1.5rem);
  vertical-align: middle;
  flex: none;
}
/* Fallback: if the display face fails to load, keep the gradient readable */
@supports not (background-clip: text) {
  .svc-marquee__item:nth-child(4n + 1) { -webkit-text-fill-color: #f15b26; color: #f15b26; }
  .svc-marquee__item:nth-child(4n + 3) { -webkit-text-fill-color: #1a2b2e; color: #1a2b2e; }
}

/* Section background atmospheres (from the Stitch "tech-agency-atmosphere"
   layer — a fine coordinate grid with soft orange bloom) */
.section-atmos {
  background-color: #f8fafc;
  background-image:
    radial-gradient(circle at 10% 20%, rgba(235, 108, 1, 0.035) 0%, transparent 40%),
    radial-gradient(circle at 90% 80%, rgba(235, 108, 1, 0.025) 0%, transparent 45%),
    linear-gradient(to right, rgba(226, 232, 240, 0.4) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(226, 232, 240, 0.4) 1px, transparent 1px);
  background-size: 100% 100%, 100% 100%, 48px 48px, 48px 48px;
}
.section-atmos-light {
  background-color: #ffffff;
  background-image:
    radial-gradient(circle at 85% 15%, rgba(235, 108, 1, 0.03) 0%, transparent 35%),
    radial-gradient(circle at 15% 85%, rgba(59, 130, 246, 0.015) 0%, transparent 40%);
}

/* Google-palette colour mesh ---------------------------------------------
   Ambient backdrop for the Google Reviews section: the four Google brand
   colours as overlapping soft fields, blue top-left, red top-right, yellow
   bottom-left, green bottom-right.

   Built from four radial-gradient layers on one element rather than four
   blurred divs. That is both cheaper (no `filter: blur()` repaint) and
   consistent with .section-atmos / .section-atmos-light above. The fields are
   anchored outside the reading area so the review cards stay on clean white,
   and the alphas are kept low — this is a tint behind text, not a feature.

   The section keeps its own .section-atmos-light background; this layer sits
   on top of it via z-index, so nothing is overridden. */
.gmesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background-image:
    radial-gradient(38rem 38rem at 6% -8%, rgba(66, 133, 244, 0.18) 0%, rgba(66, 133, 244, 0) 62%),
    radial-gradient(32rem 32rem at 96% 16%, rgba(234, 67, 53, 0.16) 0%, rgba(234, 67, 53, 0) 62%),
    radial-gradient(30rem 30rem at 14% 92%, rgba(251, 188, 5, 0.2) 0%, rgba(251, 188, 5, 0) 62%),
    radial-gradient(34rem 34rem at 92% 98%, rgba(52, 168, 83, 0.16) 0%, rgba(52, 168, 83, 0) 62%);
}
/* The mesh is a positioned sibling, so the content has to be lifted above it.
   Scoped to this section so no other layout is touched. */
.section-gmesh > .container {
  position: relative;
  z-index: 1;
}

/* --------------------------------------------------------------------------
   Decoration layer — the ambient art system

   Art has to be addable without moving a single layout box, so it is painted on
   layers that are taken out of flow entirely: either an empty presentational
   `<div class="deco …">`, or a ::before on the element that already owns the
   box. Both take no space, intercept no pointer, and never carry text.

   Two entry points, and they are deliberately different classes because a
   section and an art layer must never be confused for one another:

     .deco        an empty child layer.  <div class="deco deco--contour"></div>
     .deco-art    the host itself, drawn through ::before. <section class="section deco-art deco-art--contour">
                  Adding artwork to a whole band therefore needs one class and
                  no HTML edit at all.

   .deco-art sets position:relative + isolation so the art cannot escape its
   band or paint over a sibling, and lifts the direct content children above it
   in the same rule — generically, so no section ever needs a bespoke rule just
   to stay readable.
   -------------------------------------------------------------------------- */
.deco {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  border-radius: inherit;
  opacity: var(--deco-opacity, 1);
}
.deco-art {
  position: relative;
  isolation: isolate;
}
.deco-art::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: var(--deco-opacity, 1);
}
.deco-art > .container,
.deco-art > .container-narrow,
.deco-art > .row { position: relative; z-index: 1; }

/* --- textures: repeated, edge to edge -------------------------------------- */
.deco--grid,
.deco-art--grid::before { background-image: var(--art-grid); background-size: 48px 48px; }
.deco--dots,
.deco-art--dots::before { background-image: var(--art-dots); background-size: 24px 24px; }
.deco--dots-brand,
.deco-art--dots-brand::before { background-image: var(--art-dots-brand); background-size: 26px 26px; }
.deco--hatch,
.deco-art--hatch::before { background-image: var(--art-hatch); background-size: 10px 10px; }
/* Fade the tiles out toward the reading area so body copy never sits on the
   busiest part of a texture. Masked rather than filtered — a mask is a paint
   hint, a blur is a repaint on every scroll frame. */
.deco--grid-fade,
.deco-art--grid-fade::before,
.deco--dots-fade,
.deco-art--dots-fade::before {
  -webkit-mask-image: radial-gradient(120% 100% at 50% 40%, transparent 28%, #000 100%);
  mask-image: radial-gradient(120% 100% at 50% 40%, transparent 28%, #000 100%);
}

/* --- motifs: one artwork, anchored to a corner ----------------------------- */
.deco--contour,
.deco-art--contour::before {
  background: var(--art-contour) no-repeat right -80px top -80px / 480px 480px;
}
.deco--network,
.deco-art--network::before {
  background: var(--art-network) no-repeat left -70px bottom -70px / 440px 440px;
}
.deco--orbit,
.deco-art--orbit::before {
  background: var(--art-orbit) no-repeat right -120px top -140px / 620px 620px;
}
.deco--ribbon,
.deco-art--ribbon::before {
  background: var(--art-ribbon) no-repeat right -60px bottom -40px / 720px 480px;
}
.deco--wave,
.deco-art--wave::before {
  background: var(--art-wave) no-repeat left bottom / 100% 260px;
}
.deco--bloom-brand,
.deco-art--bloom-brand::before {
  background: var(--art-bloom-brand) no-repeat right -140px top -140px / 640px 640px;
}
.deco--bloom-violet,
.deco-art--bloom-violet::before {
  background: var(--art-bloom-violet) no-repeat left -160px bottom -160px / 640px 640px;
}

/* Motifs are sized in absolute pixels, so they need a second set of sizes below
   the tablet breakpoint where the layout collapses to one column. The opacity
   multiplier is the single lever for "too much artwork on a phone". */
@media (max-width: 767px) {
  .deco--contour,
  .deco-art--contour::before {
    background-size: 300px 300px;
    background-position: right -90px top -90px;
  }
  .deco--network,
  .deco-art--network::before { background-size: 280px 280px; }
  .deco--orbit,
  .deco-art--orbit::before {
    background-size: 380px 380px;
    background-position: right -120px top -110px;
  }
  .deco--ribbon,
  .deco-art--ribbon::before { background-size: 480px 320px; }
  .deco,
  .deco-art::before { opacity: calc(var(--deco-opacity, 1) * 0.75); }
}
@media (max-width: 479px) {
  .deco--contour,
  .deco-art--contour::before { background-size: 220px 220px; }
  .deco--orbit,
  .deco-art--orbit::before { background-size: 280px 280px; }
}


/* Skills marquee (legacy flat pill variant, kept for reuse) */
.skill-card {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: 48px;
  padding: 0 1.25rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text);
  transition: all 0.25s var(--ease);
  white-space: nowrap;
}
.skill-card:hover {
  border-color: var(--brand);
  color: var(--brand);
  background: var(--brand-light);
  transform: translateY(-2px) scale(1.03);
}

/* --------------------------------------------------------------------------
   10. Accreditations
   -------------------------------------------------------------------------- */
.accred-panel {
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 2rem;
  position: relative;
  overflow: hidden;
  box-shadow: var(--sh-1);
}
@media (min-width: 1024px) {
  .accred-panel { padding: 3rem; }
}
.accred-head {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding-bottom: 2rem;
  margin-bottom: 2rem;
  border-bottom: 1px solid var(--border);
}
@media (min-width: 768px) {
  .accred-head {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }
}
.accred-head p {
  margin-top: 0.5rem;
  max-width: 42rem;
}
.accred-tier {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-3);
}
.accred-tier .icon {
  width: 18px;
  height: 18px;
  color: var(--brand);
}
.accred-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 1.5rem;
  background: #fff;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease),
    transform 0.3s var(--ease);
}
/* Micro-zoom on the whole card, paired with the icon tile's own scale below.
   3% is deliberately stronger than the 1.5% used by .card-hover / .lp-card so
   the platform tiles read as interactive on a touch-laptop viewport. */
.accred-card:hover {
  border-color: rgba(var(--brand-rgb), 0.6);
  box-shadow: 0 10px 25px -5px rgba(17, 24, 39, 0.06);
  transform: translateY(-4px) scale(1.03);
}
/* Platform tile on the left, "Active Partner" pill on the right. The reference
   puts a 48px bordered light-grey icon box first; ours previously led with the
   pill and used a bare 34px SVG. */
.accred-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}
.accred-card__icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0.625rem;
  flex: none;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--sh-1);
  transition: transform 0.25s var(--ease);
}
.accred-card:hover .accred-card__icon {
  transform: scale(1.08);
}
.accred-card__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}
/* Raster partner marks (e.g. the Meta background PNG) are not square, so they
   letterbox with `contain` rather than being centre-cropped — a `cover` fit on
   the 940x788 Meta asset trims the ends off the wordmark inside a 48px tile.
   Explicit modifier class rather than `:has(img)` so it does not depend on
   selector support. */
.accred-card__icon--img {
  padding: 0.375rem;
  background: #fff;
}
.accred-card__icon img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
  object-position: center;
}
.accred-card h3 {
  margin-top: 0.25rem;
}
.accred-card > p {
  font-size: 0.875rem;
  color: var(--text-2);
}
/* Rule-separated capability block, matching the reference's
   `mt-space-md pt-space-sm border-t` with a "Key Capabilities" label. */
.accred-card__caps {
  margin-top: auto;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  display: grid;
  gap: 0.375rem;
}
.accred-card__caps > .t-mono {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 0.25rem;
}
/* Trailing benefit line sits below the rule, outside the tag list. The
   reference renders it as a centred `text-brand-orange font-semibold` mono
   line, so the colour belongs on the element itself. The selector is a child
   combinator because `.accred-card > p` sets grey at 0,1,1 and would otherwise
   win against a single-class rule. */
.accred-card > .accred-card__foot {
  display: flex;
  justify-content: center;
  margin-top: 0.5rem;
  padding-top: 0.25rem;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 600;
letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--brand);
  margin-top: 0.5rem;
}
.cap-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

/* --------------------------------------------------------------------------
   11. Direct accountability / leadership
   -------------------------------------------------------------------------- */
.quote-block {
  position: relative;
  padding: 1.5rem 1.5rem 1.5rem 3rem;
  border-radius: var(--r-md);
  background: var(--brand-light);
  border: 1px solid rgba(224, 192, 177, 0.35);
}
.quote-block::before {
  content: "\201C";
  position: absolute;
  left: 0.875rem;
  top: 0.5rem;
  font-size: 3rem;
  line-height: 1;
  color: var(--brand);
  opacity: 0.35;
  font-family: Georgia, serif;
}
/* 11. Direct accountability / leadership ---------------------------------
   The reference lays this out as a 12-column grid: 5 columns of copy and the
   accountability quote, 7 columns of leader cards. Ours rendered a single
   stacked column at every width, so the two-column composition never appeared.
   The leader cards were also dark ink; the reference uses white elevated
   surfaces with light grey icon boxes, so the section read as a different
   design entirely. */
.acct-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 3rem;
  align-items: center;
}
@media (min-width: 1024px) {
  .acct-split {
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }
  .acct-split__lead {
    grid-column: span 5;
  }
  .acct-split__cards {
    grid-column: span 7;
  }
}
.acct-split__lead {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.acct-split__cards > .engine-banner {
  grid-column: 1 / -1;
}

/* Quote card: white elevated surface, orange quote mark, italic body, then a
   rule separating the attribution from the quote itself. */
.quote-block {
  position: relative;
  padding: 1.5rem;
  border-radius: var(--r-md);
  background: var(--elevated);
  border: 1px solid var(--border);
  box-shadow: var(--sh-1);
}
.quote-block::before {
  display: none;
}
.quote-block__mark {
  color: var(--brand);
  margin-bottom: 0.5rem;
}
.quote-block__mark .icon {
  width: 24px;
  height: 24px;
}
.quote-block blockquote {
  margin: 0;
  line-height: 1.65;
}
.quote-block__who {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}
.quote-text {
  font-style: italic;
  color: var(--text-2);
  line-height: 1.7;
  margin: 0.75rem 0;
  position: relative;
  padding: 0 0.5rem;
}
.quote-text:before {
  content: "\201C";
  position: absolute;
  left: -0.25rem;
  top: -0.35rem;
  font-size: 2.5rem;
  line-height: 0.8;
  color: var(--brand-light);
  opacity: 0.5;
}
.quote-text:after {
  content: "\201D";
  position: absolute;
  right: -0.25rem;
  bottom: -0.5rem;
  font-size: 2.5rem;
  line-height: 0.8;
  color: var(--brand-light);
  opacity: 0.5;
}
.badge-owned {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 0.5rem;
  border-radius: var(--r-sm);
  background: var(--brand-light);
  color: var(--brand);
  font-weight: 700;
  white-space: nowrap;
}

/* Light, muted label used on the white leader cards. */
.badge-soft {
  background: var(--surface);
  color: var(--text-3);
  border: 1px solid var(--border);
}

.leader-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.5rem;
  border-radius: var(--r-md);
  background: var(--elevated);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: var(--sh-1);
  position: relative;
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.leader-card:hover {
  transform: translateY(-3px) scale(1.015);
  border-color: rgba(var(--brand-rgb), 0.5);
  box-shadow: var(--sh-2);
}
.leader-card::after {
  display: none;
}
/* 64px light icon box, matching the reference's w-16 h-16 rounded-lg tile. */
.leader-avatar {
  width: 64px;
  height: 64px;
  border-radius: var(--r);
  background: var(--surface);
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  color: var(--brand);
  box-shadow: var(--sh-1);
  margin-bottom: 1rem;
  position: relative;
  z-index: 1;
}
.leader-avatar .icon {
  width: 32px;
  height: 32px;
}
/* Rule-separated status footer: left = cadence, right = access level. */
.leader-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3);
}
.leader-foot__direct {
  color: var(--text);
  font-weight: 500;
}

/* Spans both leader columns, matching the reference's sm:col-span-2 banner. */
.engine-banner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.5rem;
  border-radius: var(--r-md);
  background: var(--elevated);
  border: 1px solid var(--border);
  box-shadow: var(--sh-1);
  text-align: center;
}
@media (min-width: 640px) {
  .engine-banner {
    flex-direction: row;
    text-align: left;
  }
}
.engine-banner__text {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
/* Body copy on the leader cards. The card background is --elevated (#fff), so
   this must be a dark token — an earlier rgba(255,255,255,.7) here rendered
   white-on-white and made every paragraph in these cards invisible. */
.leader-card p {
  font-size: 0.875rem;
  color: var(--text-2);
  position: relative;
  z-index: 1;
}
/* Partner pull-quote inside a leader card. Sits above the grey `p` colour so
   it reads as a distinct voice, and keeps the accent rule as the visual anchor. */
.leader-card__quote {
  padding-left: 0.875rem;
  border-left: 2px solid rgba(var(--brand-rgb), 0.55);
  font-style: italic;
  color: var(--text);
}

/* --------------------------------------------------------------------------
   12. Service pillars
   -------------------------------------------------------------------------- */
.pillar-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.pillar-card .pillar-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}
.pillar-card h3 {
  margin-bottom: 0.625rem;
}
.pillar-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: auto;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);
  transition: color 0.2s var(--ease);
}
.pillar-cta .icon {
  width: 18px;
  height: 18px;
  color: var(--brand);
  transition: transform 0.25s var(--ease);
}
.pillar-card:hover .pillar-cta {
  color: var(--brand);
}
.pillar-card:hover .pillar-cta .icon {
  transform: translateX(4px);
}

/* --------------------------------------------------------------------------
   13. Video testimonials
   -------------------------------------------------------------------------- */
.video-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: #fff;
  overflow: hidden;
  transition: all 0.3s var(--ease);
}
.video-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-3px) scale(1.015);
  box-shadow: var(--sh-2);
}
.video-thumb {
  position: relative;
  aspect-ratio: 16 / 10;
  background: linear-gradient(135deg, var(--ink) 0%, #1f2937 60%, #374151 100%);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.video-thumb::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.12) 0.5px, transparent 0.5px);
  background-size: 14px 14px;
}
.video-play {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff;
  transition: all 0.3s var(--ease);
}
.video-play .icon {
  width: 26px;
  height: 26px;
  margin-left: 3px;
}
.video-card:hover .video-play {
  background: var(--brand);
  border-color: var(--brand);
  box-shadow: var(--sh-brand-lg);
  transform: scale(1.08);
}
.video-duration {
  position: absolute;
  right: 0.625rem;
  bottom: 0.625rem;
  z-index: 1;
  padding: 0.125rem 0.5rem;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.7);
  color: #fff;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
}
.video-cat {
  position: absolute;
  left: 0.625rem;
  top: 0.625rem;
  z-index: 1;
}
.video-body {
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  flex: 1;
}
.video-body h3 {
  font-size: 1rem;
}
.video-result {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--brand);
}
.video-rail {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 2.5rem;
}
.rail-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--ink);
  transition: all 0.2s var(--ease);
}
.rail-btn:hover:not(:disabled) {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
  transform: scale(1.05);
}
.rail-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.rail-btn .icon {
  width: 20px;
  height: 20px;
}

/* --------------------------------------------------------------------------
   14. Results / case studies
   -------------------------------------------------------------------------- */
.case-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 480px), 1fr));
}
.case-card {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 2rem;
  border-radius: var(--r-md);
  background: #fff;
  border: 1px solid var(--border);
  transition: all 0.3s var(--ease);
}
.case-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-3px) scale(1.015);
  box-shadow: var(--sh-2);
}
.case-card blockquote {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  font-style: italic;
  color: var(--text-2);
}
/* Name and role lead the card, sector pill sits opposite, with a rule beneath —
   the reference layout. Ours led with an initials avatar and pushed the
   attribution into a footer line at the bottom of the card. */
.case-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 1rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}
.case-pill {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 0.5rem;
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text-2);
  font-size: 0.8125rem;
  font-weight: 700;
  white-space: nowrap;
}
.case-pill--brand {
  background: var(--brand-light);
  color: var(--brand);
}
.case-metrics {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem;
}
.case-metric {
  font-weight: 700;
  line-height: 1.1;
  color: var(--text);
}
.case-metric--lead {
  font-size: 2rem;
  letter-spacing: -0.02em;
  color: var(--brand);
}
.case-metric--sub {
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}
.case-metric-label {
  font-size: 1rem;
  font-weight: 500;
  color: var(--text);
}
.case-metric-sep {
  color: var(--text-3);
}
/* Challenge and solution share one muted box with inline prefixes. */
.case-note {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin-top: auto;
  padding: 1rem;
  border-radius: var(--r);
  background: var(--surface);
  border: 1px solid var(--border);
}
.case-note p {
  margin: 0;
  font-family: var(--f-mono);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--text-2);
}
.case-note b {
  color: var(--brand);
  font-weight: 700;
}
.case-note p + p b {
  color: var(--text);
}
/* .case-block was replaced by .case-note (one box, inline prefixes) to match
   the reference layout. Removed rather than left as dead CSS. */
.case-mini {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.25rem;
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--surface);
  transition: all 0.25s var(--ease);
}
.case-mini:hover {
  background: #fff;
  border-color: var(--brand);
  transform: translateY(-2px) scale(1.015);
}
.case-mini .icon {
  width: 22px;
  height: 22px;
  color: var(--brand);
  flex: none;
}
.case-mini b {
  display: block;
  font-size: 0.9375rem;
}
.case-mini span {
  font-size: 0.8125rem;
  color: var(--text-2);
}

/* --------------------------------------------------------------------------
   15. Reviews carousel
   -------------------------------------------------------------------------- */
.reviews-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  margin-bottom: 2.5rem;
}
.stars {
  display: inline-flex;
  gap: 2px;
  color: #f59e0b;
}
.stars .icon {
  width: 16px;
  height: 16px;
}
.rating-big {
  font-size: 2.25rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
}
.reviews-viewport {
  overflow: hidden;
  padding-inline: 0.25rem;
}
.reviews-track {
  display: flex;
  gap: 1.5rem;
  transition: transform 0.55s var(--ease);
  will-change: transform;
}
.review-card {
  flex: none;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.75rem;
  border-radius: var(--r-md);
  background: #fff;
  border: 1px solid var(--border);
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.review-card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--sh-1);
}
@media (min-width: 700px) {
  .review-card { width: calc((100% - 1.5rem) / 2); }
}
@media (min-width: 1060px) {
  .review-card { width: calc((100% - 3rem) / 3); }
}
.review-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.review-avatar {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--brand-light);
  border: 1px solid rgba(224, 192, 177, 0.4);
  color: var(--brand);
  font-family: var(--f-mono);
  font-size: 0.8125rem;
  font-weight: 700;
  flex: none;
}
.review-card blockquote {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--text-2);
  flex: 1;
}
.review-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: 0.875rem;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.reviews-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.dots {
  display: flex;
  gap: 0.375rem;
}
.dots button {
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--border-strong);
  transition: all 0.3s var(--ease);
}
.dots button[aria-current="true"] {
  width: 24px;
  background: var(--brand);
}

/* --------------------------------------------------------------------------
   16. Growth protocol (phases)
   -------------------------------------------------------------------------- */
.phase-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 2rem;
  border-radius: var(--r-md);
  background: #fff;
  border: 1px solid var(--border);
  overflow: hidden;
  transition: all 0.3s var(--ease);
}
.phase-card:hover {
  border-color: rgba(var(--brand-rgb), 0.5);
  transform: translateY(-3px) scale(1.015);
  box-shadow: var(--sh-2);
}
.phase-num {
  font-size: 3.5rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.04em;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--border-strong);
  position: absolute;
  right: 1rem;
  top: 0.75rem;
  transition: color 0.3s var(--ease), -webkit-text-stroke-color 0.3s var(--ease);
}
.phase-card:hover .phase-num {
  color: rgba(var(--brand-rgb), 0.12);
  -webkit-text-stroke-color: rgba(var(--brand-rgb), 0.4);
}
.phase-phase {
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

/* --------------------------------------------------------------------------
   17. Pricing
   -------------------------------------------------------------------------- */
.price-card {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  height: 100%;
  padding: 2rem;
  border-radius: var(--r-md);
  background: #fff;
  border: 1px solid var(--border);
  position: relative;
  transition: all 0.3s var(--ease);
}
.price-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-3px) scale(1.015);
  box-shadow: var(--sh-2);
}
.price-card.featured {
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand), var(--sh-brand);
}
.price-card.featured::before {
  content: "";
  position: absolute;
  inset: -1px -1px auto -1px;
  height: 4px;
  border-radius: var(--r-md) var(--r-md) 0 0;
  background: linear-gradient(90deg, var(--brand), #fb923c, var(--brand));
}
.price-card .featured-flag {
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
}
.price-amount {
  display: flex;
  align-items: baseline;
  gap: 0.25rem;
}
.price-amount b {
  font-size: 2.75rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
}
.price-amount span {
  font-size: 0.875rem;
  color: var(--text-3);
}
.price-list {
  display: grid;
  gap: 0.625rem;
  flex: 1;
}
.price-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* --------------------------------------------------------------------------
   18. Audit form
   -------------------------------------------------------------------------- */
.audit-wrap {
  display: grid;
  gap: 2rem;
  align-items: start;
}
/* A grid item's automatic minimum size is its min-content width, so an
   unbreakable token inside (the email in .audit-note) floors the column and
   pushes the whole page into horizontal scroll below ~400px. min-width: 0
   lets the item shrink to the column and the text wrap normally. */
.audit-wrap > * {
  min-width: 0;
}
@media (min-width: 1024px) {
  .audit-wrap {
    grid-template-columns: 0.85fr 1.15fr;
    gap: 3.5rem;
  }
}
.audit-list {
  display: grid;
  gap: 0.75rem;
  margin-top: 1.5rem;
}
.audit-note {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1.5rem;
  padding: 0.75rem 1rem;
  border-radius: var(--r);
  background: var(--brand-light);
  border: 1px solid rgba(224, 192, 177, 0.35);
  font-size: 0.8125rem;
  color: var(--text-2);
}
.audit-note .icon {
  width: 18px;
  height: 18px;
  color: var(--brand);
  flex: none;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.field label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
}
.field label span {
  color: var(--brand);
}
.field input,
.field select,
.field textarea {
  height: 44px;
  padding: 0 0.875rem;
  border-radius: var(--r);
  border: 1px solid var(--border);
  background: #fff;
  font: inherit;
  font-size: 0.875rem;
  color: var(--text);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
  width: 100%;
}
.field textarea {
  height: auto;
  padding: 0.75rem 0.875rem;
  resize: vertical;
}
.field input::placeholder,
.field textarea::placeholder {
  color: var(--text-3);
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(var(--brand-rgb), 0.15);
}
.field-error {
  font-size: 0.75rem;
  color: #ba1a1a;
  display: none;
}
.field.has-error input {
  border-color: #ba1a1a;
}
.field.has-error .field-error {
  display: block;
}
.form-grid {
  display: grid;
  gap: 1rem;
}
@media (min-width: 640px) {
  .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .form-grid .span-2 { grid-column: 1 / -1; }
}
.form-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.5rem;
}
.form-foot .form-fine {
  font-size: 0.75rem;
  color: var(--text-3);
}
.form-success {
  display: none;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-radius: var(--r);
  background: #ecfdf5;
  border: 1px solid #a7f3d0;
  color: #065f46;
  font-size: 0.875rem;
}
.form-success.is-visible {
  display: flex;
  animation: slide-up 0.5s var(--ease) both;
}
.form-success .icon {
  width: 20px;
  height: 20px;
  flex: none;
}

/* Honeypot — visually gone, still reachable by a bot, never by a person.
   `overflow: hidden` keeps the label's real text (~348px) from propagating
   into the ancestor scroll boxes; `clip` alone would hide the pixels but not
   the layout. */
.honeypot {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

/* Submission failure banner */
.form-failed {
  display: none;
  padding: 0.875rem 1.25rem;
  border-radius: var(--r);
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #991b1b;
  font-size: 0.875rem;
  line-height: 1.5;
}
.form-failed.is-visible {
  display: block;
  animation: slide-up 0.45s var(--ease) both;
}

/* --------------------------------------------------------------------------
   19. Bundles / offers
   -------------------------------------------------------------------------- */
.offer-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  height: 100%;
  padding: 1.75rem;
  border-radius: var(--r-md);
  background: var(--ink);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.1);
  position: relative;
  overflow: hidden;
  transition: transform 0.3s var(--ease), border-color 0.3s var(--ease);
}
.offer-card:hover {
  transform: translateY(-3px) scale(1.015);
  border-color: rgba(var(--brand-rgb), 0.5);
}
.offer-card::after {
  content: "";
  position: absolute;
  left: -20%;
  top: -60%;
  width: 70%;
  height: 200%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.06), transparent);
  transform: rotate(18deg);
  transition: transform 0.6s var(--ease);
}
.offer-card:hover::after {
  transform: rotate(18deg) translateX(220%);
}
.offer-card p {
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.72);
}
.offer-value {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  /* Offer cards are dark panels, so this needs the light brand member. */
  color: var(--brand);
}
.offer-cta {
  margin-top: auto;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 0.875rem;
  font-weight: 600;
  color: #fff;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  transition: color 0.2s var(--ease), gap 0.25s var(--ease);
}
.offer-cta:hover {
  color: var(--brand);
  gap: 0.625rem;
}

/* --------------------------------------------------------------------------
   20. FAQ accordion
   -------------------------------------------------------------------------- */
.faq-item {
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: #fff;
  overflow: hidden;
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.faq-item + .faq-item {
  margin-top: 0.75rem;
}
.faq-item.is-open {
  border-color: rgba(var(--brand-rgb), 0.5);
  box-shadow: var(--sh-1);
}
.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 1.125rem 1.25rem;
  text-align: left;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text);
  position: relative;
  transition: color 0.2s var(--ease);
}
/* The active question is marked with an orange rule under it. Drawn as a
   pseudo-element rather than a border so opening an item does not shift the
   answer below it by the border's height. */
.faq-q::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.35s var(--ease);
}
.faq-item.is-open .faq-q::after {
  transform: scaleX(1);
}
.faq-q:hover {
  color: var(--brand);
}
.faq-q .icon {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--text-3);
  transition: transform 0.3s var(--ease), color 0.3s var(--ease);
}
.faq-item.is-open .faq-q {
  color: var(--brand);
}
.faq-item.is-open .faq-q .icon {
  transform: rotate(180deg);
  color: var(--brand);
}
.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ease);
}
.faq-item.is-open .faq-a {
  grid-template-rows: 1fr;
}
.faq-a > div {
  overflow: hidden;
}
.faq-a p {
  padding: 0 1.25rem 1.25rem;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--text-2);
}

/* --------------------------------------------------------------------------
   21. CTA
   -------------------------------------------------------------------------- */
.cta-section {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  color: #fff;
  padding-block: var(--section-y);
  isolation: isolate;
}
.cta-section::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image: radial-gradient(rgba(255, 255, 255, 0.09) 0.5px, transparent 0.5px);
  background-size: 20px 20px;
}
.cta-section::after {
  content: "";
  position: absolute;
  z-index: -1;
  right: -10rem;
  bottom: -10rem;
  width: 34rem;
  height: 34rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--brand-rgb), 0.35), transparent 65%);
  filter: blur(20px);
  pointer-events: none;
}
.cta-grid {
  display: grid;
  gap: 2.5rem;
  align-items: center;
}
@media (min-width: 900px) {
  .cta-grid {
    grid-template-columns: 1.2fr 0.8fr;
    gap: 4rem;
  }
}
.cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}
.cta-points {
  display: grid;
  gap: 0.75rem;
  padding: 1.75rem;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
}
.cta-points .check {
  color: rgba(255, 255, 255, 0.85);
}
.cta-points .check .icon {
  color: var(--brand);
}

/* --------------------------------------------------------------------------
   22. Footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 4rem 0 2rem;
}
/* Bordered widget panel. Recreates the Bootstrap Brain "Footer 7" composition
   — an outlined container holding widget columns, with a separate colophon bar
   beneath it — using this site's own tokens rather than a Bootstrap grid. */
.footer-panel {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--elevated);
  box-shadow: var(--sh-1);
  overflow: hidden;
}
.footer-panel__grid {
  display: grid;
  gap: 0;
}
.footer-widget {
  padding: 2rem 1.5rem;
}
/* Hairline dividers between widgets, drawn as a border on the widget itself so
   they collapse to full-width rules once the grid stacks on narrow screens. */
.footer-widget + .footer-widget {
  border-top: 1px solid var(--border);
}
.footer-widget__title {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* --brand-hover, not --text-2 and not --brand. These headings were asked for
     in the logo orange. The logo's own orange measures #e86800, which is what
     --brand (#eb6c01) already carries, so --brand is the exact brand match —
     but on this footer's #f9fafb background it lands at 3.01:1, and these are
     12px/600, which is not WCAG "large text", so AA wants 4.5:1.
     --brand-hover (#c2410c) is the same hue one step down and reaches 4.95:1.
     An earlier note here recorded that these headings had been 11px #9ca3af on
     white at 2.54:1 and were lifted to --text-2 for that reason; going to a
     brand colour must not undo that. */
  color: var(--brand-hover);
  margin-bottom: 1.25rem;
}
.footer-widget__note {
  font-size: 0.875rem;
  color: var(--text-2);
  margin-bottom: 1.25rem;
  max-width: 24rem;
}
@media (min-width: 640px) {
  .footer-widget {
    padding: 2.25rem 2rem;
  }
}
@media (min-width: 900px) {
  .footer-panel__grid {
    grid-template-columns: 1.15fr 1.6fr 1fr;
  }
  .footer-widget + .footer-widget {
    border-top: 0;
    border-left: 1px solid var(--border);
  }
}

/* Opening hours: label/value rows on a shared baseline. */
.footer-hours {
  display: grid;
  gap: 0.5rem;
}
.footer-hours__row {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: 0.5rem;
  align-items: baseline;
  font-size: 0.875rem;
}
.footer-hours__key {
  font-weight: 600;
  color: var(--text);
}
.footer-hours__val {
  color: var(--text-2);
}
.footer-brand img {
  height: 36px;
  width: auto;
}
.footer-brand p {
  margin-top: 1rem;
  max-width: 26rem;
  font-size: 0.875rem;
  color: var(--text-2);
}
.footer-brand b {
  display: block;
  margin-top: 1rem;
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
}
.footer-contact {
  display: grid;
  gap: 0.5rem;
  margin-top: 1.25rem;
}
.footer-contact a,
.footer-contact span {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--text-2);
  transition: color 0.2s var(--ease);
}
.footer-contact a:hover {
  color: var(--brand);
}
.footer-contact .icon {
  width: 16px;
  height: 16px;
  color: var(--brand);
  flex: none;
}

/* Company social profiles and the Google Partner verification badge. */
.footer-social {
  margin-top: 1.25rem;
}
.footer-social__label {
  display: block;
  margin-bottom: 0.75rem;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
  font-weight: 600;
}
.footer-social__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
  margin: 0;
}
.social-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: 38px;
  padding: 0 0.9rem 0 0.75rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--elevated);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-2);
  white-space: nowrap;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease),
    background-color 0.2s var(--ease), box-shadow 0.2s var(--ease),
    transform 0.2s var(--ease);
}
.social-link .icon {
  width: 17px;
  height: 17px;
  flex: none;
  color: var(--text-3);
  transition: color 0.2s var(--ease);
}
.social-link:hover,
.social-link:focus-visible {
  color: var(--brand-hover);
  border-color: rgba(var(--brand-rgb), 0.45);
  background: var(--brand-light);
  transform: translateY(-2px);
  box-shadow: var(--sh-brand);
}
.social-link:hover .icon,
.social-link:focus-visible .icon {
  color: var(--brand);
}

/* Google Partner badge. Links to the public partner record so the claim is
   verifiable rather than decorative. */
.partner-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  margin-top: 1rem;
  padding: 0.6rem 1rem 0.6rem 0.7rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--elevated);
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease),
    box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
}
.partner-badge__g {
  width: 26px;
  height: 26px;
  flex: none;
}
.partner-badge__text {
  display: grid;
  gap: 0.1rem;
  line-height: 1.2;
}
.partner-badge__text b {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--text);
}
.partner-badge__verified {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* --brand-hover is 3.56:1 on white, which fails AA at this size. --text-3
     carries the same "verified, secondary" reading at 4.8:1. */
  color: var(--text-3);
}
.partner-badge__verified .icon {
  width: 13px;
  height: 13px;
  color: var(--brand);
  flex: none;
}
.partner-badge:hover,
.partner-badge:focus-visible {
  border-color: rgba(var(--brand-rgb), 0.45);
  background: var(--brand-light);
  transform: translateY(-2px);
  box-shadow: var(--sh-brand);
}
/* Link groups inside the services widget. Four groups at two columns so the
   panel keeps its three-column shape at desktop instead of stretching. */
.footer-cols {
  display: grid;
  gap: 1.75rem 1.5rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 640px) {
  .footer-cols {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (min-width: 1280px) {
  .footer-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.footer-cols h3 {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* --brand-hover, matching .footer-widget__title. These are the same 12px/600
     uppercase headings in the same footer, so they take the same orange and the
     same 4.95:1 on #f9fafb. --text-3 (11px #9ca3af, 2.54:1) was the old value
     here; see .footer-widget__title for why the brand orange is stepped down
     from --brand rather than used at full strength. */
  color: var(--brand-hover);
  font-weight: 600;
  margin-bottom: 0.875rem;
}
.footer-cols li + li {
  margin-top: 0.5rem;
}
.footer-cols a {
  font-size: 0.875rem;
  color: var(--text-2);
  transition: color 0.2s var(--ease), padding-left 0.2s var(--ease);
}
.footer-cols a:hover {
  color: var(--brand);
  padding-left: 4px;
}
/* Colophon bar: logo left, copyright centre, status right. Mirrors the
   Bootstrap Brain footer-7 colophon row — logo, credits, then socials — but
   keeps this site's monospace status chip instead of a social icon cluster,
   because the social profiles already sit in the contact widget above. */
.footer-colophon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  margin-top: 1.5rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--elevated);
  box-shadow: var(--sh-1);
}
.footer-colophon img {
  height: 30px;
  width: auto;
}
.footer-colophon__copy {
  font-size: 0.8125rem;
  /* --text-2 for the same WCAG reason as the widget titles; the old
     .footer-bottom rule used --text-3, which is 2.54:1 on white. */
  color: var(--text-2);
}
.footer-colophon__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
}
.footer-colophon__site {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--text-2);
}
.footer-colophon__site .icon {
  width: 15px;
  height: 15px;
  color: var(--text-3);
}
.footer-status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.25rem 0.75rem;
  border-radius: var(--r-pill);
  background: var(--brand-light);
  border: 1px solid rgba(224, 192, 177, 0.4);
  color: var(--brand);
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   23. Scroll reveal
   -------------------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Back to top */
.to-top {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 45;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: var(--sh-2);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: all 0.3s var(--ease);
}
.to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.to-top:hover {
  background: var(--brand);
  transform: translateY(-2px);
  box-shadow: var(--sh-brand);
}
.to-top .icon {
  width: 20px;
  height: 20px;
}

/* --------------------------------------------------------------------------
   24. Utilities
   -------------------------------------------------------------------------- */
.stack-xs { display: grid; gap: 0.5rem; }
.stack-sm { display: grid; gap: 0.75rem; }
.stack-md { display: grid; gap: 1rem; }
.stack-lg { display: grid; gap: 1.5rem; }
.stack-xl { display: grid; gap: 2rem; }
.row { display: flex; align-items: center; gap: 0.75rem; }
.row-wrap { flex-wrap: wrap; }
.between { justify-content: space-between; }
.center { justify-content: center; }
.mt-auto { margin-top: auto; }
.mt-1 { margin-top: 0.75rem; }
.mt-2 { margin-top: 1.5rem; }
.mt-3 { margin-top: 2rem; }
.mt-4 { margin-top: 3rem; }
.mt-5 { margin-top: 5rem; }
.text-center { text-align: center; }
.mx-auto { margin-inline: auto; }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.divider {
  height: 1px;
  background: var(--border);
  border: 0;
  margin: 0;
}

/* ==========================================================================
   Legal pages (privacy.html / terms.html)
   Prose layout for the policy pages. Reuses the same tokens as the rest of
   the site so the legal pages inherit the brand without a second stylesheet.
   ========================================================================== */
.legal-doc { max-width: 78ch; }

.legal-doc h2 {
  font-family: var(--f-display);
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin-top: 2.75rem;
  margin-bottom: 0.85rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
  scroll-margin-top: 7rem;
}
.legal-doc h2:first-of-type { margin-top: 2rem; padding-top: 0; border-top: 0; }

.legal-doc h3 {
  font-family: var(--f-display);
  font-size: 1.05rem;
  font-weight: 600;
  margin-top: 1.75rem;
  margin-bottom: 0.5rem;
}

.legal-doc p { color: var(--text-2); line-height: 1.75; margin-bottom: 1rem; }
.legal-doc p strong { color: var(--text); font-weight: 600; }

.legal-doc ul,
.legal-doc ol { color: var(--text-2); line-height: 1.75; margin: 0 0 1rem; padding-left: 1.35rem; }
.legal-doc li { margin-bottom: 0.5rem; }
.legal-doc li::marker { color: var(--brand); }

.legal-doc a { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }
.legal-doc a:hover { color: var(--brand); }

.legal-doc code {
  font-family: var(--f-mono);
  font-size: 0.85em;
  background: var(--surface-2);
  padding: 0.1em 0.4em;
  border-radius: var(--r-sm);
}

.legal-meta {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem;
  font-family: var(--f-mono);
  font-size: 0.75rem; color: var(--text-3);
  margin-top: 1.25rem;
}

/* Definition-style rows for the data-collection table on the privacy page */
.legal-table { width: 100%; border-collapse: collapse; margin: 1.25rem 0 1.5rem; font-size: 0.9rem; }
.legal-table th,
.legal-table td { text-align: left; padding: 0.7rem 0.85rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.legal-table th { font-family: var(--f-mono); font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-3); }
.legal-table td { color: var(--text-2); }
.legal-table td:first-child { color: var(--text); font-weight: 500; }
.legal-table tbody tr:last-child td { border-bottom: 0; }

.legal-callout {
  display: flex; gap: 0.85rem; align-items: flex-start;
  background: var(--brand-light);
  border: 1px solid var(--brand-subtle);
  border-radius: var(--r-md);
  padding: 1rem 1.15rem;
  margin: 1.5rem 0;
}
.legal-callout .icon { width: 20px; height: 20px; color: var(--brand); flex-shrink: 0; margin-top: 2px; }
.legal-callout p { color: var(--ink-soft); margin: 0; font-size: 0.9rem; }

/* In-page contents list */
.legal-toc { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: 1.15rem 1.35rem; margin: 2rem 0; }
.legal-toc h2 { margin: 0 0 0.75rem; padding: 0; border: 0; font-size: 0.75rem; font-family: var(--f-mono); text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-3); }
.legal-toc ol { margin: 0; padding-left: 1.2rem; columns: 2; column-gap: 2rem; font-size: 0.85rem; }
.legal-toc li { break-inside: avoid; margin-bottom: 0.35rem; }

@media (max-width: 640px) {
  .legal-toc ol { columns: 1; }
  .legal-doc h2 { font-size: 1.15rem; }
  .legal-table { font-size: 0.8rem; }
  .legal-table th, .legal-table td { padding: 0.55rem 0.5rem; }
}

/* ==========================================================================
   404 page
   ========================================================================== */
.nf-404 { position: relative; text-align: center; overflow: hidden; }
.nf-404__atmos { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.nf-404__atmos i { position: absolute; display: block; border-radius: 50%; }
.nf-404__a { width: 620px; height: 620px; top: -260px; left: 50%; margin-left: -310px;
             background: radial-gradient(circle, rgba(235, 108, 1,.16) 0%, rgba(235, 108, 1,0) 68%); }
.nf-404__b { width: 520px; height: 520px; bottom: -240px; left: 50%; margin-left: -260px;
             background: radial-gradient(circle, rgba(123,44,199,.12) 0%, rgba(123,44,199,0) 68%); }

.nf-404__code {
  font-family: var(--f-mono);
  font-size: clamp(4rem, 16vw, 7.5rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--brand);
  margin-bottom: 0.5rem;
}
.nf-404__msg { max-width: 42rem; margin-inline: auto; }
.nf-404__msg p { color: var(--text-2); line-height: 1.7; margin-top: 0.75rem; }

.nf-404__tags {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  justify-content: center;
  margin-top: 2.25rem;
}

/* ==========================================================================
   Landing page shell (service + insight pages)
   Reuses the existing tokens and card primitives. No new colour, radius or
   spacing value is introduced here.
   ========================================================================== */

/* --- page hero --- */
.lp-hero {
  position: relative;
  padding-block: 4.5rem 4rem;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
.lp-hero__mesh { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.lp-hero__mesh i { position: absolute; display: block; border-radius: 50%; }
.lp-hero__a { width: 640px; height: 640px; top: -280px; right: -160px;
             background: radial-gradient(circle, rgba(var(--brand-rgb), .18) 0%, rgba(var(--brand-rgb), 0) 68%); }
.lp-hero__b { width: 560px; height: 560px; bottom: -300px; left: -180px;
             background: radial-gradient(circle, rgba(123, 44, 199, .10) 0%, rgba(123, 44, 199, 0) 68%); }
.lp-hero__inner { max-width: 52rem; }
.lp-hero h1 { margin-top: 1rem; }
.lp-hero__sub { margin-top: 1.25rem; font-size: 1.125rem; line-height: 1.65; color: var(--text-2); max-width: 44rem; }
.lp-hero__cta { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }
.lp-hero__meta { display: flex; flex-wrap: wrap; gap: 0.5rem 1.75rem; margin-top: 2rem;
                 font-family: var(--f-mono); font-size: 0.75rem; color: var(--text-3); }

/* --- breadcrumb --- */
.lp-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
             font-family: var(--f-mono); font-size: 0.75rem; color: var(--text-3); }
.lp-crumbs a { color: var(--text-3); text-decoration: none; }
.lp-crumbs a:hover { color: var(--brand-hover); }
.lp-crumbs .sep { opacity: 0.65; }
.lp-crumbs [aria-current] { color: var(--text-2); }

/* --- generic section wrappers --- */
.lp-section { padding-block: 4rem; }
.lp-section--tint { background: var(--surface); border-block: 1px solid var(--border); }
.lp-section__head { max-width: 46rem; margin-bottom: 2.5rem; }
.lp-section__head h2 { margin-top: 0.75rem; }
.lp-section__head p { margin-top: 1rem; color: var(--text-2); line-height: 1.7; }

/* --- feature grid --- */
.lp-grid { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.lp-grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); }

.lp-card {
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 1.5rem;
  box-shadow: var(--sh-1);
  transition: box-shadow .25s var(--ease), transform .25s var(--ease), border-color .25s var(--ease);
}
.lp-card:hover { box-shadow: var(--sh-2); transform: translateY(-2px) scale(1.015); border-color: var(--border-strong); }
.lp-card h3 { margin-bottom: 0.5rem; }
.lp-card p { color: var(--text-2); font-size: 0.95rem; line-height: 1.65; }
.lp-card__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: var(--r);
  background: var(--brand-light);
  color: var(--brand);
  border: 1px solid var(--brand-subtle);
  margin-bottom: 1rem;
}
.lp-card__icon .icon { width: 22px; height: 22px; }

/* --- numbered process list --- */
.lp-steps { display: grid; gap: 1rem; counter-reset: lpstep; }
.lp-step {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 1.25rem;
  align-items: start;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 1.35rem 1.5rem;
  box-shadow: var(--sh-1);
}
.lp-step__num {
  counter-increment: lpstep;
  display: flex; align-items: center; justify-content: center;
  width: 3rem; height: 3rem;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: #fff;
  font-family: var(--f-mono);
  font-size: 0.9rem; font-weight: 600;
}
.lp-step__num::before { content: counter(lpstep, decimal-leading-zero); }
.lp-step h3 { margin-bottom: 0.4rem; }
.lp-step p { color: var(--text-2); line-height: 1.7; }

/* --- deliverable checklist --- */
.lp-checks { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.lp-check { display: flex; gap: 0.65rem; align-items: flex-start; font-size: 0.95rem; color: var(--text-2); line-height: 1.55; }
.lp-check .icon { width: 20px; height: 20px; color: var(--brand); flex-shrink: 0; margin-top: 1px; }
.lp-check strong { color: var(--text); font-weight: 600; }

/* --- platform / channel chips --- */
.lp-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.lp-chip {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  color: var(--text-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  padding: 0.4rem 0.8rem;
}
.lp-chip .icon { width: 14px; height: 14px; color: var(--brand); }

/* --- proof / stat row --- */
.lp-stats { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }
.lp-stat { text-align: left; padding: 1.35rem 1.5rem; background: var(--elevated);
           border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--sh-1); }
.lp-stat__v { font-family: var(--f-display); font-size: 2rem; font-weight: 700; line-height: 1.1; color: var(--brand); }
.lp-stat__l { margin-top: 0.5rem; font-family: var(--f-mono); font-size: 0.7rem;
              text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-3); }
.lp-stat__s { margin-top: 0.6rem; font-size: 0.85rem; color: var(--text-2); line-height: 1.55; }

/* --- case study pull --- */
.lp-proof {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--r-md);
  padding: 1.5rem 1.75rem;
}
.lp-proof__q { font-size: 1.05rem; line-height: 1.7; color: var(--ink-soft); font-style: italic; }
.lp-proof__by { margin-top: 1rem; display: flex; flex-wrap: wrap; gap: 0.35rem 0.75rem;
               font-family: var(--f-mono); font-size: 0.75rem; color: var(--text-3); }
.lp-proof__by b { color: var(--text-2); font-weight: 600; }
.lp-proof__m { margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid var(--border);
               display: flex; flex-wrap: wrap; gap: 1.5rem; }
.lp-proof__m div { display: flex; flex-direction: column; }
.lp-proof__m b { font-family: var(--f-display); font-size: 1.5rem; font-weight: 700; color: var(--brand); line-height: 1.1; }
.lp-proof__m span { margin-top: 0.25rem; font-family: var(--f-mono); font-size: 0.68rem;
                    text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-3); }

/* --- FAQ reuse (standalone pages need their own instances) --- */
.lp-faq { display: grid; gap: 0.75rem; }
.lp-faq__item { background: var(--elevated); border: 1px solid var(--border);
                border-radius: var(--r-md); overflow: hidden; transition: border-color .2s var(--ease); }
.lp-faq__item.is-open { border-color: var(--border-strong); box-shadow: var(--sh-1); }
.lp-faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  width: 100%; padding: 1.15rem 1.35rem;
  background: none; border: 0; cursor: pointer;
  font-family: var(--f-display); font-size: 1rem; font-weight: 600;
  color: var(--text); text-align: left;
  position: relative;
}
/* Same active-question marker as the homepage accordion, again as a
   pseudo-element so the panel does not shift when an item opens. */
.lp-faq__q::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.35s var(--ease);
}
.lp-faq__item.is-open .lp-faq__q::after {
  transform: scaleX(1);
}
.lp-faq__q .icon { width: 20px; height: 20px; color: var(--text-3); flex-shrink: 0;
                  transition: transform .3s var(--ease); }
.lp-faq__item.is-open .lp-faq__q .icon { transform: rotate(180deg); color: var(--brand); }
.lp-faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .35s var(--ease); }
.lp-faq__item.is-open .lp-faq__a { grid-template-rows: 1fr; }
.lp-faq__a > div { overflow: hidden; }
.lp-faq__a p { padding: 0 1.35rem 1.35rem; color: var(--text-2); line-height: 1.7; font-size: 0.95rem; }

/* --- closing CTA band --- */
.lp-cta {
  background: var(--ink);
  color: #fff;
  border-radius: var(--r-lg);
  padding: 3rem 2.5rem;
  text-align: center;
}
.lp-cta h2 { color: #fff; }
.lp-cta p { margin: 1rem auto 0; max-width: 40rem; color: rgba(255, 255, 255, .78); line-height: 1.7; }
.lp-cta__row { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; margin-top: 2rem; }
.lp-cta__note { margin-top: 1.5rem; font-family: var(--f-mono); font-size: 0.75rem; color: rgba(255, 255, 255, .78); }

/* --- related links --- */
.lp-related { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.lp-related a {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 1rem 1.15rem;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r);
  text-decoration: none;
  font-size: 0.9rem; font-weight: 500; color: var(--text);
  transition: border-color .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.lp-related a:hover { border-color: var(--brand); transform: translateX(2px); box-shadow: var(--sh-1); }
.lp-related a .icon { width: 18px; height: 18px; color: var(--brand); flex-shrink: 0; }

/* --- prose block for long-form copy --- */
.lp-prose { max-width: 70ch; }
.lp-prose h2 { margin-top: 2.75rem; margin-bottom: 0.85rem; padding-top: 1.5rem; border-top: 1px solid var(--border); scroll-margin-top: 7rem; }
.lp-prose h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.lp-prose h3 { margin-top: 1.75rem; margin-bottom: 0.5rem; }
.lp-prose p, .lp-prose li { color: var(--text-2); line-height: 1.75; }
.lp-prose p { margin-bottom: 1rem; }
.lp-prose strong { color: var(--text); font-weight: 600; }
.lp-prose ul, .lp-prose ol { margin: 0 0 1.25rem; padding-left: 1.35rem; }
.lp-prose li { margin-bottom: 0.5rem; }
.lp-prose li::marker { color: var(--brand); }
.lp-prose a { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }
.lp-prose table { width: 100%; border-collapse: collapse; margin: 1.25rem 0 1.5rem; font-size: 0.9rem; }
.lp-prose th, .lp-prose td { text-align: left; padding: 0.7rem 0.85rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.lp-prose th { font-family: var(--f-mono); font-size: 0.7rem; font-weight: 600;
               text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-3); }
.lp-prose td { color: var(--text-2); }
.lp-prose td:first-child { color: var(--text); font-weight: 500; }

@media (max-width: 640px) {
  .lp-hero { padding-block: 3rem 2.5rem; }
  .lp-hero__sub { font-size: 1rem; }
  .lp-section { padding-block: 3rem; }
  .lp-step { grid-template-columns: 2.5rem 1fr; gap: 1rem; padding: 1.15rem 1.25rem; }
  .lp-step__num { width: 2.5rem; height: 2.5rem; font-size: 0.8rem; }
  .lp-cta { padding: 2.25rem 1.5rem; }
  .lp-card { padding: 1.25rem; }
}

/* --------------------------------------------------------------------------
   Card hover lift — a brand-tinted shadow on every card in every section.

   Placed last so it wins over the individual .card-hover / .lp-card /
   .accred-card hover rules above, which each set their own neutral shadow.
   Collected here so a new card type joins this one list instead of needing a
   second rule, and so the shadow stays identical everywhere.
   -------------------------------------------------------------------------- */
.card-hover:hover,
.accred-card:hover,
.leader-card:hover,
.skill-card:hover,
.video-card:hover,
.case-card:hover,
.pillar-card:hover,
.phase-card:hover,
.price-card:hover,
.offer-card:hover,
.review-card:hover,
.lp-card:hover {
  box-shadow: var(--sh-brand-card);
  border-color: rgba(var(--brand-rgb), 0.4);
}

/* --------------------------------------------------------------------------
   Card hover — micro-zoom everywhere (Option A) + advanced feature treatment
   (Option C: rim sweep + inset brand-glow ring).

   Every declaration here uses compositor-friendly properties only
   (transform / opacity / box-shadow), matching the site's motion tokens
   (--ease, 250–350ms). Per the project convention, card hover motion is
   applied under every prefers-reduced-motion alongside the lifts already
   declared above; smooth SCROLL alone is the one user preference that is
   gated, in main.js.
   -------------------------------------------------------------------------- */

/* offer/case/lp cards host ::before/::after effects — they need a
   positioning context. offer-card already declares it; the other two are
   promoted here (static→relative never moves the box).                    */
.offer-card,
.case-card,
.lp-card {
  position: relative;
}

/* review & pillar cards had no hover transform of their own; give them the
   same micro-zoom. Their brand shadow + border arrive from the global
   card-hover rule above, so only the transform + a transition are required. */
.review-card,
.pillar-card {
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease),
    transform 0.25s var(--ease);
}
.review-card:hover {
  transform: translateY(-2px) scale(1.015);
}
.pillar-card:hover {
  transform: scale(1.015);
}

/* Option C — specular top rim fades in + inset brand ring scales open on the
   feature showcase cards. offer-card keeps its signature ::after band sweep,
   so it receives the rim only.                                              */
.offer-card::before,
.case-card::before,
.lp-card::before,
.accred-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, rgba(var(--brand-rgb), 0.5), transparent);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
  pointer-events: none;
}
.offer-card:hover::before,
.case-card:hover::before,
.lp-card:hover::before,
.accred-card:hover::before {
  opacity: 1;
}
.case-card::after,
.lp-card::after,
.accred-card::after {
  content: "";
  position: absolute;
  inset: 2px;
  border-radius: calc(var(--r-md) - 2px);
  box-shadow: inset 0 0 0 2px rgba(var(--brand-rgb), 0.18);
  opacity: 0;
  transform: scale(0.96);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
  pointer-events: none;
}
.case-card:hover::after,
.lp-card:hover::after,
.accred-card:hover::after {
  opacity: 0.85;
  transform: scale(1);
}

/* ==========================================================================
   Landing page art direction
   The service and insight pages were reading as long columns of text on flat
   white. Everything below is decoration for the existing `.lp-*` primitives:
   background layers, icon tiles and washes. No box moves, no text changes, no
   new content. All of it reuses the tokens and the artwork in
   assets/img/art/, so the landing pages and the home page now share one
   visual language instead of two.

   The cards themselves get their wash from the shared `.card-art` opt-in list
   further up this file — `.lp-card` is on that list. These rules add the
   supporting detail around them.
   ========================================================================== */

/* --- hero ------------------------------------------------------------------
   The hero already had two radial blobs. It now gets a fine grid, an orbit
   motif, a ribbon of curves and a corner bloom, stacked back to front. All four
   are `.deco` layers: out of flow, behind the copy, never a paint target for
   Largest Contentful Paint — the LCP element on these pages is still the h1. */
.lp-hero {
  background-color: var(--bg);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0) 62%, var(--surface) 100%);
}
.lp-hero .deco--orbit { opacity: 0.7; }
.lp-hero .deco--ribbon { opacity: 0.55; }
.lp-hero__mesh { z-index: 0; }
.lp-hero > .container { position: relative; z-index: 1; }

/* The eyebrow, h1 and sub sit over the art, so they carry their own weight
   rather than relying on the background being quiet everywhere. */
.lp-hero__inner { position: relative; }
.lp-hero h1 { text-wrap: balance; }
.lp-hero__sub { max-width: 46rem; }

/* A hairline rule under the hero ties it to the first section instead of
   letting the band end on nothing. */
.lp-hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background: linear-gradient(90deg, rgba(var(--brand-rgb), 0) 0%, rgba(var(--brand-rgb), 0.35) 22%, rgba(var(--brand-rgb), 0.35) 78%, rgba(var(--brand-rgb), 0) 100%);
  pointer-events: none;
}

/* --- section bands ---------------------------------------------------------
   Plain `.lp-section` is white; tinted is `--surface`. Both were flat, so both
   get a texture. Tinted carries the heavier pair because it has the lower
   contrast to work with; white carries only a faint grid. */
.lp-section {
  position: relative;
  isolation: isolate;
  background-image: var(--art-grid);
  background-size: 48px 48px;
  background-position: center;
}
/* Fade the grid away from the middle so the copy column stays clean. */
.lp-section::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(120% 78% at 50% 42%, rgba(255, 255, 255, 0.94) 26%, rgba(255, 255, 255, 0) 100%);
}
.lp-section--tint {
  background-color: var(--surface);
  background-image:
    radial-gradient(46rem 30rem at 88% -6%, var(--deco-ink) 0%, rgba(var(--brand-rgb), 0) 64%),
    radial-gradient(40rem 26rem at 6% 104%, var(--deco-violet-soft) 0%, rgba(var(--accent-rgb), 0) 64%),
    var(--art-dots);
  background-size: 100% 100%, 100% 100%, 26px 26px;
  background-repeat: no-repeat, no-repeat, repeat;
  border-block: 1px solid var(--border);
}
.lp-section--tint::before {
  background: radial-gradient(120% 78% at 50% 42%, rgba(249, 250, 251, 0.9) 26%, rgba(249, 250, 251, 0) 100%);
}

/* The section head gets an accent bar so the eyebrow/h2 pair reads as a unit
   rather than as loose text. */
.lp-section__head { position: relative; }
.lp-section__head .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.lp-section__head .eyebrow::before {
  content: "";
  width: 1.5rem;
  height: 2px;
  border-radius: var(--r-pill);
  background: var(--brand);
  opacity: 0.7;
}

/* --- card watermark glyph --------------------------------------------------
   The card's own icon, blown up into a ghost behind the copy. It is a second
   `<use>` of a symbol the card already references, so it stays topically
   related to the card without a second asset, and it is aria-hidden and
   textless, so it adds nothing a screen reader has to skip. */
.lp-card__mark {
  position: absolute;
  top: -0.75rem;
  right: -0.5rem;
  width: 7rem;
  height: 7rem;
  z-index: 0;
  pointer-events: none;
  color: var(--brand);
  opacity: 0.07;
  transform: rotate(-8deg);
  transition: opacity 0.4s var(--ease), transform 0.5s var(--ease);
}
.lp-card:hover .lp-card__mark { opacity: 0.13; transform: rotate(-4deg) scale(1.04); }
.lp-card__icon,
.lp-card h3,
.lp-card p { position: relative; z-index: 1; }

/* --- icon tile -------------------------------------------------------------
   `.lp-card__icon` was a flat 44px square. It becomes a gradient tile with an
   inner ring and a brand glow, and it lifts on hover with the card. */
.lp-card__icon {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background:
    linear-gradient(140deg, var(--brand-subtle) 0%, var(--brand-light) 52%, rgba(255, 255, 255, 0) 100%),
    var(--surface);
  box-shadow: inset 0 0 0 1px rgba(var(--brand-rgb), 0.18),
    0 6px 16px -8px rgba(var(--brand-rgb), 0.45);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.lp-card__icon::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--art-dots-brand);
  background-size: 11px 11px;
  -webkit-mask-image: linear-gradient(200deg, #000 0%, transparent 70%);
  mask-image: linear-gradient(200deg, #000 0%, transparent 70%);
  opacity: 0.5;
}
.lp-card:hover .lp-card__icon {
  transform: translateY(-2px) scale(1.06);
  box-shadow: inset 0 0 0 1px rgba(var(--brand-rgb), 0.3),
    0 10px 22px -8px rgba(var(--brand-rgb), 0.55);
}

/* --- process steps ---------------------------------------------------------
   A vertical rail joins the numbered markers, which is what makes a list of
   cards read as a sequence. Drawn on the grid container, not on a step, so no
   step needs to know it is not the last one. */
.lp-steps { position: relative; }
.lp-step { position: relative; overflow: hidden; }
.lp-step__num {
  position: relative;
  box-shadow: 0 0 0 4px var(--elevated), 0 6px 14px -6px rgba(17, 24, 39, 0.35);
  transition: background-color 0.3s var(--ease), color 0.3s var(--ease);
}
.lp-step:hover .lp-step__num { background: var(--brand); }
.lp-step__num::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  border: 1px solid rgba(var(--brand-rgb), 0.4);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
.lp-step:hover .lp-step__num::after { opacity: 1; }

/* --- stat tiles ------------------------------------------------------------
   A left accent bar and a warm top wash. `--stat-accent` is the single hook a
   caller can set to recolour a tile without a new class. */
.lp-stat {
  position: relative;
  overflow: hidden;
  border-left: 3px solid var(--stat-accent, var(--brand));
  background-image: radial-gradient(120% 100% at 100% 0%, var(--deco-ink) 0%, rgba(var(--brand-rgb), 0) 62%);
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
}
.lp-stat:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-2);
  border-color: var(--border-strong);
  border-left-color: var(--stat-accent, var(--brand));
}
.lp-stat__v { color: var(--stat-accent, var(--brand)); }

/* --- deliverable checks ----------------------------------------------------
   Each check gets a soft brand plate behind its tick so a long checklist has
   some rhythm instead of reading as one grey block of text. */
.lp-check {
  padding: 0.85rem 1rem;
  background: var(--elevated);
  border: 1px solid var(--border);
  border-radius: var(--r);
  transition: border-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.lp-check:hover { border-color: var(--brand); transform: translateX(2px); }
.lp-check .icon {
  width: 22px;
  height: 22px;
  padding: 3px;
  border-radius: var(--r-pill);
  background: var(--brand-light);
}

/* --- proof block -----------------------------------------------------------
   The pull-quote gets a quote glyph watermark and the brand hairline it
   already had, turned up a notch. */
.lp-proof { position: relative; overflow: hidden; }
.lp-proof::before {
  content: "\201C";
  position: absolute;
  top: -1.75rem;
  right: 1.25rem;
  font-family: var(--f-display);
  font-size: 9rem;
  line-height: 1;
  color: var(--brand);
  opacity: 0.08;
  pointer-events: none;
}
.lp-proof__q, .lp-proof__by, .lp-proof__m { position: relative; }

/* --- FAQ ------------------------------------------------------------------- */
.lp-faq__item { transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease); }
.lp-faq__item:hover { border-color: var(--border-strong); }
.lp-faq__q { transition: color 0.2s var(--ease); }
.lp-faq__q:hover { color: var(--brand); }

/* --- related links --------------------------------------------------------- */
.lp-related a { position: relative; overflow: hidden; }
.lp-related a::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--brand);
  transform: scaleY(0);
  transform-origin: center;
  transition: transform 0.25s var(--ease);
}
.lp-related a:hover::before { transform: scaleY(1); }
.lp-related a .icon {
  padding: 4px;
  box-sizing: content-box;
  border-radius: var(--r-pill);
  background: var(--brand-light);
  transition: background-color 0.2s var(--ease);
}
.lp-related a:hover .icon { background: var(--brand-subtle); }

/* --- closing CTA band ------------------------------------------------------
   Ink, so it takes the light-on-dark texture and an orbit motif rather than
   the light washes used on the white cards. */
.lp-cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  box-shadow: var(--sh-3);
}
.lp-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--art-hatch);
  background-size: 10px 10px;
  opacity: 0.9;
  -webkit-mask-image: radial-gradient(90% 120% at 50% 0%, #000 0%, transparent 78%);
  mask-image: radial-gradient(90% 120% at 50% 0%, #000 0%, transparent 78%);
}
.lp-cta::after {
  content: "";
  position: absolute;
  right: -140px;
  top: -160px;
  width: 480px;
  height: 480px;
  z-index: -1;
  pointer-events: none;
  background: var(--art-orbit) no-repeat center / 100% 100%;
  opacity: 0.5;
}

/* --- proof stat row -------------------------------------------------------- */
.lp-stats { position: relative; }

@media (max-width: 767px) {
  .lp-hero { background-image: none; }
  /* Only the plain white band loses its grid. `.lp-section--tint` carries the
     heavier pair of washes, which is what stops a one-column page reading as an
     empty sheet — dropping those too is what left the tinted bands blank on
     phones when this rule was written without the `:not`. */
  .lp-section:not(.lp-section--tint) { background-image: none; }
  .lp-cta::after { right: -180px; top: -120px; width: 340px; height: 340px; opacity: 0.35; }
  .lp-proof::before { font-size: 6rem; top: -1rem; right: 0.75rem; }
}

/* ==========================================================================
   Legal pages — privacy and terms

   These two are the palest pages on the site: a single white section holding a
   long run of body copy with no imagery, no icons and no frame, which is
   exactly what makes them read as an unfinished layout. Nothing below moves,
   reorders or rewrites a word. It gives the document a band, a panel, an icon
   on every numbered clause, and a contents box that looks like navigation.

   The clause icons are `<svg class="icon">` elements already sitting inside the
   `<h2>` — they are aria-hidden and carry no text, so heading order and the
   accessible name of every heading are unchanged.
   ========================================================================== */
.legal-doc {
  position: relative;
  isolation: isolate;
  background-color: var(--elevated);
  background-image:
    radial-gradient(90% 220px at 100% 0%, var(--deco-ink) 0%, rgba(var(--brand-rgb), 0) 68%),
    var(--art-grid);
  background-size: 100% 220px, 48px 48px;
  background-repeat: no-repeat, repeat;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 2rem 2.25rem 2.5rem;
  box-shadow: var(--sh-1);
  max-width: 78ch;
}

/* The meta strip above the document becomes a row of chips, so the reader can
   see at a glance how current the page is before reading a word of it. */
.legal-meta {
  gap: 0.5rem;
  margin-top: 1.25rem;
}
.legal-meta > span {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.7rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--border);
}
.legal-meta > span::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--brand);
  opacity: 0.7;
}

/* Contents box. Sticky on desktop so a reader working through twelve clauses
   can always see where they are; it drops out of the flow on mobile. */
.legal-toc {
  position: relative;
  background: var(--surface);
  background-image: var(--art-dots);
  background-size: 22px 22px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--r-md);
  padding: 1.25rem 1.5rem;
  margin: 0 0 2rem;
  box-shadow: var(--sh-1);
}
.legal-toc h2 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.85rem;
  padding: 0;
  border: 0;
  font-size: 0.72rem;
  font-family: var(--f-mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-3);
}
.legal-toc h2::before {
  content: "";
  width: 1.25rem;
  height: 2px;
  border-radius: var(--r-pill);
  background: var(--brand);
  opacity: 0.7;
}
.legal-toc li { margin-bottom: 0.45rem; }
.legal-toc a {
  color: var(--text-2);
  text-decoration: none;
  transition: color 0.2s var(--ease);
}
.legal-toc a:hover { color: var(--brand); text-decoration: underline; }

/* Numbered clauses get a leading icon so the document has a scannable rhythm
   and the eye can find the next section without reading the heading. */
.legal-doc h2 {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}
.legal-doc h2 > .icon {
  width: 22px;
  height: 22px;
  flex: none;
  padding: 4px;
  box-sizing: content-box;
  border-radius: var(--r);
  background: var(--brand-light);
  border: 1px solid var(--brand-subtle);
  color: var(--brand);
}
.legal-doc h2:first-of-type { margin-top: 1rem; }
.legal-doc h3 { position: relative; padding-left: 0.9rem; }
.legal-doc h3::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 4px;
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--brand);
  opacity: 0.6;
}

/* Tables get a tinted header and a zebra pass, which is what stops a long
   definition list reading as a wall. */
.legal-table thead th {
  background: var(--surface);
  border-bottom: 1px solid var(--border-strong);
}
.legal-table tbody tr:nth-child(even) { background: rgba(var(--slate-rgb), 0.045); }
.legal-table tbody tr { transition: background 0.2s var(--ease); }
.legal-table tbody tr:hover { background: var(--brand-light); }
.legal-table td { border-bottom: 1px solid var(--border); }

/* Lists inside the document get a marker chip so they separate from paragraphs. */
.legal-doc li { padding-left: 0.35rem; }

.legal-callout {
  box-shadow: 0 10px 24px -14px rgba(var(--brand-rgb), 0.5);
  border-left: 3px solid var(--brand);
}
.legal-callout .icon {
  width: 34px;
  height: 34px;
  padding: 7px;
  box-sizing: content-box;
  border-radius: var(--r);
  background: var(--elevated);
  border: 1px solid var(--brand-subtle);
  margin-top: 0;
}

@media (min-width: 1024px) {
  .legal-toc { position: sticky; top: 6.5rem; }
}
@media (max-width: 640px) {
  .legal-doc { padding: 1.5rem 1.25rem 2rem; }
  .legal-doc h2 { font-size: 1.15rem; gap: 0.55rem; }
  .legal-toc { padding: 1.1rem 1.15rem; }
}

/* ==========================================================================
   404
   The error page already had two soft blobs. It gains the same texture and
   motif vocabulary as the rest of the site so a dead link still looks like
   part of the brand rather than a browser default.
   ========================================================================== */
.nf-404 {
  position: relative;
  isolation: isolate;
  background-image: var(--art-grid);
  background-size: 48px 48px;
  background-position: center;
}
.nf-404::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(120% 80% at 50% 45%, rgba(255, 255, 255, 0.95) 24%, rgba(255, 255, 255, 0) 100%);
}
.nf-404__code {
  background-image: linear-gradient(180deg, var(--brand) 0%, var(--brand-hover) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  opacity: 0.16;
}
.nf-404__msg { position: relative; }
.nf-404__tags .tag { transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease); }
.nf-404__tags .tag:hover {
  border-color: var(--brand);
  transform: translateY(-2px);
  box-shadow: var(--sh-2);
}
@media (max-width: 767px) {
  .nf-404 { background-image: none; }
}

/* ==========================================================================
   `.card-art` — the shared card treatment, and the opt-in list

   A brand wash and a dot field across the top of a card, painted as background
   layers on the card itself rather than through a pseudo-element. Two reasons:

   1. `::before` and `::after` are already spoken for on these components by the
      specular top rim and the inset brand ring. A background layer cannot
      collide with either of them.
   2. It cannot move a layout box, so a card gains art without gaining height,
      and `background-color` survives because `background-image` is a separate
      longhand from the `background` shorthand that set it.

   THIS BLOCK IS LAST IN THE FILE ON PURPOSE. Every one of these components
   declares its own surface with the `background` shorthand — `.case-card` sets
   `background: #fff`, `.lp-card` sets `background: var(--elevated)`, and so on —
   and the shorthand resets `background-image` to `none`. Placed anywhere earlier
   in the sheet, all of those silently win and the art never paints. That is not
   hypothetical: the first attempt at this block sat in layer 9 and was silently
   wiped on six of the eight cards. `_artcheck.js` exists to catch exactly that,
   because no structural check can see it.

   `.card-art--ink` is the dark-surface variant — the wash inverts, because a
   light gradient on an ink card reads as a rendering fault rather than as art.
   `.card-art--tall` and `.card-art--flush` change the band height only.

   The opt-in list is declared here rather than as `class="card-art"` in the
   HTML so that every card's markup, ids, order and text stay exactly as they
   were. A component joins this list — never a section, never a bare element
   selector.

   DELIBERATELY NOT IN THE LIST, on the client's instruction, because a brand
   wash across the top edge of these reads as an orange drop shadow sitting on
   the card rather than as artwork:
     .accred-card   Official Accreditations & Certifications
     .phase-card    The Growth Protocol
     .price-card    Transparent Investment
     .offer-card    Strategic Bundles (ink, so its wash was the orange one)
   These four keep their own border, radius, hover and shadow. They are listed
   here so the omission reads as a decision rather than an oversight.

   Also absent on purpose: `.video-card` and `.review-card` already carry real
   media, and a wash behind a video poster only muddies it. */
.pillar-card,
.case-card,
.leader-card,
.lp-card,
.card-art {
  background-image:
    radial-gradient(150% var(--card-art-h, 96px) at 88% 0%, var(--deco-brand-mid) 0%, rgba(var(--brand-rgb), 0) 66%),
    radial-gradient(130% var(--card-art-h, 96px) at 4% 0%, var(--deco-violet-soft) 0%, rgba(var(--accent-rgb), 0) 64%),
    var(--art-dots-brand),
    linear-gradient(180deg, var(--brand-light) 0%, rgba(255, 255, 255, 0) 100%);
  background-repeat: no-repeat, no-repeat, repeat, no-repeat;
  background-size: 100% var(--card-art-h, 96px), 100% var(--card-art-h, 96px),
    26px 26px, 100% var(--card-art-h, 96px);
  background-position: 0 0;
}
.card-art--tall { --card-art-h: 148px; }
.card-art--flush { --card-art-h: 100%; }

/* The dark-surface variant of the same treatment. `.offer-card` was on this list
   and has been removed, so this now applies only when a component opts in with
   `card-art--ink` on its own element. */
.card-art--ink {
  background-image:
    radial-gradient(150% var(--card-art-h, 96px) at 88% 0%, rgba(var(--brand-rgb), 0.34) 0%, rgba(var(--brand-rgb), 0) 66%),
    var(--art-hatch),
    linear-gradient(180deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0) 100%);
  background-size: 100% var(--card-art-h, 96px), 10px 10px, 100% var(--card-art-h, 96px);
  background-repeat: no-repeat, repeat, no-repeat;
}

@media (max-width: 767px) {
  .card-art,
  .pillar-card,
  .case-card,
  .leader-card,
  .lp-card { --card-art-h: 72px; }
  .card-art--tall { --card-art-h: 112px; }
}
