/* ---------- Barlow Semi Condensed (self-hosted) ----------
   Was loaded from fonts.googleapis.com, which cost two extra DNS/TLS
   handshakes on the render-blocking path and sent every visitor's IP to
   Google. The usual argument for the CDN — a shared cross-site cache — has
   not applied since browsers partitioned the HTTP cache, so every visitor
   was downloading these fresh anyway.

   Licence: SIL Open Font License 1.1, which permits redistribution.

   font-display: swap preserves what '&display=swap' did on the old URL:
   text paints immediately in the fallback face rather than staying
   invisible while the webfont loads.

   Paths are relative, not root-relative: a CSS url() resolves against the
   STYLESHEET, not the document, and styles.css sits at the site root — so
   'assets/fonts/x.woff2' is correct from /updates/<slug> just as from /.
   Root-relative works when served but breaks the page opened straight off
   disk over file://, which is a real way this project gets viewed.

   Vietnamese subsets are deliberately not shipped; latin and latin-ext
   cover this site. unicode-range means a visitor only downloads the subset
   their content actually needs. */

@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/barlow-semi-condensed-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('assets/fonts/barlow-semi-condensed-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('assets/fonts/barlow-semi-condensed-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('assets/fonts/barlow-semi-condensed-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('assets/fonts/barlow-semi-condensed-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Semi Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('assets/fonts/barlow-semi-condensed-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Figma variable collection */
  --bass-blue-dark: #0C3D7A;
  --bass-blue-light: #0B8BE5;
  --bass-accent: #FABA26;
  --bass-accent-hover: #FFC94A;
  --blue-darkest: #001833;
  --bg: #EDEEED;
  --eyebrow-gray: #EDEEED;
  --blue-darker: #022758;
  --white: #FFFFFF;
  --black: #1F2226;

  /* --bass-blue-light lifted ~20% toward white, for small text on a dark
     background. The brand blue is only about 4.9:1 on --blue-darkest at body
     sizes, and less than that where it sits over the hero photo rather than
     flat navy; this reads as the same blue at 6.4:1. Not a replacement for
     --bass-blue-light, which is also used on white and does not need it. */
  --bass-blue-light-on-dark: #3CA2EA;

  /* Channel forms of the colors above, for rgba(var(--x-rgb), <alpha>) */
  --blue-darker-rgb: 2,39,88;
  --blue-darkest-rgb: 0,24,51;
  --bass-accent-rgb: 250,186,38;
  --bass-blue-light-rgb: 11,139,229;
  --white-rgb: 255,255,255;

  --max: 1208px;
  --gutter: 36px;
  --radius: 0;

  /* Rendered stroke weight for the large content icons (cards, features,
     confirmations). These sets are not drawn at one scale — the card set is on a
     24 viewBox and the feature set on a 128 — so a raw stroke-width means a
     different rendered weight in each. Every use site therefore converts this
     token into that icon's own units with `* viewBox / rendered-px`, which is
     why each rule carries that calc rather than the bare token.

     This used to be done with vector-effect: non-scaling-stroke instead, which
     is tidier but leans on the least consistently implemented corner of SVG:
     Chrome rendered the feature icons at half weight. The calc is arithmetic
     every engine agrees on. The tradeoff is that it hardcodes the rendered size
     — if an icon box becomes fluid (clamp(), a breakpoint override), update the
     divisor to match or the sets silently drift apart again.

     Small inline icons (link arrows, nav chevrons, contact rows) are NOT on this
     token and should not be — they sit around 2px, and 3.5px on an 18px arrow
     would read as a different, much heavier icon set. */
  --icon-stroke: 3.5px;

  --ease: cubic-bezier(.22,.61,.36,1);
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: "Barlow Semi Condensed", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  /* 500 is the lightest face we load (see the wght@500;600;700 request in
     each page head). Stated explicitly so unweighted text can't silently
     get lighter if a 400 face is ever added to that request — it currently
     renders at 500 only because the browser falls back to the nearest
     available weight. */
  font-weight: 500;
  color: var(--blue-darker);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; height: auto; }
button { font: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
.accent { color: var(--bass-accent); }
ul { list-style: none; margin: 0; padding: 0; }

.container {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--bass-accent); color: var(--blue-darker);
  padding: 8px 14px; font-weight: 700; z-index: 100;
}
.skip-link:focus { left: 8px; top: 8px; }

/* ============================================================
   LOGO
   ============================================================ */
.logo {
  display: inline-flex; align-items: center;
  flex-shrink: 0; /* never let the brand mark compress in the header row */
  transition: transform .25s var(--ease), opacity .25s var(--ease);
}
.logo:hover { transform: translateY(-1px); opacity: .9; }
.logo img {
  display: block;
  width: 200px; height: auto;
  user-select: none;
}
.site-header .logo img { width: 220px; }

/* ============================================================
   SITE HEADER (nav over hero)
   ============================================================ */
.site-header {
  position: absolute; inset: 0 0 auto 0;
  display: flex; align-items: center;   /* centres the row inside the taller band */
  min-height: 140px;
  padding-top: 28px; padding-bottom: 28px;
  z-index: 4;
  transition: padding .25s var(--ease), min-height .25s var(--ease), background-color .25s var(--ease), box-shadow .25s var(--ease);
}
/* Scrolled state: anchor to the top as a narrow dark-blue band. Toggled by
   site.js (`is-stuck`) once the user scrolls down; removed back at the top. */
.site-header.is-stuck {
  position: fixed;
  background: var(--blue-darkest);
  min-height: 0;                      /* the taller band is the un-scrolled state only */
  padding-top: 12px; padding-bottom: 12px;
  z-index: 50;
  box-shadow: 0 10px 15px rgba(0,0,0,.55);
}
.nav-home-mobile { display: none; }

.nav-close {
  display: none;
  position: absolute;
  top: 22px; right: 18px;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  background: transparent;
  border: 0;
  color: var(--white);
  cursor: pointer;
  padding: 0;
  transition: color .2s var(--ease), transform .2s var(--ease);
}
.nav-close svg { width: 26px; height: 26px; display: block; }
.nav-close:hover, .nav-close:focus-visible { color: var(--bass-accent); }
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px;
}

/* flex:1 + flex-end matters now that the phone is a third child of
   __inner: with plain space-between the row would spread to
   logo · nav · phone and drag the nav into the middle. Letting the nav
   absorb the free space and right-align its own contents keeps the
   desktop row reading logo ......... nav · CTA · phone. */
.nav { display: flex; align-items: center; gap: 16px; flex: 1; justify-content: flex-end; }
/* Two-class selector so these beat the base `.btn` rules (which appear later
   in the file with equal specificity). Text size matches the nav items (16px). */
.btn.site-header__cta {
  padding: 7px 13px;
  font-size: 16px; letter-spacing: .5px;
  white-space: nowrap; flex-shrink: 0;
  margin: 0 9px;                    /* breathing room from the nav items and the phone */
}

/* CTA + phone side by side, right side of the nav (Figma 267:1929 "actions") */
.site-header__actions {
  display: flex; flex-direction: row;
  align-items: flex-start;
  justify-content: center;
  gap: 8px;
  flex-shrink: 0;
}
/* Phone treatment mirrors the coming-soon page: white vanity line with the
   dialable number in light blue underneath, both shifting to accent on hover.
   Right-aligned so it sits flush to the container edge beside the CTA. */
.site-header__phone {
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 1px;
  text-decoration: none;
  text-align: right;
  line-height: 1.15;
  color: var(--white);
}
.site-header__phone-vanity {
  font-size: 13px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase;
  transition: color .25s var(--ease);
}
.site-header__phone-num {
  font-size: 13px; font-weight: 600; letter-spacing: .5px;
  color: var(--bass-blue-light-on-dark);
  transition: color .25s var(--ease);
}
.site-header__phone:hover .site-header__phone-vanity,
.site-header__phone:focus-visible .site-header__phone-vanity,
.site-header__phone:hover .site-header__phone-num,
.site-header__phone:focus-visible .site-header__phone-num { color: var(--bass-accent); }

.nav > ul {
  display: flex; gap: 34px;
  align-items: baseline;
}
.nav > ul > li { position: relative; }
.nav > ul > li > a,
.nav > ul > li > .nav__top {
  color: var(--bass-accent);
  font-weight: 700; font-size: 16px; letter-spacing: 0.5px;
  line-height: 1;
  text-transform: uppercase;
  padding: 6px 0;
  position: relative;
  background: transparent; border: 0; cursor: pointer;
  transition: color .25s var(--ease);
}
.nav > ul > li > a {
  display: inline-flex; align-items: center; gap: 8px;
}
.nav > ul > li > .nav__top {
  display: inline-flex; align-items: baseline; gap: 6px;
}
.nav__top > a {
  padding: 0;
  display: inline;
  line-height: inherit;
  letter-spacing: inherit;
}
.nav__top svg {
  width: 12px; height: 8px;
  flex-shrink: 0;
  align-self: center;
}
.nav > ul > li > a::after,
.nav > ul > li > .nav__top::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -6px;
  height: 4px;
  background: var(--white);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .35s var(--ease);
}
.nav > ul > li:hover > a,
.nav > ul > li:focus-within > a,
.nav > ul > li:hover > .nav__top,
.nav > ul > li:focus-within > .nav__top { color: var(--white); }
.nav__top:hover > a,
.nav__top:focus-visible > a { color: inherit; }
.nav > ul > li > a:hover::after,
.nav > ul > li > a:focus-visible::after { transform: scaleX(1); }
.nav > ul > li.is-current > a,
.nav > ul > li.is-current > .nav__top { color: var(--white); }
.nav > ul > li.is-current > .nav__top svg { color: var(--bass-accent); }
/* On hover/focus the whole item goes white — including the current-page caret */
.nav > ul > li.is-current:hover > .nav__top svg,
.nav > ul > li.is-current:focus-within > .nav__top svg { color: var(--white); }
.nav > ul > li.is-current > a::after,
.nav > ul > li.is-current > .nav__top::after { transform: scaleX(1); background: var(--white); }

