/* ===== src/assets/css/tokens.css ===== */
/* ============================================================
   Design tokens
   Source: /docs/02-design-system.md and the canonical homepage
   mockup at /docs/mockups/homepage.html
   ============================================================ */

:root {
  /* ---- Backgrounds ---- */
  --bg-dark: #0f0f0e;
  --bg-dark-2: #131312;
  --bg-light: #ebe6db;
  --bg-light-2: #e1dccf;

  /* ---- Brand ---- */
  --orange: #DC734C;
  --orange-bright: #E88160;
  --orange-pale: #F0B580;
  --blue: #165D94;
  --blue-bright: #5BA8DC;

  /* ---- Text ----
     The "-3" tints are muted/secondary text. WCAG AA wants 4.5:1
     against the surrounding background for normal-weight body text.
     - text-light-3 (white at 0.5) on bg-dark blends to ≈5.15:1 ✓
     - text-dark-3 at 0.5 on bg-light blends to ≈3.11:1 ✗ — bumped
       to 0.65 so it lands at ≈5.06:1 with margin to spare. Still
       visibly less prominent than text-dark-2 (0.7). Lighthouse
       caught the original on .cap-problem on the services hub. */
  --text-light: #f6f3ee;
  --text-light-2: rgba(255, 255, 255, 0.72);
  --text-light-3: rgba(255, 255, 255, 0.5);
  --text-dark: #1a1815;
  --text-dark-2: rgba(26, 24, 21, 0.7);
  --text-dark-3: rgba(26, 24, 21, 0.65);

  /* ---- Borders ---- */
  --border-on-dark: rgba(255, 255, 255, 0.1);
  --border-strong-on-dark: rgba(255, 255, 255, 0.18);
  --border-on-light: rgba(0, 0, 0, 0.12);
  --border-strong-on-light: rgba(0, 0, 0, 0.2);

  /* ---- Selection ---- */
  --selection-bg: rgba(220, 115, 76, 0.3);

  /* ---- Type ----
     Web font first, metric-matched Arial fallback second (defined
     in base.css's @font-face block), then platform sans-serif.
     The Fallback entries carry ascent/descent/size overrides so
     the layout doesn't shift when the web font swap happens. */
  --font-display: "Inter Tight", "Inter Tight Fallback", system-ui, -apple-system, sans-serif;
  --font-body: "Inter", "Inter Fallback", system-ui, -apple-system, sans-serif;
  --weight-regular: 400;
  --weight-medium: 500;

  /* Letter spacing presets */
  --tracking-display: -0.035em;
  --tracking-h3: -0.02em;
  --tracking-stat: -0.04em;
  --tracking-eyebrow: 0.2em;
  --tracking-strip: 0.18em;

  /* ---- Layout ---- */
  --container-max: 1200px;
  --container-pad: 48px;
  --container-pad-mobile: 24px;
  --section-pad-y: 96px;
  --section-pad-y-mobile: 64px;

  /* Nav height. Hero sections pull themselves up by -var(--nav-h) so the
     transparent over-hero nav can sit on top of the hero's topo edge to
     edge. Keep in sync with .nav padding + logo height in nav.css. */
  --nav-h: 78px;

  /* ---- Radii ---- */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-card: 10px;
  --radius-card-lg: 14px;

  /* ---- Easing ---- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* ---- Z-index scale ---- */
  --z-nav: 50;
  --z-modal: 100;
  --z-modal-backdrop: 99;
}

/* Mobile nav: padding drops to 16/16, but the 40px hamburger toggle sets
   the flex-row height, so total stays 72px across all mobile widths. */
@media (max-width: 760px) {
  :root { --nav-h: 72px; }
}

::selection {
  background: var(--selection-bg);
  color: inherit;
}

/* ===== src/assets/css/base.css ===== */
/* ============================================================
   Base styles
   Self-hosted fonts + reset + body + typography + buttons +
   container + reveal
   ============================================================ */

/* ---- Self-hosted web fonts ----
   Inter (body) and Inter Tight (display) shipped as latin-subset
   variable WOFF2s from /assets/fonts/. Replaces the earlier
   render-blocking Google Fonts <link> chain. The two preload tags
   in base.njk point at the same files so they're in flight before
   this CSS is parsed.

   font-display: swap → render with the fallback immediately and
   swap to the web font once it loads. The "<family> Fallback"
   faces below carry metric overrides matched to Arial so the
   fallback occupies the same vertical space as the web font; the
   swap doesn't trigger a layout shift. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/inter-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Inter Tight";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/inter-tight-latin.woff2") format("woff2");
}

/* Metric-matched fallbacks. Values from font-style-matcher/Capsize
   for Inter / Inter Tight against Arial — close enough that a
   regular paragraph or H1 occupies the same vertical space before
   and after the web font swaps in, eliminating CLS from the swap. */
@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 107.40%;
  ascent-override: 90.00%;
  descent-override: 22.43%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Inter Tight Fallback";
  src: local("Arial");
  size-adjust: 105.78%;
  ascent-override: 91.40%;
  descent-override: 22.78%;
  line-gap-override: 0%;
}

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

html {
  scroll-behavior: smooth;
}

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

body {
  font-family: var(--font-body);
  font-weight: var(--weight-regular);
  background: var(--bg-light);
  color: var(--text-dark);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  line-height: 1.6;
}

body.modal-open {
  overflow: hidden;
}

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

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

button {
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  background: none;
  border: none;
  color: inherit;
}

ul, ol {
  list-style: none;
}

main {
  display: block;
}

#main:focus { outline: none; }

/* ---- Display headings ---- */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-display);
  line-height: 1.15;
  color: inherit;
}
h3 { letter-spacing: var(--tracking-h3); }

/* ---- Container ---- */
.container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-pad);
}

@media (max-width: 760px) {
  .container { padding: 0 var(--container-pad-mobile); }
}

/* ---- Eyebrows ---- */
.eyebrow {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-weight: var(--weight-medium);
}

/* ---- Orange gradient text accent (on dark) ---- */
.accent {
  background: linear-gradient(135deg, var(--orange-pale) 0%, var(--orange) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---- Richer orange accent for headings on light backgrounds ---- */
.accent-light {
  background: linear-gradient(135deg, var(--orange) 0%, #B85738 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---- Inline arrow (for "Learn more →" style links) ---- */
.arrow {
  display: inline-block;
  transition: transform 0.3s var(--ease-out);
}

/* ---- Buttons ---- */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 24px;
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: var(--weight-medium);
  background: linear-gradient(180deg, var(--orange-bright) 0%, var(--orange) 100%);
  color: #0c0c0c;
  border: none;
  box-shadow: 0 0 0 1px rgba(220, 115, 76, 0.3),
              0 8px 24px -8px rgba(220, 115, 76, 0.4);
  transition: transform 0.2s var(--ease-out), box-shadow 0.3s ease;
  cursor: pointer;
  text-decoration: none;
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px rgba(220, 115, 76, 0.5),
              0 12px 32px -8px rgba(220, 115, 76, 0.5);
}

.btn-secondary-dark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 22px;
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: var(--weight-medium);
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-light);
  border: 1px solid rgba(255, 255, 255, 0.32);
  transition: background 0.2s ease, border-color 0.2s ease;
  cursor: pointer;
  text-decoration: none;
}
.btn-secondary-dark:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.5);
}
.btn-secondary-dark:hover .arrow { transform: translateX(3px); }

.btn-secondary-light {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 22px;
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: var(--weight-medium);
  background: transparent;
  color: var(--text-dark);
  border: 1px solid var(--border-strong-on-light);
  transition: background 0.2s ease, border-color 0.2s ease;
  cursor: pointer;
  text-decoration: none;
}
.btn-secondary-light:hover {
  background: rgba(0, 0, 0, 0.05);
  border-color: rgba(0, 0, 0, 0.32);
}
.btn-secondary-light:hover .arrow { transform: translateX(3px); }

.btn-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: var(--weight-medium);
  cursor: pointer;
  transition: opacity 0.2s ease;
}
.btn-link:hover { opacity: 0.75; }
.btn-link:hover .arrow { transform: translateX(3px); }

/* ---- Reveal-on-scroll ----
   Targets get .reveal; IntersectionObserver toggles .in.
   Opacity-only — the previous translateY(20px) → translateY(0)
   pattern visually shifted things upward, which read fine but
   Lighthouse flagged adjacent layout content as part of the
   shift. Dropping the transform keeps the gentle fade-in and
   removes the CLS contribution. Per /docs/02-design-system.md:
   0.9s, ease-out curve, 0.08s sequenced delays. */
.reveal {
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
}
.reveal.in {
  opacity: 1;
}
.reveal.delay-1 { transition-delay: 0.08s; }
.reveal.delay-2 { transition-delay: 0.16s; }
.reveal.delay-3 { transition-delay: 0.24s; }
.reveal.delay-4 { transition-delay: 0.32s; }
.reveal.delay-5 { transition-delay: 0.40s; }
.reveal.delay-6 { transition-delay: 0.48s; }

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transition: none;
  }
  .arrow { transition: none; }
}

