:root {
  --bg-base:          #000000;
  --bg-depth:         #0a0a0a;
  --glass-bg:         rgba(255, 255, 255, 0.05);
  --glass-border:     rgba(255, 255, 255, 0.12);
  --accent:           #c8cdd4;
  --accent-light:     #e8eaed;
  --accent-dark:      #8e949c;
  --accent-hover:     #b0b7bf;
  --accent-glow:      rgba(200, 205, 212, 0.12);
  --accent-gradient:  linear-gradient(135deg,
                        #e8eaed 0%,
                        #9ba3ab 40%,
                        #c8cdd4 60%,
                        #e2e5e8 100%);
  --text-primary:     #ffffff;
  --text-body:        #e5e7eb;
  --text-muted:       #9ca3af;
  --border-subtle:    rgba(255, 255, 255, 0.08);
  --border-glass:     rgba(255, 255, 255, 0.14);

  /* V2 semantic tokens — additive aliases over the palette above.
     Existing component CSS keeps using the names above unchanged;
     new V2 components (hex system, parallax hero) use these. */
  --bg:            var(--bg-base);
  --surface:       var(--bg-depth);
  --surface-2:     #151515;
  --surface-3:     #1c1c1c;
  --text:          var(--text-primary);
  --text-secondary: var(--text-body);
  --silver:        var(--accent);
  --silver-dark:   var(--accent-dark);
  --silver-light:  var(--accent-light);
  --border:        var(--border-subtle);
  --border-strong: var(--border-glass);

  /* V2.1 spacing scale — the deliberate rhythm tokens the layout/
     alignment audit introduces. Mapped onto values already in use
     across the stylesheet (not invented numbers), so applying them
     doesn't shift anything visually — it just gives the repeated,
     structural values (section rhythm, grid gaps) a shared name
     instead of being restated as literals everywhere. */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs:  0.75rem;
  --space-sm:  1rem;
  --space-md:  1.5rem;
  --space-lg:  2rem;
  --space-xl:  3rem;
  --space-2xl: 4.5rem;
  --space-3xl: 6rem;

  /* V2 Phase 2 — spacing and type scale. Used by the refined nav, card,
     trust-rail and cookie-banner components below; existing components
     keep their original hand-tuned values untouched. Independent, named
     differently, from the --space-3xs..3xl scale above — both are kept,
     each still has real consumers. */
  --space-1: 0.25rem; --space-2: 0.5rem;  --space-3: 0.75rem;
  --space-4: 1rem;    --space-5: 1.25rem; --space-6: 1.5rem;
  --space-8: 2rem;    --space-10: 2.5rem; --space-12: 3rem;
  --text-xs: 0.8125rem; --text-sm: 0.875rem; --text-base: 1rem;
  --text-lg: 1.125rem;  --text-xl: 1.25rem; --text-2xl: 1.5rem;
}

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

html, body {
  margin: 0; padding: 0;
  background-color: #000000 !important;
  color: #d1d5db;
  font-family: 'Inter', system-ui, sans-serif;
  line-height: 1.6;
  overflow-x: hidden;
}

.skip-link {
  position: absolute; top: auto; left: -9999px; z-index: 9999;
  padding: 0.75rem 1.25rem; background: #000; color: #fff;
  font-size: 1rem; font-weight: 600; text-decoration: none;
  border-radius: 0 0 4px 0; transition: left 0s;
}
.skip-link:focus { left: 0; top: 0; }

h1,h2,h3,h4,h5,h6 {
  font-family: 'Poppins','Inter',sans-serif;
  color: #ffffff; margin: 0 0 1rem; line-height: 1.2;
  letter-spacing: -0.01em;
}
/* Deliberate type scale — previously every heading below h1 fell back to
   the browser's UA default size, so hierarchy was accidental rather than
   designed. */
h1 { font-size: clamp(2.25rem, 4.5vw, 3.25rem); font-weight: 700; }
h2 { font-size: clamp(1.65rem, 3vw, 2.15rem); font-weight: 700; }
h3 { font-size: 1.2rem; font-weight: 600; letter-spacing: -0.005em; }
h4 { font-size: 1.05rem; font-weight: 600; letter-spacing: 0; }
p { margin: 0 0 1rem; color: #e5e7eb; }
li, td { color: #e5e7eb; }
small, .muted { color: #9ca3af; }
a { color: inherit; }
img { max-width: 100%; display: block; }
.container { width: min(1160px, calc(100% - 2rem)); margin: 0 auto; }

/* ── MOUSE GLOW ── */
#mouse-glow {
  position: fixed; top: 0; left: 0;
  width: 240px; height: 240px; border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255,255,255,0.09) 0%,
    rgba(255,255,255,0.04) 35%,
    rgba(255,255,255,0.01) 60%,
    transparent 75%);
  pointer-events: none; z-index: 9998;
  transform: translate(-50%, -50%);
  transition: opacity 0.3s ease; will-change: left, top;
}
@media (hover: none), (max-width: 768px) {
  #mouse-glow { display: none !important; }
}

/* ── ACCESSIBILITY ── */
.sr-only {
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); border:0;
}
.focus\:not-sr-only:focus {
  position:fixed; left:1rem; top:1rem;
  width:auto; height:auto; clip:auto; margin:0;
  padding:0.6rem 1rem; background:#fff; color:#000;
  z-index:3000; border-radius:0.5rem;
}
a:focus-visible,button:focus-visible,
input:focus-visible,select:focus-visible,
textarea:focus-visible {
  outline:3px solid var(--accent); outline-offset:2px;
}