/* Dropdown */
.nav__sub {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  width: max-content;
  /* Sized so the longest label that is meant to stay on one line fits with
     headroom: "Commercial Real Estate" needs 159px, and 212px less the 44px
     of horizontal padding leaves 168px. At the old 204px it cleared by a
     single pixel, so any wider fallback font (before Barlow loads) wrapped
     it. Genuinely long labels — "Breaker & Component Sourcing" and the like
     — still wrap onto two lines by design. */
  max-width: 212px;
  background: var(--blue-darkest);
  padding: 12px 0;
  opacity: 0; visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .25s var(--ease), transform .25s var(--ease), visibility 0s linear .25s;
  box-shadow: 0 14px 40px -12px rgba(0,0,0,.5);
  z-index: 10;
}
.nav__sub::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 4px;
  background: var(--white);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .35s var(--ease);
}
.nav > ul > li:hover > .nav__sub::before,
.nav > ul > li:focus-within > .nav__sub::before { transform: scaleX(1); }
.nav__sub li { display: block; }
.nav__sub a {
  display: block;
  padding: 10px 22px;
  font-size: 14px; letter-spacing: 0.5px; line-height: 1.3;
  color: var(--bass-accent);
  text-transform: uppercase;
  transition: background .2s var(--ease), color .2s var(--ease), padding-left .2s var(--ease);
}
.nav__sub a::after { display: none; }
/* Slight indent on hover — text nudges 4px right, hit area stays put.
   padding-right drops by the same 4px the left gains, so the content box
   keeps its width. Growing padding-left alone narrowed the text area on
   hover, which wrapped labels that only just fit ("Commercial Real Estate"
   needs 159px of a 160px box — it wrapped the moment hover took 4px). */
.nav__sub a:hover, .nav__sub a:focus-visible {
  color: var(--white);
  padding-left: 26px;
  padding-right: 18px;
}
/* Featured dropdown entry (NFPA 70B). Lifted out of the yellow list with a
   white bolder label, an accent bar down its left edge, and a rule beneath
   that separates it from the rest of the menu. No hover-background rule here
   on purpose — the mobile menu strips backgrounds and this would outrank it. */
.nav__sub li.is-featured {
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(var(--white-rgb), .14);
}
.nav__sub li.is-featured a {
  color: var(--white);
  font-weight: 700;
  box-shadow: inset 3px 0 0 var(--bass-accent);
}
.nav > ul > li:hover > .nav__sub,
.nav > ul > li:focus-within > .nav__sub {
  opacity: 1; visibility: visible;
  transform: translateY(0);
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}

/* When site header sits on a light background instead of over the hero */
.site-header--solid {
  position: relative;
  background: var(--blue-darkest);
}
.site-header--solid .nav > ul > li > a,
.site-header--solid .nav > ul > li > .nav__top { color: var(--bass-accent); }

.nav-toggle {
  display: none;
  background: transparent; border: 0;
  width: 44px; height: 44px;
  padding: 10px; gap: 5px;
  flex-direction: column; justify-content: center;
  position: relative; z-index: 5;
}
.nav-toggle span {
  display: block; height: 2px; background: var(--white);
  transition: transform .3s var(--ease), opacity .2s var(--ease);
  transform-origin: center;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  position: relative;
  min-height: 576px;
  color: var(--white);
  background: var(--blue-darkest);
  overflow: hidden;
  padding-bottom: 80px;
  /* No isolation here: it would make .hero a stacking context and trap the
     fixed (stuck) header inside it, letting later sections paint over it.
     The hero's own layering is handled by child z-indexes. */
}
.hero__bg {
  position: absolute; inset: 0;
  z-index: 0;
  /* Same tint pipeline as .page-hero__photo — see there for the reasoning.
     The isolation belongs on THIS element and not on .hero: isolating the
     hero itself would trap the fixed header (see the note above), while
     isolating the background only confines the blend, and the header is a
     sibling of this element rather than a child. */
  background: var(--bass-blue-dark);
  isolation: isolate;
}
.hero__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  mix-blend-mode: luminosity;
  /* hero-home.webp has a mean luminance of 100, so .30 lands it on the ~30 the
     two heroes share. See .page-hero__img for why the value is per-photo. */
  filter: brightness(.30) contrast(1.08);
  transform: scale(1.04);
  animation: heroZoom 16s var(--ease) forwards;
}
@keyframes heroZoom {
  to { transform: scale(1); }
}
/* A legibility scrim only. The blue now comes from the blend above, so the
   uniform 22% darkening layer and the heavy tinting stops that used to live
   here are gone — they would be tinting an already-tinted result. What is
   left is the darkening the text actually needs: the left where the h1 and
   lede sit, the top under the transparent header, and the bottom edge. */
.hero__overlay {
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(var(--blue-darkest-rgb),0.93) 0%, rgba(var(--blue-darkest-rgb),0.70) 38%, rgba(var(--blue-darkest-rgb),0.32) 70%, rgba(var(--blue-darkest-rgb),0.50) 100%),
    linear-gradient(180deg, rgba(var(--blue-darkest-rgb),0.80) 0%, rgba(var(--blue-darkest-rgb),0.64) 12%, rgba(var(--blue-darkest-rgb),0.08) 40%, rgba(var(--blue-darkest-rgb),0.08) 68%, rgba(var(--blue-darkest-rgb),0.62) 100%);
}
.hero__mark {
  position: absolute;
  top: 50%;
  right: -4%;
  height: 105%;
  width: auto;
  transform: translateY(-50%) translateX(40px);
  opacity: 0;
  pointer-events: none;
  animation: heroMarkIn 1.4s .25s var(--ease) forwards;
}
@keyframes heroMarkIn {
  0%   { opacity: 0; transform: translateY(-50%) translateX(80px); }
  100% { opacity: 1; transform: translateY(-50%) translateX(0); }
}

.hero__inner {
  position: relative;
  z-index: 2;
  padding-top: 144px;
}
.hero__text {
  max-width: 540px;
}
.hero__title {
  font-size: clamp(48px, 6.4vw, 64px);
  font-weight: 700;
  line-height: .95;
  letter-spacing: 0;
  text-transform: uppercase;
  margin: 0 0 28px 0;
}
.hero__title-white { display: block; color: var(--white); }
.hero__title-accent { display: block; color: var(--bass-blue-light); }

.hero__lede {
  font-size: 22px; line-height: 1.5; font-weight: 500;
  color: var(--white);
  max-width: 460px;
  margin: 0 0 36px 0;
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 14px 22px;
  font-weight: 700; font-size: 18px; letter-spacing: 1.2px;
  text-transform: uppercase;
  border: 0; cursor: pointer;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), background-color .25s var(--ease);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.btn span {
  letter-spacing: 0;
}
.btn svg { width: 22px; height: 22px; flex-shrink: 0; transition: transform .35s var(--ease); }

/* TEMPORARY — hides the arrow on every button pointing at the contact page:
   the 34 "Request Services" CTAs plus "Get an Asset Audit". Delete this whole
   block to restore it; the markup is untouched, so nothing else has to be
   undone.

   Matched by destination rather than by label, since CSS cannot read text.
   Both href forms are needed: the build rewrites internal links to "/contact",
   but the source files still say "contact.html" and the dev server serves
   those directly. Buttons going anywhere else keep their arrow. */