/* ---- SVG noise overlay (for dark sections) ---- */
.noise {
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/><feColorMatrix values='0 0 0 0 0.95 0 0 0 0 0.88 0 0 0 0 0.78 0 0 0 0.55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.7'/></svg>");
  opacity: 0.05;
  pointer-events: none;
  z-index: 1;
  mix-blend-mode: overlay;
}

/* ---- Skip to main link (a11y) ---- */
.skip-link {
  position: absolute;
  top: -100px;
  left: 16px;
  background: var(--bg-dark);
  color: var(--text-light);
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  z-index: 1000;
  transition: top 0.2s var(--ease-out);
}
.skip-link:focus { top: 16px; }

/* ===== src/assets/css/components/sections.css ===== */
/* ============================================================
   Section primitives
   The .section / .section-light / .section-dark / .section-header
   pattern repeats across every Phase 1 page.
   Source: /docs/mockups/homepage-v2.html.
   ============================================================ */

.section {
  padding: var(--section-pad-y) 0;
  position: relative;
}

.section-light {
  background: var(--bg-light);
  color: var(--text-dark);
}
.section-light .eyebrow { color: var(--blue); }

/* Same as .section-light but on the deeper cream background. Used
   when two light sections sit adjacent and the rhythm needs
   visible contrast (Process, Services hub, others). */
.section-tinted {
  background: var(--bg-light-2);
  color: var(--text-dark);
}
.section-tinted .eyebrow { color: var(--blue); }

.section-dark {
  background:
    radial-gradient(ellipse 700px 500px at 90% 0%, rgba(22, 93, 148, 0.10), transparent 60%),
    radial-gradient(ellipse 600px 400px at 0% 100%, rgba(220, 115, 76, 0.06), transparent 60%),
    var(--bg-dark);
  color: var(--text-light);
  position: relative;
  overflow: hidden;
}
.section-dark .noise { opacity: 0.04; z-index: 1; }
.section-dark .container { position: relative; z-index: 2; }
.section-dark .eyebrow { color: var(--blue-bright); }
.section-dark h2 { color: var(--text-light); }
.section-dark .lede { color: var(--text-light-2); }

.section-header {
  max-width: 720px;
  margin-bottom: 56px;
}
.section-header h1,
.section-header h2 {
  font-size: 40px;
  line-height: 1.15;
  margin-top: 14px;
  margin-bottom: 16px;
  letter-spacing: var(--tracking-display);
}
.section-header .lede {
  font-size: 17px;
  line-height: 1.65;
  color: var(--text-dark-2);
}
.section-dark .section-header .lede { color: var(--text-light-2); }

/* Centered section head variant — used on service detail pages where
   sections call attention back to the middle column. Sibling to the
   left-aligned .section-header above; same outer dimensions, different
   alignment + spacing. */
.section-head {
  max-width: 720px;
  margin: 0 auto 56px;
  text-align: center;
}
.section-head .eyebrow {
  display: block;
  margin-bottom: 18px;
}
.section-head h2 {
  font-size: 38px;
  line-height: 1.15;
  margin-bottom: 18px;
  color: var(--text-dark);
}
.section-head p {
  font-size: 17px;
  line-height: 1.6;
  color: var(--text-dark-2);
}
.section-dark .section-head h2 { color: var(--text-light); }
.section-dark .section-head p { color: var(--text-light-2); }

/* "See the full process →" style after-section link button. */
.section-cta {
  margin-top: 48px;
  text-align: center;
}
.section-cta-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 28px;
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: var(--weight-medium);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-light);
  border: 1px solid rgba(255, 255, 255, 0.22);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s var(--ease-out);
}
.section-cta-link:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.4);
  transform: translateY(-1px);
}
.section-cta-link:hover .arrow { transform: translateX(3px); }

.section-cta-link.on-light {
  background: rgba(0, 0, 0, 0.04);
  color: var(--text-dark);
  border-color: var(--border-on-light);
}
.section-cta-link.on-light:hover {
  background: rgba(0, 0, 0, 0.06);
  border-color: var(--border-strong-on-light);
}

@media (max-width: 980px) {
  .section-header h1,
  .section-header h2 { font-size: 32px; }
}
@media (max-width: 760px) {
  .section { padding: var(--section-pad-y-mobile) 0; }
  .section-header { margin-bottom: 36px; }
  .section-header h1,
  .section-header h2 { font-size: 28px; }
  .section-header .lede { font-size: 15px; }
}

/* ===== src/assets/css/components/strip.css ===== */
/* ============================================================
   Horizontal strip — dark band sandwiched between sections.
   Used for:
   - Homepage social-proof strip (client logos)
   - About certifications strip (cert badges)
   - Service detail page credibility strips (Phase D continued)

   Inner content varies; the skeleton (dark bg, edge fades, single
   row layout) stays the same.
   ============================================================ */

.strip {
  background: var(--bg-dark-2);
  border-top: 1px solid var(--border-on-dark);
  border-bottom: 1px solid var(--border-on-dark);
  padding: 28px 0;
  position: relative;
  z-index: 2;
  overflow: hidden;
  color: var(--text-light-2);
}

.strip::before,
.strip::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 80px;
  z-index: 2;
  pointer-events: none;
}
.strip::before {
  left: 0;
  background: linear-gradient(90deg, var(--bg-dark-2) 0%, transparent 100%);
}
.strip::after {
  right: 0;
  background: linear-gradient(-90deg, var(--bg-dark-2) 0%, transparent 100%);
}

.strip-inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 48px;
}

.strip-label {
  font-size: 11px;
  letter-spacing: var(--tracking-strip);
  text-transform: uppercase;
  color: var(--text-light-3);
  white-space: nowrap;
}

@media (max-width: 760px) {
  .strip { padding: 22px 0; }
  .strip-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 0 var(--container-pad-mobile);
  }
}

/* ===== src/assets/css/components/hero-topo.css ===== */
/* ============================================================
   Hero topo — photographic dark-blue topo background used on
   every page hero except the homepage.

   Per /docs/02-design-system.md, all content page heroes (About,
   Process, Services hub, service detail pages, Pricing, Why
   Trailguide, FAQs) use this same photographic topo. The
   homepage keeps its own .home-hero-topo (also photographic but
   at higher opacity / different drift tuning) — that legacy
   class can be folded into this one if a future refactor wants
   the consolidation.

   Usage:
     <section class="some-hero">
       <div class="hero-topo" aria-hidden="true"></div>
       ...
     </section>

   The host hero section needs `position: relative` and
   `overflow: hidden`; this element is absolutely positioned to
   fill it. Hero content above this should sit on its own
   stacking context (z-index: 2 or higher).
   ============================================================ */

.hero-topo {
  position: absolute;
  inset: -10%;
  background-image: var(--topo-dark-blue);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0.5;
  z-index: 0;
  pointer-events: none;
  animation: heroTopoDrift 24s ease-in-out infinite alternate;
}

@keyframes heroTopoDrift {
  0%   { transform: translate3d(-2%, -1%, 0) scale(1.10) rotate(-0.3deg); }
  50%  { transform: translate3d(2%, 1%, 0)  scale(1.13) rotate(0.2deg); }
  100% { transform: translate3d(-1%, 2%, 0) scale(1.11) rotate(-0.2deg); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-topo {
    animation: none;
    transform: scale(1.08);
  }
}

/* ===== src/assets/css/components/topo-callback.css ===== */
/* ============================================================
   Light-gray topo callback — decorative photographic topo image
   drifting behind content on cream-background sections.

   Used as a page-intro background on hero-less utility pages
   (Services hub, Pricing) and as a mid-page callback on service
   detail pages (e.g. the "How we sequence the work" section on
   the Implementation page). Source image is the same
   hero-topo-light-gray.jpg as the dark hero topo, just rendered
   at ~0.5 opacity over cream rather than 0.85 over navy.

   Usage:
     <section class="some-section">              <!-- relative + overflow-hidden -->
       <div class="topo-callback" aria-hidden="true"></div>
       <div class="container">…</div>            <!-- z-index 2+ above the topo -->
     </section>

   The host section needs `position: relative` and `overflow: hidden`;
   this element is absolutely positioned to fill it. Section content
   should sit on its own stacking context above the topo (z-index 2+).
   ============================================================ */

.topo-callback {
  position: absolute;
  inset: -6%;
  background-image: var(--topo-light-gray);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0.5;
  z-index: 0;
  pointer-events: none;
  animation: topoCallbackDrift 38s ease-in-out infinite alternate;
}

@keyframes topoCallbackDrift {
  0%   { transform: translate3d(-1.5%, -1%, 0) scale(1.06) rotate(-0.2deg); }
  50%  { transform: translate3d(1.5%, 1%, 0)  scale(1.08) rotate(0.15deg); }
  100% { transform: translate3d(-0.5%, 1.5%, 0) scale(1.07) rotate(-0.15deg); }
}

@media (prefers-reduced-motion: reduce) {
  .topo-callback {
    animation: none;
    transform: scale(1.05);
  }
}

/* ===== src/assets/css/components/industries.css ===== */
/* ============================================================
   Industries grid — 3-up cards with icon, headline, body, and
   tag pills. Used on the homepage and the services hub. The
   markup is identical between the two; copy varies per page.

   Source: /docs/mockups/homepage-v2.html and
           /docs/mockups/services-hub.html.

   Lifted from pages/homepage.css when services-hub became the
   second use. The footnote variant on the homepage uses the
   `.industries-footnote-icon` block (an info-circle inside a
   blue chip); the services hub uses a plainer text footnote
   without the icon. Both styles are below.
   ============================================================ */

.ind-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.ind-card {
  background: var(--bg-light);
  border: 1px solid var(--border-on-light);
  border-radius: var(--radius-card-lg);
  padding: 32px 28px;
  transition: transform 0.3s var(--ease-out), border-color 0.3s ease, box-shadow 0.3s ease;
}
.ind-card:hover {
  transform: translateY(-3px);
  border-color: var(--border-strong-on-light);
  box-shadow: 0 12px 32px -12px rgba(26, 24, 21, 0.12);
}

.ind-icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-card);
  background: rgba(220, 115, 76, 0.1);
  color: var(--orange);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 22px;
}
.ind-card:nth-child(2) .ind-icon {
  background: rgba(22, 93, 148, 0.1);
  color: var(--blue);
}
.ind-icon svg { width: 22px; height: 22px; }

