﻿/* ══════════════════════════════════════════════════════════════════════════
   FUNDED FINANCIAL NETWORK — Main Stylesheet
   Theme: Brand palette — mid navy / gold

   PALETTE SOURCE — the whole site keys off these tokens, and every hardcoded
   rgba() in this file and in the templates was migrated to match. If the
   palette changes again, update the tokens here AND re-run a sweep for
   hardcoded rgb triplets — several rules need literal rgba() values for alpha
   compositing and cannot reference a var().

     #0B1F3A  deep navy    page ground, navbar, footer
     #16365F  primary navy alternating section backgrounds
     #1C3F6E  secondary    cards, panels, hover surfaces
     #D8A123  gold         buttons, borders, links, highlights  (UNCHANGED)
     #FFF14F  gold bright  hover / active state                 (UNCHANGED)
     #F8F9F7  text         primary foreground

   PALETTE HISTORY — the navies were lifted out of near-black (#020A19 /
   #0D182B / #1F2636) to lighten the site's overall mood while keeping the
   same blue family. Every new value was chosen by contrast ratio rather than
   by eye; the measured figures are recorded against each token below. The
   gold was deliberately left untouched so the accent still pops.

   --text-muted was lifted at the same time and NOT independently: on the
   lighter #1C3F6E card surface the old #9AA7B8 measured 4.15:1, under AA for
   body text. The two move together — if a navy is ever darkened again,
   re-check the muted text against it before assuming it still passes.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── CSS Variables ───────────────────────────────────────────────────────── */
:root {
  /* Contrast vs white / --text-muted / --gold, measured:
       --navy-dark   16.52 / 9.15 / 7.11
       --navy        12.16 / 6.74 / 5.24
       --navy-light  10.58 / 5.86 / 4.55
     All clear AA for body text; the first two clear AAA.

     --navy-light was picked to the 4.5 gold figure specifically: card <h3>s
     are gold at 1.1rem bold, which is just UNDER the 18.66px large-text
     threshold, so they need the full 4.5 rather than 3.0. A lighter card
     (#1E4270) measured 4.37 and failed on /services. Darkening the gold was
     not an option — the accent is fixed. */
  --navy-dark:   #0B1F3A;   /* deep navy — page ground, navbar, footer */
  --navy:        #16365F;   /* primary navy — alternating section backgrounds */
  --navy-light:  #1C3F6E;   /* secondary navy — cards, panels, hover surfaces */

  /* Light surfaces. Section backgrounds are now white by default with the
     blue-grey as the quieter alternate, so navy reads as an accent and a card
     colour rather than as large slabs of dark. */
  --surface:     #FFFFFF;   /* primary light section background */
  --surface-alt: #EDF1F7;   /* very light blue-grey — alternate light band */

  --gold:        #D8A123;   /* accent — buttons, borders, links, highlights */
  --gold-light:  #FFF14F;   /* bright — hover / active state */
  /* Derived from the accent for depth and muted rules; not brand-supplied. */
  --gold-deep:   #A87A16;
  --gold-dim:    #6E5620;

  --white:       #FFFFFF;
  --text-light:  #F8F9F7;   /* primary text */
  /* Lifted from #9AA7B8 with the navies — see PALETTE HISTORY above. */
  --text-muted:  #B6C2D2;
  --danger:      #e05252;
  --success:     #3cb878;
  --border:      rgba(216,161,35,0.22);
  --radius:      8px;
  --shadow:      0 4px 24px rgba(0,0,0,0.3);
  --transition:  0.2s ease;
  --font-heading: 'Cinzel', serif;
  --font-body:    'Open Sans', sans-serif;
  /* .navbar's own height (68px) + .site-header's 1px border-bottom. The sticky
     header occupies exactly this much space once scrolled; anything that needs
     to clear it (page-hero top padding, anchor-jump scroll offset) reads from
     this one value instead of repeating the arithmetic. */
  --nav-height: 69px;
}

/* ── Reset & Base ────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* scroll-padding-top keeps an in-page anchor jump (e.g. a footer link ending in
   #something) from landing with its target's top edge under the sticky nav —
   the browser treats --nav-height as a no-go margin at the top of the
   scrollport when it settles a jump, the same way it already does for the
   page-hero's own top padding below. */
html { scroll-behavior: smooth; scroll-padding-top: var(--nav-height); font-size: 16px; background: var(--navy-dark); }

body {
  font-family: var(--font-body);
  background: var(--navy-dark);
  color: var(--text-light);
  line-height: 1.6;
}

/* ── Global Gold Glow Accents ────────────────────────────────────────────── */

/* Gold buttons carry a resting glow that intensifies on hover.
   The previous `goldPulse 4s infinite` animation was removed: it ran on every
   .btn-gold simultaneously (hero, nav, CTA, every "Discuss Now"), so several
   elements throbbed continuously with no user input. Perpetual pulsing gold
   reads as an ad banner rather than as premium, and it had no reduced-motion
   guard. Glow on hover is user-triggered, which is the correct trade. */
.btn-gold {
  box-shadow: 0 0 6px rgba(216,161,35,0.25), 0 2px 8px rgba(0,0,0,0.2);
  transition: box-shadow var(--transition);
}
.btn-gold:hover {
  box-shadow: 0 0 30px rgba(216,161,35,0.75), 0 4px 18px rgba(216,161,35,0.3);
}

/* ── Pulsing CTA ─────────────────────────────────────────────────────────────
   Every gold button that leads to the application pulses. Rather than tagging
   each one by hand across seven templates (and forgetting one later), they are
   matched by destination: any gold <a> pointing at /apply is a funnel entry
   point and animates automatically. New apply CTAs inherit this for free.

   `.btn-pulse` remains available to opt in a button that is NOT an apply link.

   NOTE: this intentionally also covers apply CTAs labelled differently —
   "Start Your Application", "Apply Now — It's Free", "Apply for This Amount" —
   since they are the same action. To pulse only literal "Apply Now" buttons,
   drop the attribute selector and tag those individually with .btn-pulse.

   "Submit Inquiry" (#discussSubmitBtn) and gold "Discuss Now" triggers now
   pulse too — the brief extends this to every button leading to a form, and
   the modal is a form. Deliberately still excluded: .btn-gold generally, so
   non-funnel gold buttons ("Learn More") stay static and the motion keeps
   meaning "this is the way forward" rather than decorating the page. */
@keyframes ctaPulse {
  0%, 100% { box-shadow: 0 0 10px rgba(216,161,35,0.35), 0 2px 8px  rgba(0,0,0,0.25); }
  50%      { box-shadow: 0 0 26px rgba(216,161,35,0.70), 0 4px 18px rgba(216,161,35,0.25); }
}
/* 3s → 2.25s. The brief asked for "roughly 2s to 1.5s" — a ~25% nudge; the
   actual starting value was 3s, so the same proportional nudge lands at
   2.25s. Going to a literal 1.5s would have doubled the rate and started to
   read as flashing, which the brief explicitly ruled out.
   All selectors below share this one duration and all start on page render,
   so every pulsing CTA stays in sync. Change the value in one place only. */
.btn-pulse,
a.btn-gold[href$="/apply"],
#discussSubmitBtn,
.btn-gold[data-discuss-now] {
  animation: ctaPulse 2.25s ease-in-out infinite;
}
/* Hover takes over from the pulse so the two never fight for the shadow. */
.btn-pulse:hover,
a.btn-gold[href$="/apply"]:hover,
#discussSubmitBtn:hover,
.btn-gold[data-discuss-now]:hover {
  animation: none;
  box-shadow: 0 0 30px rgba(216,161,35,0.75), 0 4px 18px rgba(216,161,35,0.3);
}

/* Soft glow on nav header bottom border */
.site-header {
  box-shadow: 0 2px 16px rgba(0,0,0,0.4), 0 0 18px rgba(216,161,35,0.08);
}