.btn[href="/contact"] svg,
.btn[href="contact.html"] svg {
  display: none;
}

/* Keyboard focus ring — applies to every variant */
.btn:focus-visible {
  outline: 3px solid var(--bass-blue-light);
  outline-offset: 3px;
}

/* Disabled — <button disabled>, or <a aria-disabled="true" class="is-disabled"> */
.btn:disabled,
.btn[aria-disabled="true"],
.btn.is-disabled {
  opacity: .45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
  pointer-events: none;
}

/* Spacing utility for buttons that follow body copy */
.btn--spaced { margin-top: 24px; }

/* --- Primary: solid accent --- */
.btn--primary {
  background: var(--bass-accent);
  color: var(--blue-darker);
  box-shadow: 0 6px 20px -8px rgba(0,0,0,.4);
}
.btn--primary::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(120deg, transparent 30%, rgba(var(--white-rgb),.55) 50%, transparent 70%);
  transform: translateX(-110%);
  transition: transform .7s var(--ease);
  z-index: -1;
}
.btn--primary:hover {
  background: var(--bass-accent-hover);
  transform: translateY(-2px);
  box-shadow: 0 14px 30px -10px rgba(var(--bass-accent-rgb),.55);
}
.btn--primary:hover::before { transform: translateX(110%); }
.btn--primary:hover svg { transform: translateX(6px); }
.btn--primary:active { transform: translateY(0); }

/* --- Outline: bordered, fills on hover --- */
.btn--outline {
  background: transparent;
  color: var(--blue-darker);
  box-shadow: inset 0 0 0 2px var(--blue-darker);
}
.btn--outline:hover {
  background: var(--blue-darker);
  color: var(--white);
  transform: translateY(-2px);
}
.btn--outline:hover svg { transform: translateX(6px); }
.btn--outline:active { transform: translateY(0); }

/* --- Outline (light): for dark backgrounds --- */
.btn--outline-light {
  background: transparent;
  color: var(--white);
  box-shadow: inset 0 0 0 2px var(--white);
}
.btn--outline-light:hover {
  background: var(--white);
  color: var(--blue-darker);
  transform: translateY(-2px);
}
.btn--outline-light:hover svg { transform: translateX(6px); }
.btn--outline-light:active { transform: translateY(0); }

/* ============================================================
   PUNCH POINTS
   ============================================================ */
.features {
  padding: 76px var(--gutter) 90px;
  background: var(--white);
}
.features__title {
  font-size: clamp(28px, 3.6vw, 38px);
  font-weight: 700; letter-spacing: 0px;
  text-align: center; text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 18px 0;
}
.features__rule {
  width: 80px; height: 4px;
  background: var(--bass-accent);
  margin: 0 auto 56px;
  transform-origin: center;
}
.features__grid {
  max-width: 1080px; margin: 0 auto;
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 0;
  position: relative;
}
.feature {
  text-align: center;
  padding: 18px 22px;
  position: relative;
}
.feature + .feature::before {
  content: "";
  position: absolute; left: 0; top: 12px; bottom: 12px;
  width: 3px;
  background: rgba(var(--blue-darker-rgb),.25);
}
.feature__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 64px; height: 64px;
  color: var(--bass-blue-dark);
  margin: 0 auto 16px;
}
.feature__icon svg {
  width: 100%; height: 100%;
  /* 128-unit viewBox rendered at 64px, so one rendered px is two icon units.
     Resolves to 7 — the same value the markup's stroke-width="7" attribute
     carries, which is why this set already looked right before the token. */
  stroke-width: calc(var(--icon-stroke) * 128 / 64);
}
.feature h3 {
  font-size: 20px; font-weight: 700; letter-spacing: 0;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 12px 0;
  line-height: 1.2;
}
.feature p {
  font-size: 16px; font-weight: 500;
  line-height: 1.4;
  color: var(--blue-darker);
  margin: 0;
}

/* ============================================================
   PHOTO FEATURE
   ============================================================ */
/* The band keeps its 1280/400 proportion as a FLOOR, not a fixed height —
   31.25vw is 400/1280. Content sets the height when it needs more, so longer
   copy grows the band instead of being clipped by the overflow rule. */
.photo-feature {
  position: relative;
  width: 100%;
  min-height: clamp(380px, 31.25vw, 560px);
  display: flex;
  background: var(--blue-darkest);
  overflow: hidden;
}
.photo-feature__photo {
  position: absolute; inset: 0;
  z-index: 0;
}
.photo-feature__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}
.photo-feature__shapes {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 1;
  pointer-events: none;
}
.photo-feature__overlay {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex; align-items: center;
  padding-block: 64px;
  pointer-events: none;
}
.photo-feature__overlay .container {
  width: 100%;
  pointer-events: auto;
}
.photo-feature__content {
  display: flex; flex-direction: column;
  align-items: flex-start;
  color: var(--white);
}
.photo-feature__content h2 {
  font-size: clamp(26px, 3vw, 36px);
  font-weight: 700; line-height: 1.05; letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--bass-accent);
  margin: 0 0 22px 0;
  max-width: 440px;
}
.photo-feature__content p {
  font-size: clamp(16px, 1.5vw, 22px);
  line-height: 1.5; font-weight: 500;
  margin: 0 0 32px 0;
  max-width: 340px;
}

/* ============================================================
   FOOTER
   ============================================================ */
.footer {
  background: var(--blue-darkest);
  color: var(--white);
  padding: 64px 0 56px;
}
.footer__grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr 1fr 1fr;
  gap: 40px;
  align-items: start;
}
.footer__brand p {
  margin-top: 16px;
  font-size: 14px; line-height: 1.35; font-weight: 500;
  max-width: 280px;
  color: var(--white);
}
/* h2, not h4: these are the footer's own section headings, and following the
   page's last <h2> with an <h4> skipped a level in the document outline. The
   visual treatment is entirely in this rule, so the tag change is invisible. */
.footer__col h2,
.footer__brand h2 {
  font-size: 14px; font-weight: 700;
  letter-spacing: 0.5px; text-transform: uppercase;
  margin: 0 0 18px 0;
  color: var(--white);
}
.footer__col ul li,
.footer__plain li {
  margin: 0 0 8px 0;
  font-size: 12px; line-height: 100%; font-weight: 500;
}
.footer__col ul li a {
  font-size: 12px;
  line-height: 100%;
  color: var(--bass-accent);
  transition: color .25s var(--ease);
  position: relative;
}
.footer__col ul li a:hover,
.footer__col ul li a:focus-visible {
  color: var(--white);
}
.footer__plain li,
.footer__plain a { color: var(--bass-accent); }
.footer__plain a:hover { color: var(--bass-accent); }
/* Two-version phone, mirroring the coming-soon page: vanity number in the
   footer's gold, dialable digits in light blue, both to white on hover. */
.footer__phone {
  display: inline-flex; flex-wrap: wrap; align-items: baseline;
  gap: 6px;
}
.footer__phone-vanity { color: var(--bass-accent); transition: color .25s var(--ease); }
.footer__phone-num { color: var(--bass-blue-light); transition: color .25s var(--ease); }
.footer__phone:hover .footer__phone-vanity,
.footer__phone:focus-visible .footer__phone-vanity,
.footer__phone:hover .footer__phone-num,
.footer__phone:focus-visible .footer__phone-num { color: var(--white); }
.footer__social {
  display: flex; gap: 16px;
  margin-top: 18px;
}
.footer__social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  color: var(--white);
  transition: color .25s var(--ease), transform .25s var(--ease);
}
.footer__social svg { width: 22px; height: 22px; }
.footer__social a:hover { color: var(--bass-accent); }

/* ============================================================
   REVEAL ON SCROLL
   ============================================================ */
.reveal {
  opacity: 0;
  transition: opacity .8s var(--ease), transform .8s var(--ease);
  will-change: opacity, transform;
}
.reveal[data-reveal="up"]   { transform: translateY(28px); }
.reveal[data-reveal="left"] { transform: translateX(-32px); }
.reveal[data-reveal="zoom"] { transform: scaleX(0); }
.reveal.is-visible {
  opacity: 1;
  transform: none;
}
.reveal[data-reveal="zoom"].is-visible { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .reveal { opacity: 1; transform: none !important; }
}

/* ============================================================
   MOBILE
   ============================================================ */
@media (max-width: 960px) {
  .features__grid { grid-template-columns: repeat(2, 1fr); row-gap: 36px; }
  .feature + .feature::before { display: none; }
  .feature:nth-child(2)::before {
    content: ""; position: absolute; left: 0; top: 12px; bottom: 12px;
    width: 3px; background: rgba(var(--blue-darker-rgb),.25);
  }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 36px; }
}