.ind-card h3 {
  font-size: 22px;
  line-height: 1.2;
  margin-bottom: 14px;
  letter-spacing: -0.025em;
}

.ind-card p {
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-dark-2);
  margin-bottom: 22px;
}

.ind-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.ind-tag {
  font-size: 11px;
  padding: 5px 11px;
  border: 1px solid var(--border-on-light);
  border-radius: 999px;
  color: var(--text-dark-2);
  background: rgba(0, 0, 0, 0.02);
  transition: background 0.2s ease, border-color 0.2s ease;
}
.ind-tag:hover {
  background: rgba(0, 0, 0, 0.04);
  border-color: var(--border-strong-on-light);
}

/* ---- Footnote variants ---- */

/* Homepage: callout box with an info-icon chip on the left. */
.industries-footnote {
  margin: 40px auto 0;
  padding: 24px 32px;
  display: flex;
  align-items: center;
  gap: 18px;
  background: rgba(22, 93, 148, 0.05);
  border: 1px solid rgba(22, 93, 148, 0.18);
  border-radius: 12px;
  max-width: 880px;
}
.industries-footnote-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  background: rgba(22, 93, 148, 0.12);
  color: var(--blue);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.industries-footnote-icon svg { width: 18px; height: 18px; }
.industries-footnote p {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--text-dark-2);
  margin: 0;
}
.industries-footnote strong {
  color: var(--text-dark);
  font-weight: var(--weight-medium);
}

/* Services hub: plain centered paragraph, no chip, with an
   inline "Get in touch" link that opens the consultation modal. */
.industries-footnote--plain {
  display: block;
  margin: 36px auto 0;
  padding: 0;
  background: none;
  border: none;
  max-width: 720px;
  text-align: center;
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-dark-3);
}
.industries-footnote--plain a {
  color: var(--blue);
  text-decoration: none;
  border-bottom: 1px solid rgba(22, 93, 148, 0.3);
  transition: border-color 0.2s ease, color 0.2s ease;
  cursor: pointer;
}
.industries-footnote--plain a:hover {
  border-bottom-color: var(--blue);
  color: var(--orange);
}

/* ---- Responsive ---- */

@media (max-width: 980px) {
  .ind-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 760px) {
  .ind-grid { grid-template-columns: 1fr; }
  .industries-footnote {
    flex-direction: column;
    align-items: flex-start;
    padding: 22px 24px;
    gap: 14px;
  }
}

/* ===== src/assets/css/components/cred-strip.css ===== */
/* ============================================================
   Credibility strip — three Zoho badges in a tight horizontal
   band beneath the hero of every service detail page.

   Content lives in src/_data/credibility.yml; markup in
   src/_includes/components/cred-strip.njk. The strip is a fixed
   sitewide component — no per-page variants.

   Each item is a badge with a single-line credential name beneath
   it. Round Creator badges render at 140×140 (their 1:1 source
   aspect). The Premium Partner badge uses a pre-trimmed PNG (200×59
   content box) and renders at 140 tall, natural-width, so it sits
   as a wider rectangle alongside the round badges. Flex layout
   (not equal-column grid) accommodates the asymmetric widths.
   ============================================================ */

.cred-strip {
  background: var(--bg-dark-2);
  border-top: 1px solid var(--border-on-dark);
  border-bottom: 1px solid var(--border-on-dark);
  padding: 22px 0;
}

.cred-strip-grid {
  display: flex;
  justify-content: space-around;
  align-items: center;
  gap: 32px;
  flex-wrap: wrap;
}

.cred-strip-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  min-width: 0;
}

/* The Eleventy Image shortcode wraps the badge in a <picture> with
   the class on the rendered <img>. Round badges render at their 1:1
   source aspect (140×140). The .cred-strip-badge--wide modifier
   keeps the same height; width comes from the trimmed source PNG's
   natural ~3.4:1 aspect, so the Premium Partner reads as a wider
   rectangle on the same center line as the round badges. */
.cred-strip-badge {
  height: 140px;
  width: auto;
  flex-shrink: 0;
  object-fit: contain;
}
.cred-strip-badge--wide {
  /* Premium Partner sized by width rather than height. The trimmed
     source PNG is ~3.4:1, so 180px wide lands at ~53px tall — visibly
     shorter than the 140px round badges but balanced in visual mass.
     Row vertical centering (align-items: center on .cred-strip-grid)
     keeps all three items on the same horizontal center line. */
  height: auto;
  width: auto;
  max-width: 180px;
}

.cred-strip-content h3 {
  font-size: 14.5px;
  font-weight: var(--weight-medium);
  letter-spacing: -0.01em;
  color: var(--text-light);
  line-height: 1.3;
}

@media (max-width: 980px) {
  .cred-strip { padding: 28px 0; }
  .cred-strip-grid {
    flex-direction: column;
    gap: 28px;
  }
  .cred-strip-badge { height: 110px; }
  /* Stays width-driven on mobile too — restate height:auto so the base
     mobile-badge height (110) doesn't win on source-order. */
  .cred-strip-badge--wide { height: auto; }
}

/* ===== src/assets/css/components/use-cases.css ===== */
/* ============================================================
   Use-cases grid — 3-column card grid used on service detail
   pages to enumerate the common starting points / common
   builds for the service. Each card has an icon chip, title,
   italic customer-voice quote, and description. Cards alternate
   orange/blue accent on the icon by position (odd → orange,
   even → blue) for rhythm.

   Lifted from pages/services/implementation.css when Creator
   (the second service page) landed with the same component.

   Page-specific options:
   - Wrap in `<section class="section section-light">` for the
     standard light treatment, or `.section-tinted` if a deeper
     cream is needed (e.g. when the use cases sit next to other
     light sections).
   ============================================================ */

.uc-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.uc-card {
  background: rgba(255, 255, 255, 0.45);
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: var(--radius-card-lg);
  padding: 28px;
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s ease, border-color 0.3s ease;
}
.uc-card:hover {
  transform: translateY(-3px);
  border-color: rgba(0, 0, 0, 0.16);
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.15);
}

.uc-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
}
.uc-card:nth-child(odd) .uc-icon {
  background: rgba(220, 115, 76, 0.12);
  color: var(--orange);
}
.uc-card:nth-child(even) .uc-icon {
  background: rgba(22, 93, 148, 0.12);
  color: var(--blue);
}
.uc-icon svg { width: 22px; height: 22px; }

.uc-card h3 {
  font-size: 19px;
  color: var(--text-dark);
  margin-bottom: 10px;
  line-height: 1.3;
  letter-spacing: var(--tracking-h3);
}
.uc-quote {
  font-size: 13px;
  color: var(--text-dark-3);
  font-style: italic;
  margin-bottom: 12px;
  line-height: 1.5;
}
.uc-desc {
  font-size: 14px;
  color: var(--text-dark-2);
  line-height: 1.6;
}

@media (max-width: 980px) {
  .uc-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .uc-grid { grid-template-columns: 1fr; }
  .uc-card { padding: 24px 22px; }
}

/* ===== src/assets/css/components/svc-process.css ===== */
/* ============================================================
   Service-page process strip — 4-up grid of step cards used on
   service detail pages to walk through how an engagement runs.
   Each step has a small label ("Step 1"), title, and short body.
   Cards alternate accent — typically blue / blue / orange /
   orange — driven off explicit `.proc-step--blue` /
   `.proc-step--orange` modifier classes per step.

   Distinct from the homepage process grid (which uses different
   styling and lives in pages/homepage.css). This component is
   service-page-specific.

   Lifted from pages/services/implementation.css when Creator
   (the second service page) landed with the same component.
   ============================================================ */

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

