/* ═══════════════════════════════════════════════════════════════
   BULLCHASE — MRO SUPPLY & SERVICES
   styles.css — Production stylesheet
   Built by Entelijan Studios
═══════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────
   SELF-HOSTED FONTS
   Manrope is a variable font — one file covers all weights 400–800

   font-display: optional (not swap) — with swap, every page load renders
   the fallback font first, then reflows to Manrope/DM Sans the moment they
   finish downloading, even with the preload hint in head-assets.html. That
   reflow was the actual cause of the nav "settling" (link/button widths
   changing after first paint, once traced past a couple of layout-side
   fixes). `optional` gives the font a short window (~100ms) to be ready
   before first paint; if it makes it — which a small preloaded file
   typically will, and always will once cached from an earlier page view —
   it's used with zero swap. If it doesn't, that page view keeps the
   fallback rather than reflowing later. Trade-off: a cold-cache first visit
   on a slow connection may not show the brand font on that specific load.
───────────────────────────────── */
@font-face {
  font-family: 'Manrope';
  font-weight: 400 800;
  font-style: normal;
  font-display: optional;
  src: url('../fonts/manrope-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: 'Manrope';
  font-weight: 400 800;
  font-style: normal;
  font-display: optional;
  src: url('../fonts/manrope-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: 'DM Sans'; font-weight: 400; font-style: normal; font-display: optional; src: url('../fonts/dmsans-400.woff2') format('woff2'); }
@font-face { font-family: 'DM Sans'; font-weight: 500; font-style: normal; font-display: optional; src: url('../fonts/dmsans-500.woff2') format('woff2'); }

/* ─────────────────────────────────
   BASE TOKENS
───────────────────────────────── */
/* Brand tokens. These were generated from src/css/tokens.css by build.mjs and
   mirrored into two stylesheets; the static tree was deleted on 2026-08-23, so
   THIS IS NOW THE ONLY COPY and it is the right place to edit them. The old
   marker said "do not edit here", which would now send you to a file that does
   not exist. */
:root {
  --navy:         #192340;
  --navy-d:       #111a30;
  --orange:       #E85C22;
  --orange-h:     #d14e18;
  --orange-light: #FEE9DF;
  --white:        #ffffff;
  --off:          #F7F5F2;
  --dark:         #141414;
  --mid:          #444;
  --muted:        #888;
  --border:       #E3DDD6;
  --font:         'Manrope', 'DM Sans', system-ui, sans-serif;

  /* Heading & subtitle type scale (fluid clamps). Modest ~10-13% bump per
     meeting note "bigger fonts on headers/subtitles" — tokenized so no
     magic literals leak into the heading rules that reference these. */
  --fs-hero:            clamp(42px, 6vw,   78px);  /* .hero-h1               (was 38/5.5vw/70) */
  --fs-hero-m:          clamp(38px, 8.5vw, 54px);  /* .hero-h1 @mobile       (was 34/8vw/48)   */
  --fs-hero-sub:        17px;                        /* .hero-sub              (was 15px)        */
  --fs-section-h2:      clamp(33px, 3.8vw, 56px);  /* .section-h2            (was 30/3.5vw/50) */
  --fs-eyebrow:         12px;                        /* .eyebrow               (was 11px)        */
  --fs-page-hero:       clamp(40px, 5.4vw, 66px);  /* .page-hero-h1          (was 36/5vw/60)   */
  --fs-page-hero-m:     clamp(31px, 7.5vw, 44px);  /* .page-hero-h1 @mobile  (was 28/7vw/40)   */
  --fs-page-hero-sub:   19px;                        /* .page-hero-sub         (was 17px)        */
  --fs-page-hero-sub-m: 16px;                        /* .page-hero-sub @mobile (was 15px)        */

  /* Small uppercase label/badge text — the same 11px micro-copy pattern,
     independently duplicated across a dozen unrelated components. Does NOT
     replace .contact-section a::after (a print-only debug rule that happens
     to share the value coincidentally, not part of this pattern). */
  --fs-label: 11px; /* .trust-label, .trust-logo, .cta-eyebrow, .certs-label,
                        .cert-badge, .contact-info-label, .about-float-lbl, .contract-tag,
                        .b2b-node span, .call-inline-text small.
                        NOT .stat-lbl: it is uppercase micro-copy like these but has
                        always been 13px, and listing it here read as if it tracked this
                        token when no rule ever referenced it. */

  /* Small body/description copy. 13px everywhere until Reggie asked for a step up
     on the 2026-08-31 call. Tokenized rather than bumped in place because the value
     was duplicated across five unrelated components — the same drift the heading
     scale above exists to stop. Deliberately EXCLUDES the uppercase label rules
     (.stat-lbl, .team-role) and the nav sign-in controls (.nav-portal-form input,
     .nav-portal-signin): those share 13px coincidentally, and widening the nav pair
     is what would break layout-audit's "nav fits the viewport" check. */
  --fs-body-sm: 14px; /* .service-card-desc, .footer-brand-p, .product-card-subs,
                          .page-hero-service-desc, .contact-channels-label  (was 13px) */

  /* Radius + shadow — previously defined in a second, scattered :root further
     down in each stylesheet (styles.css ~line 1935) instead of here; moved to
     the single source alongside the rest of the tokens. Values unchanged. */
  --radius-pill: 100px;
  --radius-card: 18px;
  --shadow-card: 0 16px 48px rgba(0,0,0,0.10);
}

/* Frame width. It sat outside the token block above because that region used to
   be overwritten by the static build. Nothing overwrites it now, so this could
   be folded into the block above whenever someone is next in here.

   Full-bleed bands (footer, stats bar) keep their background edge-to-edge while
   their CONTENT lines up with the 1280px-capped sections above and below —
   without this they drifted to the screen edges on wide monitors. The nav is
   excluded on purpose; see the note on the `nav` rule. */
:root {
  --frame-max: 1280px;
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  scroll-snap-type: y proximity;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; }
}

body {
  background: var(--navy);
  font-family: var(--font);
  font-size: 16px;
  color: var(--dark);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { text-decoration: none; color: inherit; }
img { display: block; max-width: 100%; }
ul { list-style: none; }

/* ─────────────────────────────────
   STICKY MOBILE CALL BAR (hidden on desktop)
───────────────────────────────── */
.mobile-call-bar {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 200;
  background: var(--orange);
  padding: 14px 24px;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
}

.mobile-call-bar a {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--white);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.mobile-call-bar svg {
  flex-shrink: 0;
}

/* ─────────────────────────────────
   PAGE WRAPPER (navy padding around hero)
───────────────────────────────── */
.page-wrap {
  padding: 0;
}

/* ─────────────────────────────────
   HERO CARD
───────────────────────────────── */
.hero-card {
  border-radius: 0;
  overflow: hidden;
  position: relative;
  /* svh (small viewport height) measures the viewport with mobile browser chrome
     SHOWN, so the hero doesn't jump as the URL bar collapses on scroll. Declared
     once here rather than patched per-breakpoint — the old arrangement left raw
     100vh applying between 769px and 900px, the one band no override covered.
     The vh line is the fallback for browsers without svh support. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: #1a3040;
}

/* Gradient overlay — darkens slightly on scroll via JS .scrolled class */
.hero-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    95deg,
    rgba(10, 20, 40, 0.85) 0%,
    rgba(10, 20, 40, 0.58) 45%,
    rgba(10, 20, 40, 0.15) 100%
  );
  border-radius: inherit;
  z-index: 1;
  transition: background 0.4s ease;
}

.hero-card.scrolled::before {
  background: linear-gradient(
    95deg,
    rgba(10, 20, 40, 0.92) 0%,
    rgba(10, 20, 40, 0.70) 45%,
    rgba(10, 20, 40, 0.30) 100%
  );
}

/* ─────────────────────────────────
   HERO GRAIN TEXTURE OVERLAY
───────────────────────────────── */
.hero-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 200px 200px;
}

/* ─────────────────────────────────
   GRADIENT TEXT UTILITY
───────────────────────────────── */
.gradient-text {
  background: linear-gradient(95deg, var(--white) 0%, var(--orange) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  color: transparent;
}

/* ─────────────────────────────────
   HERO VIDEO & POSTER (Ken Burns)
───────────────────────────────── */
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
  /* Rotator: all videos start hidden; JS adds .active to the current one */
  opacity: 0;
  transition: opacity 1.5s ease-in-out;
  will-change: opacity;
}
.hero-video.active { opacity: 1; }

/* Ken Burns poster — shown on mobile (video hidden), hidden on desktop */
.hero-poster {
  position: absolute;
  inset: 0;
  background-image: url('../video/hero-poster.jpg');
  background-size: cover;
  background-position: center 30%;
  z-index: 0;
  display: none;
  animation: kenburns 22s ease-in-out infinite alternate;
}

@keyframes kenburns {
  0%   { transform: scale(1.00) translateX(0px) translateY(0px); background-position: 50% 30%; }
  50%  { transform: scale(1.05) translateX(-8px) translateY(4px); background-position: 52% 32%; }
  100% { transform: scale(1.10) translateX(8px) translateY(-4px); background-position: 48% 28%; }
}

/* ─────────────────────────────────
   SCROLL-DOWN INDICATOR (hero bottom)
───────────────────────────────── */
.scroll-indicator {
  position: absolute;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 12;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: rgba(255,255,255,0.55);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  animation: scrollBounce 2.2s ease-in-out infinite;
  cursor: pointer;
  transition: color .2s, opacity .3s;
  background: none;
  border: none;
  font-family: var(--font);
  padding: 0;
}

.scroll-indicator svg {
  width: 28px;
  height: 28px;
  stroke-width: 2;
  filter: drop-shadow(0 1px 4px rgba(0,0,0,0.4));
}

.scroll-indicator:hover { color: rgba(255,255,255,0.9); }

@keyframes scrollBounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(10px); }
}