/* Glow on logo text */
.logo-text {
  text-shadow: 0 0 18px rgba(216,161,35,0.18);
}

/* NOTE: a global `h1, h2 { text-shadow: 0 0 30px rgba(216,161,35,0.08) }` used
   to sit here. It applied to every heading on every page — too faint to read as
   deliberate, but enough to haze all heading text. Removed rather than reduced.
   Glow is an accent: it only works where it is scarce. */

/* NOTE: the hero numerals deliberately carry NO glow. A halo behind an
   inscriptional serif fills the counters and softens the cut of the letterform,
   which is exactly the quality that makes the face look expensive. Their
   presence comes from size, spacing and the metallic sheen instead — see
   .stat-value further down. */

/* Glow on hero headline gold span. Kept deliberately low — at this type size a
   strong halo softens the letterforms, and the headline now competes with the
   pulsing CTA below it for attention. The glow should suggest depth, not haze. */
.hero-headline .gold {
  text-shadow: 0 0 14px rgba(216,161,35,0.15);
}

/* Soft glow behind featured cards */
.card-featured {
  box-shadow: 0 0 30px rgba(216,161,35,0.18), 0 8px 32px rgba(0,0,0,0.3);
}

/* Glow on featured testimonial */
.testimonial-featured {
  box-shadow: 0 0 24px rgba(216,161,35,0.14), 0 4px 16px rgba(0,0,0,0.2);
}

/* Glow on form focus state */
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  box-shadow: 0 0 0 3px rgba(216,161,35,0.15), 0 0 12px rgba(216,161,35,0.12);
}

/* Glow on the CTA banner */
.cta-banner {
  box-shadow: inset 0 0 80px rgba(216,161,35,0.04);
}

/* Section eyebrow glow */
.section-eyebrow {
  text-shadow: 0 0 14px rgba(216,161,35,0.4);
}

/* Step numbers glow */
.step-num {
  text-shadow: 0 0 12px rgba(216,161,35,0.3);
}

/* Rating badge glow on hover */
.rating-badge:hover {
  box-shadow: 0 0 20px rgba(216,161,35,0.2);
  transition: box-shadow 0.3s ease;
}

/* ── Reduced motion ──────────────────────────────────────────────────────────
   Respect the OS-level "reduce motion" setting. Motion-sensitive users can
   experience nausea or migraine from animation and parallax. Colour, glow and
   hover states are all preserved — only movement is neutralised, so nothing
   becomes unreadable or loses its affordance.
   The hero stat count-up in static/js/main.js checks this same preference in
   JS and renders final values immediately. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Neutralise lift-on-hover transforms without disabling the hover shadow. */
  .card:hover {
    transform: none;
  }
  /* Apply CTAs keep a static glow rather than freezing on an arbitrary
     mid-animation frame — they still read as the primary action. */
  .btn-pulse,
  a.btn-gold[href$="/apply"] {
    animation: none !important;
    box-shadow: 0 0 18px rgba(216,161,35,0.5), 0 2px 8px rgba(0,0,0,0.25);
  }
}

a { color: var(--gold); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4, h5 {
  font-family: var(--font-heading);
  line-height: 1.25;
}

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

ul { list-style: none; }

.container {
  width: 100%;
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

.text-center { text-align: center; }
.mt-2 { margin-top: 2rem; }
.gold { color: var(--gold); }
.gold-link { color: var(--gold); text-decoration: underline; }
/* --gold measures ~2.2:1 on the light surfaces and fails AA as link text.
   #6B4708 is the established gold-on-light value used site-wide (7.5:1) and
   still reads as the same accent. */
.section-pale .gold-link,
.section-light .gold-link { color: #6B4708; }
/* ...but NOT inside a dark panel sitting on that light surface. .contact-card
   is navy, so the darkened gold measured 1.46:1 inside it — the same
   descendant-override trap the legal contact panel hit. Dark panels keep the
   full-strength accent. */
.section-pale .contact-card .gold-link,
.section-light .contact-card .gold-link { color: var(--gold); }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-block;
  padding: 0.65rem 1.5rem;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.03em;
  cursor: pointer;
  border: 2px solid transparent;
  transition: all var(--transition);
  text-align: center;
  white-space: nowrap;
}
.btn:hover { text-decoration: none; transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn-gold {
  background: var(--gold);
  color: var(--navy-dark);
  border-color: var(--gold);
}
.btn-gold:hover { background: var(--gold-light); border-color: var(--gold-light); color: var(--navy-dark); }

.btn-outline {
  background: transparent;
  color: var(--gold);
  border-color: var(--gold);
}
.btn-outline:hover { background: var(--gold); color: var(--navy-dark); }

.btn-ghost {
  background: transparent;
  color: var(--text-muted);
  border-color: var(--navy-light);
}
.btn-ghost:hover { border-color: var(--gold); color: var(--gold); }

.btn-lg { padding: 0.85rem 2rem; font-size: 1rem; }
.btn-sm { padding: 0.35rem 0.85rem; font-size: 0.8rem; }

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* ── Navigation ──────────────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--navy-dark);
  border-bottom: 1px solid var(--gold-dim);
  box-shadow: 0 2px 16px rgba(0,0,0,0.4);
}

.navbar {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: 68px;
}

.nav-logo {
  display: flex;
  align-items: center;
  gap: 0;
  text-decoration: none;
  flex-shrink: 0;
}
.logo-img {
  height: 52px;
  width: auto;
  max-width: 320px;
  object-fit: contain;
}
.logo-text {
  font-family: var(--font-heading);
  font-size: 1rem;
  color: var(--white);
  letter-spacing: 0.06em;
  line-height: 1.2;
}

.nav-links {
  display: flex;
  gap: 0.25rem;
  margin-left: auto;
}
.nav-link {
  color: var(--text-muted);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.4rem 0.7rem;
  border-radius: 4px;
  transition: color var(--transition), background var(--transition);
}
.nav-link:hover, .nav-link.active {
  color: var(--gold);
  background: rgba(216,161,35,0.08);
  text-decoration: none;
}

.nav-actions {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* Click-to-call. Deliberately its own element outside .nav-links/.nav-actions:
   both of those are display:none below 768px until the hamburger is opened
   (see the mobile block below), and the number has to stay reachable without
   that extra tap — that's the whole point of putting a phone number in a nav
   bar. Sits between the links and the Apply button in the DOM, so on desktop
   it rides along in the same right-aligned cluster that .nav-links' own
   margin-left:auto already pushes over; on mobile, .nav-links and .nav-actions
   collapse to zero width around it and it's left sitting next to the logo
   and the toggle, which is exactly where it needs to be. */
.nav-phone {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--gold);
  font-weight: 700;
  font-size: 0.85rem;
  white-space: nowrap;
  flex-shrink: 0;
}
.nav-phone:hover { color: var(--gold-light); text-decoration: none; }

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  margin-left: auto;
}
.nav-toggle span {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--gold);
  border-radius: 2px;
  transition: all var(--transition);
}

/* ── Hero ────────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  /* Sized to the viewport MINUS the sticky nav, so the whole hero — eyebrow,
     headline, paragraph, Apply Now and the stat row — fits one screen with no
     scrolling. It was 92vh, which ignored the 69px nav above it and pushed the
     counters below the fold on a standard laptop.
     svh (small viewport height) rather than vh so mobile browsers measure
     against the viewport WITH their address bar showing; plain vh measures the
     collapsed-toolbar height and hides the bottom of the hero on first paint.
     The vh line is the fallback for engines without svh. */
  min-height: calc(100vh - var(--nav-height));
  min-height: calc(100svh - var(--nav-height));
  display: flex;
  align-items: center;
  /* The photo moved to .hero-slide when this became a carousel. The navy
     stays as the ground colour so the hero is never bare white in the gap
     before the first image decodes. */
  background-color: var(--navy-dark);
  overflow: hidden;
}