/* Collapse the nav to the hamburger drawer at 1024 (not 720): the header CTA
   sits at nav text-size, making the desktop row too wide for tablets/small
   laptops, so it would otherwise overflow. The CTA rides inside the drawer. */
@media (max-width: 1024px) {
  .nav-toggle { display: flex; }
  .site-header { z-index: 1000; }
  .nav {
    position: fixed; inset: 0;
    flex-direction: column; align-items: flex-start; justify-content: flex-start;
    overflow-y: auto;                 /* long submenus (12 industries) stay reachable */
    background: var(--blue-darkest);
    padding: 100px 32px 40px;
    transform: translateX(100%);
    transition: transform .4s var(--ease);
    z-index: 999;
  }
  .nav.is-open { transform: translateX(0); }
  /* Tap-to-call stays in the header bar at every width. The nav is fixed and
     out of the flow here, so the row is logo · phone · hamburger; margin-left
     auto groups the phone with the toggle instead of stranding it mid-row.
     `order` is set only in here — desktop keeps DOM order. */
  .site-header__phone { order: 1; margin-left: auto; white-space: nowrap; }
  .nav-toggle { order: 2; }
  .btn.site-header__cta { font-size: 15px; padding: 12px 22px; margin: 12px 0 0; }
  .nav-close { display: inline-flex; }
  .nav ul {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
  }
  .nav > ul > li > a,
  .nav > ul > li > .nav__top,
  .nav__top > a,
  .nav__sub a { font-size: 22px; line-height: 1.2; }
  .nav-home-mobile { display: block; }
}

@media (max-width: 720px) {
  :root { --gutter: 22px; }

  /* Phone-width header budget: at 375px the full-size logo, both phone lines
     and the hamburger do not fit, and the phone wraps to five lines. The logo
     gives up some size and the vanity line is dropped — the dialable number is
     the one that has to survive, since it is the thing being tapped. The
     vanity line still shows on tablets, which have the room. */
  .site-header__inner { gap: 12px; }
  .site-header .logo img { width: 148px; }
  .site-header__phone-vanity { display: none; }
  .site-header__phone-num { font-size: 15px; }

  .hero { min-height: 496px; padding-bottom: 48px; }
  .hero__inner { padding-top: 112px; }
  .hero__text { max-width: 100%; }

  /* Both heroes let their text run the full width from here down, so the
     left-to-right fade would drop the end of every line onto the bright side
     of the photo — worst on the accent-blue headline, which is the lightest
     text on the page. Flatten the horizontal pass so the darkness carries
     across; the photo still reads, just less brightly on the right. */
  .hero__overlay,
  .page-hero__scrim {
    background:
      linear-gradient(90deg, rgba(var(--blue-darkest-rgb),.89) 0%, rgba(var(--blue-darkest-rgb),.72) 100%),
      linear-gradient(180deg, rgba(var(--blue-darkest-rgb),.70) 0%, rgba(var(--blue-darkest-rgb),.10) 45%, rgba(var(--blue-darkest-rgb),.54) 100%);
  }
  .hero__title { font-size: 44px; }
  .hero__lede { font-size: 18px; max-width: none; }
  .hero__mark {
    top: 0; right: -22%; height: 90%; opacity: .7;
    transform: none;
    animation: none;
  }
  .hero__text .btn { display: flex; width: 100%; justify-content: center; }
  .photo-feature__content .btn { display: flex; width: 100%; justify-content: center; }

  .logos__row { gap: 18px; }
  .logos__row li { flex: 1 1 40%; }
  .logos__row li svg { height: 54px; }

  .features { padding: 56px var(--gutter) 64px; }
  .features__grid { grid-template-columns: 1fr; gap: 36px; }
  .feature + .feature::before,
  .feature:nth-child(2)::before { display: none; }
  .feature::after {
    content: ""; display: block;
    width: 40px; height: 1px;
    background: rgba(var(--blue-darker-rgb),.3);
    margin: 24px auto 0;
  }
  .feature:last-child::after { display: none; }

  .photo-feature {
    min-height: 0;
    flex-direction: column;
    background: var(--blue-darker);
  }
  .photo-feature__photo {
    position: relative; inset: auto;
    height: 280px;
    flex-shrink: 0;
  }
  .photo-feature__photo img { height: 280px; }
  .photo-feature__shapes { display: none; }
  .photo-feature__overlay {
    display: block;
    flex: none;
    padding-block: 0; /* the stacked layout pads .photo-feature__content instead */
  }
  .photo-feature__content {
    padding: 40px 0 48px;
    align-items: flex-start;
  }
  .photo-feature__content h2 { font-size: 28px; }
  .photo-feature__content p { font-size: 18px; max-width: none; }

  .footer { padding: 48px 0; }
  .footer__grid { grid-template-columns: 1fr; gap: 32px; }
  .footer__brand p { max-width: none; }
}

@media (max-width: 420px) {
  .hero__title { font-size: 38px; }
  .btn { padding: 13px 18px; font-size: 16px; }
}

/* ============================================================
   SUB-PAGE HERO
   ============================================================ */
.page-hero {
  position: relative;
  /* ~22% darker than --blue-darkest for a deeper hero backdrop */
  background: color-mix(in srgb, var(--blue-darkest) 78%, #000);
  color: var(--white);
  overflow: hidden;
  isolation: isolate;
  min-height: 360px;
  display: flex; align-items: flex-end;
  padding: 140px 0 60px;
}
/* Optional hero photo, injected per section by site.js. The flat background
   above stays as the fallback for sections without one, and shows while the
   image decodes. */
/* The tint is done here rather than baked into the asset, so the brand colour
   stays a token: change --bass-blue-dark and every hero photo follows. Supply
   ordinary full-colour photographs. */
.page-hero__photo {
  position: absolute; inset: 0;
  z-index: 0;
  background: var(--bass-blue-dark);
  /* Confines the blend below to this box. Without it the image would blend
     with whatever the hero is painted over. */
  isolation: isolate;
}
.page-hero__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: var(--hero-photo-position, center);
  /* luminosity keeps the photo's tonal structure and takes hue and saturation
     from the blue underneath. A full-colour photo comes out brand-tinted; a
     photo that is ALREADY tinted comes out the same, because its hue is
     discarded either way. So both kinds of source work, and swapping a
     pre-tinted asset for an untreated one needs no code change.
     brightness() sets how dark the result sits — the photo's own exposure
     would otherwise decide, and stock photos vary far too much for that.

     The value is therefore per-photo, derived rather than eyeballed: divide
     the target rendered luminance (~30) by the source's mean luminance. It
     is set from HERO_PHOTOS in site.js, which records the source figure
     alongside it; the fallback here only covers a photo added without one. */
  mix-blend-mode: luminosity;
  filter: brightness(var(--hero-photo-brightness, .3)) contrast(1.08);
}
/* A legibility scrim, not a tint — these photos arrive already tinted to the
   brand blue, so re-tinting here would double up and flatten them. Darkest at
   the left (the h1 and lede sit bottom-left), at the top (the transparent
   header overlays it) and at the bottom edge, clearing toward the right so the
   photo is actually visible. */
.page-hero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(var(--blue-darkest-rgb),.93) 0%, rgba(var(--blue-darkest-rgb),.68) 45%, rgba(var(--blue-darkest-rgb),.26) 100%),
    /* The top stop holds through 14% rather than falling away immediately:
       the transparent header sits in that band, and with a photo behind it
       its links would otherwise depend on whatever the photo happens to do
       in the top-right corner. */
    linear-gradient(180deg, rgba(var(--blue-darkest-rgb),.80) 0%, rgba(var(--blue-darkest-rgb),.66) 14%, rgba(var(--blue-darkest-rgb),.08) 48%, rgba(var(--blue-darkest-rgb),.54) 100%);
}
.page-hero__mark {
  position: absolute;
  top: 50%; right: -8%;
  height: 140%;
  transform: translateY(-50%);
  opacity: .9;
  pointer-events: none;
  z-index: 1;
}
.page-hero__inner {
  position: relative; z-index: 2;
  width: 100%;
}
.breadcrumbs {
  display: flex; align-items: center;
  gap: 8px;
  font-size: 13px; font-weight: 600; letter-spacing: 0.5px;
  text-transform: uppercase;
  color: rgba(var(--white-rgb),.6);
  margin-bottom: 24px;
}
.breadcrumbs a {
  color: var(--bass-accent);
  transition: color .2s var(--ease);
}
.breadcrumbs a:hover { color: var(--white); }
.breadcrumbs svg { width: 10px; height: 10px; opacity: .6; flex-shrink: 0; }
/* The current-page crumb is an article title on post pages, which is long
   enough to wrap to three lines on a phone and repeat the headline sitting
   directly beneath it. Truncate rather than shorten the label itself — the
   full title still goes to BreadcrumbList, where it is the useful form. */