.proc-step {
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: var(--radius-card);
  padding: 26px 24px 28px;
  position: relative;
}
.proc-step--blue { border-top: 3px solid var(--blue); }
.proc-step--orange { border-top: 3px solid var(--orange); }

.proc-step-num {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-dark-3);
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.proc-step-num .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--orange);
}
.proc-step--blue .proc-step-num .dot { background: var(--blue); }

.proc-step h3 {
  font-size: 18px;
  color: var(--text-dark);
  margin-bottom: 10px;
  line-height: 1.25;
  letter-spacing: var(--tracking-h3);
}
.proc-step p {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-dark-2);
}

@media (max-width: 980px) {
  .proc-steps { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .proc-steps { grid-template-columns: 1fr; }
}

/* ===== src/assets/css/components/case-study.css ===== */
/* ============================================================
   "Standard 3-stat" case study card — dark section, prose body
   on the left + 3 stat callouts on the right. Per the design
   system this is the default case study treatment for service
   detail pages. Subtle topo line accents are inlined as SVG in
   the page template (kept as markup rather than CSS so each
   page can tweak path geometry).

   Lifted from pages/services/implementation.css when Creator
   (the second service page) landed with the same component.

   Page-specific options:
   - The disclaimer can render inside .cs-results (Implementation)
     or inside .cs-body as a trailing paragraph (Creator). Both
     placements pick up `.cs-disclaimer` styling.
   ============================================================ */

.cs-section {
  background: var(--bg-dark);
  color: var(--text-light);
  position: relative;
  overflow: hidden;
}
.cs-topo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.cs-section .container { position: relative; z-index: 2; }

.cs-wrap {
  max-width: 1000px;
  margin: 0 auto;
}

.cs-card {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 56px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, rgba(255, 255, 255, 0.02) 100%);
  border: 1px solid var(--border-on-dark);
  border-radius: 16px;
  padding: 48px;
}
.cs-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--orange-bright);
  font-weight: var(--weight-medium);
  margin-bottom: 20px;
}
.cs-card h2 {
  font-size: 30px;
  color: var(--text-light);
  margin-bottom: 22px;
  line-height: 1.2;
}
.cs-body p {
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--text-light-2);
  margin-bottom: 16px;
}
.cs-body p:last-child { margin-bottom: 0; }
.cs-body strong { color: var(--text-light); font-weight: var(--weight-medium); }

.cs-results {
  border-left: 1px solid var(--border-on-dark);
  padding-left: 40px;
  display: flex;
  flex-direction: column;
  gap: 28px;
}
.cs-result-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-light-3);
  margin-bottom: 8px;
  font-weight: var(--weight-medium);
}
.cs-result-num {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: var(--weight-medium);
  line-height: 1;
  margin-bottom: 6px;
  letter-spacing: var(--tracking-stat);
}
.cs-result:nth-child(odd) .cs-result-num { color: var(--orange-bright); }
.cs-result:nth-child(even) .cs-result-num { color: var(--blue-bright); }
.cs-result-text {
  font-size: 13.5px;
  color: var(--text-light-2);
  line-height: 1.5;
}
.cs-disclaimer {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-light-3);
  font-style: italic;
}

/* Inline "read the full case study" link rendered below the body
   paragraphs of a service-page case study block. Optional, opt-in
   per service via the singleton's case_study.read_more field. */
.cs-read-more {
  margin: 18px 0 0;
  font-size: 14px;
  line-height: 1.4;
}
.cs-read-more a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--orange-bright);
  text-decoration: none;
  font-weight: var(--weight-medium);
  border-bottom: 1px solid rgba(232, 129, 96, 0.35);
  transition: color 0.2s ease, border-color 0.2s ease;
}
.cs-read-more a:hover {
  color: var(--orange-pale);
  border-bottom-color: var(--orange-pale);
}
.cs-read-more .arrow {
  transition: transform 0.2s var(--ease-out);
}
.cs-read-more a:hover .arrow {
  transform: translateX(3px);
}

@media (max-width: 980px) {
  .cs-card { grid-template-columns: 1fr; gap: 36px; padding: 36px 28px; }
  .cs-results {
    border-left: none;
    border-top: 1px solid var(--border-on-dark);
    padding-left: 0;
    padding-top: 28px;
  }
}

@media (max-width: 640px) {
  .cs-card { padding: 28px 22px; }
  .cs-card h2 { font-size: 24px; }
}

/* ===== src/assets/css/components/svc-hero.css ===== */
/* ============================================================
   Service detail page hero — 2-col grid: copy on the left,
   "what we mean by ___" side card on the right. Photographic
   dark-blue topo behind via the shared .hero-topo component
   plus a soft top-and-bottom darkening overlay.

   Lifted from pages/services/{implementation,creator}.css when
   Portals (the third service detail page) landed with the same
   shape. Every service detail page uses this hero pattern.

   Usage:
     <section class="svc-hero">
       <div class="hero-topo" aria-hidden="true"></div>
       <div class="noise" aria-hidden="true"></div>
       <div class="svc-hero-inner">
         <div class="container">
           <div class="svc-hero-grid">
             <div class="svc-hero-content">…</div>
             <aside class="svc-hero-side">
               <div class="what-card">…</div>
             </aside>
           </div>
         </div>
       </div>
     </section>
   ============================================================ */

.svc-hero {
  position: relative;
  overflow: hidden;
  background-color: #0a1828;
  background-image:
    radial-gradient(ellipse 700px 450px at 88% 10%, rgba(220, 115, 76, 0.18), transparent 65%),
    radial-gradient(ellipse 600px 420px at 5% 95%, rgba(22, 93, 148, 0.18), transparent 65%);
  color: var(--text-light);
  /* Pull the hero up behind the transparent nav-wrap--over-hero so the
     topo runs edge-to-edge. Stays in sync with --nav-h in tokens.css. */
  margin-top: calc(var(--nav-h) * -1);
  padding-top: var(--nav-h);
}

/* Soft top-and-bottom darkening so text on the topo reads cleanly. */
.svc-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 24, 40, 0.35) 0%, rgba(10, 24, 40, 0.15) 50%, rgba(10, 24, 40, 0.55) 100%);
  z-index: 1;
  pointer-events: none;
}

.svc-hero-inner {
  position: relative;
  z-index: 2;
  padding: 64px 0 96px;
}

.svc-hero-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 64px;
  align-items: start;
}

.svc-hero-content {
  max-width: 640px;
  position: relative;
  z-index: 3;
}
.svc-hero .eyebrow {
  color: var(--orange-bright);
  margin-bottom: 24px;
  display: block;
}
.svc-hero h1 {
  font-size: 52px;
  line-height: 1.05;
  color: var(--text-light);
  margin-bottom: 24px;
}

.svc-hero-lede {
  font-size: 19px;
  line-height: 1.55;
  color: var(--text-light-2);
  margin-bottom: 32px;
}

.svc-hero-actions {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
}

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

/* "What we mean by ___" side card. Glassy, sits over the hero topo. */
.what-card {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-card-lg);
  padding: 32px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.what-card-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--orange-bright);
  font-weight: var(--weight-medium);
  margin-bottom: 18px;
}
.what-card h2 {
  font-size: 22px;
  line-height: 1.25;
  color: var(--text-light);
  margin-bottom: 16px;
}
.what-card p {
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--text-light-2);
  margin-bottom: 14px;
}
.what-card p:last-of-type { margin-bottom: 22px; }

.what-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.what-tag {
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 11.5px;
  color: var(--text-light-2);
  letter-spacing: 0.02em;
}

@media (max-width: 980px) {
  .svc-hero-grid { grid-template-columns: 1fr; gap: 40px; }
  .svc-hero h1 { font-size: 40px; }
}

@media (max-width: 640px) {
  .svc-hero-inner { padding: 48px 0 72px; }
  .svc-hero h1 { font-size: 34px; }
  .svc-hero-lede { font-size: 16px; }
}

/* ===== src/assets/css/components/svc-hero-label.css ===== */
/* ============================================================
   Service-page hero identifier — icon + label group sitting
   above the H1 on service detail pages, in place of the legacy
   monospace eyebrow. The icon is a 20px Lucide glyph in a 36px
   orange-tinted rounded-square container; the label renders in
   Inter Tight at 32px / 500 / -0.02em.

   Lifted from pages/services/implementation.css when the icon +
   label treatment rolled out across all six service detail pages.

   Usage:
     {% from "components/svc-hero-label.njk" import serviceHeroLabel %}
     {{ serviceHeroLabel('implementation', 'Implementation and configuration') }}

   Markup the macro emits (kept here for reference):
     <div class="svc-hero-label reveal in">
       <span class="svc-hero-label-icon" aria-hidden="true">
         <svg …>…</svg>
       </span>
       <span class="svc-hero-label-text">…</span>
     </div>
   ============================================================ */