/* ── Hero carousel ───────────────────────────────────────────────────────────
   Two stacks change together on one index: the images here and the headlines
   below. Both crossfade on opacity alone — no transform, no repaint of the
   fixed content — so the eyebrow, sub-copy, CTA and stat row sit completely
   still while the slide behind them changes. */
.hero-slides { position: absolute; inset: 0; z-index: 0; }
.hero-slide {
  position: absolute;
  inset: 0;
  /* Gradient first so it layers OVER the photo. Same three stops the static
     hero used, so the headline keeps exactly the contrast it had. */
  background-image:
    linear-gradient(135deg, rgba(11,31,58,0.82) 0%, rgba(22,54,95,0.75) 60%, rgba(28,63,110,0.68) 100%),
    var(--slide-img);
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 900ms ease-in-out;
}
.hero-slide.is-active { opacity: 1; }

/* Headline stack. CSS grid with every child in the same cell: the h1 keeps
   the height of the TALLEST headline, so the CTA and stats below never jump
   when a two-line headline follows a one-line one. An absolutely-positioned
   stack would collapse the h1 to zero height and do exactly that. */
/* The two one-line headlines ("Fast approval", "Same-day funding") still sit
   in a box sized for the two-line ones, so ~75px of slack remains on those
   slides. Centring splits it above and below the headline (~37px each)
   instead of dumping all of it between the headline and the paragraph, where
   it reads as a hole in the layout. */
.hero-headline { display: grid; align-items: center; }
.hero-headline-slide {
  grid-area: 1 / 1;
  opacity: 0;
  transition: opacity 900ms ease-in-out;
  pointer-events: none;
}
.hero-headline-slide.is-active { opacity: 1; }

/* Pagination dots. Sized past the 24px hit-area floor via padding while the
   visible dot stays small — a 10px tap target is unusable on a phone. */
.hero-dots {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: 1.75rem;
  transform: translateX(-50%);
  display: flex;
  gap: 0.35rem;
}
.hero-dot {
  appearance: none;
  border: 0;
  background: none;
  padding: 0.55rem 0.35rem;
  cursor: pointer;
  line-height: 0;
}
.hero-dot::before {
  content: "";
  display: block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(255,255,255,0.35);
  border: 1px solid rgba(255,255,255,0.45);
  transition: background var(--transition), border-color var(--transition), transform var(--transition);
}
.hero-dot:hover::before { background: rgba(255,255,255,0.6); }
.hero-dot.is-active::before {
  background: var(--gold);
  border-color: var(--gold);
  transform: scale(1.18);
}
.hero-dot:focus-visible::before {
  outline: 2px solid var(--gold-light);
  outline-offset: 3px;
}

/* Motion is decorative here: every slide's headline is already in the DOM and
   the dots still work, so honouring the preference costs the user nothing.
   main.js also skips its timer under the same query — this rule only removes
   the crossfade itself. */
@media (prefers-reduced-motion: reduce) {
  .hero-slide, .hero-headline-slide, .hero-sub-slide { transition: none; }
}

.hero-overlay {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 30% 60%, rgba(216,161,35,0.06) 0%, transparent 60%);
  pointer-events: none;
}

.hero-content {
  position: relative;
  z-index: 2;
  /* Widened twice, both times because the stat row outgrew the cap and wrapped:
     680px -> 820px when the numerals were enlarged, then 820px -> 900px when the
     unit labels went from "HR"/"MO" to "HOURS"/"MONTHS" (the row needs ~822px).
     If the stat labels or numeral size change again, re-measure the row before
     assuming it still fits. The headline and sub-copy wrap naturally well
     before this width, so widening costs nothing elsewhere. */
  max-width: 900px;
  /* Vertical rhythm tightened throughout this block so the stat row clears the
     fold on a laptop. Every reduction below is GAP only — no font-size, line-
     height or max-width was touched, so the type reads exactly as before, just
     with less air between the pieces. Roughly 5rem of dead space came out
     between the padding, the four margins and the hero height above. */
  padding: 2.25rem 0;
}

.hero-eyebrow {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.6rem;      /* was 1rem */
}

.hero-headline {
  /* Max reduced 4.5rem -> 4.25rem (72px -> 68px). This is a SPACING fix, not a
     type preference: the headline stack reserves the height of its tallest
     slide, and at 72px "Approval based on your monthly revenue" wrapped to
     THREE lines inside the 900px column while slide 1 takes two. That left
     80px of dead space under the headline on slide 1 and 159px on the
     one-line slides. At 68px the long headline fits two lines, the reserved
     box drops 238px -> 150px, and slide 1's slack goes to zero.
     Widening the column was the alternative and was rejected: .hero-content
     is 900px so the copy stays clear of the photograph on the right. */
  font-size: clamp(2.5rem, 6vw, 4.25rem);
  color: var(--white);
  line-height: 1.1;
  margin-bottom: 0.75rem;     /* was 1.25rem — paragraph pulled up under it */
}

.hero-sub {
  font-size: 1.1rem;
  color: var(--text-muted);
  max-width: 540px;
  margin-bottom: 1.5rem;      /* was 2rem — button pulled up under it */
  line-height: 1.7;
}

/* Paragraph stack, rotating with the headline. Same grid-in-one-cell approach
   as .hero-headline: the <p> holds the height of the TALLEST paragraph, so
   Apply Now and the stat row below it stay put as the copy changes rather than
   jumping a line-height every five seconds. */
.hero-sub { display: grid; }
.hero-sub-slide {
  grid-area: 1 / 1;
  opacity: 0;
  transition: opacity 900ms ease-in-out;
  pointer-events: none;
}
.hero-sub-slide.is-active { opacity: 1; }

.hero-cta {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 2rem;        /* was 3rem — stat row pulled up */
}

.hero-stats {
  display: flex;
  gap: 1.75rem;
  align-items: center;
  flex-wrap: wrap;
}
.stat { display: flex; flex-direction: column; }

/* Sits above the numeral and reads into it ("Get up to" -> "$1,000,000").
   Its whole job is to be visually distinct from the figure, so it takes the
   opposite of every choice .stat-value makes below: the body face instead of
   Cinzel, light weight instead of 400-weight capitals, small instead of
   display-sized, and muted instead of gold. Wide tracking keeps it legible at
   this size and ties it to .stat-label underneath. */
.stat-prelabel {
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 300;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.45rem;
  text-shadow: 0 1px 3px rgba(0,0,0,0.55);
}

/* Hero numerals. Cinzel is a Trajan-style inscriptional face — it reads as
   engraved capitals, and that elegance depends on restraint:
     · weight 400, not 700. At bold the serifs thicken and the letterforms go
       from carved to chunky. The face carries the presence on its own.
     · open letter-spacing. Inscriptional type was cut with generous spacing;
       tightening it is what makes display serifs look cramped and cheap.
     · a narrow top-lit sheen rather than a three-stop gradient. Light falling
       across a struck surface, not a colour ramp.
     · no glow. Restraint is the whole point — the halo was fighting the serifs.
   `tabular-nums` holds every digit to one width so the count-up cannot make the
   row jitter as it climbs through different figures. */