.breadcrumbs [aria-current] {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.page-hero .page-hero__eyebrow {
  font-size: 16px; font-weight: 700; letter-spacing: 0;
  text-transform: uppercase;
  color: rgba(var(--white-rgb), 0.6);
  margin: 0 0 14px 0;
}
.page-hero h1 {
  font-size: clamp(36px, 5.2vw, 64px);
  font-weight: 700; line-height: .95; letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--white);
  margin: 0 0 16px 0;
  max-width: 760px;
}
.page-hero h1 .accent { color: var(--bass-blue-light); }
.page-hero p {
  font-size: clamp(16px, 1.4vw, 20px);
  line-height: 1.55; font-weight: 500;
  max-width: 620px;
  margin: 0;
  color: rgba(var(--white-rgb),.92);
}

/* ============================================================
   GENERIC SECTION
   ============================================================ */
.section {
  padding: 80px 0;
  background: var(--white);
}
/* Tightened vertical rhythm — opt-in per section via .section--tight */
.section--tight { padding: 64px 0; }
.section--tight .card-grid { gap: 24px; }
.section--tight .card { padding: 30px 32px; }
.section--tight .card__icon { margin-bottom: 16px; }
.section--tight .card h3 { margin-bottom: 11px; }
.section--tight .card p { margin-bottom: 20px; }
.section--alt { background: var(--bg); }
.section__head {
  text-align: center;
  margin-bottom: 56px;
}
.section__eyebrow {
  font-size: 14px; font-weight: 700; letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--bass-blue-light);
  margin: 0 0 12px 0;
}
.section h2 {
  font-size: clamp(28px, 3.6vw, 40px);
  font-weight: 700; line-height: 1.05; letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 14px 0;
}
.section__rule {
  width: 80px; height: 4px;
  background: var(--bass-accent);
  margin: 24px auto 0;
}

/* ============================================================
   SERVICE / INDUSTRY / CONTENT CARDS
   ============================================================ */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
/* Balanced two-up variant — for sets of 2 or 4 cards */
.card-grid--2 {
  grid-template-columns: repeat(2, 1fr);
  max-width: 920px;
  margin-inline: auto;
}

.card {
  background: var(--white);
  padding: 36px 32px;
  border-top: 3px solid var(--bass-accent);
  position: relative;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
  display: flex; flex-direction: column;
  min-height: 100%;
}
.section--alt .card { background: var(--white); }
.card:hover {
  transform: translateY(-6px);
  box-shadow: 0 22px 40px -22px rgba(var(--blue-darkest-rgb),.32);
}
.card__icon {
  width: 56px; height: 56px;
  color: var(--bass-blue-dark);
  margin-bottom: 18px;
  transition: color .25s var(--ease), transform .35s var(--ease);
}
/* 24-unit viewBox rendered at 56px — see --icon-stroke for why this is a calc. */
.card__icon svg { width: 100%; height: 100%; stroke-width: calc(var(--icon-stroke) * 24 / 56); }
.card:hover .card__icon { color: var(--bass-accent); transform: scale(1.06) rotate(-2deg); }
/* Cards with no "Learn more"/"View service" link aren't interactive — no lift. */
.card:not(:has(.card__link)) { transition: none; }
.card:not(:has(.card__link)):hover { transform: none; box-shadow: none; }
.card:not(:has(.card__link)):hover .card__icon { color: var(--bass-blue-dark); transform: none; }
.card h3 {
  font-size: 22px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 12px 0;
  line-height: 1.15;
}
.card p {
  font-size: 16px; line-height: 1.5;
  margin: 0 0 22px 0;
  flex-grow: 1;
}
.card__link {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 14px; letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--bass-blue-light);
  margin-top: auto;
  transition: color .25s var(--ease), gap .25s var(--ease);
}
.card__link svg { width: 18px; height: 14px; transition: transform .3s var(--ease); }
.card__link:hover { color: var(--bass-accent); gap: 14px; }
.card__link:hover svg { transform: translateX(4px); }
/* Make the whole card clickable: the "Learn more" link stretches to cover the
   card (no nested anchors, link text stays the accessible name). */
.card__link::after { content: ""; position: absolute; inset: 0; z-index: 1; }

/* Image-led card */
.card--media { padding: 0; border-top: 0; overflow: hidden; }
.card--media .card__media {
  position: relative;
  aspect-ratio: 16/10;
  background: var(--bass-blue-dark);
  overflow: hidden;
}
.card--media .card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.card--media:hover .card__media img { transform: scale(1.05); }
.card--media .card__body { padding: 28px 32px 32px; display: flex; flex-direction: column; flex-grow: 1; }
.card--media .card__tag,
.featured-post__media .card__tag {
  display: inline-block;
  background: var(--bass-accent);
  color: var(--blue-darker);
  font-weight: 700; font-size: 12px; letter-spacing: 1.4px;
  text-transform: uppercase;
  padding: 4px 10px;
  position: absolute;
  top: 16px; left: 16px;
  z-index: 2;
}

/* ============================================================
   SPLIT (IMAGE + TEXT)
   ============================================================ */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  /* Graphics in the left column align to the top of the copy on the right,
     not centered in the column. */
  align-items: start;
}
/* A split with nothing in its media column would strand half the row empty.
   This collapses it to a single column at reading measure — same 820px the
   .prose and .check-grid measures use. */
.split--measure { grid-template-columns: 1fr; max-width: 820px; margin: 0 auto; }
.split__media {
  position: relative;
  aspect-ratio: 4/3;
  background: var(--bass-blue-dark);
  overflow: hidden;
}
.split__media::after {
  content: "";
  position: absolute; inset: auto 0 0 auto;
  width: 60%; height: 12px;
  background: var(--bass-accent);
}
.split__media img { width: 100%; height: 100%; object-fit: cover; }
.split__body h2 { color: var(--blue-darker); }
.split__body .accent { color: var(--bass-accent); }
.split__body p {
  font-size: 18px; line-height: 1.6; font-weight: 500;
  margin: 0 0 16px 0;
}
.split__body ul {
  margin: 16px 0 24px;
}
.split__body ul li {
  font-size: 17px; line-height: 1.45;
  position: relative;
  padding: 8px 0 8px 32px;
  border-bottom: 1px solid rgba(var(--blue-darker-rgb),.12);
}
.split__body ul li::before {
  content: "";
  position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 16px; height: 2px;
  background: var(--bass-accent);
}
.split__body ul li:last-child { border-bottom: 0; }

/* ============================================================
   VERTICAL "BY THE NUMBERS" PANEL (About story)
   A vertical timeline of headline figures — navy panel, gold
   nodes on an axis. Replaces a split__media in the left column.
   ============================================================ */
.story-stats {
  position: relative;
  background: var(--blue-darker);
  padding: 52px 44px 52px 64px;
  overflow: hidden;
}
.story-stats::after {
  content: "";
  position: absolute; right: 0; bottom: 0;
  width: 60%; height: 12px;
  background: var(--bass-accent);
}
.story-stats::before {
  content: "";
  position: absolute; left: 31px; top: 66px; bottom: 66px;
  width: 2px;
  background: rgba(var(--bass-accent-rgb), .35);
}
/* The same brand mark the heroes carry, as a watermark. It sits lower here
   than in a hero: there it overlays a photograph that competes with it, while
   this is a flat panel where the shape would otherwise pull attention off the
   figures. The panel already has position:relative and overflow:hidden. */
.story-stats__mark {
  position: absolute;
  top: 50%; right: -14%;
  height: 118%;
  width: auto;
  transform: translateY(-50%);
  opacity: .5;
  pointer-events: none;
  z-index: 0;
}
/* Keeps the figures above the watermark. They are already positioned, so this
   only makes the order explicit rather than dependent on source order. */
.story-stat { position: relative; z-index: 1; padding: 30px 0; }
.story-stat:first-child { padding-top: 4px; }
.story-stat:last-child { padding-bottom: 4px; }
.story-stat::before {
  content: "";
  position: absolute; left: -40px; top: 12px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--bass-accent);
  box-shadow: 0 0 0 4px rgba(var(--bass-accent-rgb), .2);
}
.story-stat__num {
  display: block;
  font-size: clamp(44px, 4.6vw, 62px);
  font-weight: 700; line-height: 1; letter-spacing: 0;
  color: var(--bass-accent);
}
.story-stat__label {
  display: block; margin-top: 10px;
  font-size: 13px; font-weight: 600; letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(var(--white-rgb), .65);
}