.svc-hero-label {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 32px;
}

.svc-hero-label-icon {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 8px;
  background: rgba(220, 115, 76, 0.14);
  border: 1px solid rgba(220, 115, 76, 0.3);
  color: var(--orange);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.svc-hero-label-icon svg { width: 20px; height: 20px; }

.svc-hero-label-text {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: var(--weight-medium);
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--text-light);
}

@media (max-width: 640px) {
  .svc-hero-label { gap: 12px; margin-bottom: 24px; }
  .svc-hero-label-icon { width: 32px; height: 32px; }
  .svc-hero-label-icon svg { width: 18px; height: 18px; }
  .svc-hero-label-text { font-size: 24px; }
}

/* ===== src/assets/css/components/capabilities.css ===== */
/* ============================================================
   Service-page capabilities grid — 10-row 2-col grid on dark.
   Plain-language list of what a service can do, with each row
   tinted orange or blue via .cap-row--orange / .cap-row--blue
   modifier classes for rhythm.

   Lifted from pages/services/creator.css when Portals (the third
   service detail page) landed with the same shape. Used on
   Creator and Portals; Implementation does not have this section.

   Page-specific decoration (e.g. inline topo-line SVG behind the
   grid on Creator) stays in the page CSS file. The .cap-section
   container itself is shared.
   ============================================================ */

.cap-section {
  background: var(--bg-dark);
  color: var(--text-light);
  position: relative;
  overflow: hidden;
}
.cap-section .container {
  position: relative;
  z-index: 2;
}

.cap-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.cap-row {
  display: flex;
  gap: 18px;
  padding: 22px 24px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--border-on-dark);
  border-radius: var(--radius-card);
  transition: background 0.3s ease, border-color 0.3s ease;
}
.cap-row:hover {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.14);
}

.cap-row-icon {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cap-row-icon svg { width: 20px; height: 20px; }

.cap-row--orange .cap-row-icon {
  background: rgba(220, 115, 76, 0.14);
  color: var(--orange-bright);
}
.cap-row--blue .cap-row-icon {
  background: rgba(22, 93, 148, 0.18);
  color: var(--blue-bright);
}

.cap-row-content h3 {
  font-size: 16px;
  color: var(--text-light);
  margin-bottom: 4px;
  letter-spacing: var(--tracking-h3);
}
.cap-row-content p {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-light-2);
}

@media (max-width: 980px) {
  .cap-grid { grid-template-columns: 1fr; }
}

/* ===== src/assets/css/components/related-services.css ===== */
/* ============================================================
   Related-services rail — 2-up callout cards on light. Used at
   the bottom of service detail pages to point at sibling services.
   First card renders blue, second orange (driven by the
   .related-card--blue / .related-card--orange modifiers added in
   the page template).

   Lifted from pages/services/implementation.css when Integrations
   (the fourth service detail page) landed with the same shape.
   Distinct from the single full-width related-service callout
   used by Creator and Portals — that pattern is still page-
   specific until naming gets reconciled.

   Usage:
     <section class="section section-light related-section">
       <div class="container">
         <div class="related-grid">
           <a class="related-card related-card--blue" href="…">
             <div class="related-eyebrow">Related service</div>
             <h3>…</h3>
             <p>…</p>
             <span class="related-link">… <span class="arrow">→</span></span>
           </a>
           <a class="related-card related-card--orange" href="…">…</a>
         </div>
       </div>
     </section>
   ============================================================ */

.related-section { background: var(--bg-light); }

.related-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

.related-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  border-radius: 16px;
  padding: 36px 36px 32px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s ease;
}
.related-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.15);
}
.related-card--blue {
  background: linear-gradient(135deg, rgba(22, 93, 148, 0.06) 0%, rgba(22, 93, 148, 0.02) 100%);
  border: 1px solid rgba(22, 93, 148, 0.2);
}
.related-card--orange {
  background: linear-gradient(135deg, rgba(220, 115, 76, 0.06) 0%, rgba(220, 115, 76, 0.02) 100%);
  border: 1px solid rgba(220, 115, 76, 0.22);
}

.related-eyebrow {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-weight: var(--weight-medium);
}
.related-card--blue .related-eyebrow { color: var(--blue); }
.related-card--orange .related-eyebrow { color: var(--orange); }

.related-card h3 {
  font-size: 22px;
  color: var(--text-dark);
  line-height: 1.25;
  letter-spacing: var(--tracking-h3);
}
.related-card p {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text-dark-2);
  flex: 1;
}

.related-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 20px;
  border-radius: var(--radius-md);
  font-size: 13.5px;
  font-weight: var(--weight-medium);
  align-self: flex-start;
  margin-top: 4px;
  transition: background 0.2s ease, transform 0.2s var(--ease-out);
}
.related-card--blue .related-link {
  background: var(--blue);
  color: var(--text-light);
}
.related-card--blue:hover .related-link { background: #1a6fac; }
.related-card--orange .related-link {
  background: var(--orange);
  color: #0c0c0c;
}
.related-card--orange:hover .related-link { background: var(--orange-bright); }
.related-card:hover .related-link .arrow { transform: translateX(3px); }

@media (max-width: 980px) {
  .related-grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .related-card { padding: 28px; }
}

/* ===== src/assets/css/components/related-callout.css ===== */
/* ============================================================
   Single full-width related-service callout — used on service
   detail pages that point at a single sibling service. Distinct
   from the 2-up `.related-section` rail in components/related-
   services.css; this is a 1-card variant with a content column
   on the left and a button-style link on the right.

   Lifted from creator.css and portals.css when Strategy (the
   third service detail page to use this shape) landed.

   Two color modifiers:
   - .related-callout--blue    blue tint, blue link (used when
                               the callout points at a blue-accent
                               service, e.g. Implementation, Portals)
   - .related-callout--orange  orange tint, orange link (used when
                               the callout points at an orange-accent
                               service, e.g. Creator)

   Usage:
     <section class="section section-light related-callout-section">
       <div class="container">
         <a class="related-callout related-callout--blue" href="…">
           <div class="related-callout-content">
             <span class="eyebrow related-callout-eyebrow">Related service</span>
             <h3>…</h3>
             <p>…</p>
           </div>
           <span class="related-callout-link">…<span class="arrow">→</span></span>
         </a>
       </div>
     </section>
   ============================================================ */

.related-callout-section { background: var(--bg-light); }

.related-callout {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 40px;
  align-items: center;
  border-radius: 16px;
  padding: 40px 44px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.3s var(--ease-out), box-shadow 0.3s ease;
}
.related-callout:hover {
  transform: translateY(-2px);
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.15);
}

.related-callout--blue {
  background: linear-gradient(135deg, rgba(22, 93, 148, 0.06) 0%, rgba(22, 93, 148, 0.02) 100%);
  border: 1px solid rgba(22, 93, 148, 0.2);
}
.related-callout--orange {
  background: linear-gradient(135deg, rgba(220, 115, 76, 0.06) 0%, rgba(220, 115, 76, 0.02) 100%);
  border: 1px solid rgba(220, 115, 76, 0.22);
}

.related-callout-eyebrow {
  display: block;
  margin-bottom: 14px;
}
.related-callout--blue .related-callout-eyebrow { color: var(--blue); }
.related-callout--orange .related-callout-eyebrow { color: var(--orange); }

.related-callout-content h3 {
  font-size: 24px;
  color: var(--text-dark);
  margin-bottom: 10px;
  letter-spacing: var(--tracking-h3);
  line-height: 1.25;
}
.related-callout-content p {
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-dark-2);
  max-width: 620px;
}