/* ─────────────────────────────────
   NAVIGATION
───────────────────────────────── */
nav {
  position: relative;
  z-index: 10;
  display: flex;
  align-items: center;
  /* Fixed gap, not justify-content: space-between. With space-between, ANY
     sibling's rendered width changing (a link going bold, a web font
     finishing its swap, anything in nav-actions) redistributes ALL gaps at
     once — including the one right after the logo, even though the logo and
     "Home" never changed themselves. That's what made the gap look like it
     was "settling". A fixed gap here is immune to that; .nav-actions below
     uses margin-left: auto to absorb the leftover space at the far right
     instead, so only that one edge moves. */
  gap: var(--nav-gap);
  /* Nav sizing tokens. At full size the contents need 1585px (measured: logo
     415 + links 533 + actions 461 + 80 padding + 2×48 gap), so anything below a
     1600px monitor pushed "Get Your Quote" and the Sign In button off the right
     edge — at 1280 by 265px. Charles asked (2026-08-04) that the login boxes NOT
     be hidden if it can be avoided, so these shrink the nav in tiers instead;
     the boxes only drop at the width where shrinking can no longer fit them.
     Overridden in the tiers below and verified by `npm run test:layout`. */
  --nav-logo-h: 60px;
  /* Floor for the fluid logo height. A token because the ≤1024px tier needs to
     lower it: clamp() returns the MIN when max < min, so a smaller --nav-logo-h
     alone is silently ignored while this stays at 34px. Restored to 34px in the
     ≤900px block, where the phone layout wants the wordmark legible again. */
  --nav-logo-min: 34px;
  --nav-gap: 48px;
  --nav-pad-x: 40px;
  --nav-link-gap: 32px;
  --nav-btn-pad-x: 24px;
  --nav-input-w: 104px;
  /* Still NOT capped to --frame-max (unlike footer/.stats-bar): the gutter is
     what gives the contents room, so capping it would clip them sooner. */
  padding: 24px var(--nav-pad-x);
  transition: background .3s ease, padding .3s ease;
}

/* Sticky frosted nav on scroll */
.hero-card.scrolled nav {
  position: sticky;
  top: 0;
}

.nav-sticky {
  position: fixed !important;
  top: 0; left: 0; right: 0;
  z-index: 100;
  background: rgba(25, 35, 64, 0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  /* See the note on `nav` above — deliberately not capped to --frame-max. */
  padding: 14px var(--nav-pad-x);
  border-bottom: 1px solid rgba(255,255,255,0.06);
}

.nav-logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.nav-logo img {
  /* The mark is 463×67 — a 6.91:1 ratio — so a flat height:60px renders it 415px
     wide. With .nav-logo{flex-shrink:0} it could not give way, so below ~503px it
     overflowed the viewport and pushed .nav-hamburger off-screen entirely: on a
     390px phone the menu button was unreachable and the wordmark was cut mid-word.
     Scaling the height fluidly keeps it inside the nav at every width. 9vw hits
     the 60px cap at 667px, so desktop is unchanged; the 34px floor keeps the
     wordmark legible and still fits a 360px viewport (235px logo + 40px
     hamburger + 48px padding = 323px). */
  height: clamp(var(--nav-logo-min), 9vw, var(--nav-logo-h));
  width: auto;
  display: block;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.4));
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--nav-link-gap);
}

.nav-links a {
  color: rgba(255,255,255,0.82);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.01em;
  transition: color .2s;
  white-space: nowrap;
}

.nav-links a:hover { color: var(--white); }

.nav-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  margin-left: auto;
}

.nav-portal {
  color: var(--white);
  font-size: 14px;
  font-weight: 700;
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.35);
  padding: 11px var(--nav-btn-pad-x);
  border-radius: 100px;
  transition: background .2s, border-color .2s;
  white-space: nowrap;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  cursor: pointer;
}

.nav-portal:hover {
  background: rgba(255,255,255,0.25);
  border-color: rgba(255,255,255,0.6);
}

/* Shown only by the ≤1200px tier, which is also where .nav-portal-form hides.
   Reuses .nav-portal for its appearance so the two never drift apart. */
.nav-portal-fallback { display: none; }

.nav-cta {
  background: var(--orange);
  color: var(--white) !important;
  font-size: 14px;
  font-weight: 700;
  padding: 11px var(--nav-btn-pad-x);
  border-radius: 100px;
  letter-spacing: 0.01em;
  transition: background .2s;
  white-space: nowrap;
}

.nav-cta:hover { background: var(--orange-h); transform: translateY(-1px); }

/* Hamburger button — hidden on desktop */
.nav-hamburger {
  display: none;
  /* Stands in for .nav-actions at the far right on mobile (nav-actions is
     display:none there) — same margin-left: auto so it still hugs the right
     edge instead of participating in the fixed `gap` on nav. */
  margin-left: auto;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px; height: 40px;
  cursor: pointer;
  background: none;
  border: none;
  padding: 4px;
  flex-shrink: 0;
}

.nav-hamburger span {
  display: block;
  height: 2px;
  background: rgba(255,255,255,0.9);
  border-radius: 2px;
  transition: all 0.3s ease;
  transform-origin: center;
}

/* Hamburger → X when open */
.nav-hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-hamburger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nav-hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ─────────────────────────────────
   MOBILE MENU OVERLAY
───────────────────────────────── */
.mobile-menu {
  /* Height comes from inset:0 on a fixed box, NOT 100vh — vh does not shrink
     for iOS Safari's collapsing toolbars, which would push the footer below
     the fold on exactly the phones this menu exists for. */
  position: fixed;
  inset: 0;
  /* Must outrank .mobile-call-bar (200), which is fixed to the bottom edge and
     otherwise paints over the menu's Sign In button — unclickable, and a
     contradiction of this element's own aria-modal="true". Safe against the
     modals (also 200): a closed .mobile-menu is opacity:0 + pointer-events:none
     so it cannot cover anything, and main.js's modal open() calls closeMenu()
     before showing one, so the two are never open together. */
  z-index: 210;
  background: var(--navy-d);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  opacity: 0;
  /* visibility, not opacity alone: opacity:0 still leaves the six links, the
     login form and the CTA in the tab order, so on desktop a keyboard user
     tabbed straight into an invisible menu. pointer-events only stops the
     mouse. .modal-overlay already does exactly this; the menu was the outlier.
     Transitioning visibility alongside opacity keeps the fade intact. */
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.3s ease, visibility 0.3s ease;

  /* Top strip owned by the absolutely-positioned logo (28px offset + 55px tall)
     and close button. Declared once here because .mobile-menu-scroll needs it
     twice and it must move in lockstep with .mobile-menu-logo. */
  --mm-top-zone: 100px;
  /* Horizontal strip reserved for .mobile-menu-close: its 24px right offset
     plus its 32px rendered width (8px padding either side of a 28px glyph),
     plus a 16px gap. .mobile-menu-logo uses this as its right bound. Keep the
     two in step: if the close button's offset, padding or font-size changes,
     this is the number that has to move with it. */
  --mm-close-zone: 72px;
}

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

/* Links + footer scroll as one unit; the logo and close button sit outside it
   so they stay put. Before 2026-08-03 the footer was position:absolute at
   bottom:40px and only the links were laid out, so the menu reserved NO space
   for the footer: once the stacked portal login form landed in it the footer
   grew to ~200px and covered the bottom links on 8 of 9 tested viewports (by
   278px in landscape, where the first link was also pushed off the top). */
.mobile-menu-scroll {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;              /* without this the flex item refuses to shrink, so it never scrolls */
  overflow-y: auto;
  overscroll-behavior: contain;  /* the body overflow:hidden lock does not stop iOS scroll-chaining */
  scroll-padding-top: var(--mm-top-zone);  /* keyboard/Tab scrolling can't park a link under the logo */
  /* No horizontal padding: the links carry their own (40px, 28px ≤480px), so
     they and their separator borders stay edge-to-edge. */
  padding: var(--mm-top-zone) 0 40px;
}

/* Auto margins rather than justify-content:center — centred content in a
   scroll container has its overflowing TOP clipped and unreachable, whereas
   auto margins collapse to 0 the moment there is no free space. Child
   combinator so this cannot hit the footer's CTA, which is also an <a>. */
.mobile-menu-scroll > a:first-of-type { margin-top: auto; }

.mobile-menu-logo {
  position: absolute;
  top: 28px; left: 28px;
  /* Bounded on the right so it CANNOT reach the close button. Previously only
     `left` was set, so the 463×67 mark (6.9:1) wanted 380px at its 55px height
     and a global max-width squeezed it to the viewport edge — not to where the
     × starts. On every phone width from 320 to 390 the button sat 56px inside
     the wordmark; at 430 it still overlapped by 34px. Bounding the box makes
     the collision impossible at any width, rather than picking a height that
     happens to clear it today. */
  right: var(--mm-close-zone);
}

.mobile-menu-logo img {
  /* max-height rather than height, with auto on both axes, so the mark scales
     down proportionally inside that box instead of being squashed by max-width
     while a fixed height holds it at 55px. */
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 55px;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.4));
}

.mobile-menu-close {
  position: absolute;
  top: 24px; right: 24px;
  background: none;
  border: none;
  color: rgba(255,255,255,0.6);
  cursor: pointer;
  padding: 8px;
  line-height: 1;
  font-size: 28px;
  transition: color .2s;
}

.mobile-menu-close:hover { color: var(--white); }

.mobile-menu a {
  display: block;
  color: rgba(255,255,255,0.85);
  font-size: 28px;
  font-weight: 700;
  padding: 16px 40px;
  text-align: center;
  letter-spacing: -0.02em;
  transition: color .2s;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  width: 100%;
}

.mobile-menu a:first-of-type { border-top: 1px solid rgba(255,255,255,0.06); }
.mobile-menu a:hover { color: var(--orange); }

.mobile-menu-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  /* Pairs with the first link's margin-top:auto to split the free space above
     and below the links; collapses to 0 when the menu overflows. */
  margin-top: auto;
  /* Fixed floor on the links→footer gap: the auto margin above is 0 exactly
     when space is tightest, which is when separation matters most. */
  padding-top: 24px;
  /* Was shrink-to-fit (absolutely positioned), which made .mobile-portal-form's
     width:100% resolve against the CTA pill — the login fields rendered 193px
     wide at every viewport. */
  width: min(340px, calc(100% - 48px));
}

.mobile-menu-footer a.cta {
  background: var(--orange);
  color: var(--white) !important;
  font-size: 16px;
  padding: 14px 40px;
  border-radius: 100px;
  border: none;
}

/* ─────────────────────────────────
   HERO BODY
───────────────────────────────── */
.hero-body {
  position: relative;
  z-index: 10;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 20px 56px 56px;
  max-width: 740px;
}

.hero-h1 {
  font-size: var(--fs-hero);
  font-weight: 800;
  line-height: 1.08;
  color: var(--white);
  letter-spacing: -0.03em;
  margin-bottom: 20px;
}