/* ============================================================
   SIDE NAV (sub-page rail)
   ============================================================ */
.page-grid {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 64px;
  align-items: start;
}
.subnav-photo {
  margin: 0;
  position: sticky;
  top: 32px;
  overflow: hidden;
  background: var(--blue-darker);
}
.subnav-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
}

/* ============================================================
   LONG-FORM PROSE
   ============================================================ */
/* Layout modifiers, not base rules: inside .page-grid the column already
   sets the width, so a bare .prose must stay unconstrained. Every prose
   block in a full-width section used to carry these as inline styles. */
/* Full shorthand, not margin-inline: some of these are <p> elements, whose
   default block margins the original inline `margin:0 auto` suppressed. */
.prose--measure { max-width: 820px; margin: 0 auto; }
/* Centred standfirst under a section heading. */
.prose--intro { max-width: 720px; margin: 0 auto 44px; text-align: center; }

.prose h2 {
  font-size: clamp(24px, 2.6vw, 32px);
  font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 16px 0;
  line-height: 1.1;
}
.prose h3 {
  font-size: 22px; font-weight: 700; letter-spacing: 0;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 32px 0 10px;
}
.prose p {
  font-size: 18px; line-height: 1.65; font-weight: 500;
  margin: 0 0 20px 0;
}
.prose a:not(.btn) {
  color: var(--bass-blue-light);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color .2s var(--ease);
}
.prose a:not(.btn):hover { color: var(--bass-accent); }
.prose p:has(+ p),
.prose ul, .prose ol {
  margin-bottom: 20px;
}
.prose ul li, .prose ol li {
  font-size: 17px; line-height: 1.55;
  padding: 6px 0 6px 28px;
  position: relative;
}
.prose ul li::before {
  content: "";
  position: absolute; left: 0; top: 16px;
  width: 14px; height: 2px;
  background: var(--bass-accent);
}
.prose strong { color: var(--blue-darker); }

/* ============================================================
   STAT ROW
   ============================================================ */
.stat-row {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 0;
  background: var(--blue-darker);
  color: var(--white);
  padding: 56px 0;
}
.stat {
  text-align: center; padding: 20px;
  border-left: 1px solid rgba(var(--white-rgb),.15);
}
.stat:first-child { border-left: 0; }
.stat__num {
  font-size: clamp(40px, 5vw, 64px);
  font-weight: 700; line-height: 1; letter-spacing: 0;
  color: var(--bass-accent);
  margin-bottom: 8px;
  display: block;
}
.stat__label {
  font-size: 14px; font-weight: 600; letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--bg);
}

/* ============================================================
   TESTIMONIAL
   ============================================================ */
.testimonial {
  position: relative;
  background: var(--blue-darker);
  color: var(--white);
  padding: 80px 0;
  overflow: hidden;
  isolation: isolate;
}
.testimonial::before {
  content: "";
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;
  background: linear-gradient(135deg, transparent 70%, rgba(var(--bass-blue-light-rgb),.18) 100%);
  z-index: 0;
}
.testimonial__inner {
  position: relative; z-index: 1;
  max-width: 900px; margin: 0 auto;
  text-align: center;
}
.testimonial__quote-mark {
  font-size: 120px; line-height: 1; color: var(--bass-accent);
  font-family: Georgia, serif;
  margin-bottom: -50px;
}
.testimonial__quote {
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 600; line-height: 1.35; letter-spacing: 0;
  color: var(--white);
  margin: 0 0 32px 0;
}
.testimonial__rule {
  width: 60px; height: 3px;
  background: var(--bass-accent);
  margin: 0 auto 22px;
}
.testimonial__author {
  font-size: 18px; font-weight: 700; letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--bass-accent);
  margin: 0;
}
.testimonial__title {
  font-size: 15px; font-weight: 500; letter-spacing: 0;
  color: rgba(var(--white-rgb),.7);
  margin: 4px 0 0;
}

/* ============================================================
   TRUST CHIPS BAND
   Slim strip of credential chips, typically under a page hero.
   ============================================================ */
.chip-band {
  background: var(--blue-darker);
  padding: 18px var(--gutter);
}
.chip-band__inner {
  max-width: var(--max);
  margin: 0 auto;
  display: flex; flex-wrap: wrap;
  gap: 12px 14px;
  justify-content: center;
}
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 700; letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--white);
  padding: 7px 15px;
}
.chip::before {
  content: ""; width: 7px; height: 7px;
  background: var(--bass-accent);
  flex-shrink: 0;
}

/* ============================================================
   CALLOUT (highlighted note inside a content section)
   ============================================================ */
.callout {
  background: var(--blue-darker);
  border-left: 4px solid var(--bass-accent);
  padding: 26px 30px;
  margin: 32px 0 0;
}
.callout p {
  font-size: 16px; line-height: 1.65; font-weight: 500;
  color: rgba(var(--white-rgb),.78);
  margin: 0;
}
.callout strong { color: var(--white); }

/* ============================================================
   CHECK GRID (multi-column ticked list, e.g. equipment coverage)
   ============================================================ */
.check-grid {
  list-style: none;
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 2px 40px;
  margin: 8px 0 0; padding: 0;
}
/* Constrained + centred under a section heading (the common placement). */
.check-grid--measure { max-width: 820px; margin: 24px auto 0; }
/* Single column, tucked directly under the text it belongs to. */
.check-grid--single { grid-template-columns: 1fr; margin-top: 4px; }
.check-grid li {
  position: relative;
  font-size: 17px; line-height: 1.45; font-weight: 500;
  color: var(--blue-darker);
  padding: 12px 0 12px 32px;
  border-bottom: 1px solid rgba(var(--blue-darker-rgb),.12);
}
.check-grid li::before {
  content: "";
  position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 16px; height: 2px;
  background: var(--bass-accent);
}

/* ============================================================
   NUMBERED PROCESS STEPS
   ============================================================ */
.steps {
  max-width: 820px;
  margin: 0 auto;
  counter-reset: step;
}
.step {
  display: grid; grid-template-columns: 72px 1fr;
  gap: 24px; align-items: start;
  padding: 28px 0;
  border-bottom: 1px solid rgba(var(--blue-darker-rgb),.12);
}
.step:last-child { border-bottom: 0; }
.step__num {
  font-size: 44px; font-weight: 700; line-height: 1;
  letter-spacing: -1px;
  color: var(--bass-accent);
}
.step__body h3 {
  font-size: 20px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 8px;
}
.step__body p {
  font-size: 16px; line-height: 1.6;
  margin: 0;
}

/* ============================================================
   CTA BAND (full-width dark call to action)
   ============================================================ */
.cta-band {
  background: var(--blue-darker);
  padding: 64px var(--gutter);
}
.cta-band__inner {
  max-width: var(--max);
  margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 48px; flex-wrap: wrap;
}
.cta-band h2 {
  flex: 1 1 460px;
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 700; line-height: 1.1; letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--white);
  margin: 0;
}
.cta-band__actions {
  display: flex; flex-direction: column; gap: 14px;
  align-items: flex-start;
  flex-shrink: 0;
}

/* ============================================================
   STANDARDS & COMPLIANCE BAND (dark reference grid)
   ============================================================ */
.standards {
  background: var(--blue-darker);
  padding: 76px var(--gutter);
}
.standards__inner {
  max-width: var(--max);
  margin: 0 auto;
}
.standards__head {
  text-align: center;
  margin-bottom: 44px;
}
.standards__head h2 {
  font-size: clamp(28px, 3.6vw, 40px);
  font-weight: 700; line-height: 1.05; letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--white);
  margin: 0 0 14px;
}
.standards__lead {
  font-size: 17px; line-height: 1.6; font-weight: 500;
  color: rgba(var(--white-rgb),.6);
  max-width: 720px;
  margin: 0 auto;
}
.standards__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.standard {
  background: rgba(var(--white-rgb),.05);
  border: 1px solid rgba(var(--white-rgb),.1);
  border-left: 3px solid var(--bass-accent);
  padding: 20px 22px;
}
.standard__name {
  font-size: 16px; font-weight: 700; letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--white);
  margin: 0 0 6px;
}
.standard__desc {
  font-size: 14px; line-height: 1.55;
  color: rgba(var(--white-rgb),.55);
  margin: 0;
}

/* ============================================================
   FAQ (accordion)
   ============================================================ */