.stat-value {
  font-family: var(--font-heading);
  /* Fluid so the row scales down between breakpoints instead of wrapping —
     "$2,000,000" is the widest value and drives the whole row's width. */
  font-size: clamp(1.9rem, 3.4vw, 2.75rem);
  line-height: 1.08;
  font-weight: 400;
  letter-spacing: 0.045em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  background: linear-gradient(180deg, var(--gold-light) 0%, var(--gold) 72%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* Fallback for engines without background-clip:text — @supports below. */
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .stat-value { color: var(--gold); background: none; }
}

/* Labels carry the meaning — a number without its unit is noise — so they stay
   bright enough to read against the photograph. Elegance comes from tracking
   rather than weight here: wide-spaced small capitals read as considered, where
   bold small capitals read as shouty. Dropping 600 -> 500 and opening the
   letter-spacing keeps them just as visible while calming them down. */
.stat-label {
  font-size: 0.74rem;
  color: var(--text-light);
  font-weight: 500;
  margin-top: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-shadow: 0 1px 3px rgba(0,0,0,0.55);
}
/* Hairline rule, fading at both ends so it reads as a light separator rather
   than a drawn border. */
.stat-divider {
  width: 1px;
  height: 64px;
  background: linear-gradient(180deg, transparent 0%, var(--gold-dim) 45%, var(--gold-dim) 55%, transparent 100%);
  opacity: 0.75;
}

.hero-graphic {
  position: absolute;
  right: 4%;
  top: 50%;
  transform: translateY(-50%);
  width: 200px;
  opacity: 0.6;
  pointer-events: none;
}

/* ── Page Hero (inner pages) ─────────────────────────────────────────────── */
.page-hero {
  position: relative;
  background:
    linear-gradient(135deg, rgba(11,31,58,0.9) 0%, rgba(22,54,95,0.88) 60%, rgba(28,63,110,0.82) 100%),
    url("/static/images/bg-skyscrapers.jpg") center 70% / cover no-repeat;
  /* Top padding is the section's own 4rem PLUS --nav-height, not instead of it —
     .site-header is `position: sticky`, so at scroll position 0 it still sits in
     normal flow above this section like any other sticky-not-yet-stuck element,
     but the H1 immediately below only cleared it by the thickness of a font
     descender. Shared across all 7 pages using .page-hero (apply, tools,
     contact, the three legal pages, services) since the nav overlaps every one
     of them identically — this is a structural fix, not a services-page-only
     patch. */
  padding: calc(4rem + var(--nav-height)) 0 3.5rem;
  border-bottom: 1px solid var(--gold-dim);
  overflow: hidden;
}
.page-hero .container { position: relative; z-index: 1; }
.page-hero-sm { padding: calc(2.5rem + var(--nav-height)) 0 2rem; }
.page-hero h1 { color: var(--gold); font-size: clamp(1.8rem, 4vw, 3rem); margin: 0.5rem 0; }
.page-hero-sub { color: var(--text-muted); font-size: 1.05rem; max-width: 560px; margin-top: 0.5rem; }

/* ── Sections ────────────────────────────────────────────────────────────── */
.section { position: relative; padding: 5rem 0; }
/* Section surfaces after the palette lift:
     .section-navy  = --navy       (the accent band — use it sparingly)
     .section-pale  = --surface     (white, the default light band)
     .section-light = --surface-alt (very light blue-grey)

   .section-light finally means what it says. It used to be the DARKEST
   surface on the site (--navy-dark), a leftover from the all-dark palette;
   the five pages that used it as a full-width dark slab — apply_sign,
   apply_success and the three legal pages — were moved to .section-pale,
   and its only remaining users are the homepage's two photo sections, which
   already rendered pale through .section-photo's veil. */
.section-navy {
  background-color: var(--navy);
  background-image:
    radial-gradient(circle at 15% 20%, rgba(216,161,35,0.05) 0%, transparent 40%),
    radial-gradient(circle at 85% 80%, rgba(216,161,35,0.04) 0%, transparent 45%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'%3E%3Cg fill='none' stroke='%23CF9026' stroke-opacity='0.04' stroke-width='1'%3E%3Cpath d='M0 40h80M40 0v80'/%3E%3Ccircle cx='40' cy='40' r='2'/%3E%3C/g%3E%3C/svg%3E");
}
.section-light {
  background-color: var(--surface-alt);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60' viewBox='0 0 60 60'%3E%3Ccircle cx='2' cy='2' r='1.4' fill='%23CF9026' fill-opacity='0.05'/%3E%3C/svg%3E");
}

/* ── Section photo backgrounds ───────────────────────────────────────────── */
/* Adds a real photo behind a section with a tinted overlay so content stays readable */
.section-photo { position: relative; background-size: cover; background-position: center; background-attachment: scroll; }
.section-photo::before {
  content: "";
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none;
}
/* Photo overlays. Literal rgba() because they alpha-composite over a photograph
   and cannot reference a var() — so they do NOT follow a token change
   automatically. Update them by hand whenever the palette moves.

   .section-light keeps its pale veil: these two homepage sections are a
   deliberate light break between the dark ones. Because that veil is light, the
   type inside them must be DARK — see the overrides directly below. Only
   .section-photo.section-light is light; a plain .section-light (forms, legal
   pages) is dark and inherits the normal light-on-dark type. */
.section-photo.section-navy::before  { background: linear-gradient(135deg, rgba(11,31,58,0.93) 0%, rgba(22,54,95,0.90) 60%, rgba(28,63,110,0.85) 100%); }
.section-photo.section-light::before { background: linear-gradient(135deg, rgba(237,241,247,0.93) 0%, rgba(237,241,247,0.88) 100%); }
/* .section-pale gets the identical pale veil. It is a separate class from
   .section-light (see the .section-pale block below for why) but the same
   #F2F4F7 surface, so it takes the same two gradient stops at the same 0.93 /
   0.88 opacities rather than a second set tuned by eye — that is what makes
   the services page read as the same component as the homepage. Keep these
   three selectors in step: change one opacity, change its partner. */
.section-photo.section-pale::before  { background: linear-gradient(135deg, rgba(237,241,247,0.93) 0%, rgba(237,241,247,0.88) 100%); }

/* ── Pale surface sections ───────────────────────────────────────────────────
   Opt-in via `.section-pale`, used in place of `.section-light`. Gives a page
   the same pale treatment as the homepage's veiled photo sections.

   Deliberately a separate class rather than a change to `.section-light`:
   that class is also used by /apply, the signing and success pages, all three
   legal pages and /tools, none of which were asked to change. Swap a template
   to `.section-pale` to opt it in.

   Surfaces INSIDE these sections (cards, contact panels, form inputs) stay dark
   on purpose — that dark-panel-on-pale pattern is already how the homepage
   sections read, so their own light-on-dark type keeps working untouched. Only
   type sitting directly on the pale background is darkened here. */
.section-pale {
  /* White, lifted from #F2F4F7 with the palette change — the default light
     band. .section-light carries the blue-grey alternate. */
  background-color: var(--surface);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60' viewBox='0 0 60 60'%3E%3Ccircle cx='2' cy='2' r='1.4' fill='%23D8A123' fill-opacity='0.06'/%3E%3C/svg%3E");
}
.section-pale h1,
.section-pale h2,
.section-pale h3,
.section-pale h4,
.section-pale .service-body h2 { color: var(--navy); }

.section-pale p,
.section-pale li,
.section-pale .section-sub,
.section-pale .service-body p,
.section-pale .service-features li { color: #33404F; }

.section-pale .service-ideal { color: #4A5566; }
.section-pale .form-group label { color: #33404F; }

/* Form controls on a pale surface. The site-wide inputs are dark fields with
   light text, which is correct on the dark pages but reads as broken on a white
   one — a form is the one place users expect the field to be lighter than the
   page, not darker. These give pale sections conventional light inputs.
   Applies to every form inside a .section-pale (currently /apply and /contact),
   so the two stay consistent. */
.section-pale .form-group input,
.section-pale .form-group select,
.section-pale .form-group textarea {
  background: #FFFFFF;
  color: var(--navy);
  border-color: #C2CBD8;
}
/* Placeholders here carry real instructions ("As registered with the state"),
   not decoration, so they are held to the 4.5:1 AA body-text bar rather than
   the usual faint grey — #667382 measures 4.84:1 on white. */
.section-pale .form-group input::placeholder,
.section-pale .form-group textarea::placeholder { color: #667382; }
.section-pale .form-group input:focus,
.section-pale .form-group select:focus,
.section-pale .form-group textarea:focus {
  border-color: var(--gold-deep);
  box-shadow: 0 0 0 3px rgba(216,161,35,0.22);
}
/* Checkbox/radio rows and any loose helper text sitting on the pale surface. */
.section-pale .checkbox-row,
.section-pale .checkbox-row label,
.section-pale small { color: #33404F; }

/* The brand accent is only ~2.1:1 on a pale backdrop, so it fails AA as text.
   Use the darker gold for small type; larger gold headings are unaffected. */
.section-pale .section-eyebrow {
  color: #6B4708;
  text-shadow: none;
}
.section-pale .service-divider { border-top-color: rgba(22,54,95,0.14); }

/* Panels keep their dark treatment and their own light type. */
.section-pale .card h3,
.section-pale .contact-card h3,
.section-pale .contact-card h4 { color: var(--gold); }
.section-pale .card p,
.section-pale .contact-card p,
.section-pale .contact-item p,
.section-pale .contact-item small { color: var(--text-muted); }
.section-pale .contact-item strong { color: var(--text-light); }

/* Dark type for the pale-veil sections — scoped to .section-header ONLY.
   Do not widen these selectors to bare h2/h3/p: the cards inside these sections
   are dark panels (--navy-light), so a descendant rule turns their titles dark-on-dark
   (measured 1.17:1, i.e. invisible). Only the header text sits on the veil;
   everything inside a card keeps the normal light-on-dark treatment.
   The eyebrow needs its own darker gold — the accent is ~2.1:1 here, failing AA. */
.section-photo.section-light > .container > .section-header h2 { color: var(--navy); }
.section-photo.section-light > .container > .section-header .section-sub { color: #33404F; }
.section-photo.section-light > .container > .section-header .section-eyebrow {
  color: #6B4708;
  text-shadow: none;
}
.section-photo > .container { position: relative; z-index: 1; }

/* Each class supplies one photo, two ways: `background-image` for a
   .section-photo band, and --cta-photo for the .cta-banner.cta-photo variant
   above (which needs the URL as a layer inside its own shorthand). Setting
   both means one class works in either place.

   To change a section's photo, change its class in the template — that is the
   only edit required. To add a photo, drop the .jpg in static/images/ and add
   a row here following the same two-line shape. */
.bg-photo-workers     { background-image: url("/static/images/bg-workers.jpg");
                        --cta-photo: url("/static/images/bg-workers.jpg"); }
.bg-photo-framing     { background-image: url("/static/images/bg-framing.jpg");
                        --cta-photo: url("/static/images/bg-framing.jpg"); }
.bg-photo-finance     { background-image: url("/static/images/bg-finance.jpg");
                        --cta-photo: url("/static/images/bg-finance.jpg"); }
.bg-photo-cafe        { background-image: url("/static/images/bg-cafe.jpg");
                        --cta-photo: url("/static/images/bg-cafe.jpg"); }
.bg-photo-crane       { background-image: url("/static/images/bg-crane.jpg");
                        --cta-photo: url("/static/images/bg-crane.jpg"); }
.bg-photo-skyscrapers { background-image: url("/static/images/bg-skyscrapers.jpg");
                        --cta-photo: url("/static/images/bg-skyscrapers.jpg"); }

.section-header { margin-bottom: 3rem; }
.section-eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.5rem;
}
.section-navy .section-eyebrow { color: var(--gold); }
.section-navy h2 { color: var(--white); }
.section-navy .section-sub { color: var(--text-muted); }
.section-sub { color: var(--text-muted); font-size: 1.05rem; max-width: 560px; margin: 0.5rem auto 0; }

/* ── About Us ────────────────────────────────────────────────────────────── */
.about-copy {
  max-width: 720px;
  margin: 0 auto;
}
.about-copy p {
  color: var(--text-muted);
  font-size: 1.05rem;
  line-height: 1.85;
  margin-bottom: 1.5rem;
}
/* Inline company name inside a body paragraph — glow removed entirely.
   At body text size a halo reduces legibility and gains nothing; the gold
   colour and heading font already differentiate it. */
.about-copy .gold {
  font-family: var(--font-heading);
}
/* Closing pull-quote is large enough to carry a glow, but at reduced strength. */
.about-copy .about-closing {
  font-family: var(--font-heading);
  font-size: 1.3rem;
  color: var(--gold);
  text-align: center;
  text-shadow: 0 0 16px rgba(216,161,35,0.25);
  margin-top: 2rem;
  margin-bottom: 0;
}

/* ── Cards ───────────────────────────────────────────────────────────────── */
.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
}

/* Padding tightened from 2rem after the decorative emoji icons were removed
   site-wide — the taller top padding was balanced against a 2.5rem icon plus
   its 1rem margin, and without them the heading sat low in the card. */
.card {
  background: var(--navy-light);
  border: 1px solid rgba(216,161,35,0.18);
  border-radius: 12px;
  padding: 1.6rem 1.5rem;
  position: relative;
  transition: box-shadow var(--transition), transform var(--transition);
}
.card:hover { box-shadow: var(--shadow); transform: translateY(-4px); }

.card-featured {
  background: var(--navy);
  border-color: var(--gold);
  color: var(--text-light);
}
.card-featured h3 { color: var(--gold); }
.card-featured p { color: var(--text-muted); }

.card-badge {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--gold);
  color: var(--navy-dark);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.2rem 0.75rem;
  border-radius: 20px;
}

.card h3 { margin-bottom: 0.75rem; font-size: 1.1rem; }
.card p { color: var(--text-muted); font-size: 0.9rem; margin-bottom: 1.5rem; }

/* .cards-grid's own column rule is auto-fit(minmax(240px,1fr)), which renders
   4 columns inside the 1160px .container — fine where the card count is
   incidental, but the "Why Business Owners Come to Us" grid (services.html)
   needs exactly 3 across on desktop. Pinned here rather than left to auto-fit;
   breakpoints match the existing 900px/768px pair .footer-grid already uses
   below, so this collapses on the same schedule as the rest of the page. */
.situation-grid { grid-template-columns: repeat(3, 1fr); }

/* Homepage "Our Commitments". Same reason as .situation-grid above: with three
   cards, .cards-grid's auto-fit(minmax(240px,1fr)) still lays out 4 tracks at
   this container width and leaves an empty column. Collapses on the same
   schedule as the rest of the page (see the 900/768 breakpoints below). */
.commitments-grid { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .commitments-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) { .commitments-grid { grid-template-columns: 1fr; } }

/* ── Steps ───────────────────────────────────────────────────────────────── */
.steps {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.step {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--gold-dim);
  border-radius: 12px;
  padding: 1.75rem 1.25rem;
  text-align: center;
  flex: 1;
  min-width: 160px;
  max-width: 220px;
}
.step-num {
  font-family: var(--font-heading);
  font-size: 2rem;
  color: var(--gold);
  margin-bottom: 0.75rem;
}
.step h4 { color: var(--white); margin-bottom: 0.5rem; font-size: 1rem; }
.step p { color: var(--text-muted); font-size: 0.85rem; }
.step-arrow { color: var(--gold-dim); font-size: 1.5rem; padding-top: 2.5rem; }

/* Pale-band variant of the step card, used by services' "How it works".
   White-on-off-white was tried first and failed twice over: .step's own
   4%-white fill vanishes on a pale band (and its pure-white h4 measured
   1.0:1 — literally invisible), and a solid white card on #F2F4F7 separates
   by only 1.03:1, so the whole band read as one flat white slab.

   Resolved by inverting instead: the card goes dark navy, matching the
   .card treatment on the "Three ways to get there" band directly above it
   (--navy-light fill, 12px radius, gold accent), so both pale bands on this
   page carry the same dark-card-on-light-ground rhythm. Light text returns,
   which is what .step was built for. Scoped to .section-pale so the
   homepage's own steps, which sit on navy, are untouched. */
.section-pale .step {
  background: var(--navy-light);
  border: 1px solid rgba(216,161,35,0.18);
  border-top: 3px solid var(--gold);
  border-radius: 12px;
  box-shadow: 0 4px 18px rgba(16,24,40,0.14);
}
.section-pale .step h4 { color: var(--white); }
.section-pale .step p  { color: var(--text-muted); }
.section-pale .step-num { color: var(--gold); }
/* Arrows sit on the pale ground between the cards, not on them, so they stay
   dark — the gold-dim base is near-invisible against off-white. */
.section-pale .step-arrow { color: rgba(22,54,95,0.35); }

/* Equal-height step cards, every page. .steps sets align-items:flex-start, so
   each card sized to its own copy — on the homepage's four-step row that gave
   heights of 257 / 192 / 236 / 257, i.e. a ragged bottom edge. Stretch levels
   them to the tallest. Widths were already equal (flex:1 with the 220px cap),
   so the explicit basis just states it rather than leaving it implied.

   This was originally scoped to .services-page and is now general — the
   homepage row had exactly the same problem.

   Confined to the row layout: below 768px .steps switches to
   flex-direction:column and centres the cards, and align-items:stretch there
   would stretch them on the CROSS axis (width) instead, pinning each card to
   the left edge of the column. */
@media (min-width: 769px) {
  .steps { align-items: stretch; }
  .step  { flex: 1 1 220px; }
}

/* ── Testimonials ────────────────────────────────────────────────────────── */
.testimonials-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.5rem;
}
.testimonial {
  background: var(--navy-light);
  border-radius: 12px;
  padding: 1.75rem;
  border: 1px solid rgba(216,161,35,0.18);
}
.testimonial-featured {
  background: var(--navy);
  border-color: var(--gold);
}
.section-navy .testimonial { background: rgba(255,255,255,0.04); border-color: var(--navy-light); }
.section-navy .testimonial-featured { border-color: var(--gold); }
.stars { color: var(--gold); font-size: 1.1rem; margin-bottom: 0.75rem; }
.quote { font-style: italic; color: var(--text-muted); font-size: 0.9rem; line-height: 1.65; margin-bottom: 1rem; }
.testimonial-featured .quote { color: var(--text-muted); }
.section-navy .quote { color: var(--text-muted); }
.testimonial-author strong { display: block; font-size: 0.9rem; color: var(--text-light); }
.testimonial-featured .testimonial-author strong { color: var(--gold); }
.section-navy .testimonial-author strong { color: var(--text-light); }
.testimonial-author span { font-size: 0.8rem; color: var(--text-muted); }
.section-navy .testimonial-author span { color: var(--text-muted); }

/* ── Ratings ─────────────────────────────────────────────────────────────── */
.ratings-row {
  display: flex;
  justify-content: center;
  gap: 2rem;
  flex-wrap: wrap;
  margin-bottom: 2rem;
}
.rating-badge {
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--gold-dim);
  border-radius: 12px;
  padding: 1.5rem 2rem;
  text-align: center;
  min-width: 160px;
}
.rating-logo { font-family: var(--font-heading); color: var(--gold); font-size: 1rem; margin-bottom: 0.5rem; }
.rating-stars { color: var(--gold); font-size: 1.1rem; margin-bottom: 0.25rem; }
.rating-score { color: var(--white); font-size: 1.25rem; font-weight: 700; }
.rating-count { color: var(--text-muted); font-size: 0.8rem; margin-top: 0.25rem; }

/* ── Services page ───────────────────────────────────────────────────────── */
.service-row {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 2.5rem;
  align-items: start;
  padding: 1rem 0;
}
.service-row-reverse { grid-template-columns: 1fr 100px; }
.service-row-reverse .service-icon-col { order: 2; }
.service-row-reverse .service-body { order: 1; }

.service-icon-wrap {
  width: 80px;
  height: 80px;
  background: var(--navy);
  border: 2px solid var(--gold-dim);
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.2rem;
}
.service-body h2 { color: var(--text-light); margin-bottom: 0.75rem; font-size: 1.5rem; }
.service-body p { color: var(--text-muted); margin-bottom: 1rem; line-height: 1.7; }
.service-features { margin: 0.75rem 0 1rem; padding-left: 1.2rem; list-style: disc; }
.service-features li { color: var(--text-muted); font-size: 0.9rem; margin-bottom: 0.35rem; }
.service-ideal { font-size: 0.9rem; color: #666; margin-bottom: 1.25rem; }
.service-divider { border: none; border-top: 1px solid rgba(216,161,35,0.18); margin: 2.5rem 0; }

/* ── Services page redesign (scoped to .services-page) ──────────────────────
   Everything below is deliberately scoped under .services-page rather than
   changed on the shared h1-h5/section-header/card rules above. The brief was
   to redesign THIS page's typography and cards, not the site's — Cinzel on
   h2-h5 and the dark .card treatment are both still correct on every other
   page (home, tools, contact, the legal pages) and stay untouched there. */

/* Cinzel is a Trajan-style inscriptional face with no true lowercase — its
   "lowercase" glyphs are just smaller capitals, which is what reads as
   small-caps on every heading site-wide and makes a copy-dense page like this
   one feel heavy. The H1 keeps it (rule below re-asserts it explicitly,
   since the override underneath is a plain element selector); h2 down to h5
   drop to the body face at a normal weight so the page reads as text again,
   not as an inscription. */
.services-page h1 { font-family: var(--font-heading); }
.services-page h2,
.services-page h3,
.services-page h4,
.services-page h5 {
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
}

/* Pain-point cards ("Why Business Owners Come to Us"). Previously the shared
   dark .card (navy-light bg, gold h3) at a harsh jump straight off the pale
   Scoped to .services-page rather than to a section background class: this
   page alternates navy/pale bands, and keying the white card to .section-pale
   meant the cards fell back to the dark shared .card — invisible — the moment
   their band flipped to navy. White cards read correctly on both bands, and
   the .services-page path still outranks .section-pale .card h3/p (equal
   specificity, resolved by source order) regardless of rule order. */
.services-page .situation-grid .card {
  background: #FFFFFF;
  border: 1px solid #E3E7EE;
  border-top: 3px solid var(--gold);
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(16,24,40,0.06);
}
.services-page .situation-grid .card:hover {
  /* .card's base hover (var(--shadow)) is tuned for a dark card on a dark
     section — near-black at 30% opacity reads as a smudge on white. A
     lift with no colour is enough feedback here. */
  box-shadow: 0 6px 20px rgba(16,24,40,0.10);
}
.services-page .situation-grid .card h3 {
  color: #101828;             /* near-black, not the section's default navy */
  font-size: 1.05rem;
  margin-bottom: 0.6rem;
}
.services-page .situation-grid .card p {
  color: #475467;             /* dark grey body text */
  margin-bottom: 0;           /* no CTA below it any more to space away from */
}

/* Product cards ("Three ways to get there"): equal height, with the button
   pinned to the bottom edge of each so the three line up on one horizontal
   line regardless of how many lines of copy sit above them.

   Three things are needed and all three are load-bearing:
     1. stretch on the grid items — otherwise each card sizes to its own copy;
     2. the card itself becomes a column flex container;
     3. margin-top:auto on the button eats the leftover space above it.
   Drop any one and the buttons go ragged again. .cards-grid is a grid, whose
   default align-items IS stretch, but .card sets no height behaviour of its
   own, so the button would still sit directly under the last paragraph.

   :not(.situation-grid) matters — the six pain-point cards below share the
   .cards-grid class, and without it they get the flex treatment too even
   though they have no button. */
.services-page .cards-grid:not(.situation-grid) .card {
  display: flex;
  flex-direction: column;
}
.services-page .cards-grid:not(.situation-grid) .card .card-cta {
  margin-top: auto;
  align-self: flex-start;   /* button sized to its label, not full card width */
}
/* .card p carries a 1.5rem bottom margin intended for cards that end on text.
   Here the button provides the breathing room, so the last paragraph before
   it doesn't need to as well. */
.services-page .cards-grid .card p:last-of-type { margin-bottom: 1.25rem; }

/* Gap between cards, and the vertical rhythm above the grid, both widened —
   the tighter spacing read as a dense block rather than six distinct cards. */
.services-page .situation-grid { gap: 2.5rem; }
.services-page .pain-points .section-header { margin-bottom: 4rem; }
.services-page .pain-points .section-header .section-sub { margin-top: 1rem; }

/* ── Post-footer fine print ──────────────────────────────────────────────────
   The marketplace disclosure, rendered into base.html's post_footer block so
   it is the last element on the page. It used to sit in its own pale band
   directly under the CTA at full body size, where it competed with the Apply
   Now button; it is now fine print, below the footer.

   Still legible, not hidden: 0.78rem at 1.65 line-height, and the grey below
   clears AA. A disclosure nobody can read is worse than no disclosure, so do
   not shrink or lighten this further. */
.page-fine-print {
  background: var(--navy-dark);            /* continues the footer's ground */
  padding: 0 0 2rem;
}
.marketplace-note {
  border-left: 3px solid var(--gold);      /* gold bar kept, per the brief */
  background: rgba(216,161,35,0.05);
  border-radius: 0 6px 6px 0;
  padding: 0.85rem 1.1rem;
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.65;
  /* Muted grey on the dark ground. Measured 7.0:1 against --navy-dark, so it
     clears AA at this size with room to spare while still reading as
     secondary to everything above it. */
  color: #9AA4B2;
}
.marketplace-note strong { color: #C3CBD6; font-weight: 600; }
.marketplace-note a { color: var(--gold); text-decoration: underline; }
.marketplace-note a:hover { color: var(--gold-light); }

/* ── Industries We Serve ─────────────────────────────────────────────────────
   Replaces the removed "Do you qualify?" grid and keeps its three-column
   rhythm (12 trades = 4 clean rows). Text only, no icons. Colours are set for
   the navy band it sits on; the gold left rule is the only accent. */
.industries-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.85rem 2.5rem;
}
.industries-grid li {
  color: var(--text-light);
  font-size: 1rem;
  padding: 0.65rem 0 0.65rem 1rem;
  border-left: 2px solid var(--gold-dim);
  transition: border-color var(--transition), color var(--transition);
}
.industries-grid li:hover { border-left-color: var(--gold); color: var(--white); }
.industries-note {
  margin-top: 2.25rem;
  color: var(--text-muted);
  font-size: 1rem;
}
@media (max-width: 900px) { .industries-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .industries-grid { grid-template-columns: 1fr; gap: 0.4rem 0; } }

/* ── Services page CTA ───────────────────────────────────────────────────────
   The page's band order now finishes DARK: the CTA is navy so the gold Apply
   Now button carries maximum contrast against it. That is exactly what the
   shared .cta-banner already does, so the pale overrides that used to live
   here (a #F2F4F7 CTA, plus a matching light .site-footer reached via
   :has()) are gone rather than rewritten. Removing the footer override also
   ends the inconsistency where /services was the only page with a light
   footer — the footer is dark site-wide again. Nothing page-specific is
   needed here now; this comment marks that the absence is deliberate. */

/* ── CTA Banner ──────────────────────────────────────────────────────────── */
.cta-banner {
  position: relative;
  background: linear-gradient(135deg, var(--navy-dark) 0%, var(--navy-light) 100%);
  border-top: 1px solid var(--gold-dim);
  border-bottom: 1px solid var(--gold-dim);
  padding: 4rem 0;
  overflow: hidden;
}
/* Photo variant of the CTA banner. The gradient, sizing and focal point used
   to be hardcoded alongside a single bg-crane.jpg URL, so a second page could
   not reuse the treatment without copying all four values and drifting from
   them. They now live here once, and the photo arrives through --cta-photo,
   set by whichever .bg-photo-* class is on the element. Both the homepage and
   the services page hit this exact rule — that is the "same component"
   requirement — and only the image differs.

   .bg-photo-* also sets `background-image` directly (for .section-photo
   sections); this rule is two classes to their one, so the layered shorthand
   here wins on the CTA regardless of source order. */
.cta-banner.cta-photo {
  background-image:
    linear-gradient(135deg, rgba(11,31,58,0.92) 0%, rgba(28,63,110,0.88) 100%),
    var(--cta-photo);
  background-size: cover;
  background-position: center 30%;
}
.cta-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(ellipse at 50% 120%, rgba(216,161,35,0.1) 0%, transparent 60%);
  pointer-events: none;
}
.cta-banner .container { position: relative; z-index: 1; }
.cta-banner h2 { color: var(--white); margin-bottom: 0.75rem; }
.cta-banner p { color: var(--text-muted); margin-bottom: 1.75rem; font-size: 1.05rem; }

/* ── Forms ───────────────────────────────────────────────────────────────── */
.form-group { display: flex; flex-direction: column; gap: 0.35rem; }
.form-group label {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 0.65rem 0.85rem;
  border: 1.5px solid #ccd3de;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: 0.9rem;
  background: var(--navy-light);
  color: var(--text-light);
  transition: border-color var(--transition), box-shadow var(--transition);
  outline: none;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(216,161,35,0.15);
}
.form-group input::placeholder,
.form-group textarea::placeholder { color: #aab; }
.form-group textarea { resize: vertical; min-height: 90px; }

.req { color: var(--danger); }

/* Alert boxes */
.alert {
  padding: 1rem 1.25rem;
  border-radius: var(--radius);
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
}
.alert-error {
  background: rgba(224,82,82,0.1);
  border: 1px solid var(--danger);
  color: var(--danger);
}
.alert-error ul { margin-top: 0.5rem; padding-left: 1.2rem; list-style: disc; }
.alert-success {
  background: rgba(60,184,120,0.1);
  border: 1px solid var(--success);
  color: var(--success);
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.site-footer {
  background: var(--navy-dark);
  border-top: 1px solid var(--gold-dim);
  color: var(--text-muted);
  padding-top: 3.5rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 2.5rem;
  padding-bottom: 3rem;
}
.footer-brand .logo-text { font-size: 1.1rem; display: block; margin-bottom: 0.75rem; }
.footer-tagline { color: var(--text-muted); font-size: 0.9rem; font-style: italic; }
.footer-grid h4 {
  color: var(--gold);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 1rem;
}
.footer-links ul li, .footer-legal ul li { margin-bottom: 0.5rem; }
.footer-links a, .footer-legal a {
  color: var(--text-muted);
  font-size: 0.88rem;
  transition: color var(--transition);
}
.footer-links a:hover, .footer-legal a:hover { color: var(--gold); text-decoration: none; }
.footer-contact p { font-size: 0.88rem; margin-bottom: 0.4rem; }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.06);
  padding: 1.25rem 0;
  font-size: 0.8rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
/* Was rgba(154,167,184,0.6) — the pre-lift --text-muted at 60% alpha, which
   measured 3.3:1 on the new lighter footer ground and failed AA. A solid
   colour rather than an alpha knock-back, because the alpha was what pushed
   it under: this is the legal disclaimer and it has to be readable. */
.disclaimer { color: #8FA0B8; font-size: 0.75rem; }

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .service-row, .service-row-reverse {
    grid-template-columns: 1fr;
  }
  .service-row-reverse .service-icon-col { order: 0; }
  .service-row-reverse .service-body { order: 0; }
  .situation-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 768px) {
  .nav-links, .nav-actions { display: none; }
  .nav-links.open, .nav-actions.open { display: flex; }

  .nav-toggle { display: flex; }

  .navbar {
    flex-wrap: wrap;
    height: auto;
    padding: 0.75rem 0;
  }

  .nav-links {
    flex-direction: column;
    width: 100%;
    background: var(--navy);
    border-top: 1px solid var(--gold-dim);
    padding: 1rem 0;
    gap: 0;
  }
  .nav-link { padding: 0.65rem 1rem; display: block; }

  .nav-actions {
    flex-direction: column;
    width: 100%;
    padding: 0.5rem 1rem 1rem;
    gap: 0.5rem;
  }
  .nav-actions .btn { text-align: center; }

  .hero-graphic { display: none; }
  .hero-stats { gap: 1.25rem; }
  .stat-divider { display: none; }
  .steps { flex-direction: column; align-items: center; }
  .step-arrow { transform: rotate(90deg); padding: 0; }
  .footer-grid { grid-template-columns: 1fr; }
  .situation-grid { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
  .hero-headline { font-size: 2.2rem; }
  .hero-cta { flex-direction: column; }
  .btn-lg { width: 100%; }
}

/* ── Discuss Now — Inquiry Modal ─────────────────────────────────────────── */
.discuss-modal-overlay {
  display: none;
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(11,31,58,0.85);
  align-items: center; justify-content: center;
  padding: 2rem 1rem;
  overflow-y: auto;
}
.discuss-modal-overlay.open { display: flex; }
.discuss-modal-box {
  background: var(--navy-light);
  border: 2px solid var(--gold);
  border-radius: 12px;
  width: 100%; max-width: 560px;
  padding: 2.5rem 2rem;
  position: relative;
  box-shadow: 0 0 40px rgba(216,161,35,0.35);
}
.discuss-modal-box h3 {
  color: var(--text-light);
  font-size: 1.4rem;
  margin-bottom: 0.4rem;
}
.discuss-modal-sub {
  color: #666;
  font-size: 0.9rem;
  margin-bottom: 1.5rem;
}
.discuss-modal-close {
  position: absolute;
  top: 1rem; right: 1rem;
  background: none; border: none;
  font-size: 1.2rem; cursor: pointer;
  color: #999; line-height: 1;
}
.discuss-modal-close:hover { color: var(--gold); }
.discuss-error-banner {
  display: none;
  background: rgba(224,82,82,0.1);
  border: 1px solid var(--danger);
  border-radius: 8px;
  padding: 0.85rem 1.1rem;
  margin-bottom: 1.25rem;
  color: #b03030;
  font-size: 0.88rem;
}
.discuss-error-banner.visible { display: block; }
@media (max-width: 600px) {
  .discuss-modal-box { padding: 2rem 1.25rem; }
}

/* ── Legal Documents (Privacy Policy, Terms of Service, Disclosures) ─────────
   These three pages moved from a dark slab to the white .section-pale surface
   with the palette lift, so every colour here was inverted. The old values
   (--text-light headings, --text-muted body) were light-on-dark and measured
   around 1.1:1 on white — invisible, not merely low-contrast.

   Measured on #FFFFFF: headings #101828 17.75:1, body #33404F 10.57:1,
   meta #5A6B80 5.96:1. */
.legal-doc { max-width: 800px; margin: 0 auto; }
.legal-doc .legal-meta {
  color: #5A6B80; font-size: 0.85rem; margin-bottom: 2rem;
  padding-bottom: 1rem; border-bottom: 1px solid #e0e4ea;
}
.legal-doc h2 {
  color: #101828; font-size: 1.3rem;
  margin-top: 2.25rem; margin-bottom: 0.85rem;
  padding-bottom: 0.5rem; border-bottom: 2px solid var(--gold);
}
.legal-doc h2:first-of-type { margin-top: 0; }
.legal-doc h3 { color: #101828; font-size: 1.05rem; margin-top: 1.5rem; margin-bottom: 0.6rem; }
.legal-doc p { color: #33404F; font-size: 0.95rem; line-height: 1.75; margin-bottom: 1rem; }
.legal-doc ul, .legal-doc ol { color: #33404F; font-size: 0.95rem; line-height: 1.75; margin: 0 0 1rem 1.3rem; }
.legal-doc li { margin-bottom: 0.4rem; }
.legal-doc strong { color: #101828; }
/* Inline links in body copy: --gold is ~2.1:1 on white. #6B4708 is the
   established gold-on-light value used across the site (7.53:1). */
.legal-doc a { color: #6B4708; text-decoration: underline; }
.legal-doc a:hover { color: var(--navy-dark); }
.legal-doc .legal-callout {
  background: rgba(216,161,35,0.08);
  border-left: 4px solid var(--gold);
  border-radius: 6px;
  padding: 1rem 1.25rem;
  margin: 1.25rem 0;
  font-size: 0.92rem;
  color: #33404F;               /* was --text-muted: 1.6:1 on the white surface */
}
.legal-doc .legal-contact {
  background: var(--navy);
  border-radius: 8px;
  padding: 1.5rem 1.75rem;
  margin-top: 2.5rem;
  color: var(--text-light);
}
.legal-doc .legal-contact h3 { color: var(--gold); margin-top: 0; }
.legal-doc .legal-contact p { color: var(--text-light); margin-bottom: 0.4rem; }
/* The .legal-doc colour inversions above are descendant rules, so they reach
   INTO this navy panel and turned its <strong> near-black on navy (1.46:1).
   Everything inside a dark panel keeps the light-on-dark treatment. */
.legal-doc .legal-contact strong,
.legal-doc .legal-contact a { color: var(--text-light); }
.legal-doc .legal-toc a { color: var(--text-light); text-decoration: none; }
.legal-doc .legal-toc a:hover { color: var(--gold); }
/* .legal-toc and .legal-contact stay NAVY PANELS on the white page — that is
   the dark-card-on-light-surface pattern used everywhere else on the site, and
   it keeps navy present as an accent. Their inner type stays light-on-dark,
   which is why it is not inverted below. */
.legal-toc {
  background: var(--navy-light);
  border: 1px solid #e0e4ea;
  border-radius: 8px;
  padding: 1.25rem 1.5rem;
  margin-bottom: 2rem;
}
.legal-toc h4 { color: var(--text-light); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 0.75rem; }
.legal-toc ol { margin: 0 0 0 1.2rem; font-size: 0.88rem; }
.legal-toc a { color: var(--text-light); }
.legal-toc a:hover { color: var(--gold); }

/* ── Checkboxes ─────────────────────────────────────────────────────────────
   One look for every checkbox on the site (today: the e-sign consent and the
   mailing-address box). The consent carries ESIGN weight, so it has to be
   unmistakable and easy to hit with a thumb.
   - 22px box with a 2px navy border: 15:1 against the cream consent panel.
   - Checked: brand gold fill with a dark navy tick.
   - The box never shrinks (flex-shrink:0) and aligns with the FIRST line of a
     wrapped label, with a 12px gap.
   - Tap target: the whole row is at least 44px tall and full width, and a tap
     anywhere on it toggles the box (see main.js); links inside still work. */
.checkbox-row {
  display: flex; align-items: flex-start; gap: 12px;
  margin: 0.25rem 0; padding: 11px 0; min-height: 44px; cursor: pointer;
}
.checkbox-row label { flex: 1 1 auto; min-width: 0; margin: 0; line-height: 1.5; cursor: pointer; }
input[type="checkbox"] {
  -webkit-appearance: none; appearance: none;
  position: relative; box-sizing: border-box;
  flex: 0 0 22px; flex-shrink: 0;
  width: 22px; height: 22px; min-width: 22px; margin: 1px 0 0; padding: 0;
  border: 2px solid var(--navy-dark); border-radius: 5px; background-color: #FFFFFF;
  cursor: pointer;
}
input[type="checkbox"]:checked {
  background-color: var(--gold);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4 10.5l4 4 8-9' fill='none' stroke='%230B1F3A' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: center; background-repeat: no-repeat; background-size: 100%;
}
input[type="checkbox"]:focus-visible { outline: 3px solid var(--navy-dark); outline-offset: 3px; }

/* ── Contrast fixes found by the site-wide scan (WCAG AA, 4.5:1) ──────────────
   Required-field asterisk: --danger (#e05252) is 3.8:1 on white. */
.section-pale .req { color: #A31F1F; }
/* Outline buttons use gold text, which is 2.3:1 on a pale section. */
.section-pale .btn-outline { color: var(--navy); border-color: var(--navy); }
.section-pale .btn-outline:hover { background: var(--navy); color: #FFFFFF; }