.hero-sub {
  font-size: var(--fs-hero-sub);
  color: rgba(255,255,255,0.72);
  line-height: 1.7;
  max-width: 460px;
  margin-bottom: 40px;
  font-weight: 400;
}

.hero-btns {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* Buttons */
.btn-orange {
  background: var(--orange);
  color: var(--white);
  font-size: 14px;
  font-weight: 700;
  padding: 14px 28px;
  border-radius: 100px;
  border: none;
  cursor: pointer;
  transition: background .2s, transform .15s;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

.btn-orange:hover { background: var(--orange-h); transform: translateY(-1px); }

.btn-glass {
  background: rgba(255,255,255,0.12);
  color: var(--white);
  font-size: 14px;
  font-weight: 600;
  padding: 13px 26px;
  border-radius: 100px;
  border: 1.5px solid rgba(255,255,255,0.28);
  cursor: pointer;
  transition: background .2s;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  backdrop-filter: blur(4px);
}

.btn-glass:hover { background: rgba(255,255,255,0.22); transform: translateY(-1px); }

/* ─────────────────────────────────
   TRUST BAR (bottom of hero card)
───────────────────────────────── */
.trust-bar {
  position: relative;
  z-index: 10;
  border-top: 1px solid rgba(255,255,255,0.10);
  padding: 20px 56px;
  display: flex;
  align-items: center;
  gap: 40px;
  background: rgba(0,0,0,0.22);
  backdrop-filter: blur(8px);
  flex-wrap: wrap;
}

.trust-label {
  font-size: var(--fs-label);
  font-weight: 700;
  color: rgba(255,255,255,0.85);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.trust-logos {
  display: flex;
  align-items: center;
  gap: 36px;
  flex: 1;
  flex-wrap: wrap;
}

.trust-logo {
  font-size: 12px;
  font-weight: 700;
  color: rgba(255,255,255,0.40);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  transition: color .2s;
}

.trust-logo:hover { color: rgba(255,255,255,0.75); }
.trust-logo svg { opacity: 0.5; }

/* ─────────────────────────────────
   SHARED CONTENT WRAPPER
───────────────────────────────── */
.content-wrap {
  background: var(--white);
}

/* ─────────────────────────────────
   SHARED SECTION UTILITIES
───────────────────────────────── */
.eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--orange);
  display: block;
  margin-bottom: 14px;
}

.section-h2 {
  font-size: var(--fs-section-h2);
  font-weight: 800;
  line-height: 1.1;
  color: var(--dark);
  letter-spacing: -0.025em;
}

/* Fade-in animation (triggered by IntersectionObserver) */
.fade-up {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.fade-up.visible {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger delay helpers */
.delay-1 { transition-delay: 0.08s; }
.delay-2 { transition-delay: 0.16s; }
.delay-3 { transition-delay: 0.24s; }
.delay-4 { transition-delay: 0.32s; }
.delay-5 { transition-delay: 0.40s; }
.delay-6 { transition-delay: 0.48s; }

/* ─────────────────────────────────
   ABOUT SECTION
───────────────────────────────── */
.about-section {
  padding: 96px 56px;
  max-width: 760px;
  margin: 0 auto;
}

.about-h2 {
  margin-bottom: 22px;
}

.about-desc {
  font-size: 15px;
  color: var(--muted);
  line-height: 1.8;
  margin-bottom: 32px;
  max-width: 480px;
}

.about-features {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 40px;
}

.about-feature {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 14px;
  color: var(--mid);
  line-height: 1.6;
}

.about-feature-dot {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--orange-light);
  border: 2px solid var(--orange);
  flex-shrink: 0;
  margin-top: 1px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.about-feature-dot svg {
  color: var(--orange);
}

.about-cta-row {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.call-inline {
  display: flex;
  align-items: center;
  gap: 10px;
}

.call-inline-icon {
  width: 44px; height: 44px;
  background: var(--orange);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
  flex-shrink: 0;
}

.call-inline-text small {
  display: block;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.call-inline-text strong {
  font-size: 15px;
  font-weight: 700;
  color: var(--dark);
}

/* ─────────────────────────────────
   SERVICES SECTION
───────────────────────────────── */
.services-section {
  padding: 96px 56px 96px;
  max-width: 1280px;
  margin: 0 auto;
}

.services-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 48px;
  gap: 24px;
  flex-wrap: wrap;
}

.services-head p {
  font-size: 14px;
  color: var(--muted);
  max-width: 340px;
  line-height: 1.75;
}

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

.service-card {
  background: var(--off);
  border-radius: 18px;
  padding: 32px 28px;
  position: relative;
  overflow: hidden;
  transition: box-shadow .25s, transform .2s, border-color .2s, border-top-color .2s;
  border: 1px solid transparent;
  border-top: 3px solid transparent;
}

.service-card:hover {
  box-shadow: 0 16px 48px rgba(0,0,0,0.10);
  transform: translateY(-4px);
  border-color: var(--border);
  border-top: 3px solid var(--orange);
}


.service-card:hover .service-card-icon {
  background: var(--orange);
  color: var(--white);
}

.service-card-icon {
  width: 50px; height: 50px;
  background: var(--orange-light);
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--orange);
  margin-bottom: 20px;
  transition: background .2s, color .2s;
}

.service-card-title {
  font-size: 17px;
  font-weight: 700;
  color: var(--dark);
  margin-bottom: 10px;
  letter-spacing: -0.01em;
  padding-right: 40px;
}

.service-card-desc {
  font-size: var(--fs-body-sm);
  color: var(--muted);
  line-height: 1.7;
}

.service-card-desc a { color: var(--orange); }


/* ─────────────────────────────────
   CERTIFICATIONS SECTION
───────────────────────────────── */
.certs-section {
  background: var(--off);
  padding: 56px;
  border-top: 1px solid var(--border);
}

.certs-inner {
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 48px;
  flex-wrap: wrap;
  justify-content: space-between;
}

.certs-label {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
}

.certs-logos {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  flex: 1;
  justify-content: flex-end;
}

.cert-badge {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 16px;
  border-radius: 100px;
  background: var(--white);
  border: 1px solid var(--border);
  font-size: var(--fs-label);
  font-weight: 700;
  color: var(--mid);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: border-color .2s, color .2s, box-shadow .2s;
}

.cert-badge:hover {
  border-color: var(--orange);
  color: var(--orange);
  box-shadow: 0 4px 16px rgba(232,92,34,0.10);
}

.cert-badge svg {
  color: var(--orange);
  flex-shrink: 0;
}

/* ─────────────────────────────────
   STATS BAR
───────────────────────────────── */
.stats-bar {
  background: var(--navy);
  padding: 64px max(56px, calc((100% - var(--frame-max)) / 2));
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.stat-item {
  padding: 32px 40px;
  border-right: 1px solid rgba(255,255,255,0.08);
  text-align: center;
}

.stat-item:last-child { border-right: none; }

.stat-num {
  font-size: 52px;
  font-weight: 800;
  color: var(--white);
  line-height: 1;
  letter-spacing: -0.04em;
}

.stat-num sup {
  font-size: 22px;
  color: var(--orange);
  vertical-align: super;
}

.stat-lbl {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.75);
  margin-top: 12px;
}

/* contracts-section styles in appended CSS below */

/* contact-section layout in appended CSS below */

.contact-info {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.contact-form {
  background: var(--off);
  border-radius: 20px;
  padding: 40px;
  border: 1px solid var(--border);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
}

.form-group:last-of-type {
  margin-bottom: 24px;
}

.form-group label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--mid);
}

.form-group input,
.form-group textarea,
.form-row-group input {
  width: 100%;
  font-family: var(--font);
  font-size: 14px;
  color: var(--dark);
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
  outline: none;
  transition: border-color .2s, box-shadow .2s;
  -webkit-appearance: none;
}

.form-group input:focus,
.form-group textarea:focus {
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(232,92,34,0.10);
}

.form-group textarea {
  resize: vertical;
  min-height: 120px;
}

.form-submit {
  width: 100%;
  background: var(--orange);
  color: var(--white);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 700;
  padding: 15px 32px;
  border-radius: 100px;
  border: none;
  cursor: pointer;
  transition: background .2s, transform .15s;
}

.form-submit:hover {
  background: var(--orange-h);
  transform: translateY(-1px);
}

/* form-success in appended CSS (flex layout, .visible class) */

/* ─────────────────────────────────
   CTA SECTION
───────────────────────────────── */
.cta-section {
  position: relative;
  overflow: hidden;
  padding: 110px 56px;
  text-align: center;
  background: #0e1929;
}

.cta-section::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url('../img/cta-bg.jpg');
  background-size: cover;
  background-position: center;
  opacity: 0.10;
}

.cta-inner {
  position: relative;
  z-index: 1;
  max-width: 620px;
  margin: 0 auto;
}

.cta-eyebrow {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
  display: block;
  margin-bottom: 16px;
}

.cta-h2 {
  font-size: clamp(34px, 4vw, 58px);
  font-weight: 800;
  color: var(--white);
  letter-spacing: -0.03em;
  line-height: 1.08;
  margin-bottom: 20px;
}

.cta-p {
  font-size: 15px;
  color: rgba(255,255,255,0.5);
  line-height: 1.75;
  margin-bottom: 40px;
}

.cta-btns {
  display: flex;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}

.btn-white-outline {
  background: transparent;
  color: var(--white);
  font-size: 14px;
  font-weight: 600;
  padding: 14px 28px;
  border-radius: 100px;
  border: 1.5px solid rgba(255,255,255,0.25);
  cursor: pointer;
  transition: background .2s, border-color .2s;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.btn-white-outline:hover {
  background: rgba(255,255,255,0.10);
  border-color: rgba(255,255,255,0.5);
  transform: translateY(-1px);
}

/* ─────────────────────────────────
   FOOTER
───────────────────────────────── */
footer {
  background: var(--navy);
  padding: 72px max(56px, calc((100% - var(--frame-max)) / 2)) 36px;
}

.footer-top {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1.4fr;
  gap: 56px;
  padding-bottom: 56px;
  border-bottom: 1px solid rgba(255,255,255,0.07);
}

.footer-logo {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.footer-logo img {
  height: 50px;
  width: auto;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.3));
}

.footer-brand-p {
  font-size: var(--fs-body-sm);
  color: rgba(255,255,255,0.30);
  line-height: 1.75;
  max-width: 240px;
}

.footer-col h5 {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.22);
  margin-bottom: 22px;
}

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