.faq {
  max-width: 840px;
  margin-inline: auto;
}
.faq__item {
  border-bottom: 1px solid rgba(var(--blue-darker-rgb),.14);
}
.faq__item summary {
  list-style: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px;
  padding: 24px 0;
  font-size: 19px; font-weight: 700; letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--blue-darker);
  transition: color .2s var(--ease);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary:hover { color: var(--bass-blue-light); }
.faq__item summary::after {
  content: ""; flex-shrink: 0;
  width: 14px; height: 14px;
  border-right: 2px solid var(--bass-accent);
  border-bottom: 2px solid var(--bass-accent);
  transform: rotate(45deg) translateY(-3px);
  transition: transform .25s var(--ease);
}
.faq__item[open] summary::after { transform: rotate(-135deg) translateY(-3px); }
.faq__item p {
  font-size: 16px; line-height: 1.7;
  margin: 0; padding: 0 0 26px;
  max-width: 760px;
}

/* ============================================================
   PROFILES (team)
   ============================================================ */
.profiles {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 28px;
}
.profile {
  text-align: left;
  transition: transform .35s var(--ease);
}
.profile:hover { transform: translateY(-4px); }
.profile__photo {
  position: relative;
  aspect-ratio: 3/4;
  background: var(--bass-blue-dark);
  overflow: hidden;
  margin-bottom: 18px;
}
.profile__photo::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 50%; height: 6px;
  background: var(--bass-accent);
  transition: width .35s var(--ease);
}
.profile:hover .profile__photo::after { width: 100%; }
.profile__photo svg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  color: rgba(var(--white-rgb),.4);
}
.profile h3 {
  font-size: 18px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 4px 0;
}
.profile__title {
  font-size: 14px; font-weight: 600; letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--bass-blue-light);
  margin: 0 0 10px 0;
}
.profile__bio {
  font-size: 15px; line-height: 1.5;
  color: var(--blue-darker);
  margin: 0;
}

/* ============================================================
   CONTACT FORM
   ============================================================ */
.contact-grid {
  display: grid; grid-template-columns: 1fr 1.4fr;
  gap: 64px;
  align-items: start;
}
.contact-info h2 {
  margin-bottom: 18px;
  color: var(--blue-darker);
}
.contact-info p {
  font-size: 17px; line-height: 1.55; font-weight: 500;
  margin: 0 0 28px 0;
  color: var(--blue-darker);
}
.contact-info__rows {
  display: flex; flex-direction: column; gap: 22px;
  border-top: 1px solid rgba(var(--blue-darker-rgb),.15);
  padding-top: 28px;
}
.contact-info__row {
  display: flex; gap: 16px;
}
.contact-info__row svg {
  width: 26px; height: 26px; color: var(--bass-blue-light); flex-shrink: 0;
}
.contact-info__row strong {
  display: block;
  font-size: 13px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin-bottom: 4px;
}
.contact-info__row a, .contact-info__row span {
  font-size: 17px; font-weight: 500;
  color: var(--blue-darker);
}
.contact-info__row a:hover { color: var(--bass-blue-light); }
/* Two-tone phone, mirroring the footer: vanity in the body color, dialable
   digits in light blue. */