.related-callout-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 22px;
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: var(--weight-medium);
  white-space: nowrap;
  transition: background 0.2s ease;
}
.related-callout--blue .related-callout-link {
  background: var(--blue);
  color: var(--text-light);
}
.related-callout--blue:hover .related-callout-link { background: #1a6fac; }
.related-callout--orange .related-callout-link {
  background: var(--orange);
  color: #0c0c0c;
}
.related-callout--orange:hover .related-callout-link { background: var(--orange-bright); }
.related-callout:hover .related-callout-link .arrow { transform: translateX(3px); }

@media (max-width: 980px) {
  .related-callout { grid-template-columns: 1fr; gap: 24px; }
}

@media (max-width: 640px) {
  .related-callout { padding: 28px; }
}

/* ===== src/assets/css/components/cta-section.css ===== */
/* ============================================================
   CTA section — closing dark CTA used on the homepage, About,
   and other Phase 1 pages. Extracted from pages/homepage.css
   when About became the second use.
   ============================================================ */

.cta-section {
  background:
    radial-gradient(ellipse 800px 500px at 85% 50%, rgba(220, 115, 76, 0.10), transparent 60%),
    radial-gradient(ellipse 700px 450px at 15% 50%, rgba(22, 93, 148, 0.12), transparent 60%),
    var(--bg-dark);
  color: var(--text-light);
  padding: 120px 0;
  position: relative;
  overflow: hidden;
}
.cta-section .container { position: relative; z-index: 2; }
.cta-content {
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
  position: relative;
  z-index: 2;
}
.cta-content .eyebrow {
  color: var(--orange-bright);
  display: inline-block;
  margin-bottom: 20px;
}
.cta-content h2 {
  font-size: 48px;
  line-height: 1.1;
  color: var(--text-light);
  margin-bottom: 20px;
}
.cta-content > p {
  font-size: 18px;
  line-height: 1.6;
  color: var(--text-light-2);
  margin-bottom: 36px;
}
.cta-actions {
  display: flex;
  gap: 14px;
  justify-content: center;
  flex-wrap: wrap;
}

@media (max-width: 980px) {
  .cta-content h2 { font-size: 36px; }
}
@media (max-width: 760px) {
  .cta-section { padding: 80px 0; }
  .cta-content h2 { font-size: 32px; }
  .cta-content > p { font-size: 16px; }
  .cta-actions { flex-direction: column; align-items: stretch; }
  .cta-actions .btn-primary,
  .cta-actions .btn-secondary-dark {
    width: 100%;
    padding: 14px 22px;
  }
}

/* ===== src/assets/css/components/iframe-page.css ===== */
/* ============================================================
   Bare-bones iframe page
   Shared layout for utility pages whose only content is a single
   third-party iframe (Zoho Bookings, Zoho Creator payment forms,
   etc.). Used by /book-a-consult/, /book/matt/, /pay/.

   Pattern: dark charcoal bg framing the white-card iframe in a
   ~900px container. No hero, no copy, no breadcrumb — just nav,
   iframe, footer.
   ============================================================ */

.iframe-page {
  background: var(--bg-dark);
  color: var(--text-light);
  /* Generous top space so the iframe clears the standard nav, plus
     a small bottom buffer before the footer. */
  padding: 32px 0 64px;
  min-height: 70vh;
}

.iframe-page-container {
  max-width: 900px;
  margin: 0 auto;
  padding: 0 var(--container-pad);
}

.iframe-page iframe {
  display: block;
  width: 100%;
  border: 0;
}

@media (max-width: 640px) {
  .iframe-page { padding: 16px 0 48px; }
  .iframe-page-container { padding: 0 var(--container-pad-mobile); }
}

/* ===== src/assets/css/components/nav.css ===== */
/* ============================================================
   Nav (header)
   The nav-wrap is always dark — see /docs/02-design-system.md
   and the canonical mockup in /docs/mockups/homepage-v2.html.
   On hero pages it blends into the hero; on hero-less pages it
   sits as a dark band at the top of an otherwise light page.
   ============================================================ */

.nav-wrap {
  background: var(--bg-dark);
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  color: var(--text-light);
  transition: background-color 0.25s ease, box-shadow 0.25s ease,
              backdrop-filter 0.25s ease, -webkit-backdrop-filter 0.25s ease;
}

/* When the nav sits over a hero with its own background, the wrap is
   transparent so the hero topo/gradient shows through. Hero pages add
   .nav-wrap--over-hero to the wrap. */
.nav-wrap--over-hero {
  background: transparent;
}

/* Scrolled state: applied once the page is scrolled past the nav itself,
   driven by IntersectionObserver in site.js. On hero pages this swaps
   the transparent wrap for the same translucent treatment as non-hero
   pages, so the nav stays legible over any hero or light background. */
.nav-wrap.is-scrolled,
.nav-wrap--over-hero.is-scrolled {
  background: rgba(15, 15, 14, 0.82);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  box-shadow: 0 8px 24px -16px rgba(0, 0, 0, 0.6);
}

/* While the mobile menu is open, drop the nav-wrap's backdrop-filter.
   backdrop-filter establishes a containing block for position: fixed
   descendants, which would pin the mobile menu (a child of .nav-wrap)
   inside the ~78px nav band instead of the viewport — exactly the bug
   you'd hit by opening the menu after scrolling. The menu is opaque, so
   nothing's lost visually; we just need the containing block to revert
   to the viewport. Same selector specificity as .is-scrolled with an
   extra `body.menu-open` qualifier so it wins. */
body.menu-open .nav-wrap,
body.menu-open .nav-wrap.is-scrolled,
body.menu-open .nav-wrap--over-hero.is-scrolled {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

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

.nav {
  padding: 18px var(--container-pad);
  max-width: 1296px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

/* ---- Brand mark ---- */
.nav-brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: var(--text-light);
  transition: opacity 0.2s ease;
}
.nav-brand:hover { opacity: 0.85; }

/* The full wordmark logo on desktop, the bare mark on mobile —
   visibility toggled via the same breakpoint that hides .nav-links.
   The brand SVGs ship with their colored fills (orange mark, blue
   wordmark); the nav always sits on a dark surface so we force the
   logo to white. brightness(0) collapses every fill to black, then
   invert(1) flips it to white — works on any colored SVG without
   duplicating files or touching the source artwork. */
.nav-logo-full {
  display: block;
  height: 42px;
  width: auto;
  filter: brightness(0) invert(1);
}

.nav-logo-mark {
  display: none;
  height: 38px;
  width: auto;
  filter: brightness(0) invert(1);
}

/* ---- Primary links ----
   Bumped from 13px regular @ text-light-2 to 15px medium @ text-light
   so the nav reads cleanly over the photographic dark-blue topo on
   hero pages (the lower-contrast text was getting lost). */
.nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
  font-size: 15px;
  font-weight: var(--weight-medium);
  color: var(--text-light);
}

.nav-link {
  position: relative;
  padding-bottom: 2px;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: color 0.2s ease;
}
.nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--orange-bright);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.3s var(--ease-out);
}
.nav-link:hover,
.nav-link[aria-current="page"] { color: var(--text-light); }
.nav-link:hover::after,
.nav-link[aria-current="page"]::after { transform: scaleX(1); }

/* ---- Services dropdown trigger ---- */
.nav-dropdown {
  position: relative;
  display: flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  color: var(--text-light);
  background: none;
  border: none;
  padding: 0 0 2px;
  font: inherit;
}
.nav-dropdown::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: calc(100% - 14px);
  height: 1px;
  background: var(--orange-bright);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.3s var(--ease-out);
}
.nav-dropdown:hover,
.nav-dropdown[aria-expanded="true"],
.nav-dropdown[aria-current="page"] { color: var(--text-light); }
.nav-dropdown:hover::after,
.nav-dropdown[aria-expanded="true"]::after,
.nav-dropdown[aria-current="page"]::after { transform: scaleX(1); }

/* Hover bridge anchored to the trigger (not the menu). Fills the
   ~14px gap between trigger and menu so the cursor never falls into
   dead space, and overshoots left/right of the word so diagonal
   movement toward menu items doesn't drop out of the hover zone.
   Especially important for narrow trigger words like "About". */
.nav-dropdown::before {
  content: "";
  position: absolute;
  top: 100%;
  left: -20px;
  right: -20px;
  height: 22px;
}

.nav-dropdown-arrow {
  width: 11px;
  height: 11px;
  opacity: 0.8;
  transition: transform 0.3s var(--ease-out);
}
.nav-dropdown[aria-expanded="true"] .nav-dropdown-arrow,
.nav-dropdown:hover .nav-dropdown-arrow {
  transform: rotate(180deg);
  opacity: 1;
}

/* ---- Dropdown menu ---- */
.nav-dropdown-menu {
  position: absolute;
  top: calc(100% + 18px);
  left: -16px;
  min-width: 280px;
  background: rgba(15, 15, 14, 0.96);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--border-on-dark);
  border-radius: var(--radius-card);
  padding: 10px;
  box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity 0.2s ease, transform 0.2s var(--ease-out);
  z-index: var(--z-nav);
}
/* Hover bridge: prevents the menu from closing when the cursor
   crosses the gap between the trigger and the menu. */
.nav-dropdown-menu::before {
  content: "";
  position: absolute;
  top: -18px;
  left: 0;
  right: 0;
  height: 18px;
}
.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu,
.nav-dropdown[aria-expanded="true"] .nav-dropdown-menu {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.nav-dropdown-item {
  display: block;
  padding: 11px 14px;
  font-size: 13px;
  color: var(--text-light-2);
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: background 0.15s ease, color 0.15s ease;
}
.nav-dropdown-item:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-light);
}

.nav-dropdown-item-meta {
  display: block;
  font-size: 11.5px;
  color: var(--text-light-3);
  margin-top: 2px;
  line-height: 1.4;
}

.nav-dropdown-divider {
  height: 1px;
  background: var(--border-on-dark);
  margin: 8px 6px;
}

.nav-dropdown-hub {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 11px 14px;
  font-size: 13px;
  font-weight: var(--weight-medium);
  color: var(--orange-bright);
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: background 0.15s ease;
}
.nav-dropdown-hub:hover { background: rgba(220, 115, 76, 0.08); }
.nav-dropdown-hub:hover .arrow { transform: translateX(3px); }