.footer-col ul a {
  font-size: 14px;
  color: rgba(255,255,255,0.45);
  transition: color .2s;
  font-weight: 500;
}

.footer-col ul a:hover { color: var(--white); }

.footer-contact-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 20px;
}

.footer-contact-row:last-child { margin-bottom: 0; }

.footer-contact-row small {
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.20);
}

.footer-contact-row a,
.footer-contact-row span {
  font-size: 14px;
  font-weight: 600;
  color: rgba(255,255,255,0.55);
  transition: color .2s;
}

.footer-contact-row a:hover { color: var(--orange); }

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 28px;
  flex-wrap: wrap;
  gap: 10px;
}

.footer-bottom p,
.footer-bottom a {
  font-size: 12px;
  color: rgba(255,255,255,0.18);
}

.footer-bottom a:hover { color: rgba(255,255,255,0.45); }

/* ─────────────────────────────────
   SCROLLBAR
───────────────────────────────── */
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: var(--navy); }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: var(--orange); }

/* ─────────────────────────────────
   SCROLL PROGRESS BAR
───────────────────────────────── */
.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  background: var(--orange);
  z-index: 500;
  width: 0%;
  transition: width 0.1s linear;
  pointer-events: none;
}

/* ─────────────────────────────────
   BACK TO TOP BUTTON
───────────────────────────────── */
.back-to-top {
  position: fixed;
  bottom: 32px; right: 32px;
  z-index: 200;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--navy);
  border: 1.5px solid rgba(255,255,255,0.15);
  color: rgba(255,255,255,0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .3s ease, transform .3s ease, background .2s, border-color .2s;
  pointer-events: none;
}

.back-to-top.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.back-to-top:hover {
  background: var(--orange);
  border-color: var(--orange);
  color: var(--white);
}

@media (max-width: 768px) {
  .back-to-top { bottom: 72px; right: 16px; } /* clear mobile call bar */
}

/* ─────────────────────────────────
   SKIP TO CONTENT (accessibility)
───────────────────────────────── */
/* Parked off-screen; the :focus-visible rule below is what brings it in.
   Centred rather than left:16px because at left it landed on top of the
   Bullchase logo, which reads as a glitch to anyone who does not know what a
   skip link is. Centre is the one horizontal position that is clear of the
   logo at every width without hardcoding an offset: below the mobile
   breakpoint the nav collapses to a hamburger so the middle is empty, and
   above it the pill sits over the nav links instead of the brand mark.

   Deliberately NOT offset below the nav bar: the nav's rendered height is
   76-108px depending on viewport (measured across 11 widths) and does not
   track any single token -- at 1024px it is 83px tall with a 28px logo -- so
   any "just below the nav" constant would be wrong at most widths and would
   silently drift the next time the nav changes. */
.skip-to-content {
  position: fixed;
  top: -100px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  background: var(--orange);
  color: var(--white);
  font-weight: 700;
  font-size: 14px;
  padding: 10px 20px;
  border-radius: 8px;
  transition: top .2s;
}

/* :focus-visible, not :focus. With plain :focus the link also appeared on
   PROGRAMMATIC focus -- notably main.js's `lastFocus.focus()` when a quote or
   login modal closes -- so it surfaced during ordinary mouse use with no
   keyboard involved, which is what made it look like it appeared at random.
   :focus-visible still matches for keyboard users, who are the ones who need
   to see it; a screen reader user is read the link either way. */
.skip-to-content:focus-visible { top: 16px; }

/* Browsers without :focus-visible (Safari < 15.4) keep the old behaviour
   rather than losing the skip link's visible state altogether. */
@supports not selector(:focus-visible) {
  .skip-to-content:focus { top: 16px; }
}

/* Under 1024px the wordmark is wide enough to reach the middle of the bar, so
   centring alone still put the pill on top of it (caught by the skip-link
   assertion in tools/layout-audit.mjs, which measures the two rectangles).
   Drop it clear of the header instead. 104px is the tallest nav these widths
   produce (96px at 768) plus 8px; it is a measured constant, and the audit
   fails if the nav ever grows past it rather than the overlap coming back
   silently. Above 1024px the logo has shrunk out of the way and 16px is fine. */
@media (max-width: 1023px) {
  .skip-to-content:focus-visible { top: 104px; }

  @supports not selector(:focus-visible) {
    .skip-to-content:focus { top: 104px; }
  }
}

/* ─────────────────────────────────
   PRINT STYLES
───────────────────────────────── */
@media print {
  /* Hide everything non-essential */
  .hero-video, .hero-poster, .scroll-indicator,
  .mobile-call-bar, .mobile-menu, .nav-hamburger,
  .scroll-progress, .back-to-top,
  .cta-section::before, .contact-form { display: none !important; }

  /* Reset backgrounds and colors */
  body, .content-wrap, .contracts-section, .certs-section,
  .contact-section, .products-section { background: #fff !important; color: #000 !important; }
  .stats-bar, footer { background: #192340 !important; }

  /* Remove shadows and animations */
  * { box-shadow: none !important; animation: none !important; transition: none !important; }

  /* Force full opacity on fade-up elements */
  .fade-up { opacity: 1 !important; transform: none !important; }

  /* Hero — print as a simple header block */
  .hero-card {
    min-height: auto !important;
    background: var(--navy) !important;
    padding: 40px 0 !important;
  }

  .hero-card::before { display: none; }

  .hero-h1, .hero-sub { color: #fff !important; }
  .hero-btns, .trust-bar { display: none !important; }

  /* Page wrapper */
  .page-wrap { padding: 0 !important; }

  /* Nav */
  nav { position: static !important; background: transparent !important; }
  .nav-actions { display: none !important; }

  /* Typography adjustments */
  h1, h2, h3 { page-break-after: avoid; }
  p, li { orphans: 3; widows: 3; }

  /* Show URLs on links */
  .contact-section a::after { content: " (" attr(href) ")"; font-size: 11px; color: #666; }

  /* Page margins */
  @page { margin: 1in; }
}

/* ─────────────────────────────────
   WHY BULLCHASE STRIP
───────────────────────────────── */
.why-strip {
  background: var(--navy-d);
  padding: 56px;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}

.why-strip-inner {
  max-width: 1280px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
}

.why-item {
  padding: 32px 40px;
  border-right: 1px solid rgba(255,255,255,0.06);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.why-item:last-child { border-right: none; }

.why-icon {
  width: 48px; height: 48px;
  background: rgba(232,92,34,0.12);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--orange);
}

.why-item h3 {
  font-size: 18px;
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.01em;
}

.why-item p {
  font-size: 14px;
  color: rgba(255,255,255,0.40);
  line-height: 1.7;
}

/* ─────────────────────────────────
   TESTIMONIAL CARD (base styles)
   Section layout in appended CSS (.testimonials-*)
───────────────────────────────── */
.testimonial-card {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 18px;
  padding: 36px 40px;
  position: relative;
  transition: border-color .2s, background .2s;
}

.testimonial-card:hover {
  border-color: rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.06);
  transform: translateY(-4px);
}

/* testimonial-quote, testimonial-author, testimonial-name all defined in
   appended CSS below. There was a .testimonial-role too; it was deleted with
   the markup on 2026-08-31 (see partials/testimonials.html.twig). */

/* ─────────────────────────────────
   STAT COUNTER ANIMATION
───────────────────────────────── */
.count-num {
  display: inline;
}

/* ─────────────────────────────────
   PRODUCTS SECTION & CAROUSEL
───────────────────────────────── */
.products-section {
  background: var(--navy);
  padding: 96px 56px;
}

.products-inner {
  max-width: 1280px;
  margin: 0 auto;
}

.products-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 48px;
  gap: 24px;
  flex-wrap: wrap;
}

.products-h2 {
  color: var(--white) !important;
  margin-top: 8px;
}

.products-head p {
  font-size: 14px;
  color: rgba(255,255,255,0.40);
  max-width: 340px;
  line-height: 1.75;
}

/* Responsive card grid (replaces the former carousel). Top padding keeps the
   hover lift + shadow from being clipped at the top edge. */
.products-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px;
  padding-top: 8px;
}

.product-card {
  display: block;
  width: 100%;
  appearance: none;
  font: inherit;
  color: inherit;
  text-align: left;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 18px;
  padding: 28px 24px;
  transition: transform .2s, border-color .2s, box-shadow .2s;
  cursor: pointer;
}

.product-card:hover {
  transform: translateY(-4px);
  border-color: rgba(255,255,255,0.18);
  box-shadow: 0 12px 40px rgba(0,0,0,0.25);
}

.product-card-icon {
  width: 48px; height: 48px;
  background: rgba(232,92,34,0.12);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--orange);
  margin-bottom: 16px;
}

.product-card-title {
  display: block;
  font-size: 17px;
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.01em;
  line-height: 1.3;
  margin-bottom: 4px;
}

.product-card-subs {
  font-size: var(--fs-body-sm);
  color: rgba(255,255,255,0.50);
  line-height: 1.55;
  margin-top: 4px;
}

.products-cta-row {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin-top: 40px;
  flex-wrap: wrap;
}

/* ═══════════════════════════════════════════════════════════════
   RESPONSIVE BREAKPOINTS
═══════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────
   ≤1200px — Tighten spacing
───────────────────────────────── */
@media (max-width: 1200px) {
  .about-section,
  .services-section,
  .contact-inner {
    max-width: 100%;
  }
  .stats-bar {
    padding: 64px 40px;
  }
  .stat-item {
    padding: 24px 28px;
  }
}

/* ─────────────────────────────────
   ≤1024px — Two-column grids
───────────────────────────────── */
@media (max-width: 1024px) {
  .services-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .footer-top {
    grid-template-columns: 1fr 1fr;
    gap: 40px;
  }
  .contracts-inner {
    gap: 48px;
  }
  .contact-inner {
    gap: 48px;
  }
  nav {
    /* Vertical padding only — the horizontal side stays on --nav-pad-x so the
       width tiers below actually take effect. Hard-coding 28px here silently
       beat the token (same specificity, later in the file) and cost 16px of
       the slack the nav needs at this width. */
    padding: 20px var(--nav-pad-x);
  }
  .hero-body {
    padding: 20px 40px 48px;
  }
  .trust-bar {
    padding: 18px 40px;
  }
  .about-section {
    gap: 48px;
    padding: 80px 40px;
  }
  .services-section {
    padding: 80px 40px;
  }
  .certs-section {
    padding: 48px 40px;
  }
  .contracts-section {
    padding: 80px 40px;
  }
  .contact-section {
    padding: 80px 40px;
  }
  .products-section {
    padding: 80px 40px;
  }
  .cta-section {
    padding: 88px 40px;
  }
  footer {
    padding: 60px 40px 32px;
  }
}