.contact-phone { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.contact-info__row .contact-phone__num { color: var(--bass-blue-light); }

.form {
  background: var(--white);
  padding: 40px;
  border-top: 4px solid var(--bass-accent);
  box-shadow: 0 18px 48px -28px rgba(var(--blue-darkest-rgb),.25);
}
.form__row {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}
.form__row--single { grid-template-columns: 1fr; }
.form__field { display: flex; flex-direction: column; }
.form__field label {
  font-size: 13px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin-bottom: 6px;
}
.form__field input,
.form__field select,
.form__field textarea {
  font: inherit;
  font-size: 16px; font-weight: 500;
  padding: 12px 14px;
  border: 1.5px solid rgba(var(--blue-darker-rgb),.18);
  background: var(--white);
  color: var(--blue-darker);
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.form__field input:focus,
.form__field select:focus,
.form__field textarea:focus {
  outline: 0;
  border-color: var(--bass-blue-light);
  background: #f9fcff;
}
.form__field textarea { resize: vertical; min-height: 120px; }
.form__field input[aria-invalid="true"],
.form__field textarea[aria-invalid="true"] { border-color: #c0392b; }
.form__actions { margin-top: 12px; }
.form__actions .btn[aria-busy="true"] { opacity: .7; pointer-events: none; }

/* Standalone label (used where the control isn't a native form element). */
.form__label {
  font-size: 13px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin-bottom: 6px;
}

/* Multiselect dropdown (states). Native checkboxes inside a popover so the
   form still submits multiple `state` values with or without JS. */
.multiselect { position: relative; }
.multiselect__control {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font: inherit; font-size: 16px; font-weight: 500; text-align: left;
  padding: 12px 14px;
  border: 1.5px solid rgba(var(--blue-darker-rgb),.18);
  background: var(--white); color: var(--blue-darker);
  cursor: pointer;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.multiselect__control:hover { border-color: rgba(var(--blue-darker-rgb),.32); }
.multiselect__control:focus-visible,
.multiselect[data-open] .multiselect__control {
  outline: 0; border-color: var(--bass-blue-light); background: #f9fcff;
}
.multiselect__summary { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.multiselect__summary[data-empty] { color: rgba(var(--blue-darker-rgb),.5); }
.multiselect__chevron { width: 20px; height: 20px; flex: 0 0 auto; transition: transform .2s var(--ease); }
.multiselect[data-open] .multiselect__chevron { transform: rotate(180deg); }

.multiselect__menu {
  position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; right: 0;
  max-height: 260px; overflow-y: auto;
  background: var(--white);
  border: 1.5px solid rgba(var(--blue-darker-rgb),.18);
  box-shadow: 0 18px 48px -24px rgba(var(--blue-darkest-rgb),.35);
  padding: 6px;
}
.multiselect__menu[hidden] { display: none; }
/* Two-class selector so these win over the site's `.form__field label` rule
   (which would otherwise force uppercase / bold / letter-spacing on options). */
.multiselect__menu .multiselect__option {
  display: flex; align-items: center; gap: 10px;
  margin: 0; padding: 9px 10px;
  font-size: 15px; font-weight: 500; letter-spacing: normal;
  text-transform: none; color: var(--blue-darker);
  cursor: pointer;
}
.multiselect__menu .multiselect__option:hover { background: #f0f6fc; }
.multiselect__option input {
  width: 17px; height: 17px; flex: 0 0 auto; margin: 0;
  accent-color: var(--bass-blue-light);
}

/* Honeypot: kept in the DOM for bots, removed from view & a11y tree. */
.form__hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}

/* Submit status message (validation / network errors, success). */
.form__status {
  margin: 0 0 20px; padding: 12px 16px;
  font-size: 14px; font-weight: 600;
  border-left: 4px solid;
}
.form__status[hidden] { display: none; }
.form__status--error {
  color: #8a2620; background: #fdeceb; border-color: #c0392b;
}
.form__status--success {
  color: var(--blue-darker); background: #eef7ee; border-color: #2e7d32;
}
/* Direct contact routes appended to a send failure — a second line so the
   reason and the escape hatch don't run together. */
.form__status-routes { display: block; margin-top: 6px; font-weight: 500; }
.form__status-routes a { color: inherit; font-weight: 700; }
.form__status a { color: inherit; }

/* ============================================================
   UPDATES / RESOURCES GRID
   ============================================================ */
.updates-tabs {
  display: flex; gap: 6px;
  margin-bottom: 36px;
  border-bottom: 1px solid rgba(var(--blue-darker-rgb),.18);
}
.updates-tabs button {
  background: transparent; border: 0;
  padding: 14px 22px;
  font-size: 14px; font-weight: 700; letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--blue-darker);
  cursor: pointer;
  position: relative;
  transition: color .2s var(--ease);
}
.updates-tabs button::after {
  content: "";
  position: absolute; bottom: -1px; left: 22px; right: 22px;
  height: 3px;
  background: var(--bass-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .3s var(--ease);
}
.updates-tabs button.is-active,
.updates-tabs button:hover { color: var(--bass-blue-light); }
.updates-tabs button.is-active::after { transform: scaleX(1); }

/* Empty state for a post tab with no posts yet. */
.posts-empty {
  grid-column: 1 / -1;
  margin: 0; padding: 28px 0;
  font-size: 16px;
  color: rgba(var(--blue-darker-rgb), .55);
}

/* ============================================================
   ARTICLE (single post page — article.html)
   ============================================================ */
.article { max-width: 760px; }
/* Fixed frame, cropped fill — same ratio as the cards, so a cover is the same
   shape wherever it appears and a portrait photo can't run the hero to 1000px.
   The ratio lives on the figure, which also reserves the space before the
   image loads; that is what the build's width/height attributes used to do via
   height:auto. Those attributes can no longer distort anything, because the
   img is given both dimensions here and object-fit decides the crop. */
.article__cover {
  margin: 0 0 32px;
  aspect-ratio: 16/10;
  background: var(--bass-blue-dark);
  overflow: hidden;
}
.article__cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.article__body p {
  font-size: 17px; line-height: 1.65;
  margin: 0 0 20px;
}
/* Section headings inside a post body (written as "## Heading"). */
.article__body h2 {
  font-size: clamp(22px, 2.4vw, 28px);
  font-weight: 700; line-height: 1.15; letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 44px 0 14px;
}
.article__body h2:first-child { margin-top: 0; }
/* Bullet lists inside a post body (written as "- item"). Type matches the
   body paragraphs so a list reads as part of the prose, not a callout. */
.article__body ul {
  font-size: 17px; line-height: 1.65;
  margin: 0 0 20px; padding-left: 22px;
  list-style: disc;
}
.article__body li { margin: 0 0 8px; }
.article__body li::marker { color: var(--blue); }

/* Meta line — category · read time · date. Used in the article hero and,
   without the muted colour, on post cards. */
.article__meta {
  font-size: 14px; font-weight: 600; letter-spacing: 1px;
  text-transform: uppercase;
  color: rgba(var(--white-rgb), .55);
  margin: 14px 0 0;
}
.card__meta {
  font-size: 13px; font-weight: 600; letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--bass-blue-light);
  margin: -4px 0 12px;
}

/* ============================================================
   FEATURED POST (Updates — newest post, rendered wide)
   ============================================================ */
.featured-post {
  display: grid; grid-template-columns: 1fr 1fr;
  background: var(--white);
  border-top: 3px solid var(--bass-accent);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
  position: relative;
}
.featured-post:hover {
  transform: translateY(-6px);
  box-shadow: 0 22px 40px -22px rgba(var(--blue-darkest-rgb),.32);
}
/* Fixed frame, cropped fill. The ratio matches the grid cards so a featured
   post and a grid card read as the same component at two sizes. The image is
   absolutely positioned rather than height:100% — with only a min-height on
   the parent, 100% resolves to auto and a portrait photo drives the column
   to its own height, leaving dead space beside the excerpt. Absolute fill
   holds whether the height comes from the ratio or from the grid row
   stretching to match a long body. */
.featured-post__media {
  position: relative;
  aspect-ratio: 16/10;
  min-height: 340px;
  background: var(--bass-blue-dark);
  overflow: hidden;
}
.featured-post__media img,
.featured-post__media svg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.featured-post__body {
  padding: 48px 48px 52px;
  display: flex; flex-direction: column; justify-content: center;
}
.featured-post__body h3 {
  font-size: clamp(26px, 2.6vw, 34px);
  font-weight: 700; letter-spacing: .5px; line-height: 1.1;
  text-transform: uppercase;
  color: var(--blue-darker);
  margin: 0 0 12px;
}
.featured-post__excerpt {
  font-size: 18px; line-height: 1.6; font-weight: 500;
  margin: 0 0 26px;
}
.featured-post__link {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 14px; letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--bass-blue-light);
  margin-top: auto;
  transition: color .25s var(--ease), gap .25s var(--ease);
}
.featured-post__link svg { width: 18px; height: 14px; }
.featured-post__link:hover { color: var(--bass-accent); gap: 14px; }
/* Whole card clickable — the link text stays the accessible name. */
.featured-post__link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.article__cta { margin: 28px 0 0; }
.article__back {
  margin: 40px 0 0;
  padding-top: 24px;
  border-top: 1px solid rgba(var(--blue-darker-rgb), .15);
}
.article__back a {
  font-weight: 700; font-size: 14px; letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--bass-blue-light);
}
.article__back a:hover { color: var(--bass-accent); }

/* ============================================================
   CONFIRMATION
   ============================================================ */
.confirm {
  text-align: center;
  padding: 80px 0;
}
.confirm__icon {
  width: 96px; height: 96px;
  margin: 0 auto 28px;
  color: var(--bass-accent);
  display: flex; align-items: center; justify-content: center;
  background: rgba(var(--bass-accent-rgb),.12);
  border-radius: 50%;
}
/* 24-unit viewBox drawn at 56px, same ratio as the cards. The markup's
   stroke-width="2.5" rendered at 5.8px here — by far the heaviest icon on the
   site — which is what this overrides. */
.confirm__icon svg { width: 56px; height: 56px; stroke-width: calc(var(--icon-stroke) * 24 / 56); }
.confirm h1 {
  font-size: clamp(28px, 3.6vw, 44px);
  font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase;
  margin: 0 0 16px;
  color: var(--blue-darker);
}
.confirm p {
  font-size: 18px; line-height: 1.55; font-weight: 500;
  max-width: 540px; margin: 0 auto 32px;
}
.confirm .btn { margin: 0 6px; }

/* Failure variant (contact-fallback.html): the tick becomes a warning, so
   the icon must not read as the reassuring accent-yellow success mark. */
.confirm--warn .confirm__icon {
  color: var(--bass-blue-dark);
  background: rgba(var(--blue-darker-rgb),.10);
}
/* Direct contact routes — the whole point of the page, so they sit above
   the button, not buried in the footer. */
.confirm__contact {
  list-style: none;
  margin: 0 auto 32px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 12px 40px;
  align-items: center; justify-content: center;
}
.confirm__contact a {
  font-size: 20px; font-weight: 700; letter-spacing: .5px;
  color: var(--blue-darker);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.confirm__contact a:hover,
.confirm__contact a:focus-visible { color: var(--bass-accent); }
.confirm__phone { display: flex; flex-direction: column; line-height: 1.15; }
.confirm__phone-num { font-size: 15px; font-weight: 600; color: var(--bass-blue-dark); }
.confirm__phone:hover .confirm__phone-num { color: inherit; }

/* ============================================================
   MOBILE OVERRIDES FOR ALL NEW COMPONENTS
   ============================================================ */
@media (max-width: 960px) {
  .card-grid { grid-template-columns: repeat(2, 1fr); }
  .standards__grid { grid-template-columns: repeat(2, 1fr); }
  .split { grid-template-columns: 1fr; gap: 32px; }
  .page-grid { grid-template-columns: 1fr; gap: 32px; }
  .profiles { grid-template-columns: repeat(2, 1fr); }
  .stat-row { grid-template-columns: repeat(2, 1fr); padding: 36px 0; }
  .stat { padding: 18px; }
  .stat:nth-child(2) { border-left: 1px solid rgba(var(--white-rgb),.15); }
  .stat:nth-child(3) { border-left: 0; border-top: 1px solid rgba(var(--white-rgb),.15); }
  .stat:nth-child(4) { border-top: 1px solid rgba(var(--white-rgb),.15); }
  .contact-grid { grid-template-columns: 1fr; gap: 40px; }
}
@media (max-width: 720px) {
  .nav > ul { display: none; }
  .page-hero { min-height: 280px; padding: 110px 0 40px; }
  .page-hero__mark { right: -30%; opacity: .6; }
  .section { padding: 56px 0; }
  .section__head { margin-bottom: 36px; }
  .card-grid { grid-template-columns: 1fr; }
  .featured-post { grid-template-columns: 1fr; }
  .featured-post__media { min-height: 220px; }
  .featured-post__body { padding: 32px 28px 36px; }
  .standards__grid { grid-template-columns: 1fr; }
  .standards { padding: 56px var(--gutter); }
  .profiles { grid-template-columns: 1fr; }
  .form { padding: 24px; }
  .form__row { grid-template-columns: 1fr; gap: 16px; }

  /* Mobile nav drawer with submenus */
  .nav.is-open > ul { display: flex; }
  .nav__top svg { margin-left: auto; }
  .nav__sub {
    position: relative; top: 0; left: 0;
    min-width: 0; width: 100%;
    opacity: 1; visibility: visible;
    transform: none;
    transition: none;
    background: transparent;
    box-shadow: none;
    border-top: 0;
    padding: 6px 0 0 16px;
    display: none;
  }
  .nav > ul > li.is-mobile-open > .nav__sub { display: block; }
  .nav__sub a { padding: 8px 0; font-size: 22px; }
  .nav__sub a:hover { background: transparent; padding-left: 6px; }
}

.footer__brand p.footer__copyright {
  margin-top: 20px;
  font-size: 12px; font-weight: 500; letter-spacing: 0;
  color: rgba(var(--white-rgb),.55);
  max-width: 280px;
}

/* Breathing room when an in-page anchor jumps to a heading. */
main h2[id], main h3[id] { scroll-margin-top: 24px; }