/* ── NAVBAR ── */
.site-header {
  position: sticky; top: 0; z-index: 1000;
  background: rgba(0,0,0,0.5) !important;
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border-bottom: 1px solid rgba(255,255,255,0.07);
  transition: background 0.3s ease, box-shadow 0.3s ease;
}
.site-header.scrolled {
  background: rgba(0,0,0,0.92) !important;
  box-shadow: 0 4px 24px rgba(0,0,0,0.6);
}
.nav-wrap {
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: 1rem; min-height: 88px;
}
.logo-circle {
  border-radius: 50%; overflow: hidden;
  display: inline-flex; align-items: center;
  justify-content: center; background: #ffffff;
}
.logo-circle-nav {
  width:64px; height:64px;
  border: 2px solid rgba(255,255,255,0.25); padding: 6px;
}
.logo-circle-footer {
  width:80px; height:80px;
  border: 2px solid rgba(255,255,255,0.2); padding: 8px;
}
.logo-circle img {
  width:100%; height:100%;
  object-fit: contain !important; object-position: center;
}
.site-nav {
  display:flex; justify-content:center;
  align-items:center; gap:1.2rem;
}
.site-nav a:not(.cta-pill) {
  position:relative; text-decoration:none; color:#ffffff;
  font-weight:600; font-size:var(--text-sm); transition:color 0.2s;
  padding-bottom:2px;
}
.site-nav a:not(.cta-pill)::after {
  content:''; position:absolute; left:0; right:100%; bottom:0;
  height:1px; background:var(--silver);
  transition:right 0.2s ease;
}
.site-nav a:not(.cta-pill):hover { color: #c8cdd4; }
.site-nav a:not(.cta-pill):hover::after,
.site-nav a:not(.cta-pill):focus-visible::after { right:0; }
.menu-toggle {
  display:none; width:48px; height:48px;
  border:1px solid rgba(255,255,255,0.4);
  background:rgba(255,255,255,0.1);
  border-radius:0.6rem;
  align-items:center; justify-content:center;
  gap:0.25rem; flex-direction:column; cursor: pointer;
}
.menu-toggle span { width:22px; height:2px; background:#fff; }

/* Nav phone links */
.nav-phone-desktop { font-weight:600; color:#c8cdd4 !important; font-size:0.95rem; }
.nav-phone-mobile { display:none; font-weight:700; color:#c8cdd4; font-size:0.85rem; text-decoration:none; }

/* ── BUTTONS ── */
.btn {
  text-decoration:none; border-radius:9999px;
  padding:0.75rem 1.25rem; font-weight:600;
  display:inline-flex; align-items:center;
  justify-content:center; border:2px solid transparent;
  cursor:pointer; transition: all 0.2s ease;
}
/* A class-selector display rule beats the UA stylesheet's [hidden]
   selector on specificity, so any element styled with display here
   would otherwise stay visibly rendered even with the hidden attribute
   set — exactly the bug this line exists to prevent. */
.btn[hidden] { display:none !important; }
.btn-primary,
.cta-pill {
  position:relative; overflow:hidden;
  background: linear-gradient(135deg, #e8eaed 0%, #9ba3ab 40%, #c8cdd4 60%, #e2e5e8 100%) !important;
  color: #000000 !important; font-weight: 700 !important; border: none !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), 0 4px 15px rgba(200,205,212,0.15) !important;
}
.btn-primary::before,
.cta-pill::before {
  content:''; position:absolute; top:0; bottom:0; left:-60%; width:40%;
  background:linear-gradient(115deg, transparent, rgba(255,255,255,0.55), transparent);
  transform:skewX(-20deg) translateX(-20%);
  transition:transform 0.5s ease; pointer-events:none;
}
.btn-primary:hover,
.cta-pill:hover {
  background: linear-gradient(135deg, #ffffff 0%, #c8cdd4 40%, #e2e5e8 100%) !important;
  transform: translateY(-1px) !important;
}
.btn-primary:hover::before,
.cta-pill:hover::before { transform:skewX(-20deg) translateX(340%); }
@media (prefers-reduced-motion:reduce) {
  .btn-primary::before, .cta-pill::before { display:none; }
}
.btn-outline { border-color:#fff; color:#fff; background:transparent; }
.btn-outline:hover { background:rgba(255,255,255,0.1); }
.btn-outline-orange { border-color:var(--accent); color:var(--accent); background:transparent; }
.btn-dark { background:rgba(255,255,255,0.08); color:#fff; }
.btn-light { background:#fff; color:#000; }
.btn-full { width:100%; }
.hero-cta-row { display:flex; flex-wrap:wrap; gap:0.75rem; justify-content:center; }

.cta-pill {
  /* Colour/hover/sweep are on the shared .btn-primary,.cta-pill rules
     above — this just supplies the pill-specific box model, since
     .cta-pill is used standalone (not combined with .btn) in the nav. */
  padding: 0.65rem 1.4rem !important; border-radius: 9999px !important;
  text-decoration: none !important; display: inline-block !important;
}

/* ── HERO ── */
.hero {
  position:relative; min-height:100vh;
  display:flex; align-items:center;
  justify-content:center; color:#fff;
  overflow:hidden; background:#000000 !important;
}
.hero-media {
  position:absolute; top:-20%; left:0;
  width:100%; height:140%;
  object-fit:cover; object-position:center;
  will-change:transform; z-index:0;
}
.hero-overlay {
  position:absolute; inset:0;
  background:rgba(0,0,0,0.62) !important; z-index:1;
}
.hero-content { position:relative; z-index:3; text-align:center; }
.hero h1 {
  color:#fff; font-size:clamp(2.5rem,6vw,4rem);
  max-width:980px; margin-inline:auto;
}
.hero p { color:#fff; font-size:1.1rem; }
.hero-phone a { color:#fff; text-decoration:underline; font-weight:600; }

/* Hero trust rail — small structural "spec plate" tags rather than soft
   pills: flat corners, a thin silver top edge, hairline dividers between
   them, closer to an engineering nameplate than a marketing badge.
   (Design merged from Phase 2's premium redesign of this component.)

   display:inline-flex, not flex: a plain `flex` block still stretches
   to the full width of .hero-content and, with no justify-content, its
   flush-together spans sit left-aligned inside that oversized box — the
   exact "badges don't read as one balanced, centred group" bug the
   alignment audit fixed, just reintroduced by a different visual
   treatment of the same element. inline-flex sizes the whole plate to
   its content and lets it centre as a unit via the parent's
   text-align:center, the same way the plate's own bordered edge should
   only wrap its content, not the full hero width. */
.hero-trust-badges {
  display:inline-flex; flex-wrap:wrap; margin-top:1.75rem;
  border:1px solid rgba(255,255,255,0.18); border-radius:2px;
  overflow:hidden; backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
}
.hero-trust-badges span {
  position:relative; background:rgba(0,0,0,0.35);
  border-top:2px solid var(--silver);
  border-left:1px solid rgba(255,255,255,0.14);
  color:#fff; font-size:var(--text-xs); font-weight:600;
  letter-spacing:0.03em; text-transform:uppercase;
  padding:0.5rem 0.9rem;
}
.hero-trust-badges span:first-child { border-left:none; }

/* ── HERO PARALLAX ──
   Photo-only. An earlier version also carried a hex mesh layer directly
   over the hero photograph — visually wrong (photography must stay
   clean; see .hex-texture below for where the structural signature
   actually belongs). Motion is transform-only (driven by JS setting a
   CSS custom property), so it never triggers layout/paint of anything
   else. Desktop pointer devices only — see generate_js(); everywhere
   else the layer is simply static. */
.hero-media { transform:translateY(var(--hero-parallax-y, 0px)); }
@media (prefers-reduced-motion:reduce) {
  .hero-media { transform:none !important; }
}

/* ── WHAT WE DO (homepage, immediately after hero) ──
   A short, concrete "here is what we do" statement plus three plain
   text links into the real service-group anchors below — deliberately
   NOT another card grid; the decision-grid further down the page is
   the card-based routing mechanism, this is just a pointer. */
.what-we-do-routes {
  display:flex; flex-wrap:wrap; gap:0.5rem 1.5rem; margin-top:1.25rem;
  list-style:none; padding:0;
}
.what-we-do-routes a {
  color:var(--silver); font-weight:600; font-size:var(--text-sm);
  text-decoration:underline; text-underline-offset:3px;
}

/* ── SELECTIVE SPLIT-IMAGE PARALLAX ──
   Applied to exactly one homepage section (For Builders & Roofers) per
   explicit direction: hero gets the strong parallax, project imagery
   stays static, and at most one other "major split-image section" gets
   very subtle movement. Same desktop-pointer/reduced-motion/mobile
   guards as the hero (see generate_js()), a smaller ratio (0.06) so it
   reads as barely-there depth, not a second hero effect. */
.parallax-split .parallax-image { transform:translateY(var(--split-parallax-y, 0px)); will-change:transform; }
@media (prefers-reduced-motion:reduce) {
  .parallax-split .parallax-image { transform:none !important; }
}

/* ── SECTIONS ── */
.section { padding:var(--space-2xl) 0; }
.section-light { background:#0a0a0a !important; }
.section-dark  { background:#000000 !important; }
.section-dark h2,.section-dark h3,.section-dark p { color:#ffffff; }
.section-intro { color:#9ca3af; margin-bottom:1.5rem; }

/* ── PAPER (genuinely light) SECTIONS ──
   .section-light is actually #0a0a0a — near-black, barely distinguishable
   from .section-dark's #000000. Used everywhere on the site, so it isn't
   touched here (redefining it would ripple through every page's child
   text colours, which assume a dark backdrop). This is a separate,
   self-contained light surface — genuine white/black editorial contrast,
   not another shade of near-black — used deliberately on a few homepage
   sections to break up what would otherwise be dark-on-dark-on-dark for
   the entire page. */
.section-paper { background:#f2f1ee !important; }
.section-paper h2, .section-paper h3, .section-paper h4 { color:#0a0a0a; }
.section-paper p, .section-paper li, .section-paper td { color:#2b2b2b; }
.section-paper .section-intro { color:#5a5a58; }
.section-paper a:not(.btn) { color:#000; text-decoration-color:#8e949c; }
.section-paper .process-num {
  background:linear-gradient(135deg,#1c1c1c,#3a3a3a); color:#fff;
}
.section-paper .process-step h3 { color:#0a0a0a; }
.section-paper .process-step p { color:#4a4a48; }
.section-paper .direct-answer {
  color:#0a0a0a; background:#fff; border-left-color:#8e949c;
  box-shadow:0 1px 2px rgba(0,0,0,0.08);
}
.section-paper .pricing-factors { color:#2b2b2b; }
.section-paper .pricing-factors li::marker { color:#8e949c; }

/* ── TRUST RAIL ── */
.trust-bar {
  background:var(--surface) !important;
  border-top:1px solid var(--border-strong);
  border-bottom:1px solid var(--border-strong);
  padding:var(--space-8) 0; overflow-x:auto;
}
.trust-items { display:flex; gap:0; justify-content:center; flex-wrap:wrap; }
.trust-item {
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1);
  padding:0 var(--space-8); border-left:1px solid var(--border);
}
.trust-item:first-child { border-left:none; }
.trust-number,.trust-static { font-family:'Poppins',sans-serif; font-size:1.9rem; font-weight:700; color:#ffffff; letter-spacing:-0.02em; }
.trust-label { color:#9ca3af; font-size:var(--text-xs); text-align:center; text-transform:uppercase; letter-spacing:0.04em; }
@media (max-width:768px) {
  .trust-item { padding:0 var(--space-4); }
}

/* ── CARD SYSTEM ──
   Default surface is solid and architectural — a deliberate steel panel
   with a bright top edge, not glass. Heavy blur/saturate/brightness glass
   used to be applied to every card on the site; that's now reserved for
   .quote-form-card alone (the one genuine floating/input panel). Solid
   cards read as material, not as a translucent overlay effect. */
.service-card,
.testimonial-card,
.contact-card,
.social-card,
.decision-card {
  position: relative;
  background: var(--surface-2) !important;
  border: 1px solid var(--border) !important;
  border-top: 2px solid var(--border-strong) !important;
  border-radius: 10px !important;
  box-shadow: 0 1px 2px rgba(0,0,0,0.4), 0 8px 24px rgba(0,0,0,0.35) !important;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease !important;
}
.service-card:hover,
.testimonial-card:hover,
.social-card:hover,
.decision-card:hover {
  transform: translateY(-3px) !important;
  border-color: var(--silver) !important;
  box-shadow: 0 4px 8px rgba(0,0,0,0.45), 0 16px 36px rgba(0,0,0,0.4) !important;
}

/* Reserved glass — the quote form and quote wizard only (the genuine
   floating/input panels on the site). */
.glass-card,
.quote-form-card,
.quote-wizard-card {
  position: relative; overflow: hidden;
  background: rgba(255,255,255,0.045) !important;
  border: 1px solid var(--border-strong) !important;
  backdrop-filter: blur(16px) saturate(160%) !important;
  -webkit-backdrop-filter: blur(16px) saturate(160%) !important;
  border-radius: 14px !important;
  box-shadow:
    0 4px 6px rgba(0,0,0,0.4),
    0 10px 40px rgba(0,0,0,0.5),
    inset 0 1px 0 rgba(255,255,255,0.10) !important;
}
.quote-form-card:hover,
.quote-wizard-card:hover { transform: none !important; }

/* ── SERVICES GRID ──
   Both .services-grid and .service-listing always render the same 9
   SERVICES entries, so — unlike .decision-grid, which is reused with
   varying counts — this can be a fully deliberate, zero-ambiguity
   composition rather than a general-purpose fallback:
     mobile           (≤768px):     1 column
     tablet + desktop (≥769px):     3 columns → 9 = 3 + 3 + 3, always
   A 2-column tablet tier was deliberately rejected: 9 services in 2
   columns is 4 + 4 + 1, the exact orphan-row problem this system
   exists to avoid. Percentage-based flex-basis (not a fixed px
   value) means a full row always sums to exactly 100% and sits flush
   with the container edges, matching every other section. */
.services-grid, .service-listing {
  display:flex; flex-wrap:wrap; justify-content:center; gap:1rem;
}
.services-grid .service-card, .service-listing .service-card {
  flex:0 0 100%;
}
@media (min-width:769px) {
  .services-grid .service-card, .service-listing .service-card {
    flex-basis:calc(33.333% - 0.667rem);
  }
}
.service-card { padding:1.5rem; }
.service-icon {
  width:40px; height:40px; border-radius:50%;
  background: linear-gradient(135deg, #c8cdd4, #8e949c) !important;
  margin-bottom:0.75rem;
}
.service-card h2, .service-card h3, .service-card h4 { margin-bottom:0.5rem; font-size:1.1rem; }
.service-card p { margin-bottom:0.75rem; }
.service-card a { color:#e5e7eb; font-weight:600; text-decoration:none; }
.service-card a:hover { color:#ffffff; }
/* "Who is this for?" as a quick visual cue, not a sentence to read —
   a restrained outlined pill directly under the name, so a visitor
   can tell who a card is for before reading anything else. Outlined,
   not filled: a badge should be a cue, not compete with the heading. */
.service-card-audience {
  display:inline-block; color:var(--silver, #c8cdd4);
  border:1px solid rgba(200,205,212,0.4); border-radius:9999px;
  font-size:0.72rem; font-weight:700; letter-spacing:0.03em;
  text-transform:uppercase; padding:0.2rem 0.65rem; margin-bottom:0.75rem;
}
/* Same accent Emergency already uses on the homepage decision grid —
   reused here so the one genuinely time-critical service reads as
   different wherever it appears, not just on that one card. */
.service-card-urgent {
  border-color:rgba(255,100,100,0.35) !important;
  border-top-color:rgba(255,120,120,0.6) !important;
  background:rgba(255,50,50,0.06) !important;
}
.service-card-urgent:hover { border-color:rgba(255,120,120,0.55) !important; }

/* ── SERVICE GROUPS ──
   Three functional groups instead of nine equally-weighted cards —
   the product-design fix, not just a visual one: a visitor should
   recognise which third of the page is theirs before reading a single
   card. Each group is a self-contained services-grid with exactly 3
   cards, so the flex composition system above always renders one full,
   flush row per group — never an orphan. */
.services-group + .services-group { margin-top:2.5rem; }
.services-group-heading { margin-bottom:0.35rem; }
.services-group-intro { color:#9ca3af; font-size:0.95rem; margin:0 0 1.25rem; }

/* ── SPLIT GRID ── */
.split-grid { display:grid; grid-template-columns:1fr 1fr; gap:2rem; align-items:center; }
.rounded-image { border-radius:1rem; }

/* ── USP LIST ── */
.usp-list { list-style:none; padding:0; margin:0 0 1.25rem; }
.usp-list li { margin-bottom:0.7rem; padding-left:1.5rem; position:relative; color:#d1d5db; }
.usp-list li::before {
  content:'✔'; position:absolute; left:0;
  background: linear-gradient(135deg, #e8eaed, #9ba3ab);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text;
}
@supports not (-webkit-background-clip: text) {
  .usp-list li::before { color:#c8cdd4 !important; -webkit-text-fill-color:unset !important; }
}
.about-blurb {
  background:rgba(255,255,255,0.04);
  border-left:4px solid rgba(255,255,255,0.18);
  padding:0.9rem; border-radius:0.75rem; color:#d1d5db;
}

/* ── PROJECTS — EDITORIAL CARDS ──
   Photography does the work here, not card chrome: flat corners, no
   glass, no gradient overlay, no icons. Metadata (label + location) is
   always visible below the photo — it used to live in a figcaption that
   only appeared on :hover, which meant it was permanently invisible on
   touch devices (no hover state). "View project" is the one genuinely
   supplementary hover affordance; everything a customer actually needs
   to evaluate the project is visible without interaction. */
.projects-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--space-8) var(--space-6); }
/* /gallery's full portfolio only: a periodic wide tile breaks up an
   otherwise uniform wall of identical cards. grid-auto-flow:dense means a
   filtered-out (display:none) item is simply removed from the flow, so the
   remaining tiles repack cleanly — the wide positions aren't reserved gaps,
   the dense algorithm fills around whichever tiles are actually visible. */
.projects-grid-portfolio {
  grid-auto-flow: dense; gap:var(--space-10) var(--space-6);
}
.projects-grid-portfolio .project-item:nth-child(5n+1) {
  grid-column: span 2;
}
.projects-grid-portfolio .project-item:nth-child(5n+1) .project-item-media {
  aspect-ratio: 16/9;
}
@media (max-width:900px) {
  .projects-grid-portfolio .project-item:nth-child(5n+1) { grid-column: span 1; }
  .projects-grid-portfolio .project-item:nth-child(5n+1) .project-item-media { aspect-ratio: 4/5; }
}
/* "Recently Added" on /gallery only — genuine, founder-confirmed photos
   not yet matched to a town/service, so no lightbox, no area/service link,
   no category filter: just the photo (opens full-size in a new tab) and an
   honest caption. Same flat, photography-first treatment as .project-item. */
.untagged-photo-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--space-8) var(--space-6); }
.untagged-photo a { display:block; overflow:hidden; aspect-ratio:4/5; background:var(--surface-2); border-top:2px solid var(--border-strong); }
.untagged-photo img { width:100%; height:100%; object-fit:cover; display:block; transition:transform 0.5s ease; }
.untagged-photo a:hover img, .untagged-photo a:focus-visible img { transform:scale(1.04); }
.untagged-photo figcaption { padding:var(--space-3) 0 0; color:var(--text-muted); font-size:var(--text-sm); }
@media (max-width:640px) { .untagged-photo-grid { grid-template-columns:1fr; } }
.project-item { position:relative; }
.project-item-media {
  position:relative; display:block; overflow:hidden; width:100%;
  aspect-ratio:4/5; background:var(--surface-2);
  border-top:2px solid var(--border-strong);
  border-left:none; border-right:none; border-bottom:none;
  padding:0; margin:0; font:inherit; text-align:inherit; cursor:pointer;
}
.project-item-media img {
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform 0.5s ease;
}
.project-item-media:hover img,
.project-item-media:focus-visible img { transform:scale(1.04); }
.project-item-media::after {
  content:'View project 92'; position:absolute; right:var(--space-3); bottom:var(--space-3);
  background:rgba(0,0,0,0.55); border:1px solid var(--silver); color:#fff;
  font-size:var(--text-xs); font-weight:600; letter-spacing:0.02em;
  padding:0.35rem 0.7rem; opacity:0; transform:translateY(6px);
  transition:opacity 0.2s ease, transform 0.2s ease; pointer-events:none;
}
.project-item-media:hover::after,
.project-item-media:focus-visible::after { opacity:1; transform:translateY(0); }
.project-item figcaption { padding:var(--space-3) 0 0; }
.project-item-label { display:block; color:#fff; font-weight:600; font-size:var(--text-base); }
.project-item-meta { display:block; color:var(--text-muted); font-size:var(--text-sm); margin-top:0.2rem; }
.project-item-meta a { color:var(--text-muted); text-decoration:underline; text-underline-offset:2px; }
.project-item-meta a:hover { color:var(--silver); }
.project-item-desc { color:var(--text-secondary); font-size:var(--text-sm); margin:var(--space-2) 0 0; }
.project-item-service-link {
  display:inline-block; color:var(--silver); font-size:var(--text-xs); font-weight:600;
  text-decoration:none; margin-top:var(--space-2);
}
.project-item-service-link:hover { text-decoration:underline; }

/* Homepage: one large featured project + secondaries, not a wall of
   identical tiles. */
.projects-feature-grid {
  display:grid; grid-template-columns:1.4fr 1fr; gap:var(--space-8) var(--space-6);
  align-items:start;
}
.projects-feature-grid .project-item-featured .project-item-media { aspect-ratio:4/3; }
.projects-feature-grid .project-item-featured .project-item-label { font-size:var(--text-2xl); }
.projects-feature-grid .project-item-featured .project-item-desc {
  font-size:var(--text-lg); line-height:1.55; color:var(--text-secondary);
  border-left:2px solid var(--border-strong); padding-left:var(--space-4); margin-top:var(--space-3);
}
.projects-feature-secondary { display:flex; flex-direction:column; gap:var(--space-8); }
/* Desktop only: secondary projects read as a short editorial list (photo
   beside caption) rather than two more stacked cards identical to the
   featured one above. Collapses back to the normal stacked project-item at
   1024px and below, where the existing responsive rules already apply. */
@media (min-width:1025px) {
  .projects-feature-secondary .project-item { display:flex; gap:var(--space-4); align-items:flex-start; }
  .projects-feature-secondary .project-item-media { width:120px; flex:none; }
  .projects-feature-secondary .project-item-media::after { display:none; }
  .projects-feature-secondary .project-item figcaption { padding-top:0; }
}

/* /gallery: one large featured project ahead of the filterable grid —
   same "photography first, cards second" principle as the homepage,
   applied to the full portfolio page. */
.section-eyebrow {
  color:var(--silver); font-size:var(--text-xs); font-weight:700;
  text-transform:uppercase; letter-spacing:0.08em; margin:0 0 var(--space-3);
}
.projects-grid-heading { margin-top:0; }
.projects-feature-single { margin-bottom:var(--space-12); max-width:900px; }
.projects-feature-single .project-item-media { aspect-ratio:16/10; }
@media (max-width:640px) {
  .projects-feature-single .project-item-media { aspect-ratio:4/3; }
}

@media (prefers-reduced-motion:reduce) {
  .project-item-media img { transition:none; }
  .project-item-media::after { transition:none; }
}
.centered { text-align:center; }

/* ── PROJECT FILTERS ── */
.project-filters { display:flex; flex-wrap:wrap; gap:0.6rem; margin:var(--space-6) 0 var(--space-8); }
.project-filter-btn {
  background:transparent; border:1px solid var(--border-strong); color:var(--text-secondary);
  border-radius:9999px; padding:0.45rem 1.1rem; font-size:var(--text-sm); font-weight:600;
  cursor:pointer; transition:border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.project-filter-btn:hover { border-color:var(--silver); color:#fff; }
.project-filter-btn[aria-pressed="true"] {
  background:var(--silver); border-color:var(--silver); color:#000;
}
.project-item[hidden] { display:none; }

/* ── PROJECT LIGHTBOX ──
   Full-size view of the real photograph. Every control is always
   rendered (no hover-only affordances) — close/prev/next are plain
   buttons, always visible and keyboard-reachable while open. */
.project-lightbox {
  position:fixed; inset:0; z-index:100000;
  background:rgba(0,0,0,0.94);
  display:flex; align-items:center; justify-content:center;
  padding:var(--space-6);
}
.project-lightbox[hidden] { display:none; }
body.lightbox-open { overflow:hidden; }
.project-lightbox-figure {
  max-width:min(1100px, 92vw); max-height:92vh; margin:0;
  display:flex; flex-direction:column; align-items:center; gap:var(--space-4);
}
.project-lightbox-img {
  max-width:100%; max-height:72vh; width:auto; height:auto;
  object-fit:contain; border-top:2px solid var(--silver); display:block;
}
.project-lightbox-figure figcaption { text-align:center; max-width:640px; }
.project-lightbox-label { display:block; color:#fff; font-weight:600; font-size:var(--text-lg); }
.project-lightbox-meta { display:block; color:var(--text-muted); font-size:var(--text-sm); margin-top:0.2rem; }
.project-lightbox-desc { color:var(--text-secondary); font-size:var(--text-sm); margin:var(--space-2) 0 0; }
.project-lightbox-close,
.project-lightbox-prev,
.project-lightbox-next {
  position:fixed; background:rgba(10,10,10,0.7); border:1px solid var(--border-strong);
  color:#fff; border-radius:50%; width:48px; height:48px; font-size:1.4rem;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  transition:border-color 0.2s ease, background 0.2s ease;
}
.project-lightbox-close:hover,
.project-lightbox-prev:hover,
.project-lightbox-next:hover { border-color:var(--silver); background:rgba(10,10,10,0.9); }
.project-lightbox-close { top:var(--space-6); right:var(--space-6); }
.project-lightbox-prev { left:var(--space-4); top:50%; transform:translateY(-50%); }
.project-lightbox-next { right:var(--space-4); top:50%; transform:translateY(-50%); }
.project-lightbox-prev:disabled,
.project-lightbox-next:disabled { opacity:0.3; cursor:default; }
@media (max-width:640px) {
  .project-lightbox { padding:var(--space-4); }
  .project-lightbox-prev,.project-lightbox-next { width:40px; height:40px; font-size:1.1rem; }
  .project-lightbox-close { width:40px; height:40px; top:var(--space-3); right:var(--space-3); }
  .project-lightbox-prev { left:var(--space-2); }
  .project-lightbox-next { right:var(--space-2); }
}

/* ── TESTIMONIALS ── */
.testimonial-carousel { overflow:hidden; }
.testimonial-track { display:flex; transition:transform 0.5s ease; }
.testimonial-card { min-width:100%; padding:1.75rem; }
.review-stars {
  color:#f5c518; font-size:1.3rem; letter-spacing:2px;
  margin-bottom:0.75rem; display:block;
}
.review-stars span { color:#f5c518 !important; display:inline-block; line-height:1; }
.review-text {
  color:#d1d5db; font-size:0.95rem; line-height:1.7;
  font-style:italic; margin:0 0 1.25rem; padding:0; border:none;
}
.reviewer-info { display:flex; align-items:center; justify-content:space-between; gap:0.5rem; flex-wrap:wrap; }
.reviewer-name { color:#ffffff; font-family:'Poppins',sans-serif; font-weight:600; font-size:0.9rem; }
.review-source { display:flex; align-items:center; gap:0.35rem; color:#6b7280; font-size:0.78rem; }
.review-source img { width:16px; height:16px; display:inline-block; }

/* ── AREA PILLS ── */
.area-pills { list-style:none; padding:0; margin:0; display:flex; flex-wrap:wrap; gap:0.6rem; }
.area-pills li { display:inline-flex; }
.area-pill-link {
  display:inline-block; padding:0.45rem 0.9rem;
  border:1px solid #c8cdd4 !important; color:#c8cdd4 !important;
  border-radius:9999px; text-decoration:none; font-weight:500;
}
.area-pill-link:hover {
  background: linear-gradient(135deg, #e8eaed, #c8cdd4) !important;
  color: #000000 !important; border-color:transparent !important;
}

/* ── FAQ ── */
.faq-wrap { max-width:900px; }
.faq-item {
  background:rgba(255,255,255,0.03) !important;
  border:1px solid rgba(255,255,255,0.08) !important;
  border-radius:12px; margin-bottom:0.75rem;
  overflow:hidden; transition:all 0.3s ease;
}
.faq-item.open {
  border-left:3px solid #c8cdd4 !important;
  background:rgba(200,205,212,0.04) !important;
}
.faq-question {
  width:100%; text-align:left; background:transparent; border:none;
  padding:1rem; font-size:1rem; font-weight:600; cursor:pointer;
  color:#ffffff !important;
}
.faq-answer { display:none; padding:0 1rem 1rem; color:#d1d5db !important; }

/* ── QUOTE FORM ── */
.quote-form-card { padding:1.5rem; }
.quote-form-card form p { margin-bottom:0.9rem; }
.quote-form-card label { display:block; margin-bottom:0.35rem; font-weight:600; color:#ffffff !important; }
.quote-form-card input,
.quote-form-card select,
.quote-form-card textarea {
  width:100%; background:rgba(255,255,255,0.06) !important;
  border:1px solid rgba(255,255,255,0.14) !important;
  border-radius:10px !important; color:#ffffff !important;
  padding:0.7rem 0.9rem !important; font:inherit !important;
  transition:border-color 0.2s ease !important;
}
.quote-form-card input:focus,
.quote-form-card select:focus,
.quote-form-card textarea:focus {
  border-color:rgba(255,255,255,0.45) !important; outline:none !important;
  background:rgba(255,255,255,0.09) !important;
}
.quote-form-card select option { background:#0a0a0a; color:#ffffff; }
.quote-form-card textarea { min-height:120px; }
.form-message { min-height:1.2rem; font-weight:600; color:#34d399; }

/* ── QUOTE WIZARD ──
   A premium multi-step project-intake tool, built as ONE real <form>
   (same FormSubmit action, same .axis-quote-form submit/consent/analytics
   handling already used everywhere else on the site) with a client-side
   JS layer on top that shows one fieldset at a time. Without JS every
   fieldset is visible and the real submit button is already showing —
   it degrades to one long working form, not a broken one. */
.quote-wizard-card { padding:1.75rem; }
.quote-wizard-card form p { margin-bottom:0.9rem; }
.quote-wizard-card label { display:block; margin-bottom:0.35rem; font-weight:600; color:#ffffff !important; }
.quote-wizard-card .quote-optional { font-weight:400; color:#9ca3af; }
.quote-wizard-card input[type="text"],
.quote-wizard-card input[type="tel"],
.quote-wizard-card input[type="email"],
.quote-wizard-card input:not([type]),
.quote-wizard-card select,
.quote-wizard-card textarea {
  width:100%; background:rgba(255,255,255,0.06) !important;
  border:1px solid rgba(255,255,255,0.14) !important;
  border-radius:10px !important; color:#ffffff !important;
  padding:0.7rem 0.9rem !important; font:inherit !important;
  transition:border-color 0.2s ease !important;
}
.quote-wizard-card input:focus,
.quote-wizard-card select:focus,
.quote-wizard-card textarea:focus {
  border-color:rgba(255,255,255,0.45) !important; outline:none !important;
  background:rgba(255,255,255,0.09) !important;
}
.quote-wizard-card select option { background:#0a0a0a; color:#ffffff; }
.quote-wizard-card textarea { min-height:110px; }
.quote-wizard-card fieldset { border:none; padding:0; margin:0 0 1.5rem; }
.quote-wizard-card legend { font-family:'Poppins',sans-serif; font-size:1.2rem; font-weight:600; color:#fff; padding:0; margin:0 0 1rem; }
.quote-wizard-card input[type="file"] { color:var(--text-secondary); }
.quote-help-text { color:var(--text-muted); font-size:0.9rem; margin:0 0 0.75rem; }

.quote-progress ol { list-style:none; display:flex; flex-wrap:wrap; gap:0.5rem 0; padding:0; margin:0 0 1.75rem; }
.quote-progress-step {
  display:flex; align-items:center; gap:0.4rem; flex:1; min-width:0;
  color:var(--text-muted); font-size:0.78rem; font-weight:600;
}
.quote-progress-num {
  flex-shrink:0; width:1.6rem; height:1.6rem; border-radius:50%;
  border:1px solid var(--border-strong); display:flex; align-items:center; justify-content:center;
  font-size:0.8rem;
}
.quote-progress-step.is-active { color:#fff; }
.quote-progress-step.is-active .quote-progress-num { background:var(--silver); color:#000; border-color:var(--silver); }
.quote-progress-step.is-done .quote-progress-num { background:rgba(200,205,212,0.25); border-color:var(--silver); }
.quote-progress-label { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
@media (max-width:560px) {
  .quote-progress-label { display:none; }
}

.quote-choice-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:0.6rem; }
.quote-choice {
  position:relative; display:flex; align-items:center;
  border:1px solid var(--border-strong); border-radius:10px;
  padding:0.75rem 1rem; cursor:pointer; color:var(--text-secondary);
  font-weight:600; font-size:0.92rem; transition:border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.quote-choice input { position:absolute; opacity:0; width:1px; height:1px; }
.quote-choice:hover { border-color:var(--silver); color:#fff; }
.quote-choice:has(input:checked),
.quote-choice.is-checked { background:var(--silver); border-color:var(--silver); color:#000; }
.quote-choice:has(input:focus-visible),
.quote-choice.is-focused { outline:3px solid var(--silver); outline-offset:2px; }
.quote-choice input:focus-visible { outline:none; } /* outline lives on the label above instead */

.quote-emergency-banner {
  margin-top:1.25rem; padding:1rem 1.25rem; border-radius:10px;
  background:rgba(220,60,60,0.1); border:1px solid rgba(220,90,90,0.4);
  color:#fff; display:flex; flex-wrap:wrap; align-items:center; gap:0.9rem;
}
.quote-emergency-banner[hidden] { display:none !important; }
.quote-emergency-banner .btn { flex-shrink:0; }

.quote-photo-list { list-style:none; padding:0; margin:0.75rem 0 0; display:flex; flex-wrap:wrap; gap:0.6rem; }
.quote-photo-list li {
  display:flex; align-items:center; gap:0.5rem; background:rgba(255,255,255,0.06);
  border:1px solid var(--border-strong); border-radius:8px; padding:0.4rem 0.6rem; font-size:0.82rem; color:var(--text-secondary);
}
.quote-photo-list button {
  background:none; border:none; color:#f87171; cursor:pointer; font-weight:700; font-size:1rem; line-height:1; padding:0;
}
.quote-photo-status { font-size:0.82rem; color:var(--text-muted); margin:0.5rem 0 0; min-height:1.1rem; }

.quote-wizard-nav { display:flex; justify-content:space-between; gap:0.75rem; margin-top:0.5rem; }
.quote-wizard-nav .quote-next,
.quote-wizard-nav .quote-submit { margin-left:auto; }
.quote-wizard-card .form-note { font-size:0.82rem; color:#6b7280; margin-top:0.75rem; }

/* ── CTA BANNER ── */
.cta-banner {
  position:relative; overflow:hidden;
  background:linear-gradient(135deg, #111314 0%, #1e2124 50%, #111314 100%) !important;
  border-top:1px solid rgba(200,205,212,0.2) !important;
  border-bottom:1px solid rgba(200,205,212,0.2) !important;
  padding:2.4rem 0;
}
.cta-banner h2, .cta-banner p { color:#ffffff !important; }
.cta-banner-inner { position:relative; z-index:1; display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap; }

/* ── STRUCTURAL HEX TEXTURE (explicit opt-in) ──
   Axis's structural signature: a fine aluminium mesh — the hex-grid.svg
   tile at its own native ~52x90px scale (no upscaling), so it reads as
   architectural mesh rather than honeycomb. Deliberately explicit
   opt-in, not a default-on-black-background behaviour: .hex-texture is
   hand-applied, one section at a time, to markup that has been
   individually judged to be an intentional dark structural surface —
   never inferred from "this element happens to have a black
   background." A generic .section-dark/.section-light/.section
   element carries NO hex unless it also carries .hex-texture; a new
   section added later gets hex only if someone deliberately decides
   it should, which is the point — it removes the failure mode where a
   section is one missed exclusion away from getting the texture by
   accident (a real bug this replaced: the homepage's own quote form
   briefly inherited hex under an earlier "default on, opt out" version
   of this rule). Applied to: CTA banners, inner-hero identity bands,
   and the specific content sections in build_site.py individually
   marked hex-texture (decision grids, service/area/guide content
   blocks, testimonials, area-pill lists) — never to photography, forms
   (quote wizard, contact, all lead-gen sections), or dense/busy content
   (FAQ accordions) — those simply never receive the class. NEVER
   placed over photography — see .hero for why the hero's own hex layer
   was retired instead of being tucked behind the photo. At most one
   hex layer per section; never stacked, never full-viewport. Opacity
   stays low enough that the breathing should barely register as
   motion, not a visible pulse. See PHASE_E4 doc for why this replaces
   the old full-viewport canvas animation from PR #8. */
.hex-texture {
  position:relative; overflow:hidden;
}
.hex-texture::before {
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:url('/assets/images/hex-grid.svg');
  background-repeat:repeat; background-size:52px 90px;
  opacity:0.02;
  animation:hex-breathe 20s ease-in-out infinite;
}
.hex-texture > * {
  position:relative; z-index:1;
}
@keyframes hex-breathe {
  0%, 100% { opacity:0.02; }
  50% { opacity:0.05; }
}
@media (max-width:768px) {
  .hex-texture::before {
    animation:none; opacity:0.02;
  }
}
@media (prefers-reduced-motion:reduce) {
  .hex-texture::before {
    animation:none !important; opacity:0.02;
  }
}

/* ── INNER PAGES ── */
.inner-hero { background:#0a0a0a !important; padding:8rem 0 3rem; }
.inner-hero h1 { margin-bottom:0.6rem; color:#ffffff; }
.breadcrumbs { font-size:0.92rem; color:#9ca3af; margin-bottom:1rem; }
.breadcrumbs a { color:#d1d5db; text-decoration:none; }
.two-col { display:grid; grid-template-columns:1fr 1fr; gap:1.5rem; }
.contact-card { padding:1.1rem; }

/* ── FOOTER ── */
.site-footer {
  background:rgba(255,255,255,0.03) !important;
  border-top:1px solid rgba(255,255,255,0.08) !important;
  color:#9ca3af; padding-top:3rem;
}
.site-footer h2 { color:#fff; font-size:1.1rem; margin-bottom:0.8rem; }
.footer-grid { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:1.2rem; }
.site-footer ul { list-style:none; padding:0; margin:0; }
.site-footer li { margin-bottom:0.35rem; }
.site-footer a { color:#d1d5db; text-decoration:none; transition:color 0.2s; }
.site-footer a:hover { color:var(--accent); }
.footer-social-links { display:flex; gap:0.5rem; }
.footer-social-link {
  width:36px; height:36px; background:rgba(255,255,255,0.07);
  border:1px solid rgba(255,255,255,0.12); border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  transition:background 0.2s, border-color 0.2s;
}
.footer-social-link:hover {
  background:rgba(200,205,212,0.15); border-color:rgba(255,255,255,0.28);
}
.footer-social-link svg {
  width:18px; height:18px; fill:#d1d5db; transition:fill 0.2s ease;
}
.footer-social-link:hover svg { fill:#c8cdd4; }
.footer-bottom {
  text-align:center; padding:1.2rem 0 2rem;
  border-top:1px solid rgba(255,255,255,0.06); margin-top:2rem;
}
.footer-bottom p { color:#6b7280; margin-bottom:0.65rem; }
.footer-legal-links { display:flex; justify-content:center; gap:1rem; flex-wrap:wrap; }
.agency-credit { margin-top:1rem; }
.agency-credit-link {
  display:inline-flex; align-items:center; gap:0.5rem;
  color:#6b7280; font-size:0.8rem; text-decoration:none;
}
.agency-credit-link:hover { color:#9ca3af; }
.agency-logo-box { display:inline-flex; width:20px; height:20px; flex-shrink:0; }
.text-button {
  border:none; background:none; color:#d1d5db;
  text-decoration:underline; cursor:pointer; font:inherit;
}

/* ── DOMAIN MOVE BANNER ── */
.domain-move-banner {
  background:rgba(255,255,255,0.05);
  border-bottom:1px solid rgba(255,255,255,0.1);
  color:#d1d5db; text-align:center;
  padding:0.75rem 1rem; font-weight:600;
}
.domain-move-banner a { color:#c8cdd4; text-decoration:underline; }

/* ── 404 ── */
.not-found-wrap {
  min-height:100vh; display:grid; place-content:center;
  gap:0.8rem; text-align:center; padding:2rem;
  background:#000000;
}

/* ── CONNECT / SOCIAL SECTION ── */
.connect-section {
  background:#000000; padding:5rem 2rem; text-align:center;
  border-top:1px solid rgba(255,255,255,0.07);
}
.connect-inner { max-width:800px; margin:0 auto; }
.connect-section h2 {
  font-family:'Poppins',sans-serif;
  font-size:clamp(1.8rem,3vw,2.4rem);
  font-weight:700; color:#ffffff; margin:0 0 1rem;
}
.connect-section p { color:#9ca3af; font-size:1rem; margin:0 0 2.5rem; }
.social-links { display:flex; justify-content:center; gap:1.5rem; flex-wrap:wrap; }
.social-card {
  display:flex; flex-direction:column; align-items:center; gap:0.5rem;
  padding:2rem 2.5rem; min-width:160px; text-decoration:none;
}
.social-card svg { width:36px; height:36px; fill:#ffffff; transition:transform 0.2s ease; }
.social-card:hover svg { transform: scale(1.1); }
.social-card span { color:#ffffff; font-family:'Poppins',sans-serif; font-weight:600; font-size:1rem; }
.social-card small { color:#6b7280; font-size:0.78rem; }

/* ── COOKIE BAR ──
   Kept deliberately compact — this is a legal/consent control, not a
   promotional banner, so it should read and be dismissed quickly rather
   than occupying a large band of the viewport. All three controls (accept,
   reject, manage) and their accessible sizing are preserved unchanged;
   only the bar's own padding/gaps and button density were tightened. */
.cookie-bar {
  display:none; position:fixed; bottom:0; left:0; right:0; z-index:99999;
  background:var(--surface); border-top:2px solid var(--border-strong);
  padding:var(--space-3) var(--space-6); flex-wrap:wrap;
  align-items:center; justify-content:space-between; gap:var(--space-3);
}
.cookie-bar p { color:var(--text-secondary); font-size:var(--text-sm); max-width:600px; margin:0; line-height:1.4; }
.cookie-bar p strong { color:#fff; }
.cookie-bar p a { color:var(--silver); text-decoration:underline; }
.cookie-bar-actions { display:flex; flex-wrap:wrap; gap:var(--space-2); align-items:center; }
.cookie-bar-actions .btn { padding:0.5rem 1rem; font-size:var(--text-sm); }
.cookie-bar-actions .btn-manage {
  background:none; border:none; color:var(--text-muted);
  font-size:var(--text-sm); cursor:pointer; text-decoration:underline; padding:0.5rem 0;
}
.cookie-prefs-panel {
  position:fixed; bottom:80px; left:0; right:0; z-index:99998;
  background:var(--surface); border-top:1px solid var(--border-strong);
  padding:var(--space-6) var(--space-8); font-size:var(--text-sm); color:var(--text-secondary);
}
.cookie-prefs-panel .cookie-prefs-title { color:#fff; font-weight:600; margin:0 0 var(--space-4); }
.cookie-prefs-panel .cookie-prefs-row {
  display:flex; justify-content:space-between; align-items:center;
  padding:var(--space-2) 0; border-bottom:1px solid var(--border);
}
.cookie-prefs-panel .cookie-prefs-row:last-of-type { border-bottom:none; }
.cookie-prefs-panel .btn-save-prefs {
  margin-top:var(--space-4); background:linear-gradient(135deg,#e8eaed,#c8cdd4);
  color:#000; border:none; border-radius:9999px; padding:0.5rem 1.5rem;
  font-weight:700; cursor:pointer;
}
@media (max-width:768px) {
  .cookie-bar { padding:var(--space-3); gap:var(--space-2); }
  .cookie-bar p { font-size:var(--text-xs); line-height:1.35; }
  .cookie-bar-actions { gap:var(--space-2); }
  .cookie-bar-actions .btn { padding:0.45rem 0.9rem; }
}

/* ── DECISION CARDS ──
   Explicit per-breakpoint composition, not organic reflow — a card's
   width is a defined FRACTION of the row (100%, 33.333%, 20%), so a
   full row always sums to exactly 100% and sits flush with the
   container edges (matching every other section on the page), and
   only a genuinely incomplete trailing row is narrower than 100% and
   gets centred by justify-content:center. This is deliberately
   designed for the 5-card homepage instance:
     mobile  (≤768px):        1 column
     tablet  (769–1024px):    3 columns  → 5 cards = 3 + 2, centred
     desktop (≥1025px):       5 columns  → 5 cards = one full row
   Other pages reuse .decision-grid with 3/4/6 cards; the same
   percentage system still applies (a full row always reaches the
   container edges; a short last row centres instead of sticking
   left) even though the exact column counts above were tuned for 5. */
.decision-section { padding-bottom:3rem; }
.decision-grid {
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:1.25rem; margin-top:1.5rem;
}
.decision-card {
  /* Background/border/hover come from the shared card system above —
     this supplies layout (and, below, this component's explicit
     per-breakpoint composition) only. */
  flex:0 0 100%;
  padding:1.75rem 1.25rem 1.5rem;
  text-decoration:none; color:#ffffff;
  display:flex; flex-direction:column; gap:0.5rem;
}
@media (min-width:769px) {
  .decision-card { flex-basis:calc(33.333% - 0.834rem); }
}
@media (min-width:1025px) {
  .decision-card { flex-basis:calc(20% - 1rem); }
}
.decision-card-urgent {
  border-color:rgba(255,100,100,0.35) !important;
  border-top-color:rgba(255,120,120,0.6) !important;
  background:rgba(255,50,50,0.06) !important;
}
.decision-card-urgent:hover { border-color:rgba(255,120,120,0.55) !important; }
/* "Not Sure" is a deliberately different job (an open catch-all, not
   a category) — a subtly distinct treatment so its position in the
   layout (whatever row it lands on) reads as intentional rather than
   "the leftover card". Styling only; copy is unchanged in this PR. */
.decision-card-open {
  border-style:dashed !important;
  border-color:rgba(255,255,255,0.24) !important;
  background:rgba(255,255,255,0.02) !important;
}
.decision-card-open:hover { border-color:rgba(255,255,255,0.4) !important; }
.decision-icon { width:44px; height:44px; color:#c8cdd4; margin-bottom:0.25rem; }
.decision-icon svg { width:100%; height:100%; }
.decision-card h3 { font-size:1.1rem; margin:0; color:#ffffff; }
.decision-card p { font-size:0.9rem; color:#9ca3af; margin:0; }
.decision-link { font-size:0.85rem; font-weight:600; color:#c8cdd4; margin-top:auto; padding-top:0.5rem; }

/* ── PROCESS STEPS ── */
.process-steps {
  list-style:none; padding:0; margin:0;
  display:flex; flex-direction:column; gap:1.5rem;
}
.process-step { display:flex; gap:1.25rem; align-items:flex-start; }
.process-num {
  flex-shrink:0; width:2.5rem; height:2.5rem;
  background:linear-gradient(135deg,#e8eaed,#9ba3ab);
  color:#000; font-family:'Poppins',sans-serif;
  font-weight:700; font-size:1rem; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
}
.process-step h3 { font-size:1.05rem; margin-bottom:0.25rem; color:#ffffff; }
.process-step p { color:#9ca3af; font-size:0.95rem; margin:0; }

/* ── USP EVIDENCE LIST ── */
.usp-evidence { list-style:none; padding:0; }
.usp-evidence li { margin-bottom:1rem; }
.usp-evidence strong { display:block; font-weight:700; margin-bottom:0.15rem; color:#ffffff; }
.usp-evidence span { font-size:0.92rem; color:#9ca3af; }

/* ── PRICING / DIRECT ANSWER ── */
.pricing-factors { color:#d1d5db; }
.pricing-factors li { margin-bottom:0.35rem; }
.direct-answer {
  font-size:1.05rem; font-weight:600; color:#ffffff;
  background:rgba(255,255,255,0.05);
  border-left:4px solid #c8cdd4;
  padding:0.75rem 1rem; border-radius:0 0.5rem 0.5rem 0;
  margin-bottom:1.25rem;
}

/* ── SCROLL REVEAL ── */
.reveal-up,.reveal-left,.reveal-right {
  opacity:0; transition:opacity 0.6s ease, transform 0.6s ease;
}
.reveal-up    { transform:translateY(30px); }
.reveal-left  { transform:translateX(-40px); }
.reveal-right { transform:translateX(40px); }
.reveal-up.is-visible,
.reveal-left.is-visible,
.reveal-right.is-visible { opacity:1; transform:none; }

/* ── MOBILE STICKY CTA BAR ── */
.mobile-cta-bar {
  display:none; position:fixed; bottom:0; left:0; right:0;
  z-index:9999; background:var(--surface-3); padding:0;
  padding-bottom:env(safe-area-inset-bottom);
  border-top:2px solid var(--border-strong);
  height:56px; box-shadow:0 -2px 10px rgba(0,0,0,0.4);
}
.mobile-cta-bar .cta-buttons { display:flex; height:100%; }
.mobile-cta-bar .btn-call,
.mobile-cta-bar .btn-quote {
  flex:1; display:flex; align-items:center; justify-content:center;
  gap:0.5rem; font-size:16px; font-weight:700;
  text-decoration:none; transition:background 0.2s ease;
}
/* Call keeps a distinct (desaturated, on-brand-darkened) green — a
   deliberate functional exception, not a decorative one: call vs. quote
   need to read as two different actions at a glance on the one sticky
   bar every mobile visitor sees on every page. */
.mobile-cta-bar .btn-call { background:#2f6b46; color:#ffffff; border-right:1px solid var(--border); }
.mobile-cta-bar .btn-quote { background:var(--silver); color:#000000; }
.mobile-cta-bar svg { width:18px; height:18px; }
@media (max-width:768px) { .mobile-cta-bar { display:flex; } }

/* ── RESPONSIVE ── */
@media (max-width:1024px) {
  .split-grid,.two-col { grid-template-columns:1fr; }
  /* .decision-grid is not a CSS Grid any more (see the deliberate
     flex-based composition system above, with its own min-width media
     queries) — no grid-template-columns override belongs here. */
  .projects-feature-grid { grid-template-columns:1fr; }
  .projects-feature-secondary { flex-direction:row; }
  .projects-feature-secondary .project-item { flex:1; }
}
@media (max-width:640px) {
  .projects-grid { grid-template-columns:1fr; }
  .projects-feature-secondary { flex-direction:column; }
}
@media (max-width:768px) {
  .menu-toggle { display:inline-flex; }
  .nav-phone-mobile { display:inline-flex; align-items:center; }
  .nav-phone-desktop { display:none; }
  .site-nav {
    /* Deliberately not "inset:0 0 0 30%": .site-header has a
       backdrop-filter, which creates a new containing block for
       position:fixed descendants — bottom:0 would then resolve against
       the ~90px header instead of the viewport, leaving the drawer only
       as tall as the header. Explicit vh sizing sidesteps that (vh units
       are always viewport-relative regardless of containing block). */
    position:fixed; top:0; right:0; left:30%;
    height:100vh; height:100dvh; overflow-y:auto;
    background:var(--surface); border-left:1px solid var(--border-strong);
    padding:6rem var(--space-6) var(--space-6); display:flex;
    flex-direction:column; align-items:stretch; gap:0;
    transform:translateX(100%); transition:transform 0.3s ease;
  }
  .site-nav.open { transform:translateX(0); }
  .site-nav a:not(.cta-pill) {
    width:100%; padding:var(--space-4) 0;
    border-bottom:1px solid var(--border); font-size:var(--text-lg);
  }
  .site-nav a:not(.cta-pill)::after { display:none; }
  .site-nav .cta-pill, .site-nav .nav-phone-desktop { margin-top:var(--space-6); }
  .nav-wrap { grid-template-columns:auto auto; justify-content:space-between; }
  .footer-grid { grid-template-columns:1fr; }
  .hero-media { top:0 !important; height:100% !important; transform:none !important; }
}
@media (max-width:480px) {
  .social-card { width:100%; min-width:unset; }
}
@media (max-width:375px) {
  .container { width:calc(100% - 1rem); }
  .hero h1 { font-size:2.2rem; }
}
@media (max-width:320px) { .hero h1 { font-size:2rem; } }
@media (min-width:1440px) { .container { width:min(1280px,calc(100% - 3rem)); } }
@media (prefers-reduced-motion:reduce) {
  .reveal-up,.reveal-left,.reveal-right {
    opacity:1 !important; transform:none !important; transition:none !important;
  }
  *, *::before, *::after { animation:none !important; transition-duration:0.01ms !important; }
  #mouse-glow { display:none !important; }
}