/* ─────────────────────────────────
   901–1600px — Shrink the nav so it fits instead of overflowing
───────────────────────────────── */
/* Charles, 2026-08-04: "I would prefer not to hide them, but if that is the only
   fix go ahead and do it." So the login boxes survive as far down as the nav can
   be shrunk to hold them, and only drop below that. Each tier is a token
   override; `npm run test:layout` asserts nothing spills past the viewport. */
@media (max-width: 1600px) {
  nav {
    --nav-logo-h: 48px;
    --nav-gap: 36px;
    --nav-pad-x: 32px;
    --nav-link-gap: 26px;
    --nav-btn-pad-x: 20px;
    --nav-input-w: 96px;
  }
}

@media (max-width: 1400px) {
  nav {
    --nav-logo-h: 38px;
    --nav-gap: 24px;
    --nav-pad-x: 24px;
    --nav-link-gap: 18px;
    --nav-btn-pad-x: 16px;
    --nav-input-w: 88px;
  }
}

/* Below this the six links plus a two-field login cannot coexist at any
   readable size (they would need ~1235px), so the fields give way to a single
   Sign In link to the portal's own login page. This is the fallback Charles
   approved, scoped to the widths that genuinely need it rather than applied at
   1280–1440 where shrinking the nav was enough to keep the fields. */
@media (max-width: 1200px) {
  nav {
    --nav-logo-h: 34px;
    --nav-link-gap: 14px;
  }
  .nav-actions .nav-portal-form { display: none; }
  .nav-portal-fallback { display: inline-block; }
}

/* 901–1024px: the last band before the hamburger takes over at 900. Six links,
   a Sign In link and the CTA still have to fit, so this squeezes the last of the
   slack out. If this ever feels too cramped the cleaner move is to raise the
   mobile-nav breakpoint from 900 to 1024 and let the (now scrollable) mobile
   menu carry all of it — a visible behaviour change, so not made unasked. */
@media (max-width: 1024px) {
  nav {
    --nav-logo-h: 28px;
    --nav-logo-min: 28px;   /* without this the 34px floor wins and the cap is a no-op */
    --nav-link-gap: 10px;
    --nav-pad-x: 20px;
    --nav-btn-pad-x: 12px;
  }
}

/* ─────────────────────────────────
   ≤900px — Mobile nav kicks in
───────────────────────────────── */
@media (max-width: 900px) {
  nav {
    /* Undo the ≤1024px squeeze: once the links and actions are gone the nav
       holds only the logo and hamburger, so the wordmark gets its legible
       floor back rather than inheriting a size chosen to win 6px on a laptop. */
    --nav-logo-min: 34px;
    --nav-logo-h: 60px;
  }
  .nav-links,
  .nav-actions {
    display: none;
  }
  .nav-hamburger {
    display: flex;
  }
  .product-card {
    flex: 0 0 200px;
  }
  .products-section {
    padding: 64px 28px;
  }
  .page-wrap {
    padding: 0;
  }
  .hero-card {
    /* min-height comes from the base rule (100svh) — do not re-declare here. */
    border-radius: 0;
  }
  nav {
    padding: 18px 24px;
  }
  /* .nav-sticky's class selector outranks the `nav` rule above, so without this
     the inner pages kept 40px gutters on phones while the homepage hero nav
     dropped to 24px — 16px a side that pushed the hamburger off a 360px screen. */
  .nav-sticky {
    padding-inline: 24px;
  }
  .hero-body {
    padding: 20px 28px 40px;
    max-width: 100%;
  }
  .trust-bar {
    padding: 16px 28px;
    gap: 16px;
  }
  .trust-logos {
    gap: 20px;
  }
  .about-section,
  .contracts-inner {
    grid-template-columns: 1fr;
    gap: 48px;
    padding: 64px 28px;
  }
  .services-section {
    padding: 64px 28px;
  }
  .services-grid {
    grid-template-columns: 1fr;
  }
  .stats-bar {
    grid-template-columns: 1fr 1fr;
    padding: 48px 28px;
  }
  .stat-item {
    padding: 24px 20px;
    border-right: none;
    border-bottom: 1px solid rgba(255,255,255,0.08);
  }
  /* The two-column divider rules live in their own range block below, NOT
     here — see the comment there. */
  .certs-section {
    padding: 40px 28px;
  }
  .certs-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
  }
  .certs-logos {
    justify-content: flex-start;
  }
  .contracts-section {
    padding: 64px 28px;
  }
  .contact-section {
    padding: 64px 28px;
  }
  .contact-inner {
    grid-template-columns: 1fr;
    gap: 40px;
  }
  .cta-section {
    padding: 80px 28px;
  }
  footer {
    padding: 56px 28px 80px; /* extra bottom padding for mobile call bar */
  }
  .footer-top {
    grid-template-columns: 1fr 1fr;
    gap: 36px;
    padding-bottom: 40px;
  }
  .why-strip { padding: 40px 28px; }
  .why-strip-inner { grid-template-columns: 1fr; }
  .why-item {
    border-right: none;
    padding: 20px 0;
    border-bottom: 1px solid rgba(255,255,255,0.06);
  }
  .why-item:last-child { border-bottom: none; }
  .testimonial-section { padding: 64px 28px; }
  .testimonial-grid { grid-template-columns: 1fr; }
}

/* ─────────────────────────────────
   481–900px — Stats bar dividers while it is a 2×2 grid
───────────────────────────────── */
/* A RANGE query, deliberately: these selectors carry a pseudo-class, so they
   outrank the plain `.stat-item` rules in the ≤480px block below (0,2,0 beats
   0,1,0). Media queries add no specificity, so a narrower block does NOT
   override a wider one — as `max-width: 900px` these leaked into the stacked
   single-column layout and produced a stray right-hand border on items 1 and 3
   plus NO divider at all between items 3 and 4. Bounding them below at 481px
   fixes it at the source: the ≤480px block's own rules then apply unopposed,
   with no reset declarations to keep in sync. Keep the lower bound equal to the
   ≤480px breakpoint + 1. */
@media (min-width: 481px) and (max-width: 900px) {
  .stat-item:nth-child(odd) {
    border-right: 1px solid rgba(255,255,255,0.08);
  }
  .stat-item:last-child,
  .stat-item:nth-last-child(2) { border-bottom: none; }
}

/* ─────────────────────────────────
   ≤768px — Mobile (video → poster)
───────────────────────────────── */
@media (max-width: 768px) {
  /* Show Ken Burns poster, hide video */
  .hero-video { display: none; }
  .hero-poster { display: block; }

  /* Show sticky call bar */
  .mobile-call-bar { display: flex; }

  .scroll-indicator { bottom: 70px; }

  .hero-h1 {
    font-size: var(--fs-hero-m);
  }
  .trust-logo span { display: none; } /* hide text, show icon only */
  .form-row {
    grid-template-columns: 1fr;
  }
  .contact-form {
    padding: 28px 24px;
  }
  .contact-left > p {
    max-width: 100%;
  }
}

/* ─────────────────────────────────
   ≤480px — Compact mobile
───────────────────────────────── */
@media (max-width: 600px) {
  .product-card {
    flex: 0 0 calc(100% - 80px);
    scroll-snap-align: center;
  }
}


@media (max-width: 480px) {
  .products-section {
    padding: 48px 20px;
  }
  .stats-bar {
    grid-template-columns: 1fr;
    padding: 40px 24px;
  }
  .stat-item {
    border-right: none;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    padding: 20px 16px;
  }
  .stat-item:last-child { border-bottom: none; }
  .footer-top {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .certs-logos {
    gap: 10px;
  }
  .cert-badge {
    font-size: 10px;
    padding: 7px 12px;
  }
  .hero-btns {
    flex-direction: column;
    align-items: flex-start;
  }
  .trust-bar {
    gap: 12px;
  }
  .trust-logo { font-size: var(--fs-label); }
  .about-section {
    padding: 48px 20px;
  }
  .services-section {
    padding: 48px 20px;
  }
  .contracts-section,
  .contact-section {
    padding: 48px 20px;
  }
  .cta-section {
    padding: 64px 20px;
  }
  footer {
    padding: 48px 20px 80px;
  }
  .mobile-menu a {
    font-size: 22px;
    padding: 14px 28px;
  }
  .why-strip { padding: 32px 20px; }
  .testimonial-section { padding: 48px 20px; }
  .testimonial-card { padding: 28px 24px; }
  .hero-body { padding: 20px 20px 32px; }
}

/* ≤360px — narrowest phones. MUST stay after the ≤480px block above: media
   queries carry no specificity, so at 340px both match and the later one wins
   on ties. This block sat *before* ≤480px until 2026-08-05, which was harmless
   only because ≤480px happened to contain no .product-card rule. That is the
   same trap that produced the stats-bar divider bug — a narrower query does not
   override a wider one. Keep narrow-most last. */
@media (max-width: 360px) {
  .product-card { flex: 0 0 calc(100% - 56px); }
}

/* ─────────────────────────────────
   SCROLL SNAP
───────────────────────────────── */
.snap-section {
  scroll-snap-align: start;
}

/* Disable snapping on mobile — sections overflow the viewport */
@media (max-width: 768px) {
  html { scroll-snap-type: none; }
}

/* ─────────────────────────────────
   CREDENTIALS SLIDE (certs + stats grouped)
───────────────────────────────── */
.credentials-slide {
  display: flex;
  flex-direction: column;
}

/* ─────────────────────────────────
   VERTICAL SECTION NAV DOTS
───────────────────────────────── */
.section-nav {
  position: fixed;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 200;
}

.section-nav-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.5);
  border: none;
  padding: 0;
  cursor: pointer;
  transition: background 0.25s, transform 0.25s;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12), 0 1px 4px rgba(0, 0, 0, 0.12);
}

.section-nav-dot:hover {
  background: rgba(255, 255, 255, 0.85);
}

.section-nav-dot.active {
  background: var(--orange);
  transform: scale(1.4);
}

/* Hide on mobile */
@media (max-width: 768px) {
  .section-nav { display: none; }
}