/* ---- Header CTA ---- */
.nav-cta {
  padding: 11px 22px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: var(--weight-medium);
  background: linear-gradient(180deg, var(--orange-bright) 0%, var(--orange) 100%);
  color: #0c0c0c;
  border: none;
  box-shadow: 0 0 0 1px rgba(220, 115, 76, 0.3);
  cursor: pointer;
  transition: transform 0.2s var(--ease-out), box-shadow 0.3s ease;
  /* Keep "Book a consultation" on a single line so the button stays
     at its design height (~42px). When the label wrapped the whole
     nav grew taller than --nav-h, pushing hero sections out of
     alignment with the transparent nav-wrap--over-hero treatment. */
  white-space: nowrap;
}
.nav-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px rgba(220, 115, 76, 0.5),
              0 4px 16px -4px rgba(220, 115, 76, 0.3);
}

/* ---- Mobile menu toggle ---- */
.nav-mobile-toggle {
  display: none;
  width: 40px;
  height: 40px;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0;
  position: relative;
  z-index: calc(var(--z-modal) + 1);
}
.nav-mobile-toggle .bar {
  display: block;
  width: 22px;
  height: 1.5px;
  background: var(--text-light);
  margin: 5px auto;
  transition: transform 0.3s var(--ease-out), opacity 0.2s ease;
}
body.menu-open .nav-mobile-toggle .bar:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}
body.menu-open .nav-mobile-toggle .bar:nth-child(2) {
  opacity: 0;
}
body.menu-open .nav-mobile-toggle .bar:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

/* ---- Mobile menu overlay ---- */
.mobile-menu {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--bg-dark);
  color: var(--text-light);
  z-index: var(--z-modal);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--ease-out);
  overflow-y: auto;
}
.mobile-menu .noise { opacity: 0.05; z-index: 1; }

body.menu-open .mobile-menu {
  opacity: 1;
  pointer-events: auto;
}

.mobile-menu-topo {
  position: absolute;
  inset: 0;
  background-image: var(--topo-dark-blue);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0;
  z-index: 1;
  transition: opacity 0.6s ease 0.2s;
}
body.menu-open .mobile-menu-topo { opacity: 0.4; }

.mobile-menu-inner {
  position: relative;
  z-index: 2;
  padding: 88px 32px 48px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.mobile-nav-links {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 48px;
}

.mobile-nav-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 0;
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: var(--weight-medium);
  letter-spacing: -0.025em;
  color: var(--text-light);
  text-decoration: none;
  border-bottom: 1px solid var(--border-on-dark);
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s var(--ease-out),
              transform 0.5s var(--ease-out),
              color 0.2s ease;
}
.mobile-nav-link:hover { color: var(--orange-bright); }
.mobile-nav-link::after {
  content: "→";
  color: var(--text-light-3);
  font-size: 18px;
  transition: transform 0.3s var(--ease-out), color 0.2s ease;
}
.mobile-nav-link:hover::after {
  transform: translateX(4px);
  color: var(--orange-bright);
}

body.menu-open .mobile-nav-link {
  opacity: 1;
  transform: translateY(0);
}
/* :nth-of-type counts among anchor siblings only, so an interleaved
   .mobile-nav-sublinks <div> (used for dropdowns that opt into
   `children_on_mobile`) doesn't shift the staggering of the top-level
   links. Keeps About's children appearing under About without
   knocking Pricing/FAQs/Blog out of time. */
body.menu-open .mobile-nav-link:nth-of-type(1) { transition-delay: 0.15s; }
body.menu-open .mobile-nav-link:nth-of-type(2) { transition-delay: 0.20s; }
body.menu-open .mobile-nav-link:nth-of-type(3) { transition-delay: 0.25s; }
body.menu-open .mobile-nav-link:nth-of-type(4) { transition-delay: 0.30s; }
body.menu-open .mobile-nav-link:nth-of-type(5) { transition-delay: 0.35s; }
body.menu-open .mobile-nav-link:nth-of-type(6) { transition-delay: 0.40s; }
body.menu-open .mobile-nav-link:nth-of-type(7) { transition-delay: 0.45s; }

/* ---- Mobile nav sublinks ----
   Inline expansion of a dropdown's children below the parent link.
   Opted into per-dropdown via `children_on_mobile: true` in nav.yml.
   Smaller than the top-level links, indented, no bottom border, no
   arrow — they're secondary affordances. */
.mobile-nav-sublinks {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 0 16px 16px;
  border-bottom: 1px solid var(--border-on-dark);
  /* Sublinks group inherits the staggered reveal of the dropdown
     parent — they appear together as a unit when the menu opens. */
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s var(--ease-out), transform 0.45s var(--ease-out);
}
body.menu-open .mobile-nav-sublinks {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.28s;
}

.mobile-nav-sublink {
  display: flex;
  align-items: center;
  padding: 8px 0;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: var(--weight-regular);
  color: var(--text-light-2);
  text-decoration: none;
  transition: color 0.2s ease;
}
.mobile-nav-sublink::before {
  content: "";
  width: 14px;
  height: 1px;
  background: var(--text-light-3);
  margin-right: 12px;
  flex-shrink: 0;
}
.mobile-nav-sublink:hover {
  color: var(--orange-bright);
}
.mobile-nav-sublink:hover::before {
  background: var(--orange-bright);
}

.mobile-menu-cta {
  margin-top: auto;
  padding-top: 32px;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s var(--ease-out) 0.45s,
              transform 0.5s var(--ease-out) 0.45s;
}
body.menu-open .mobile-menu-cta {
  opacity: 1;
  transform: translateY(0);
}
.mobile-menu-cta .btn-primary {
  width: 100%;
  justify-content: center;
  padding: 16px 24px;
  font-size: 14px;
}

.mobile-menu-meta {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--border-on-dark);
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: var(--text-light-3);
  letter-spacing: 0.04em;
}
.mobile-menu-meta a {
  color: var(--text-light-2);
  text-decoration: none;
  transition: color 0.2s ease;
}
.mobile-menu-meta a:hover { color: var(--text-light); }

/* ---- Responsive ---- */
@media (max-width: 760px) {
  .nav {
    padding: 16px var(--container-pad-mobile);
    gap: 12px;
  }
  .nav-links { display: none; }
  .nav-mobile-toggle { display: block; }
  .mobile-menu { display: block; }
  .nav-logo-full { display: none; }
  .nav-logo-mark { display: block; }

  /* Keep the consult CTA visible in the mobile header alongside the
     hamburger so it's reachable without opening the menu. The brand
     stays left, CTA pushes to the right, hamburger sits last. */
  .nav-brand { margin-right: auto; }
  .nav-cta {
    padding: 9px 16px;
    font-size: 13px;
    letter-spacing: 0.01em;
  }
}

@media (max-width: 380px) {
  /* Tighten on the narrowest phones so brand + CTA + hamburger fit
     on one row without truncation. */
  .nav { gap: 8px; }
  .nav-cta { padding: 9px 13px; font-size: 12px; }
  .nav-logo-mark { height: 34px; }
}

@media (prefers-reduced-motion: reduce) {
  .nav-dropdown-menu,
  .mobile-menu,
  .mobile-nav-link,
  .mobile-menu-cta,
  .mobile-menu-topo {
    transition-duration: 0.001s;
  }
}

/* ===== src/assets/css/components/footer.css ===== */
/* ============================================================
   Footer
   Source: /docs/mockups/homepage-v2.html
   ============================================================ */

.site-footer {
  position: relative;
  background: var(--bg-dark);
  color: var(--text-light-2);
  padding: 72px 0 32px;
  overflow: hidden;
}

.site-footer .noise { opacity: 0.04; }

.footer-grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 48px;
  margin-bottom: 56px;
}

.footer-brand-link {
  display: inline-block;
  margin-bottom: 18px;
  transition: opacity 0.2s ease;
}
.footer-brand-link:hover { opacity: 0.85; }

.footer-logo {
  display: block;
  height: 44px;
  width: auto;
  /* Force the colored SVG to render white on the dark footer.
     See nav.css for the full rationale on this filter. */
  filter: brightness(0) invert(1);
}

.footer-brand p {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-light-2);
  max-width: 320px;
}

.footer-col h3 {
  font-family: var(--font-body);
  font-weight: var(--weight-medium);
  font-size: 11px;
  letter-spacing: var(--tracking-strip);
  text-transform: uppercase;
  color: var(--text-light-3);
  margin-bottom: 18px;
}