/* ═══════════════════════════════════════════════════════════════
   ADDITIONS — multi-page redesign
═══════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────
   ACTIVE NAV LINK
───────────────────────────────── */
.nav-links a.active {
  /* Color only, not font-weight — this class is added by JS after the page
     has already painted (main.js, per-page active-link detection). A weight
     change makes the link visibly wider right after paint, reflowing every
     link after it (and, via nav-actions' margin-left: auto, the CTA/login
     group too). Color alone distinguishes the active page with zero layout
     shift, since it never changes the link's rendered width. */
  color: var(--white);
}

/* ─────────────────────────────────
   INNER-PAGE NAV
   (nav-sticky is always on; account for its height)
───────────────────────────────── */
/* .nav-sticky is position:fixed, so it contributes no height to the flow. Pages
   with a .page-hero get their clearance from the hero's 148px top padding and
   need nothing here. Pages that render no hero (Contracts, since the band was
   removed 2026-07-29) opt in via base.html.twig's body_class block.

   89px = 60px .nav-logo img + 2×14px .nav-sticky padding + 1px border-bottom.
   Constant across breakpoints: the responsive `nav { padding: … }` rules at the
   900px and 768px breakpoints target the bare `nav` element (the hero's nav),
   and .nav-sticky's class selector outranks them, so the sticky bar keeps its
   14px padding everywhere. */
body.inner-page {
  padding-top: 89px;
}

/* ─────────────────────────────────
   INNER-PAGE HERO BANNER
───────────────────────────────── */
.page-hero {
  background: linear-gradient(135deg, var(--navy-d) 0%, var(--navy) 100%);
  padding: 148px 56px 80px;
  position: relative;
  overflow: hidden;
}

.page-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 200px 200px;
  opacity: 0.04;
  pointer-events: none;
}

.page-hero-content {
  position: relative;
  z-index: 1;
  max-width: 720px;
}

.page-hero-h1 {
  font-size: var(--fs-page-hero);
  font-weight: 800;
  color: var(--white);
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-bottom: 18px;
}

.page-hero-sub {
  font-size: var(--fs-page-hero-sub);
  color: rgba(255,255,255,0.6);
  line-height: 1.75;
  max-width: 580px;
}

@media (max-width: 768px) {
  .page-hero { padding: 120px 28px 60px; }
  .page-hero-h1 { font-size: var(--fs-page-hero-m); }
  .page-hero-sub { font-size: var(--fs-page-hero-sub-m); }
}

/* ─────────────────────────────────
   PAGE HERO — SPLIT LAYOUT (services page: hero text left, compact
   service cards right, in the same hero block instead of a separate
   full-width grid section below)
───────────────────────────────── */
.page-hero-split-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: start;
  max-width: 1280px;
  margin: 0 auto;
}

.page-hero-split-inner .page-hero-content { max-width: none; }

.page-hero-services-list {
  display: grid;
  /* minmax(0, 1fr) columns — a plain 1fr has an implicit auto minimum, so a
     card with unusually long unwrapped content could force its column
     wider than its sibling (same class of bug as the contact-page cards).
     grid-auto-rows: 1fr equalizes height across ALL rows, not just within
     a row (Grid's default only stretches items to match their own row) —
     without it, a row of two short-description cards would end up
     shorter than a row of two long-description cards. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: 12px;
}

.page-hero-service-card {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  padding: 16px 18px;
  transition: border-color .2s, background .2s;
  /* Companion to the grid's minmax(0, ...) columns — a flex item's default
     min-width is auto (its content's min-content size), which can still
     force overflow/growth even when the grid track itself is constrained. */
  min-width: 0;
}
.page-hero-service-card:hover {
  border-color: rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.06);
}

.page-hero-service-icon {
  width: 36px; height: 36px;
  border-radius: 10px;
  background: rgba(232,92,34,0.18);
  color: var(--orange);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.page-hero-service-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--white);
  margin-bottom: 4px;
}

.page-hero-service-desc {
  font-size: var(--fs-body-sm);
  color: rgba(255,255,255,0.55);
  line-height: 1.6;
}

@media (max-width: 900px) {
  .page-hero-split-inner { grid-template-columns: 1fr; gap: 40px; }
}

@media (max-width: 480px) {
  .page-hero-services-list { grid-template-columns: 1fr; }
}

/* Footer portal link (button styled like a link) */
.footer-portal-link {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0;
  text-align: left;
  text-decoration: none;
  transition: color .2s;
}

.footer-portal-link:hover { color: var(--orange); }

/* ─────────────────────────────────
   TESTIMONIALS SECTION
───────────────────────────────── */
.testimonials-section {
  background: var(--off);
  padding: 96px 56px;
}

.testimonials-head {
  text-align: center;
  margin-bottom: 56px;
}

/* Auto-scrolling marquee: the track renders several duplicate copies of the
   testimonial collection (see partials/testimonials.html.twig) so it always
   overflows the viewport; translating by exactly half the track's width loops
   seamlessly since the second half is identical to the first. */
.testimonials-viewport {
  overflow: hidden;
  max-width: 1400px;
  margin: 0 auto;
  /* Headroom so .testimonial-card:hover's translateY(-4px) lift isn't clipped
     by this same overflow:hidden (needed to hide the marquee's horizontal
     overrun). Negative margin cancels the added box height. */
  padding-top: 8px;
  margin-top: -8px;
  /* Fade the left/right edges to transparent instead of a hard clip. Eased
     with several stops (not a single ramp-then-flat) so there's no sudden
     change in the fade's slope — a hard kink like that is perceived as a
     visible line (Mach banding), even though the gradient itself is smooth. */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0%,
    rgba(0,0,0,0.15) 3%,
    rgba(0,0,0,0.45) 6%,
    rgba(0,0,0,0.8) 9%,
    black 14%,
    black 86%,
    rgba(0,0,0,0.8) 91%,
    rgba(0,0,0,0.45) 94%,
    rgba(0,0,0,0.15) 97%,
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0%,
    rgba(0,0,0,0.15) 3%,
    rgba(0,0,0,0.45) 6%,
    rgba(0,0,0,0.8) 9%,
    black 14%,
    black 86%,
    rgba(0,0,0,0.8) 91%,
    rgba(0,0,0,0.45) 94%,
    rgba(0,0,0,0.15) 97%,
    transparent 100%
  );
}

.testimonials-track {
  display: flex;
  gap: 24px;
  width: fit-content;
  /* Moves cards right-to-left. To reverse, swap the two transform values below.
     Duration is deliberately slow (~35px/s) — a fast linear scroll here reads
     as dizzying rather than lively.

     Derived from the card count (set as --marquee-cards by
     partials/testimonials.html.twig) rather than hard-coded, so adding a
     testimonial doesn't silently speed the marquee up: the keyframe travels half
     the track, so duration must scale with total width. 5.83s/card reproduces
     the original 140s at the 24 cards that value was tuned against (3
     testimonials × 8 copies). Fallback keeps it sane if the property is missing. */
  animation: testimonials-scroll calc(var(--marquee-cards, 24) * 5.83s) linear infinite;
}

.testimonials-viewport:hover .testimonials-track {
  animation-play-state: paused;
}

@keyframes testimonials-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .testimonials-track { animation: none; }
  .testimonials-viewport { overflow-x: auto; }
  .testimonials-track [aria-hidden="true"] { display: none; }
}

/* Reuse .testimonial-card (already defined in styles.css) */
.testimonial-card {
  display: flex;
  flex-direction: column;
  gap: 20px;
  transition: border-color .2s, background .2s, transform .2s, box-shadow .2s;
}

.testimonials-track .testimonial-card {
  flex: 0 0 380px;
  width: 380px;
}

.testimonial-quote {
  font-size: 16px;
  line-height: 1.75;
  color: rgba(255,255,255,0.8);
  flex: 1;
}

.testimonial-quote::before {
  content: '\201C';
  display: block;
  font-size: 48px;
  line-height: 0.8;
  color: var(--orange);
  margin-bottom: 12px;
  font-family: Georgia, serif;
}

.testimonial-author {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-top: 1px solid rgba(255,255,255,0.08);
  padding-top: 16px;
}

.testimonial-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--white);
}

/* Dark background for testimonials (they are on .off / light bg in page,
   but .testimonial-card uses translucent white on navy — so wrap section in navy) */
.testimonials-section {
  background: var(--navy);
}

/* Testimonials now directly follows the stats bar on Home (.stats-bar) and
   About (.credentials-slide, which wraps stats-bar) — both navy like this
   section, so the full 96px top padding plus the stats bar's own bottom
   padding reads as one oversized gap with no seam to break it up. Tighten
   just the top so the two navy sections sit closer together; bottom padding
   stays full since it borders a differently-colored section on both pages. */
.stats-bar + .testimonials-section,
.credentials-slide + .testimonials-section {
  padding-top: 48px;
}

@media (max-width: 640px) {
  .testimonials-section { padding: 64px 28px; }
  .testimonials-track .testimonial-card { flex-basis: 280px; width: 280px; }
}

/* ─────────────────────────────────
   HOME PAGE PRODUCT TEASER
───────────────────────────────── */
.home-products-teaser {
  background: var(--navy);
  padding: 80px 56px;
  text-align: center;
}

.home-products-teaser .section-h2 { color: var(--white); }

.teaser-cta-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 40px;
  flex-wrap: wrap;
}

@media (max-width: 640px) {
  .home-products-teaser { padding: 56px 20px; }
}

/* ─────────────────────────────────
   PAGE-LEVEL SECTION WRAPPER
   (replaces content-wrap on inner pages)
───────────────────────────────── */
.page-section {
  padding: 80px 56px;
}

.page-section-light {
  background: var(--white);
}

.page-section-off {
  background: var(--off);
}

@media (max-width: 768px) {
  .page-section { padding: 56px 28px; }
}

@media (max-width: 480px) {
  .page-section { padding: 48px 20px; }
}

/* ─────────────────────────────────
   CONTRACTS PAGE
───────────────────────────────── */
.contracts-page-wrap {
  background: var(--white);
  padding: 80px 56px;
}

@media (max-width: 768px) {
  .contracts-page-wrap { padding: 56px 28px; }
}

/* ─────────────────────────────────
   INNER-PAGE STICKY NAV BODY OFFSET
───────────────────────────────── */
/* Nav clearance for hero-less pages is handled by body.inner-page in the
   INNER-PAGE NAV section above — not here. */

/* ─────────────────────────────────
   RESPONSIVE: inner-page nav
───────────────────────────────── */
@media (max-width: 900px) {
  .page-hero { padding: 120px 28px 56px; }
}


/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE
═══════════════════════════════════════════════════════════════ */

.about-section {
  padding: 80px 56px;
  max-width: 760px;
  margin: 0 auto;
}

.about-h2 { margin-top: 12px; }

.about-desc {
  font-size: 16px;
  color: var(--muted);
  line-height: 1.8;
  margin-top: 20px;
  margin-bottom: 32px;
}

.about-features {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 36px;
}

.about-feature {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 14px;
  color: var(--mid);
  line-height: 1.5;
}

.about-feature-dot {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--orange);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  margin-top: 2px;
}

.about-cta-row {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.call-inline {
  display: flex;
  align-items: center;
  gap: 12px;
}

.call-inline-icon {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(255, 102, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--orange);
  flex-shrink: 0;
}

.call-inline-text small {
  display: block;
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  font-weight: 600;
}

.call-inline-text strong a {
  font-size: 15px;
  font-weight: 700;
  color: var(--dark);
  text-decoration: none;
  transition: color .2s;
}

.call-inline-text strong a:hover { color: var(--orange); }

/* Credentials wrapper (certs + stats stacked) */
.credentials-slide {
  background: var(--off);
}

@media (max-width: 1024px) {
  .about-section { padding: 64px 40px; }
}

@media (max-width: 640px) {
  .about-section { padding: 56px 20px; }
}


/* ═══════════════════════════════════════════════════════════════
   CONTRACTS PAGE
═══════════════════════════════════════════════════════════════ */

.contracts-section {
  padding: 80px 56px;
  max-width: 1200px;
  margin: 0 auto;
  /* Dark navy, not var(--off) — matches the site's other dark sections
     (stats-bar, products-section, testimonials-section, home-products-teaser)
     instead of being the one light "off" section in that lineup. Cards below
     switch to the same translucent glass-on-navy treatment as
     .testimonial-card / .page-hero-service-card for consistency. */
  background: var(--navy);
}

.contracts-section .section-h2 { color: var(--white); }

.contracts-head {
  max-width: 720px;
  margin-bottom: 56px;
}

.contracts-intro {
  font-size: 16px;
  color: rgba(255,255,255,0.55);
  line-height: 1.8;
  margin-top: 20px;
}

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

.contract-card {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--radius-card);
  padding: 32px;
  display: flex;
  flex-direction: column;
  transition: border-color .2s, background .2s, transform .2s;
}

.contract-card:hover {
  border-color: rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.06);
  transform: translateY(-4px);
}

.contract-card-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
}

.contract-card-header h3 {
  font-size: 18px;
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.01em;
}

.contract-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: rgba(232, 92, 34, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--orange);
  flex-shrink: 0;
}

.contract-card p {
  font-size: 14px;
  color: rgba(255,255,255,0.55);
  line-height: 1.7;
  margin-bottom: 18px;
}

.contract-tag {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  margin-top: auto;
  font-size: var(--fs-label);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--orange);
  background: rgba(255, 102, 0, 0.1);
  border: 1px solid rgba(255, 102, 0, 0.25);
  border-radius: 100px;
  padding: 4px 12px;
}

/* B2B Section */
.b2b-section {
  background: var(--off);
  padding: 80px 56px;
}

.b2b-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: center;
  max-width: 1100px;
  margin: 0 auto;
}

.b2b-text .section-h2 { margin-top: 12px; }

.b2b-text p {
  font-size: 16px;
  color: var(--muted);
  line-height: 1.8;
  margin-top: 20px;
  margin-bottom: 28px;
}

.b2b-platforms {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 32px;
}

.b2b-platform {
  font-size: 12px;
  font-weight: 600;
  color: var(--mid);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 5px 14px;
}

.b2b-cta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* .btn-glass is white-on-translucent — built for the dark hero. On this light
   (--off) section it's nearly invisible, so use a navy variant here. */
.b2b-section .btn-glass {
  background: rgba(25, 35, 64, 0.06);
  color: var(--navy);
  border-color: rgba(25, 35, 64, 0.28);
}
.b2b-section .btn-glass:hover { background: rgba(25, 35, 64, 0.12); }

.b2b-visual {
  display: flex;
  align-items: center;
  justify-content: center;
}

.b2b-diagram {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 36px 28px;
  box-shadow: var(--shadow-card);
}

.b2b-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}

.b2b-node span {
  font-size: var(--fs-label);
  font-weight: 700;
  color: var(--mid);
  line-height: 1.3;
}

.b2b-node svg { color: var(--mid); }

.b2b-node-bullchase {
  background: rgba(255, 102, 0, 0.05);
  border: 1px solid rgba(255, 102, 0, 0.15);
  border-radius: 14px;
  padding: 16px 20px;
}

.b2b-arrow { color: var(--border); }

@media (max-width: 1024px) {
  .contracts-grid { grid-template-columns: repeat(2, 1fr); }
  .b2b-inner { grid-template-columns: 1fr; gap: 48px; }
  .b2b-visual { justify-content: flex-start; }
}

@media (max-width: 768px) {
  .contracts-section, .b2b-section { padding: 56px 28px; }
}

@media (max-width: 640px) {
  .contracts-grid { grid-template-columns: 1fr; }
  .b2b-diagram { flex-direction: column; }
  .b2b-arrow { transform: rotate(90deg); }
}


/* ═══════════════════════════════════════════════════════════════
   CONTACT PAGE
═══════════════════════════════════════════════════════════════ */

.contact-section {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 80px;
  align-items: start;
  padding: 80px 56px;
  max-width: 1200px;
  margin: 0 auto;
}

.contact-info-grid {
  display: grid;
  /* minmax(0, 1fr), not bare 1fr — a plain 1fr track has an implicit `auto`
     minimum, so a cell with long unbreakable content (a long email/phone)
     can force its column wider than its sibling, unbalancing the 2x2 grid.
     minmax(0, 1fr) pins both columns to a true equal split regardless. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
  margin-top: 28px;
}

.contact-info-card {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  background: var(--off);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px;
  /* Companion fix for the grid track constraint above: a flex item's default
     min-width is `auto` (its content's min-content size), which fights the
     grid column's own minmax(0, ...) and can still force overflow/growth. */
  min-width: 0;
}

.contact-info-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: rgba(255, 102, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--orange);
  flex-shrink: 0;
}

.contact-info-icon-emergency {
  background: rgba(220, 38, 38, 0.1);
  color: #dc2626;
}

.contact-info-label {
  font-size: var(--fs-label);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 4px;
}

.contact-info-value {
  font-size: 15px;
  font-weight: 700;
  color: var(--dark);
  text-decoration: none;
  transition: color .2s;
  display: block;
  /* Long unbreakable strings (emails, phone numbers with extensions) wrap
     instead of forcing the card/column wider. */
  overflow-wrap: anywhere;
}

a.contact-info-value:hover { color: var(--orange); }

.contact-channels {
  margin-top: 28px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
}

.contact-channels-label {
  font-size: var(--fs-body-sm);
  color: var(--muted);
  margin-bottom: 12px;
}

.contact-channel-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.channel-pill {
  font-size: 12px;
  font-weight: 600;
  color: var(--mid);
  background: var(--off);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 5px 14px;
}

/* Contact Form */
.contact-form-wrap h2 { margin-bottom: 28px; }

.contact-form { display: flex; flex-direction: column; gap: 0; }

.form-row { display: flex; flex-direction: column; gap: 16px; }

.form-row-2col {
  flex-direction: row;
  gap: 16px;
  margin-bottom: 16px;
}

.form-row-2col .form-group { flex: 1; }

.form-group {
  margin-bottom: 16px;
}

.form-group label {
  display: block;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--mid);
  margin-bottom: 6px;
}

.form-group label span { color: var(--orange); }

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  box-sizing: border-box;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  color: var(--dark);
  font-family: var(--font);
  font-size: 14px;
  padding: 12px 16px;
  transition: border-color .2s, box-shadow .2s;
  appearance: none;
  -webkit-appearance: none;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(255, 102, 0, 0.12);
}

.form-group textarea { resize: vertical; min-height: 120px; }

.form-group select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='%23999' stroke-width='2'%3E%3Cpolyline points='0 1 6 7 12 1'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 40px;
}

.form-success {
  display: none;
  align-items: center;
  gap: 10px;
  background: rgba(34, 197, 94, 0.08);
  border: 1px solid rgba(34, 197, 94, 0.25);
  border-radius: 10px;
  padding: 14px 18px;
  font-size: 14px;
  font-weight: 600;
  color: #15803d;
  margin-top: 16px;
}

.form-success.visible { display: flex; }

.form-success svg { color: #22c55e; flex-shrink: 0; }

/* Grav Form plugin's own validation/delivery notice (partials/form-messages.html.twig) —
   shown on the no-JS fallback (full page reload) when a submission fails server-side. */
.lead-form .notices {
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 16px;
  font-size: 14px;
  line-height: 1.5;
}

.lead-form .notices p { margin: 0; }

.lead-form .notices.red {
  background: rgba(239, 68, 68, 0.08);
  border: 1px solid rgba(239, 68, 68, 0.25);
  color: #b91c1c;
}

.lead-form .notices.green {
  background: rgba(34, 197, 94, 0.08);
  border: 1px solid rgba(34, 197, 94, 0.25);
  color: #15803d;
}

.lead-form .notices.yellow {
  background: rgba(234, 179, 8, 0.1);
  border: 1px solid rgba(234, 179, 8, 0.3);
  color: #a16207;
}

@media (max-width: 1024px) {
  .contact-section {
    grid-template-columns: 1fr;
    gap: 56px;
  }
  .contact-info-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

@media (max-width: 768px) {
  .contact-section { padding: 56px 28px; }
  .form-row-2col { flex-direction: column; }
}

@media (max-width: 480px) {
  .contact-info-grid { grid-template-columns: 1fr; }
  .contact-section { padding: 48px 20px; }
}


/* ─────────────────────────────────
   FOCUS-VISIBLE RINGS (accessibility)
   Suppresses the default outline on mouse clicks (`:focus`)
   while showing a clear ring for keyboard navigation (`:focus-visible`).
───────────────────────────────── */
:focus { outline: none; }

.btn-orange:focus-visible,
.btn-glass:focus-visible,
.btn-white-outline:focus-visible,
.nav-cta:focus-visible,
.nav-portal:focus-visible,
.nav-hamburger:focus-visible,
.back-to-top:focus-visible,
.mobile-menu-close:focus-visible,
.form-submit:focus-visible,
.scroll-indicator:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}

.form-group input:focus-visible,
.form-group select:focus-visible,
.form-group textarea:focus-visible,
.portal-form-group input:focus-visible {
  outline: none; /* box-shadow focus state already handles these */
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(255, 102, 0, 0.18);
}

.nav-links a:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 4px;
  border-radius: 4px;
}