.footer-col ul {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.footer-col a {
  font-size: 14px;
  color: var(--text-light-2);
  text-decoration: none;
  transition: color 0.2s ease;
}
.footer-col a:hover { color: var(--text-light); }

.footer-bottom {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 24px;
  border-top: 1px solid var(--border-on-dark);
  font-size: 12px;
  color: var(--text-light-3);
  letter-spacing: 0.02em;
}

.footer-bottom-links {
  display: flex;
  gap: 20px;
}

.footer-bottom-links a,
.footer-bottom-links .footer-bottom-link--button {
  color: var(--text-light-3);
  text-decoration: none;
  transition: color 0.2s ease;
  /* Reset button styling so it sits in the row like the links. */
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: inherit;
  cursor: pointer;
}
.footer-bottom-links a:hover,
.footer-bottom-links .footer-bottom-link--button:hover { color: var(--text-light-2); }
.footer-bottom-links .footer-bottom-link--button:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

@media (max-width: 760px) {
  .site-footer { padding: 48px 0 24px; }
  .footer-grid {
    grid-template-columns: 1fr 1fr;
    gap: 32px;
    margin-bottom: 40px;
  }
  .footer-brand { grid-column: 1 / -1; }
  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
}

/* ===== src/assets/css/components/consultation-modal.css ===== */
/* ============================================================
   Consultation modal
   Spec: /docs/06-forms-and-modal.md
   ============================================================ */

.consultation-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
}
.consultation-modal[hidden] { display: none; }

.consultation-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 15, 14, 0.8);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 1;
  animation: cm-backdrop-in 0.25s ease-out forwards;
}

.consultation-modal-panel {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 640px;
  max-height: 90vh;
  background: var(--bg-light);
  border: 1px solid var(--border-on-light);
  border-radius: var(--radius-card-lg);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: cm-panel-in 0.32s var(--ease-out) forwards;
}

.consultation-modal-header {
  padding: 28px 28px 16px;
  border-bottom: 1px solid var(--border-on-light);
}

.consultation-modal-header h2 {
  font-size: 24px;
  margin-bottom: 8px;
}

.consultation-modal-header p {
  font-size: 14px;
  color: var(--text-dark-2);
  line-height: 1.55;
}

.consultation-modal-body {
  padding: 20px 28px 28px;
  overflow-y: auto;
  flex: 1;
}

.consultation-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border-on-light);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  z-index: 3;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.consultation-modal-close:hover {
  background: rgba(0, 0, 0, 0.04);
  border-color: var(--border-strong-on-light);
}
.consultation-modal-close .bar {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 1.5px;
  background: var(--text-dark);
}
.consultation-modal-close .bar:nth-child(1) { transform: translate(-50%, -50%) rotate(45deg); }
.consultation-modal-close .bar:nth-child(2) { transform: translate(-50%, -50%) rotate(-45deg); }

@keyframes cm-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes cm-panel-in {
  from { opacity: 0; transform: translateY(20px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---- Mobile: bottom sheet ---- */
@media (max-width: 760px) {
  .consultation-modal {
    padding: 0;
    align-items: flex-end;
  }
  .consultation-modal-panel {
    max-width: 100%;
    max-height: 92vh;
    border-radius: var(--radius-card-lg) var(--radius-card-lg) 0 0;
    animation: cm-panel-in-mobile 0.4s var(--ease-out) forwards;
  }
  @keyframes cm-panel-in-mobile {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .consultation-modal-backdrop,
  .consultation-modal-panel {
    animation-duration: 0.001s;
  }
}

/* ============================================================
   Consultation form
   The form is Zoho's HTML embed (not the iframe) — markup is in
   consultation-modal.njk, behavior is in the inline script below
   it. These styles live alongside the modal CSS because the form
   only renders inside the modal.
   ============================================================ */

.cf {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.cf-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.cf-label {
  font-size: 13px;
  font-weight: var(--weight-medium);
  color: var(--text-dark);
  letter-spacing: 0.01em;
}

.cf-req {
  color: var(--orange);
  font-style: normal;
  margin-left: 2px;
}

.cf input[type="text"],
.cf input[type="email"],
.cf textarea {
  width: 100%;
  padding: 12px 14px;
  font: inherit;
  font-size: 15px;
  line-height: 1.4;
  color: var(--text-dark);
  background: var(--bg-light-2);
  border: 1px solid var(--border-on-light);
  border-radius: var(--radius-sm);
  outline: none;
  transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}

.cf input[type="text"]:hover,
.cf input[type="email"]:hover,
.cf textarea:hover {
  border-color: var(--border-strong-on-light);
}

.cf input[type="text"]:focus,
.cf input[type="email"]:focus,
.cf textarea:focus {
  border-color: var(--orange);
  background: var(--bg-light);
  box-shadow: 0 0 0 3px rgba(220, 115, 76, 0.15);
}

/* :user-invalid only matches after the user has interacted with the
   field (focus + blur, or attempted submit), so empty required inputs
   don't show as red on first paint. Modern browsers only — older ones
   just skip the styling, which is fine. */
.cf input:user-invalid,
.cf textarea:user-invalid {
  border-color: rgba(180, 60, 40, 0.6);
}

.cf textarea {
  resize: vertical;
  min-height: 96px;
}

.cf-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 4px;
}

.cf-submit {
  /* Inherits .btn-primary styling. The cf-submit hook is here only so
     we can tune disabled state without touching the global button. */
  min-width: 140px;
}
.cf-submit:disabled {
  opacity: 0.7;
  cursor: progress;
}

.cf-fineprint {
  font-size: 12.5px;
  color: var(--text-dark-3);
  line-height: 1.4;
  margin: 0;
  flex: 1;
}

/* Honeypot — off-screen but still "rendered" so naive bots see and
   fill it. Don't use display:none (sophisticated bots skip those).
   No tab stop, no screen reader, no autofill. */
.cf-honey {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Turnstile widget container. The widget itself is a fixed-size iframe
   (~300x65) that Cloudflare renders into this div. Pin the min-height
   while the iframe is initializing so the layout doesn't shift when the
   token resolves, and align to the start so a narrower iframe doesn't
   look stranded mid-row on wide screens. */
.cf-turnstile {
  min-height: 65px;
  display: flex;
  align-items: center;
  margin-top: -4px; /* tighter than the .cf gap; the iframe has its own padding */
}

/* Inline error shown when the user tries to submit before the Turnstile
   token is ready. Scoped tight to the form so it picks up the form's
   muted-red invalid-field treatment without a custom palette. */
.cf-turnstile-error {
  font-size: 13px;
  line-height: 1.4;
  color: rgba(180, 60, 40, 0.95);
  margin: -4px 0 0;
}

/* Post-submit state lives at /book-a-consult/, not inline in the
   modal — see the submit handler in consultation-modal.njk. */

/* Hidden iframe target — never visible, but kept inside the panel so
   it inherits the modal lifecycle. */
.cf-zoho-target {
  display: none;
  border: 0;
  width: 0;
  height: 0;
}

/* btn-secondary-light is defined globally; the thanks-state Close button
   uses it. If/when btn-secondary-light moves to a shared button file,
   nothing here needs to change. */

/* ===== src/assets/css/components/consent-banner.css ===== */
/* ============================================================
   Cookie consent banner.

   Fixed dark band at the bottom of the viewport. Slides up
   from below on first visit (or when re-opened via the
   "Cookie preferences" footer link). Choice is persisted in
   the tg_consent cookie; the banner only mounts when there
   is no recorded choice yet.

   Markup is injected by /assets/js/consent.js; this file
   styles the resulting DOM.
   ============================================================ */

.consent-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--bg-dark-2);
  color: var(--text-light);
  border-top: 1px solid var(--border-on-dark);
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.25);
  z-index: 1000;
  transform: translateY(100%);
  opacity: 0;
  transition: transform 0.28s ease, opacity 0.28s ease;
  padding: 18px 0;
}
.consent-banner.is-visible {
  transform: translateY(0);
  opacity: 1;
}

.consent-banner-inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.consent-banner-copy {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-light-2);
  flex: 1;
}
.consent-banner-link {
  color: var(--text-light);
  text-decoration: underline;
  text-underline-offset: 2px;
  margin-left: 4px;
}
.consent-banner-link:hover {
  color: var(--orange);
}

.consent-banner-actions {
  display: flex;
  gap: 12px;
  flex-shrink: 0;
}

.consent-banner-btn {
  font-family: inherit;
  font-weight: var(--weight-medium);
  font-size: 14px;
  letter-spacing: 0.01em;
  min-height: 44px;
  padding: 0 22px;
  border-radius: var(--radius-btn, 6px);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.consent-banner-btn--accept {
  background: var(--orange);
  color: #fff;
}
.consent-banner-btn--accept:hover {
  background: var(--orange-bright, var(--orange));
  filter: brightness(1.06);
}
.consent-banner-btn--decline {
  background: transparent;
  color: var(--text-light);
  border-color: var(--border-on-dark);
}
.consent-banner-btn--decline:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.3);
}

.consent-banner-btn:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

@media (max-width: 760px) {
  .consent-banner { padding: 14px 0; }
  .consent-banner-inner {
    padding: 0 var(--container-pad-mobile);
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .consent-banner-copy { font-size: 13.5px; }
  .consent-banner-actions {
    flex-direction: row-reverse; /* Accept on the right, easier thumb reach */
  }
  .consent-banner-btn { flex: 1; padding: 0 16px; }
}

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