/* ═══════════════════════════════════════════════════════════════
   2026 meeting-note components
   (inline nav login, quote modal, lead-form honeypot, team section)
═══════════════════════════════════════════════════════════════ */

/* Visually-hidden labels for screen readers */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Inline Client Portal login in the top nav (replaces the old modal) */
.nav-portal-form {
  display: flex;
  align-items: center;
  gap: 8px;
}

.nav-portal-form input {
  width: var(--nav-input-w);
  box-sizing: border-box;
  /* Solid near-opaque fill + dark text instead of the previous "glass" look
     (8% white tint, white text) — that read fine over the solid navy sticky
     nav but on the homepage, before scroll, this form sits directly over the
     video hero with no backdrop, so a barely-tinted field was effectively
     invisible and its contrast depended entirely on the video frame behind
     it. A near-opaque fill is legible regardless of what's behind the nav. */
  background: rgba(255,255,255,0.95);
  border: 1.5px solid var(--muted);
  border-radius: 8px;
  color: var(--dark);
  font-family: var(--font);
  font-size: 13px;
  padding: 8px 10px;
  transition: border-color .2s, background .2s;
}

.nav-portal-form input::placeholder { color: var(--mid); }

.nav-portal-form input:focus {
  outline: none;
  border-color: var(--orange);
  background: var(--white);
}

.nav-portal-signin {
  background: rgba(255,255,255,0.95);
  border: 1.5px solid var(--muted);
  color: var(--navy);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 700;
  border-radius: 8px;
  padding: 8px 14px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .2s, border-color .2s, color .2s;
}

.nav-portal-signin:hover {
  background: var(--orange);
  border-color: var(--orange);
  color: var(--white);
}

/* Login form stacked inside the mobile menu */
.mobile-portal-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  margin-top: 14px;
}

.mobile-portal-form input { width: 100%; }
.mobile-portal-form .nav-portal-signin { width: 100%; text-align: center; padding: 12px; }

/* Login form stacked inside the products-page login modal (roomier than the
   nav dropdown version — the modal card has space to spare). Reuses
   .form-submit (same pill button as the lead form) for its submit button. */
.modal-portal-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.modal-portal-form input {
  width: 100%;
  box-sizing: border-box;
  background: var(--off);
  border: 1.5px solid var(--border);
  border-radius: 10px;
  color: var(--dark);
  font-family: var(--font);
  font-size: 15px;
  padding: 13px 16px;
  transition: border-color .2s, background .2s;
}

.modal-portal-form input::placeholder { color: var(--mid); }

.modal-portal-form input:focus {
  outline: none;
  border-color: var(--orange);
  background: var(--white);
}

/* Honeypot — visually removed, still in the DOM for bots */
.lead-hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Shared modal skin (quote modal, login modal) — dark backdrop, light card.
   #quote-modal / #login-modal (ids, used by js/main.js's setupModal) carry
   this styling via the shared .modal-* classes below. */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(10,15,30,0.72);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .25s, visibility .25s;
}

.modal-overlay.open { opacity: 1; visibility: visible; }

.modal-inner {
  position: relative;
  width: 100%;
  max-width: 560px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--white);
  border-radius: 20px;
  padding: 40px;
  box-shadow: 0 24px 64px rgba(0,0,0,0.4);
  transform: translateY(12px);
  transition: transform .25s;
}

.modal-overlay.open .modal-inner { transform: translateY(0); }

.modal-close {
  position: absolute;
  top: 16px; right: 16px;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--off);
  border: 1px solid var(--border);
  color: var(--mid);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .2s, color .2s;
}

.modal-close:hover { background: var(--border); color: var(--dark); }

.modal-title {
  font-size: 24px;
  font-weight: 800;
  color: var(--dark);
  letter-spacing: -0.02em;
  margin-bottom: 6px;
}

.modal-sub {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.6;
  margin-bottom: 24px;
}

/* The lead form already styles itself as a light card on the contact page;
   inside the modal the card chrome is provided by .modal-inner. */
.modal-inner .contact-form {
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
}

/* Meet the Team */
.team-section {
  padding: 80px 56px;
  max-width: 1100px;
  margin: 0 auto;
}

.team-head { text-align: center; margin-bottom: 48px; }

.team-sub {
  font-size: 15px;
  color: var(--muted);
  line-height: 1.7;
  max-width: 560px;
  margin: 12px auto 0;
}

.team-name {
  font-size: 19px;
  font-weight: 700;
  color: var(--dark);
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}

.team-role {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--orange);
  display: block;
  margin-bottom: 16px;
}

/* ─────────────────────────────────
   TEAM MEMBER BIO — text-only, on the About page. One .team-bio-inner row
   per person inside .team-list.
───────────────────────────────── */
.team-list {
  display: flex;
  flex-direction: column;
  max-width: 820px;
  margin: 0 auto;
}

.team-bio-inner {
  padding: 40px 0;
  border-bottom: 1px solid var(--border);
}
.team-bio-inner:first-child { padding-top: 0; }
.team-bio-inner:last-child { padding-bottom: 0; border-bottom: none; }

/* :not(.team-role) is load-bearing. This rule is for the bio paragraphs that
   come out of member.content; .team-role is a <p> in the same container with
   its own rule 28 lines above, and being a descendant rule this one outranked
   it on equal-class specificity by source order. The role line was therefore
   rendering 16px muted grey instead of the 13px orange its own rule asks for --
   silently, since the uppercase and letter-spacing did still apply. */
.team-bio-body p:not(.team-role) {
  font-size: 16px;
  color: var(--muted);
  line-height: 1.8;
  margin-bottom: 20px;
}

.team-linkedin {
  display: inline-block;
  font-size: 14px;
  font-weight: 700;
  color: var(--orange);
}
.team-linkedin:hover { color: var(--orange-h); }

@media (max-width: 700px) {
  .team-section { padding: 56px 24px; }
}

/* ═══════════════════════════════════════════════════════════════
   BLOG (list + post) — Grav collection-driven
═══════════════════════════════════════════════════════════════ */
.blog-section {
  background: var(--off);
  padding: 80px 56px 96px;
}
.blog-grid {
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 32px;
}
.blog-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 18px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .2s, box-shadow .2s, border-color .2s;
}
.blog-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px rgba(25, 35, 64, 0.10);
  border-color: var(--orange-light);
}
.blog-card-img { aspect-ratio: 16 / 9; overflow: hidden; background: var(--navy); }
.blog-card-img img { width: 100%; height: 100%; object-fit: cover; }
.blog-card-body { padding: 26px 26px 28px; display: flex; flex-direction: column; flex: 1; }
.blog-card-date {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--orange);
  margin-bottom: 10px;
}
.blog-card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.blog-card-title {
  font-size: 21px;
  font-weight: 800;
  line-height: 1.25;
  color: var(--dark);
  letter-spacing: -0.02em;
  margin-bottom: 12px;
}
.blog-card-excerpt { font-size: 15px; color: var(--mid); line-height: 1.7; margin-bottom: 20px; }
.blog-card-link {
  margin-top: auto;
  font-size: 14px;
  font-weight: 700;
  color: var(--orange);
  text-decoration: none;
}
.blog-card-link:hover { color: var(--orange-h); }
.blog-empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 80px 20px;
}
.blog-empty h2 { font-size: 28px; font-weight: 800; color: var(--dark); margin-bottom: 12px; }
.blog-empty p { font-size: 16px; color: var(--muted); }

.blog-post-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }

/* Single post */
.blog-post { background: var(--off); max-width: 820px; margin: 0 auto; padding: 64px 24px 88px; }
.blog-post-img { border-radius: 18px; overflow: hidden; margin-bottom: 40px; }
.blog-post-img img { width: 100%; height: auto; display: block; }
.blog-post-body { font-size: 17px; line-height: 1.85; color: var(--mid); }
.blog-post-body h2 { font-size: 28px; font-weight: 800; color: var(--dark); margin: 36px 0 16px; letter-spacing: -0.02em; }
.blog-post-body h3 { font-size: 22px; font-weight: 700; color: var(--dark); margin: 28px 0 12px; }
.blog-post-body p { margin-bottom: 20px; }
.blog-post-body ul, .blog-post-body ol { margin: 0 0 20px 22px; }
.blog-post-body li { margin-bottom: 8px; }
.blog-post-body a { color: var(--orange); }
.blog-post-back { margin-top: 48px; }

@media (max-width: 700px) {
  .blog-section { padding: 56px 24px 72px; }
  .blog-grid { gap: 24px; }
}


/* ─────────────────────────────────
   ACCOUNT PAGES (Login plugin: forgot / reset / login / profile)
   Rendered through templates/partials/base.html.twig, which adapts those
   plugin templates into this theme. Their forms ship with no theme classes at
   all, so without this block they render as raw browser defaults flush to the
   left edge — nav and footer present, everything between them unstyled.
   Scoped to .account-page so nothing here can reach the rest of the site.
───────────────────────────────── */
.account-page {
  background: var(--white);
  /* The theme's centring idiom, same as .stats-bar and the footer. */
  padding: 64px max(56px, calc((100% - var(--frame-max)) / 2));
}
.account-page-inner { max-width: 460px; }
.account-page h1 { font-size: 28px; color: var(--navy); margin-bottom: 8px; }
.account-page p { color: var(--mid); font-size: 15px; margin-bottom: 24px; }
.account-page label {
  display: block;
  font-size: var(--fs-label);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  margin-bottom: 6px;
}
.account-page input[type="text"],
.account-page input[type="email"],
.account-page input[type="password"] {
  width: 100%;
  font-family: var(--font);
  font-size: 15px;
  padding: 13px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--white);
  margin-bottom: 18px;
}
.account-page input:focus { outline: 2px solid var(--orange); outline-offset: 1px; }
.account-page button,
.account-page input[type="submit"] {
  background: var(--orange);
  color: var(--white);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 700;
  padding: 14px 30px;
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.account-page button:hover { background: var(--orange-h); }
