/* ============================== Fonts ============================== */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/outfit-variable.woff2') format('woff2-variations');
}

/* ============================== Reset ============================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { list-style: none; }

/* ============================== Tokens ============================== */
:root {
  --navy: #122741;
  --dark: #08172B;
  --blue: #0652BF;
  --bluelt: #7FB0FF;
  --grey: #5F5F5F;
  --white: #FFFFFF;
  --light: #F7F9FC;
  --line: #E1E8F0;

  --font: 'Outfit', system-ui, sans-serif;
  /* Single standard content width across the whole site, matched to what
     the "What We Do" block measured at 75vw on a real desktop window
     (1310px), now fixed instead of fluid so it stays consistent on large
     screens instead of growing unbounded. --max-w-lg is an alias kept for
     existing class names; both resolve to the same column. */
  --max-w: 1310px;
  --max-w-lg: 1310px;

  --space-1: 8px; --space-2: 16px; --space-3: 24px; --space-4: 32px;
  --space-5: 48px; --space-6: 64px; --space-7: 100px;
}

/* Standard breakpoint scale used across the site going forward:
   1024px laptop/small-desktop, 768px tablet, 480px mobile. */

body {
  font-family: var(--font);
  font-weight: 500;
  color: var(--navy);
  background: var(--white);
  line-height: 1.5;
}

h1, h2, h3, h4 { text-transform: none; letter-spacing: normal; line-height: 1.15; }
h1 { font-weight: 500; }
h2, h3, h4 { font-weight: 300; }
h2 { font-size: 50px; letter-spacing: -.9px; line-height: 1.12; }
@media (max-width: 1024px) { h2 { font-size: 42px; } }
@media (max-width: 768px) { h2 { font-size: 34px; } }
@media (max-width: 480px) { h2 { font-size: 28px; } }
/* Standard desktop size for a bare h3/p - components with their own
   fixed-size context (cards, footer, small print) keep their own explicit,
   smaller values via normal CSS specificity, so this only sets the default
   for section-level subheadings and body copy. */
h3 { font-size: 30px; letter-spacing: -.4px; }
p { font-size: 18px; font-weight: 400; line-height: 1.6; }
@media (max-width: 1024px) { h3 { font-size: 26px; } }
@media (max-width: 768px) { h3 { font-size: 22px; } p { font-size: 16px; } }

/* ============================== Layout ============================== */
.wrap { max-width: var(--max-w); margin: 0 auto; padding: 0 20px; }
.wrap-lg { max-width: var(--max-w-lg); margin: 0 auto; padding: 0 20px; }
.section { padding: var(--space-7) 0; }
@media (max-width: 768px) { .section { padding: var(--space-6) 0; } }
.center { text-align: center; max-width: 760px; margin: 0 auto; }
.right { text-align: right; max-width: 640px; margin: 0 0 0 auto; }
/* Left-anchored to the slider's own left edge (same margin-left formula as
   .svc-viewport below), not to .wrap's independent 1175px column - so the
   heading lines up with the first card regardless of viewport width. */
.align-slider { text-align: left; max-width: var(--max-w); padding-right: 20px;
  margin-left: max(40px, calc((100vw - 1460px) / 2)); }

.eyebrow { text-transform: uppercase; letter-spacing: .4px; font-weight: 600; font-size: 20px; color: var(--blue); }
/* Sentence-case label + short rule, distinct from .eyebrow's bold-uppercase
   look - used on pages that shouldn't read as a reskinned homepage section. */
.eyebrow-line { display: inline-flex; align-items: center; gap: 14px; font-size: 17px; color: var(--navy); font-weight: 500; }
.eyebrow-line::after { content: ""; display: block; width: 34px; height: 2px; background: var(--blue); }
.eyebrow.on-dark { color: var(--bluelt); }
@media (max-width: 768px) { .eyebrow { font-size: 17px; } }

.skip-link {
  position: absolute; left: -999px; top: 0; background: var(--blue); color: var(--white);
  padding: 12px 20px; z-index: 200; border-radius: 0 0 6px 0;
}
.skip-link:focus { left: 0; }

/* ============================== Buttons ============================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; font-weight: 500; letter-spacing: -.2px;
  border-radius: 3px; padding: 11px 18px; font-size: 18px; text-decoration: none; cursor: pointer; border: 1px solid transparent;
  transition: opacity .2s, background .2s;
}
.btn:hover { opacity: .88; }
.btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.btn-primary { background: var(--blue); color: var(--white); }
.btn-outline { background: transparent; color: var(--blue); border-color: var(--blue); }
.btn-secondary { background: var(--white); color: var(--navy); border-color: var(--navy); padding: 12px 22px; }
.btn-sm { font-size: 13.5px; padding: 10px 16px; }

/* ============================== Header ============================== */
/* Full-bleed bar (background spans the viewport, "as per normal"); the
   inner wrap-header is what's boxed, and matches --max-w so header/footer
   content lines up with the same content width every other section uses. */
/* Fixed (not sticky) + a spacer that reserves the same space in normal flow.
   The header used to be position:sticky and shrink itself in place - which
   changed its own height while still IN flow, shifting every section below
   it, which right at the scroll threshold could nudge the scroll position
   enough to cross back over it and re-trigger: a flicker loop. Taking the
   header out of flow means nothing it does can ever feed back into scrollY,
   and the .header-spacer below animates in lockstep so nothing visibly
   jumps. Gradient bottom edge matches the footer's own navy-to-blue
   background; compact state (JS toggles body.is-scrolled) shrinks the
   header and swaps the full lockup for just the roofline mark. */
/* The gradient edge is a ::after strip rather than border-image: border-image
   was leaving a hairline gap at the seam (a thin white line under the
   border) at some zoom/DPR combinations - a pseudo-element paints solidly
   with no such gap. */
.site-header { position: fixed; top: 0; left: 0; right: 0; width: 100%; z-index: 100; background: var(--white);
  transition: box-shadow .4s ease; }
.site-header::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: linear-gradient(135deg, var(--dark) 0%, var(--navy) 45%, var(--blue) 100%); }
body.is-scrolled .site-header { box-shadow: 0 4px 20px rgba(18,39,65,.1); }
.header-spacer { height: 104px; transition: height .4s ease; }
body.is-scrolled .header-spacer { height: 60px; }
.wrap-header { max-width: var(--max-w); margin: 0 auto; padding: 0 20px; }
.site-header .wrap-header { display: flex; align-items: center; padding-top: 10px; padding-bottom: 10px; transition: padding .4s ease; }
body.is-scrolled .site-header .wrap-header { padding-top: 6px; padding-bottom: 6px; }
.site-header .logo { display: flex; align-items: center; }
.site-header .logo img { width: auto; transition: height .4s ease; }
.site-header .logo-full { height: 84px; }
.site-header .logo-icon { display: none; height: 40px; }
body.is-scrolled .site-header .logo-full { display: none; }
body.is-scrolled .site-header .logo-icon { display: block; }
/* Compact state also drops "Call Us Today" and matches the phone number/icon
   to the rest of the nav's own icon size (16px, the nav-caret's own size);
   the number itself is set larger (18px) so it still reads clearly next to
   the icon rather than shrinking all the way down to the 15px nav text. */
body.is-scrolled .site-header .call-label { display: none; }
body.is-scrolled .site-header .call-number { font-size: 18px; transition: font-size .4s ease; }
body.is-scrolled .site-header .phone-icon svg { width: 16px; height: 16px; transition: width .4s ease, height .4s ease; }
.header-right { display: flex; align-items: center; gap: 20px; margin-left: auto; }
/* Below 900px the nav collapses into a drawer, leaving only the phone number and
   menu button here. margin-left:0 had parked them next to the logo, so on a
   tablet the whole header sat in the left third with the rest empty. */
@media (max-width: 900px) { .header-right { margin-left: auto; } }
.site-nav { display: flex; align-items: center; }
.site-nav > ul { display: flex; align-items: center; gap: 0; }
.site-nav a { display: flex; align-items: center; gap: 7px; font-weight: 600; font-size: 15px; letter-spacing: -.3px; color: #0E2E6A; text-transform: uppercase; padding: 13px 20px; }
.site-nav > ul > li { position: relative; }
/* Points right by default (collapsed state), rotates to point down only
   while the menu is actually open. */
.nav-caret { display: inline-flex; transition: transform .2s ease; transform: rotate(-90deg); }
.has-children:hover .nav-caret,
.has-children:focus-within .nav-caret { transform: rotate(0deg); }
.dropdown {
  position: absolute; top: 100%; left: -14px; min-width: 220px; background: var(--white);
  display: flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--line); border-radius: 8px; padding: 8px; box-shadow: 0 18px 40px rgba(18,39,65,.12);
  opacity: 0; visibility: hidden; transform: translateY(6px); transition: opacity .18s, transform .18s, visibility .18s;
}
.has-children:hover .dropdown,
.has-children:focus-within .dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.dropdown li a { display: block; padding: 9px 12px; border-radius: 6px; font-weight: 500; font-size: 14px; }
.dropdown li a:hover { background: var(--light); color: var(--blue); }

/* Mega menu (Our Services): wide panel, one tile per trade with a photo
   above the label, centered under the trigger rather than pinned to its
   left edge like the plain dropdown. */
.mega {
  /* 4 columns x 2 rows (8 services) - narrower than the old 6-across panel
     so tiles stay roughly the same size instead of stretching wider/taller. */
  position: absolute; top: 100%; left: 50%; width: 760px; max-width: calc(100vw - 40px);
  background: var(--white); border: 1px solid var(--line); border-radius: 16px; padding: 20px 20px 18px;
  box-shadow: 0 28px 64px rgba(18,39,65,.18);
  opacity: 0; visibility: hidden; transform: translate(-50%, 6px); transition: opacity .2s ease, transform .2s ease, visibility .2s ease;
  z-index: 60;
}
.has-children:hover .mega,
.has-children:focus-within .mega { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.mega-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px 10px; }
.mega-item { display: flex; flex-direction: column; gap: 10px; border-radius: 10px; padding: 2px; text-align: center; transition: background .2s ease; }
.mega-item:hover { background: var(--light); }
.mega-item-media { position: relative; display: block; border-radius: 8px; overflow: hidden; aspect-ratio: 4 / 3; }
.mega-item-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .35s ease; }
.mega-item:hover .mega-item-media img { transform: scale(1.07); }
/* Same dark scrim used on the service-slider cards, reversed on hover so
   the photo reveals in full colour instead of staying tinted. Capped at
   90% instead of fully solid, so the photo stays faintly visible through it. */
.mega-item-media::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,23,43,0) 0%, rgba(8,23,43,0) 5%, rgba(8,23,43,.9) 85%, rgba(8,23,43,.9) 100%);
  transition: opacity .3s ease;
}
.mega-item:hover .mega-item-media::after { opacity: 0; }
.mega-item-label { font-size: 15px; font-weight: 600; letter-spacing: -.2px; line-height: 1.25; color: var(--navy); text-transform: none; }
.mega-foot {
  display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--line); font-size: 15px; font-weight: 600; letter-spacing: -.2px; color: var(--blue); text-transform: none;
}
.mega-foot:hover { color: var(--navy); }
@media (max-width: 900px) {
  .mega { position: static; opacity: 1; visibility: visible; transform: none; box-shadow: none; border: 0; border-radius: 0;
    width: auto; max-width: none; padding: 4px 0 12px var(--space-2); display: none; }
  /* .has-children:hover/:focus-within .mega { transform: translate(-50%, 0) }
     is a desktop rule (re-centers the absolutely-positioned panel under its
     trigger) but it's a compound selector, so it out-specifies the plain
     .mega{transform:none} reset just above and keeps winning here too -
     and tapping the "Our Services" link on a touchscreen focuses it, which
     satisfies :focus-within regardless of viewport width. The result: the
     panel (now position:static, full-width) still got shoved left by half
     its own width, leaving only its right half visible and the left column
     of tiles rendered off-screen. Same specificity, declared later, so this
     wins the tie and actually keeps it at transform:none on mobile. */
  .has-children:hover .mega,
  .has-children:focus-within .mega { transform: none; }
  .has-children.is-expanded .mega { display: block; }
  .mega-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; }
  .mega-foot { justify-content: flex-start; }
}

.header-cta { display: flex; align-items: center; gap: 4px; }
.header-cta .phone-icon { color: var(--blue); flex: none; }
.header-cta a { display: flex; flex-direction: column; line-height: 1.3; }
.header-cta .call-label { font-size: 12px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: #0E2E6A; }
.header-cta .call-number { font-size: 25px; font-weight: 500; color: #0E2E6A; }

.nav-toggle { display: none; position: relative; }
.nav-toggle .icon-close { display: none; }
.nav-toggle.is-open .icon-menu { display: none; }
.nav-toggle.is-open .icon-close { display: block; }
@media (max-width: 900px) {
  .site-nav { position: fixed; inset: 0; top: 74px; background: var(--white); flex-direction: column; align-items: stretch;
    padding: var(--space-3); transform: translateX(100%); transition: transform .25s ease; overflow-y: auto; }
  .site-nav.is-open { transform: translateX(0); }
  .site-nav ul { flex-direction: column; align-items: stretch; gap: 4px; }
  .site-nav > ul > li > a { display: block; padding: 12px 4px; border-bottom: 1px solid var(--line); }
  .dropdown { position: static; opacity: 1; visibility: visible; transform: none; box-shadow: none; border: 0;
    display: none; padding-left: var(--space-2); }
  .has-children.is-expanded .dropdown { display: block; }
  .nav-toggle { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; }
  .header-cta .call-label { display: none; }
}

/* ============================== Footer ============================== */
/* Restructured after arcprojects.com.au's footer: a wide brand+tagline
   block on the left, tighter uppercase-label link columns on the right,
   then a slim divider bar with copyright + a back-to-top button - same
   shapes as their layout, but kept in our own navy-to-blue gradient
   rather than their flat light grey, so it still reads as this site. */
.site-footer { background: linear-gradient(135deg, var(--dark) 0%, var(--navy) 45%, var(--blue) 100%); color: var(--white); }
/* .wrap-lg already uses --max-w-lg (an alias of --max-w), so the footer's
   content lines up with the rest of the body without a narrower override. */
.footer-top { display: flex; gap: 60px; padding: 70px 20px 40px; flex-wrap: wrap; }
.footer-brand { flex: 0 1 300px; }
.site-footer .logo img { width: 110px; height: auto; }
.footer-tagline { color: var(--bluelt); font-size: 24px; font-weight: 500; margin-top: 22px; }
.footer-desc { color: var(--white); font-size: 15px; margin-top: 10px; max-width: 280px; }
.footer-links { flex: 1 1 auto; display: flex; gap: 40px; flex-wrap: wrap; }
.footer-links > div { flex: 1 1 150px; }
.site-footer h4 { color: var(--bluelt); font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .6px; margin-bottom: var(--space-2); }
.footer-list li { margin-bottom: 12px; font-size: 15px; font-weight: 400; }
.footer-list a:hover { color: var(--bluelt); }
.footer-list .icon-line { display: flex; align-items: flex-start; gap: 10px; }
.footer-list .icon-line svg { flex: none; margin-top: 3px; color: var(--white); }
.footer-social-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.footer-social { display: flex; gap: 10px; }
.footer-social a {
  width: 42px; height: 42px; border-radius: 8px; background: var(--white);
  display: flex; align-items: center; justify-content: center; color: var(--navy); transition: color .2s;
}
.footer-social a:hover { color: var(--blue); }
/* Longhand top/bottom only - this element also carries .wrap-lg for its
   20px side gutter, and a shorthand `padding: 22px 0` here would zero out
   left/right and silently cancel that gutter (same specificity, later in
   the cascade, so it always won). That's exactly what was happening above
   ~1150px: centered layout at mobile/tablet widths masked the missing
   padding since centered content doesn't touch the edges anyway, but the
   plain space-between row at full desktop width had nothing left to keep
   the copyright text off the browser edge. */
.footer-bottom-row { display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding-top: 22px; padding-bottom: 22px; border-top: 1px solid rgba(255,255,255,.15); }
.footer-copy { font-size: 12px; font-weight: 700; color: var(--white); }
.footer-top-btn { width: 40px; height: 40px; border-radius: 50%; border: 1px solid rgba(255,255,255,.35); flex: none;
  display: flex; align-items: center; justify-content: center; color: var(--white); transform: rotate(180deg);
  transition: background .2s, border-color .2s, color .2s; cursor: pointer; }
.footer-top-btn:hover { background: var(--white); color: var(--navy); border-color: var(--white); }
/* Tablet range (iPad-width viewports, ~561-1150px): one unified layout - the
   logo block centered on its own row, then the three link columns centered
   as a GROUP on the row below (not stretched edge to edge, since a group
   that's only as wide as it needs to be is what "centered" actually means
   here). Two earlier attempts (force all 4 columns onto one row; split at
   900px into a 4-across row vs a 2-row stack) both fought the same problem
   from the wrong angle - the columns don't all need the same width. Find
   Us's address wraps if it's too narrow, Follow Us's icon+button barely
   need any space at all, so they get explicit, different flex-basis values
   instead of splitting evenly. Link text, list-item gaps, and the social
   icon/button are all sized down a notch too - purely a fit change so the
   three columns' real content stops needing more room than this range has,
   not a deliberate style difference from desktop. */
/* Shared across the whole tablet range: tighter internal spacing and
   smaller text/controls so the columns' real content fits without
   stretching or wrapping badly. The STRUCTURE (whether the logo sits on its
   own row or joins the other three in a single row) is decided by the two
   sub-ranges below, since that genuinely does need to differ by width. */
@media (min-width: 561px) and (max-width: 1150px) {
  .footer-tagline { margin-top: 14px; }
  .footer-desc { max-width: none; margin-top: 6px; }
  .footer-list li { margin-bottom: 8px; font-size: 13.5px; }
  .footer-social a { width: 34px; height: 34px; }
  .footer-social-row { gap: 10px; }
  .footer-social-row .btn { font-size: 12px; padding: 8px 12px; }
  .footer-bottom-row { flex-direction: column; justify-content: center; align-items: center; text-align: center; gap: 14px; }
}
/* Narrower iPad-portrait widths (~561-799px): tested putting all 4 columns
   (logo + Find Us + Important Info + Follow Us) on one row here too, same
   as the wider range below - Important Info and Follow Us actually
   overflowed past the right edge of the screen (confirmed by measuring
   .footer-links' rendered right edge against the viewport width: it
   overflows by 143px at 640px, dropping to 0 only right around 780-800px).
   There simply isn't enough room for 4 real columns yet, so the logo keeps
   its own centered row here and the three link columns share a second,
   full-width row below - same "stretch + space-between" technique as the
   wider range, just stacked instead of inline. */
@media (min-width: 561px) and (max-width: 799px) {
  .footer-top { flex-direction: column; align-items: center; gap: 20px; }
  .footer-brand { display: flex; flex-direction: column; align-items: center; text-align: center; flex: 0 0 auto; }
  .footer-links { align-self: stretch; justify-content: space-between; flex-wrap: nowrap; gap: 24px; }
  .footer-links > div { flex: 0 1 auto; min-width: 0; }
}
/* From ~800px, all 4 columns comfortably fit on one row - confirmed by the
   same overflow measurement going negative (fits with room to spare) from
   800px up through the full 1150px ceiling of this tablet range. Matches
   the desktop pattern: logo on the left keeping its natural width, the
   three link columns spread across the remaining space. */
@media (min-width: 800px) and (max-width: 1150px) {
  .footer-top { flex-direction: row; flex-wrap: nowrap; align-items: flex-start; justify-content: space-between; gap: 24px; }
  .footer-brand { flex: 0 0 auto; }
  .footer-links { flex: 1 1 auto; justify-content: space-between; flex-wrap: nowrap; gap: 24px; }
  .footer-links > div { flex: 0 1 auto; min-width: 0; }
}
@media (max-width: 560px) {
  /* Every stacked gap in the footer (logo block -> Find Us -> Important Info
     -> Follow Us) unified, and pulled in further from the first pass (28px
     still read as too tall on a phone) - 16px between blocks, tighter still
     within a block (heading-to-tagline, tagline-to-desc, between list
     lines), so the whole footer reads as one compact unit instead of a
     stack of separately-spaced sections. Everything centered per the mobile
     design; the back-to-top button breaks out of that centering with
     align-self so it still sits against the row's right edge, same as the
     rest of the site's padding. */
  /* .footer-brand's 300px and .footer-links > div's 150px flex-basis values
     are sized for the DESKTOP row layout, where flex-basis sets a WIDTH.
     Flipping to flex-direction:column below turns that same basis into a
     forced HEIGHT instead - each block was reserving 300px/150px of vertical
     space regardless of how little text it actually held, which is what was
     really behind the oversized gaps (the visible "gap" property was never
     the whole story). Resetting both to their content size here is the
     actual fix; the gap value above just spaces the now-correctly-sized
     boxes apart. */
  .footer-top { flex-direction: column; gap: 16px; align-items: center; text-align: center; }
  .footer-brand { display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; }
  .footer-tagline { margin-top: 8px; font-size: 19px; }
  .footer-desc { margin-top: 4px; }
  .footer-links { flex-direction: column; gap: 16px; align-items: center; text-align: center; }
  .footer-links > div { flex: 0 0 auto; }
  .site-footer h4 { margin-bottom: 10px; }
  .footer-list li { margin-bottom: 8px; }
  .footer-list .icon-line { justify-content: center; }
  .footer-social-row { justify-content: center; }
  .footer-bottom-row { flex-direction: column; align-items: center; text-align: center; }
  .footer-top-btn { align-self: flex-end; }
}

/* ============================== Mobile: center general content ============================== */
/* Below 560px, standalone text/CTA blocks read better centered - hero copy,
   the bio (who-row) blocks, coverage/who/feature cards, the CTA band and
   guarantee section. Buttons center for free wherever their container gets
   text-align:center, since .btn is inline-flex; icon-boxes are fixed-width
   blocks so they need margin:auto explicitly. Deliberately left OUT: FAQ and
   "concerns" accordions, the check-list, and the services-intro body copy -
   long-form answers and icon+text rows read worse centered than left, the
   same reason a book doesn't centre-align its paragraphs. */
@media (max-width: 560px) {
  .hero-inner { text-align: center; }
  .hero-stat { margin: 22px auto 0; justify-content: center; }
  .who-text, .coverage-card, .who-card, .cta-left, .guarantee-text, .services-intro-left { text-align: center; }
  .coverage-card .icon-box, .guarantee-text .icon-box { margin-left: auto; margin-right: auto; }
  .feature-card-text { align-items: center; text-align: center; }
}

/* ============================== Icon boxes (shared) ============================== */
.icon-box { width: 44px; height: 44px; border-radius: 10px; background: var(--light); display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 10px rgba(18,39,65,.06); }

/* ============================== Reveal-on-scroll ============================== */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .7s ease, transform .7s cubic-bezier(.22,.68,0,1.01); }
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* ============================== Hero ============================== */
.hero { position: relative; min-height: 640px; display: flex; align-items: flex-end; overflow: hidden; }
/* Same navy-to-blue gradient as the footer - shows immediately behind the
   video and stays visible as the fallback if it never plays (some iOS
   Safari configurations block autoplay outright), instead of a static
   poster photo sitting there indefinitely. */
.hero-media { position: absolute; inset: 0; z-index: 0; background: linear-gradient(135deg, var(--dark) 0%, var(--navy) 45%, var(--blue) 100%); }
.hero-media img, .hero-media video { width: 100%; height: 100%; object-fit: cover; }
.hero-scrim { position: absolute; inset: 0; background: rgba(8,23,43,.74); z-index: 1; }
.hero-inner { position: relative; z-index: 2; padding: 70px 20px 60px; width: 100%; }
.hero h1 { font-size: 75px; line-height: 1.02; letter-spacing: -1.5px; font-weight: 500; color: var(--white); }
.hero h1.accent { color: #4C8DFF; }
.hero p { max-width: 560px; color: #C8D6EA; font-size: 22px; font-weight: 400; line-height: 1.6; margin-top: 22px; }
.hero .btn-row { display: none; }
.stars { display: inline-flex; gap: 3px; color: #F5B400; font-size: 19px; }
.hero-stat { margin-top: 22px; display: flex; align-items: center; gap: 12px; }
.hero-stat .stars { font-size: 24px; }
.hero-stat span:last-child { color: rgba(255,255,255,.75); font-size: 17px; }
@media (max-width: 1024px) { .hero h1 { font-size: 58px; } .hero p { font-size: 20px; } }
@media (max-width: 768px) { .hero h1 { font-size: 40px; } .hero p { font-size: 17px; } .hero { min-height: 560px; } }
@media (max-width: 400px) { .hero h1 { font-size: 34px; } .hero-inner { padding-top: 56px; padding-bottom: 44px; } }

/* ============================== Dark / light text sections ============================== */
.section-dark { background: var(--dark); }
.section-dark h2 { color: var(--white); }
.section-dark p { color: #9FB3CC; }
/* Blue + world-map texture variant, distinct from the plain-navy .section-dark
   used elsewhere on the site - so a trade page's testimonials don't just look
   like a re-skinned copy of the homepage's review section. */
.roofing-map-bg { position: relative; background: var(--blue); overflow: hidden; }
.roofing-map-bg::before { content: ""; position: absolute; inset: 0;
  background: url('/assets/img-raw/roofing-live-map-bg.jpg') center/cover no-repeat;
  opacity: 1; mix-blend-mode: overlay; filter: brightness(45%) contrast(100%) saturate(100%) blur(0px) hue-rotate(0deg); }
.roofing-map-bg > * { position: relative; z-index: 1; }

/* Quote form floated up over the hero instead of sitting in its own CTA
   section - pointer-events:none on the flex wrapper so the empty space
   around the card (which overlaps the hero) never blocks clicks on
   whatever is behind it; the card itself opts back in. */
.roofing-quote-float { position: relative; z-index: 5; margin-top: -543px;
  display: flex; justify-content: flex-end; pointer-events: none; }
.roofing-quote-float .quote-form { pointer-events: auto; width: 100%; max-width: 560px; }
@media (max-width: 900px) { .roofing-quote-float { margin-top: 30px; justify-content: center; padding: 0 20px; } }

/* ============================== 2-up review slider (roofing page) ============================== */
/* Reuses .rv-wrap/.rv-arrow/.rv-dots/.rv-stars/.rv-foot/.rv-name/.rv-src from
   the homepage carousel (those rules are generic already) - only the track/
   card layout differs: two fixed-size cards sliding a page at a time, no
   partial/faded cards at the edges. */
.rv2-viewport { overflow: hidden; }
.rv2-track { display: flex; gap: 24px; transition: transform .5s cubic-bezier(.65,0,.35,1); }
.rv2-card { flex: 0 0 calc(50% - 12px); min-width: 0; min-height: 260px; background: var(--white);
  border: 1px solid var(--line); border-radius: 12px; padding: 28px 30px;
  display: flex; flex-direction: column; box-shadow: 0 18px 40px rgba(18,39,65,.10); }
.rv2-card .rv-quote { color: var(--navy); line-height: 1.6; margin: 14px 0 0; flex: 0 1 auto;
  display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
.rv2-card .rv-foot { margin-top: 14px; }
@media (max-width: 640px) { .rv2-card { flex: 0 0 100%; min-height: 230px; padding: 24px 22px; } }
.center h2, .right h2, .align-slider h2 { margin-top: 16px; }
.center p, .right p, .align-slider p { line-height: 1.65; margin-top: 16px; }

/* ============================== Service slider ============================== */
/* Transform-driven, not native scroll: scroll-snap can't do a true infinite
   loop (browsers only let you scroll to real content, not wrap), so position
   is instead controlled by translateX over a [clone][real][clone] card set,
   giving full control over easing and a seamless, symmetric loop both ways.
   The left gap is a MARGIN on .svc-viewport, not padding anywhere: overflow
   clips at an element's padding edge, which sits OUTSIDE the padding area -
   a transformed child can still render inside its own ancestor's padding
   without being clipped. Margin has no such gap: the clipping box's edge
   IS the gap's edge, so nothing can ever render there, however it moves. */
/* Card width is a calc() off the viewport, not a fixed px, so "4 full
   cards + a fading 5th" holds at any desktop width rather than only at
   the one screen size 340px happened to fit nicely at - a 2560px monitor
   and a 1280px laptop both land on the same 4-plus-a-sliver layout,
   just with proportionally bigger or smaller cards. 4.4 (not 4.5) gives
   the 5th card a bit more of itself showing before the edge-fade mask
   takes over, so it reads as "fading in", not "already gone". */
.svc-outer { position: relative; padding: 0 0 20px 0;
  --svc-gap: 24px;
  --svc-margin: max(40px, calc((100vw - 1460px) / 2));
  --svc-card-w: calc((100vw - var(--svc-margin) - 4 * var(--svc-gap)) / 4.4);
}
.svc-viewport { overflow: hidden; margin-left: max(40px, calc((100vw - 1460px) / 2)); }
/* The track has no right margin (only left, to align with the site's
   content column), so on wide screens the last visible card gets clipped
   part-way across rather than lining up with the viewport edge. Rather than
   a hard cut, fade it into the page background - works for whichever card
   happens to be sitting there, at any screen width, since it's a mask over
   the clip edge itself rather than anything baked into a specific image. */
.svc-edge-fade { position: absolute; top: 0; right: 0; bottom: 0; width: 160px;
  background: linear-gradient(to right, rgba(255,255,255,0), var(--white) 88%);
  pointer-events: none; z-index: 12; }
@media (max-width: 900px) { .svc-edge-fade { width: 100px; } }
@media (max-width: 480px) { .svc-edge-fade { width: 56px; } }
.svc-track { display: flex; gap: 24px; padding: 4px 0 0;
  will-change: transform; }
.svc-card { will-change: transform, opacity; }
.svc-card { flex: 0 0 var(--svc-card-w); min-height: calc(var(--svc-card-w) * 1.529); border-radius: 10px; padding: 26px 24px;
  display: flex; flex-direction: column; justify-content: flex-end; color: var(--white); position: relative; }
.svc-card .card-media { position: absolute; inset: 0; z-index: 0; border-radius: 10px; overflow: hidden; }
.svc-card .card-media img { width: 100%; height: 100%; object-fit: cover; }
.svc-card .card-media::after { content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,23,43,0) 0%, rgba(8,23,43,0) 5%, rgba(8,23,43,1) 85%, rgba(8,23,43,1) 100%); }
.svc-card > * { position: relative; z-index: 1; }
.svc-hook { text-transform: uppercase; font-size: 13.5px; line-height: 1.3; font-weight: 600; letter-spacing: .3px; color: var(--bluelt);
  min-height: 18px; }
.svc-card h3 { font-size: 22px; line-height: 1.2; letter-spacing: -.3px; margin-top: 8px; color: var(--white); }
.svc-card p { line-height: 1.55; color: #DCE6F5; margin-top: 10px; margin-bottom: 18px;
  min-height: 56px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.svc-card .btn { align-self: flex-start; }
.svc-arrow { position: absolute; top: 50%; margin-top: -30px; width: 60px; height: 60px; border-radius: 50%;
  border: 3px solid var(--white); background: var(--navy); color: var(--white); cursor: pointer;
  display: flex; align-items: center; justify-content: center; z-index: 20;
  box-shadow: 0 10px 24px rgba(8,23,43,.3);
  transition: background .2s ease, transform .2s ease, box-shadow .2s ease; }
.svc-arrow svg { width: 24px; height: 24px; }
.svc-arrow:hover { background: var(--blue); transform: scale(1.08); box-shadow: 0 12px 28px rgba(6,82,191,.38); }
.svc-arrow:active { transform: scale(.94); }
.svc-prev { left: calc(max(40px, (100vw - 1460px) / 2) + 14px); }
.svc-next { right: 16px; }
.svc-dots { display: flex; justify-content: center; gap: 8px; margin-top: 6px; }
.svc-dot { width: 8px; height: 8px; border-radius: 50%; background: #DCE2E8; border: 0; padding: 0; cursor: pointer; transition: background .2s, transform .2s; }
.svc-dot.active { background: var(--blue); transform: scale(1.3); }
@media (max-width: 768px) { .svc-card { flex-basis: 260px; min-height: 460px; } }
@media (max-width: 480px) { .svc-card { flex-basis: 210px; min-height: 400px; } .svc-arrow { width: 44px; height: 44px; margin-top: -22px; border-width: 2px; } .svc-arrow svg { width: 18px; height: 18px; } .svc-prev { left: 14px; } .svc-next { right: 10px; } }

/* ============================== 3-step ============================== */
.steps { display: grid; grid-template-columns: repeat(3,1fr); gap: 40px; margin-top: 56px; }
/* flex-wrap lets the number and title share a line while the paragraph
   (flex-basis:100%) still drops to its own row underneath. */
.step { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 12px; }
.step .num { font-size: 26px; font-weight: 600; color: var(--blue); }
.step h3 { font-size: 21px; letter-spacing: -.3px; }
.step p { line-height: 1.6; color: var(--grey); margin-top: 4px; flex-basis: 100%; }
@media (max-width: 768px) { .steps { grid-template-columns: 1fr; gap: 32px; } }

/* How It Works, relocated under the Stay In The Loop intro text instead of
   its own centered section - single column since it now lives in the
   narrower left-hand column, not the full-width wrap. */
.steps-inline { margin-top: 40px; }
.steps-inline h2 { margin-top: 14px; }
.steps-inline .steps { grid-template-columns: 1fr; gap: 22px; margin-top: 20px; }

/* Residential / Commercial / Industrial coverage */
.coverage-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 32px; margin-top: 56px; }
.coverage-card h3 { font-size: 20px; letter-spacing: -.3px; margin-top: 16px; }
.coverage-card p { line-height: 1.6; color: var(--grey); margin-top: 10px; }
@media (max-width: 768px) { .coverage-grid { grid-template-columns: 1fr; gap: 32px; } }

/* ============================== Work gallery (full-bleed, filterable) ============================== */
/* Straddles the white/grey seam between "Where We Work" and "Stay In The
   Loop": those two sections get extra padding here, and this section pulls
   itself up into that padding by the same amount on each side, so half its
   height sits in each. +23px on top of the original 300px reserves room for
   the accent bars below, which sit entirely above/below the row's own edge
   (23px offset, 10px tall) - without it they'd eat into the whitespace
   instead of adding to it. */
.wg-gap-above { padding-bottom: 323px; }
.wg-gap-below { padding-top: 323px; }
.work-gallery { position: relative; display: flex; gap: 18px; height: 280px; margin: -170px 0 -173px; z-index: 5; }
/* Two thin accent bars above/below the row, split at the row/panel midpoint -
   blue over the first half, navy under the second, echoing the header/
   footer's own navy-to-blue direction. Scale in from the trailing edge
   (transform, not width, so the transition is GPU-cheap) once the section
   scrolls into view: the top bar grows left-to-right, the bottom bar grows
   right-to-left - like they're being drawn on rather than just appearing. */
.work-gallery::before,
.work-gallery::after { content: ""; position: absolute; height: 10px; z-index: 1;
  transform: scaleX(0); transition: transform .9s cubic-bezier(.22,.68,0,1.01); }
.work-gallery.wg-lines-in::before,
.work-gallery.wg-lines-in::after { transform: scaleX(1); }
.work-gallery::before { top: -23px; left: 0; width: 51%; background: var(--navy); transform-origin: left; }
.work-gallery::after { bottom: -23px; left: 51%; right: 0; background: var(--navy); transform-origin: right; }
.wg-row-wrap { z-index: 2; }
.wg-panel { z-index: 2; }
/* .wg-row-wrap holds only the image row's own width (never the navy panel),
   so arrows positioned at its edges can never land over the category list -
   the row is a native horizontal scroller (scroll-snap, no JS transform math)
   with fixed-width tiles so any number of images per category works, not
   just a fixed set of 7 evenly stretched to fill the row. */
.wg-row-wrap { position: relative; flex: 1 1 auto; min-width: 0; }
.wg-row { height: 100%; display: flex; gap: 14px; overflow-x: auto; overflow-y: hidden;
  scroll-behavior: smooth; scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none; }
.wg-row::-webkit-scrollbar { display: none; }
/* Exactly 7 tiles visible at once, whatever the row's own (full-bleed,
   viewport-dependent) width happens to be - percentage-based, not a fixed
   px, so "7 at a time" holds regardless of screen size. 6 gaps between 7
   tiles: (100% - 6*14px) / 7. */
.wg-tile { flex: 0 0 calc((100% - 84px) / 7); min-width: 0; position: relative; cursor: pointer; scroll-snap-align: start; }
.wg-tile img { width: 100%; height: 100%; object-fit: cover; display: block;
  transform: translateX(0); opacity: 1; transition: transform .35s ease, opacity .35s ease, filter .2s ease; }
.wg-tile:hover img { filter: brightness(.85); }
/* Leaving: quick push right + fade out. Entering: same offset from the left,
   applied with transition:none so it snaps into place before animating back
   to rest - the "new set fades/slides in" half of the swap. */
.wg-row.is-leaving .wg-tile img { transform: translateX(50px); opacity: 0; transition: transform .26s ease, opacity .26s ease; }
.wg-row.is-entering .wg-tile img { transform: translateX(-50px); opacity: 0; transition: none; }
.wg-slider-arrow { position: absolute; top: 50%; margin-top: -22px; width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; background: rgba(8,23,43,.55); color: var(--white);
  border: 1px solid rgba(255,255,255,.4); cursor: pointer; transition: background .2s ease, opacity .2s ease; z-index: 6; }
.wg-slider-arrow svg { width: 18px; height: 18px; }
.wg-slider-arrow:hover { background: var(--blue); border-color: var(--blue); }
.wg-slider-arrow:disabled { opacity: 0; pointer-events: none; }
.wg-slider-prev { left: 10px; }
.wg-slider-next { right: 10px; }
.wg-panel { flex: 0 0 260px; background: var(--navy); display: flex; align-items: center; padding: 26px 34px; }
.wg-cats { display: flex; flex-direction: column; gap: 1px; width: 100%; }
.wg-cat { background: none; border: 0; text-align: left; padding: 3px 0; font-size: 15px; font-weight: 600;
  color: rgba(255,255,255,.5); cursor: pointer; transition: color .2s ease; }
.wg-cat:hover { color: rgba(255,255,255,.85); }
.wg-cat.active { color: var(--white); }
@media (max-width: 900px) {
  .wg-gap-above { padding-bottom: var(--space-6); }
  .wg-gap-below { padding-top: var(--space-6); }
  .work-gallery { margin: 0; height: auto; flex-wrap: wrap; }
  .wg-row-wrap { flex: 1 1 100%; height: 200px; }
  .wg-tile { flex: 0 0 150px; height: 200px; }
  .wg-panel { flex: 1 1 100%; padding: 20px 24px; }
  .wg-cats { flex-direction: row; flex-wrap: wrap; gap: 8px 20px; }
}

/* Work gallery lightbox: click a tile to open a full-size view with its own
   prev/next and the same category list, so switching category and browsing
   images both work without leaving the popup. Built and appended to <body>
   by initWorkGallery() in main.js, not present in the server-rendered HTML. */
.wg-lightbox { position: fixed; inset: 0; background: rgba(8,23,43,.94); z-index: 300;
  display: flex; align-items: center; justify-content: center; padding: 60px 40px;
  opacity: 0; visibility: hidden; transition: opacity .25s ease, visibility .25s ease; }
.wg-lightbox.is-open { opacity: 1; visibility: visible; }
.wg-lightbox-inner { display: flex; gap: 40px; width: 100%; max-width: 1200px; height: 100%; align-items: center; }
.wg-lightbox-media { position: relative; flex: 1 1 auto; min-width: 0; height: 100%; display: flex; align-items: center; justify-content: center; }
.wg-lightbox-media img { max-width: 100%; max-height: 100%; border-radius: 10px; object-fit: contain;
  box-shadow: 0 30px 80px rgba(0,0,0,.5); }
.wg-lightbox-arrow { position: absolute; top: 50%; margin-top: -24px; width: 48px; height: 48px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); background: rgba(255,255,255,.08); color: var(--white);
  display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 2;
  transition: background .2s ease, border-color .2s ease; }
.wg-lightbox-arrow svg { width: 20px; height: 20px; }
.wg-lightbox-arrow:hover { background: var(--blue); border-color: var(--blue); }
.wg-lightbox-prev { left: -8px; }
.wg-lightbox-next { right: -8px; }
.wg-lightbox-panel { flex: 0 0 220px; }
.wg-lightbox-close { position: absolute; top: 24px; right: 28px; width: 42px; height: 42px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); background: rgba(255,255,255,.08); color: var(--white);
  display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 2;
  transition: background .2s ease, border-color .2s ease; }
.wg-lightbox-close:hover { background: var(--blue); border-color: var(--blue); }
.wg-lightbox-close svg { width: 18px; height: 18px; }
@media (max-width: 768px) {
  .wg-lightbox { padding: 80px 20px 24px; }
  .wg-lightbox-inner { flex-direction: column; gap: 20px; }
  .wg-lightbox-media { flex: 1 1 auto; width: 100%; order: 1; }
  .wg-lightbox-panel { flex: 0 0 auto; width: 100%; order: 2; }
  .wg-lightbox-panel .wg-cats { flex-direction: row; flex-wrap: wrap; gap: 8px 18px; }
  .wg-lightbox-prev { left: 4px; }
  .wg-lightbox-next { right: 4px; }
}

/* ============================== Feature cards (F.I.L section) ============================== */
.section-light { background: var(--light); }
.feature-row { display: flex; gap: 50px; flex-wrap: wrap; align-items: flex-start; }
.feature-left { flex: 1 1 380px; }
.feature-left h2 { margin-top: 16px; }
.feature-left p { line-height: 1.65; color: var(--grey); margin-top: 16px; }
.feature-cards { flex: 1 1 480px; display: flex; flex-direction: column; gap: 18px; width: 100%; }
.feature-card { display: flex; align-items: stretch; background: var(--white); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.feature-card-text { flex: 1 1 55%; padding: 26px 26px; display: flex; flex-direction: column; justify-content: center; }
.feature-card-media { flex: 1 1 45%; min-height: 190px; position: relative; overflow: hidden; }
.feature-card-media picture, .feature-card-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.feature-card-media::after { content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,23,43,0) 0%, rgba(8,23,43,0) 40%, rgba(8,23,43,.45) 100%); }
/* Tighter crop so the person reads larger in frame, biased toward his
   head/torso rather than a plain center zoom that would crop his face
   as much as his legs. */
.feature-card-media-zoom picture, .feature-card-media-zoom img { transform: scale(1.45); transform-origin: 45% 23%; }
.feature-card h3 { font-size: 18px; letter-spacing: -.2px; margin-top: 16px; }
.feature-card p { line-height: 1.6; color: var(--grey); margin-top: 8px; }
@media (max-width: 768px) { .feature-card { flex-direction: column; } .feature-card-media { min-height: 200px; } }

/* ============================== Who we are ============================== */
.who-row { display: flex; gap: 60px; flex-wrap: wrap; align-items: center; }
.who-img { flex: 1 1 420px; position: relative; }
/* Offset blue frame peeking out top-left, matching the live site's photo
   treatment - sits behind the image (z-index:0 vs the image's z-index:1)
   so only the exposed top/left strip reads as a frame. */
.who-img::before {
  content: ""; position: absolute; top: -28px; left: -28px;
  width: 45%; height: calc(100% + 28px);
  border: 10px solid var(--blue); z-index: 0;
}
/* height:auto is explicit, not left to default: some browsers fall back to
   treating the intrinsic `height` attribute as a literal pixel value
   instead of deriving it from the width via the image's real aspect ratio,
   which was stretching this into a tall, distorted box. */
.who-img img { width: 100%; height: auto; border-radius: 10px; display: block; position: relative; z-index: 1; }
.who-text { flex: 1 1 420px; }
.who-text h2 { margin-top: 16px; }
.who-text p { line-height: 1.65; color: var(--grey); margin-top: 18px; }
/* Mirrored variant (image right, text left) and a frameless image for
   sections that don't want the offset-blue-border treatment. */
.who-row.reverse { flex-direction: row-reverse; }
.who-img.no-frame::before { display: none; }
@media (max-width: 640px) { .who-row.reverse { flex-direction: column; } }

/* ============================== Services (roofing page etc.) ============================== */
.services-intro { display: flex; gap: 50px; flex-wrap: wrap; align-items: flex-start; margin-bottom: 40px; }
.services-intro-left { flex: 1 1 280px; }
.services-intro-right { flex: 2 1 520px; display: flex; gap: 30px; flex-wrap: wrap; }
.services-intro-right p { flex: 1 1 240px; line-height: 1.65; color: var(--grey); }
/* Same visual language as the homepage's .svc-card (photo, bottom gradient,
   label) but laid out as a static grid that fades in on scroll, not a
   slider - this list doesn't need to move, it needs to all be scannable. */
.service-card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 10px; border-top: 1px solid var(--line); padding-top: 34px; }
.service-card { position: relative; border-radius: 10px; overflow: hidden; min-height: 340px; padding: 26px 24px;
  display: flex; flex-direction: column; justify-content: flex-end; color: var(--white); }
.service-card .card-media { position: absolute; inset: 0; z-index: 0; }
.service-card .card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.service-card .card-media::after { content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,23,43,0) 0%, rgba(8,23,43,0) 5%, rgba(8,23,43,1) 85%, rgba(8,23,43,1) 100%); }
.service-card > * { position: relative; z-index: 1; }
.service-card h3 { font-size: 20px; line-height: 1.2; letter-spacing: -.3px; margin-top: 8px; color: var(--white); }
.service-card p { font-size: 16px; line-height: 1.55; color: #DCE6F5; margin-top: 10px; }
@media (max-width: 900px) { .service-card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .service-card-grid { grid-template-columns: 1fr; } }
.who-cards { display: flex; gap: 24px; flex-wrap: wrap; margin-top: 50px; }
.who-card { flex: 1 1 320px; background: var(--light); border-radius: 10px; padding: 30px 28px; transition: transform .25s ease; }
.who-card:hover { transform: translateY(-4px); }
.who-card h3 { font-size: 21px; letter-spacing: -.3px; }
.who-card p { line-height: 1.6; color: var(--grey); margin-top: 12px; margin-bottom: 18px; }
.who-card a { display: inline-flex; align-items: center; gap: 8px; color: var(--blue); font-weight: 600; font-size: 14.5px; }

/* Contact-style info cards reuse .coverage-grid/.coverage-card (About/Contact
   pages) - links inside need the accent colour instead of inheriting body text. */
.coverage-card a { color: var(--blue); }
.coverage-card a:hover { text-decoration: underline; }

/* ============================== Stat row (About) ============================== */
.stat-row { display: flex; gap: 40px; flex-wrap: wrap; justify-content: center; margin-top: 50px; padding-top: 46px; border-top: 1px solid var(--line); }
.stat-item { flex: 1 1 180px; text-align: center; }
.stat-num { font-size: 56px; font-weight: 500; letter-spacing: -1.5px; color: var(--blue); line-height: 1; }
.stat-label { display: block; margin-top: 10px; font-size: 15px; font-weight: 600; text-transform: uppercase; letter-spacing: .4px; color: var(--grey); }
@media (max-width: 768px) { .stat-num { font-size: 42px; } .stat-row { gap: 28px; margin-top: 36px; padding-top: 32px; } }

/* ============================== Check list (About / The Arden Standard) ============================== */
.check-list { display: flex; flex-direction: column; gap: 16px; margin-top: 26px; }
.check-item { display: flex; align-items: flex-start; gap: 12px; }
.check-item .icon-box { flex: none; width: 32px; height: 32px; border-radius: 8px; background: rgba(6,82,191,.08); box-shadow: none; }
.check-item span { font-size: 17px; font-weight: 500; color: var(--navy); line-height: 1.4; padding-top: 4px; }

/* ============================== Reviews ============================== */
.stars-lg { font-size: 26px; justify-content: center; }
.reviews-stat { text-align: center; font-size: 22px; letter-spacing: -.3px; margin-top: 14px; }
.section-dark .reviews-stat { color: var(--white); }
.section-dark .btn-outline { color: var(--white); border-color: rgba(255,255,255,.5); }
.rv-wrap { position: relative; max-width: var(--max-w); margin: 56px auto 0; padding: 0 70px; overflow: hidden; }
.rv-track { position: relative; height: 280px; }
/* The overflow:hidden above stops the carousel's faded side-cards from
   blowing out the page width, but that turns their edge into a hard clip.
   These masks fade that cut edge into the section's own dark background
   instead - same trick as .svc-edge-fade on the service slider, mirrored
   on both sides since this carousel is centered, not edge-aligned. */
.rv-edge-fade { position: absolute; top: 0; bottom: 0; width: 160px; pointer-events: none; z-index: 12; }
.rv-edge-fade-left { left: 0; background: linear-gradient(to left, rgba(8,23,43,0), var(--dark) 88%); }
.rv-edge-fade-right { right: 0; background: linear-gradient(to right, rgba(8,23,43,0), var(--dark) 88%); }
@media (max-width: 900px) { .rv-edge-fade { width: 100px; } }
@media (max-width: 480px) { .rv-edge-fade { width: 56px; } }
.rv-card { position: absolute; top: 0; left: 50%; width: 480px; max-width: 80vw; background: var(--white); border: 1px solid var(--line);
  border-radius: 12px; padding: 30px 32px; box-shadow: 0 18px 40px rgba(18,39,65,.10);
  transition: transform .55s cubic-bezier(.22,.68,0,1.01), opacity .55s ease; }
.rv-stars { color: #F5B400; font-size: 16px; letter-spacing: 2px; }
.rv-card .rv-quote { color: var(--navy); line-height: 1.6; margin: 14px 0 18px; display: -webkit-box;
  -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.rv-foot { display: flex; justify-content: space-between; align-items: baseline; border-top: 1px solid var(--line); padding-top: 14px; }
.rv-name { font-weight: 500; color: var(--navy); font-size: 14.5px; }
.rv-src { font-size: 12px; color: var(--blue); font-weight: 500; }
/* Same treatment as .svc-arrow on the service slider above. */
.rv-arrow { position: absolute; top: 50%; margin-top: -30px; width: 60px; height: 60px; border-radius: 50%;
  border: 0; background: var(--navy); color: var(--white); cursor: pointer;
  display: flex; align-items: center; justify-content: center; z-index: 20;
  box-shadow: 0 10px 24px rgba(8,23,43,.3);
  transition: background .2s ease, transform .2s ease, box-shadow .2s ease; }
.rv-arrow svg { width: 24px; height: 24px; }
.rv-arrow:hover { background: var(--blue); transform: scale(1.08); box-shadow: 0 12px 28px rgba(6,82,191,.38); }
.rv-arrow:active { transform: scale(.94); }
/* This section is dark navy, so the navy circle from the slider would
   nearly vanish into the background - same shape/size/hover behaviour,
   just flipped to a white circle so it's actually visible here, with a
   soft navy border to keep it defined against the white fill. */
.section-dark .rv-arrow { background: var(--white); color: var(--navy); border: 3px solid rgba(14,46,106,.35); }
.section-dark .rv-arrow:hover { background: var(--blue); color: var(--white); border-color: var(--blue); }
.rv-prev { left: 0; } .rv-next { right: 0; }
.rv-dots { display: flex; justify-content: center; gap: 8px; margin-top: 26px; }
.rv-dot { width: 8px; height: 8px; border-radius: 50%; background: #DCE2E8; border: 0; padding: 0; cursor: pointer; transition: background .2s, transform .2s; }
.rv-dot.active { background: var(--blue); transform: scale(1.3); }
@media (max-width: 640px) { .rv-wrap { padding: 0 50px; } .rv-arrow { width: 44px; height: 44px; margin-top: -22px; } .rv-arrow svg { width: 18px; height: 18px; } .section-dark .rv-arrow { border-width: 2px; } }
.reviews-cta { text-align: center; margin-top: 44px; }

/* ============================== Objection / FAQ ============================== */
/* Common Concerns: a photo alongside a clean accordion list, instead of the
   old 2x2 grid of mismatched pastel-tinted cards. */
.concerns-row { display: flex; gap: 56px; align-items: stretch; margin-top: 56px; }
.concerns-media { flex: 1 1 380px; position: relative; border-radius: 14px; overflow: hidden; min-height: 420px; }
.concerns-media picture, .concerns-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.concerns-media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(160deg, rgba(8,23,43,.05) 30%, rgba(8,23,43,.65) 100%); }
.concerns-list { flex: 1 1 480px; display: flex; flex-direction: column; }
.concern-item { display: flex; gap: 18px; padding: 24px 0; border-bottom: 1px solid var(--line); }
.concern-item:first-child { padding-top: 4px; }
.concern-item .icon-box { flex: none; }
.concern-item details { flex: 1; min-width: 0; }
@media (max-width: 900px) { .concerns-row { flex-direction: column; } .concerns-media { min-height: 260px; } }

.oc-q { font-size: 17px; font-weight: 500; letter-spacing: -.2px; color: var(--navy); cursor: pointer; list-style: none;
  display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.oc-q::-webkit-details-marker { display: none; }
.oc-q::after { content: '+'; font-size: 20px; color: var(--blue); flex: none; transition: transform .2s; }
details[open] > .oc-q::after { content: '\2212'; }
.oc-a { line-height: 1.65; color: var(--grey); margin: 14px 0 0; }

.faq-list { max-width: 1100px; margin: 48px auto 0; padding: 0 20px; column-count: 2; column-gap: 60px; }
.faq-item { break-inside: avoid; border-bottom: 1px solid var(--line); padding: 20px 0; }
.faq-item .oc-q { font-size: 16.5px; }
.faq-item .oc-a { padding-right: 30px; }
@media (max-width: 768px) { .faq-list { column-count: 1; } }

/* ============================== Guarantee ============================== */
.guarantee { background: var(--navy); }
.guarantee-row { display: flex; gap: 60px; align-items: center; flex-wrap: wrap; }
.guarantee-text { flex: 1 1 420px; }
.guarantee-text .icon-box { margin: 0; background: rgba(255,255,255,.08); width: 56px; height: 56px; }
.guarantee-text h2 { color: var(--white); margin-top: 16px; }
.guarantee-text h2 .accent { color: #4C8DFF; }
.guarantee-text p { color: #9FB3CC; line-height: 1.65; max-width: 690px; margin-top: 16px; }
.guarantee-text .btn { margin-top: 26px; }
.guarantee-media { flex: 1 1 380px; max-width: 460px; position: relative; }
.guarantee-media-main { position: relative; border-radius: 14px; overflow: hidden; box-shadow: 0 24px 50px rgba(0,0,0,.35); border: 4px solid var(--white); }
.guarantee-media-main img { width: 100%; height: auto; display: block; }
.guarantee-media-small { position: absolute; left: -20px; bottom: -30px; width: 45%; border-radius: 12px; overflow: hidden; box-shadow: 0 20px 40px rgba(0,0,0,.4); border: 4px solid var(--white); }
.guarantee-media-small img { width: 100%; height: auto; display: block; }
/* Same bottom-fade treatment as the service slider cards, for visual
   consistency between the two photo-card styles on the page. */
.guarantee-media-main::after, .guarantee-media-small::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(8,23,43,0) 0%, rgba(8,23,43,0) 5%, rgba(8,23,43,1) 85%, rgba(8,23,43,1) 100%); }
.guarantee-badge { position: absolute; right: -16px; bottom: 46px; background: var(--blue); color: var(--white);
  border-radius: 10px; padding: 16px 20px; box-shadow: 0 16px 32px rgba(6,82,191,.4);
  display: flex; flex-direction: column; align-items: center; text-align: center; line-height: 1.2; }
.guarantee-badge-num { font-size: 34px; font-weight: 700; }
.guarantee-badge-label { font-size: 15px; font-weight: 600; text-transform: uppercase; letter-spacing: .3px; margin-top: 4px; }
@media (max-width: 900px) { .guarantee-media { margin-top: 50px; max-width: 420px; } .guarantee-media-small { left: 0; } }
@media (max-width: 480px) { .guarantee-badge { right: 0; padding: 12px 16px; } .guarantee-badge-num { font-size: 27px; } .guarantee-badge-label { font-size: 12.5px; } }

/* ============================== Final CTA + form ============================== */
.cta-row { display: flex; gap: 60px; flex-wrap: wrap; align-items: flex-start; }
.cta-left { flex: 1 1 380px; }
.cta-left h2 { color: var(--white); }
.cta-left p { color: #9FB3CC; line-height: 1.65; margin-top: 16px; max-width: 460px; }
.call-direct.btn-secondary { gap: 12px; margin-top: 26px; }
.call-direct-icon { display: flex; flex: none; color: var(--blue); }
.call-direct-text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.call-direct-label { font-size: 11px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--grey); }
.call-direct-number { font-size: 19px; font-weight: 600; color: var(--navy); }
/* Pulled up so the form overlaps the hero above it, top edge level with the
   hero's button row - the same overlapping-card layout the live site uses.
   Needs its own stacking context (position+z-index) to actually paint in
   front of the hero, since .hero-inner is itself position+z-indexed and
   would otherwise win the stacking order despite coming first in the DOM. */
.cta-right { flex: 1 1 420px; margin-top: -243px; position: relative; z-index: 10; }
@media (max-width: 900px) { .cta-right { margin-top: 0; } }
.quote-form { background: var(--white); border-radius: 10px; padding: 30px; box-shadow: 0 20px 50px rgba(0,0,0,.25); }
.quote-form-intro { margin-bottom: 20px; }
.quote-form-intro h3 { font-size: 21px; color: var(--blue); }
.quote-form-intro p { font-size: 14.5px; color: var(--grey); margin-top: 6px; }
.quote-form .field-row { display: flex; gap: 14px; margin-bottom: 14px; }
.quote-form .field-row > * { flex: 1; }
.quote-form input, .quote-form textarea {
  width: 100%; border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; font: inherit; font-size: 14.5px;
  margin-bottom: 14px; color: var(--navy); background: var(--white);
}
.quote-form input:focus, .quote-form textarea:focus { outline: 2px solid var(--blue); outline-offset: 1px; }
.quote-form textarea { resize: vertical; min-height: 90px; }
.quote-form button { width: 100%; padding: 14px; font-size: 14.5px; font-weight: 600; letter-spacing: .3px; text-transform: uppercase; border-radius: 10px; }
.quote-form button[disabled] { opacity: .6; cursor: not-allowed; }
.quote-form .hp-field { position: absolute; left: -9999px; top: -9999px; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.quote-form-status { display: none; margin-top: 14px; padding: 12px 14px; border-radius: 6px; font-size: 14px; line-height: 1.5; }
.quote-form-status.is-visible { display: block; }
.quote-form-status.is-success { background: #E9F7EF; color: #1D8A5A; border: 1px solid #B6E3CB; }
.quote-form-status.is-error { background: #FBE8E8; color: #B23434; border: 1px solid #F0BCBC; }

/* ============================== Announcement banner (admin-controlled) ============================== */
.site-banner { background: var(--blue); color: var(--white); text-align: center; font-weight: 600; font-size: 15px; padding: 10px 20px; }
.site-banner a { color: var(--white); text-decoration: underline; margin-left: 6px; }

/* ============================== Blog ============================== */
.blog-head { padding-bottom: 24px; }
.blog-head h1 { font-size: 48px; letter-spacing: -1px; margin-top: 10px; }
.blog-head p { max-width: 620px; margin: 16px auto 0; color: var(--grey); font-size: 18px; line-height: 1.6; }
.blog-cats { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 0 0 34px; }
.blog-cat { font-size: 13px; font-weight: 600; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--line); color: var(--navy); background: var(--white); }
.blog-cat:hover { border-color: var(--blue); color: var(--blue); }
.blog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 26px; }
.blog-card { display: flex; flex-direction: column; background: var(--white); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; color: inherit; transition: transform .2s ease, box-shadow .2s ease; }
.blog-card:hover { transform: translateY(-3px); box-shadow: 0 16px 36px rgba(18,39,65,.12); }
.blog-card-media { aspect-ratio: 16 / 9; background: var(--light); }
.blog-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-card-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 8px; }
.blog-card-cat { font-size: 12px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase; color: var(--blue); }
.blog-card h2 { font-size: 19px; line-height: 1.3; color: var(--navy); }
.blog-card p { color: var(--grey); font-size: 14.5px; line-height: 1.55; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.blog-card-meta { margin-top: auto; font-size: 13px; color: var(--grey); padding-top: 6px; }
.blog-pager { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 40px; }
.blog-pager-count { color: var(--grey); font-size: 14px; }

.post-head { background: var(--dark); color: var(--white); padding: 60px 0 44px; }
.post-crumbs { display: flex; gap: 8px; font-size: 13px; color: #9FB3CC; margin-bottom: 14px; }
.post-crumbs a { color: #C8D6EA; }
.post-head h1 { font-size: 44px; line-height: 1.12; letter-spacing: -.8px; font-weight: 500; color: var(--white); max-width: 900px; }
.post-meta { margin-top: 16px; color: #9FB3CC; font-size: 15px; }
.post-hero { margin-top: -20px; }
.post-hero img { width: 100%; height: auto; max-height: 520px; object-fit: cover; border-radius: 14px; display: block; border: 4px solid var(--white); box-shadow: 0 18px 44px rgba(18,39,65,.16);
  /* The migrated post photos are square (1024x1024). Without a fixed ratio, height:auto
     made the hero a full square on phones - a screen-tall photo before the first line
     of the article - while wider screens cropped it to a banner. 16:9 everywhere. */
  aspect-ratio: 16 / 9; }
.post-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 56px; padding: 48px 20px 30px; }
.post-body { max-width: 720px; font-size: 17.5px; line-height: 1.75; color: #2B3A4E; }
.post-body h2 { font-size: 28px; margin: 36px 0 12px; color: var(--navy); letter-spacing: -.3px; }
.post-body h3 { font-size: 21px; margin: 28px 0 10px; color: var(--navy); }
.post-body p { margin: 0 0 18px; }
.post-body ul, .post-body ol { margin: 0 0 18px; padding-left: 24px; }
.post-body li { margin: 6px 0; }
.post-body a { color: var(--blue); text-decoration: underline; text-underline-offset: 3px; }
.post-body strong { color: var(--navy); }
.post-cta { margin-top: 40px; padding: 26px 28px; border-radius: 14px; background: var(--light); border: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 20px; align-items: center; justify-content: space-between; }
.post-cta h3 { margin: 0 0 4px; font-size: 20px; }
.post-cta p { margin: 0; font-size: 15px; color: var(--grey); }
.post-cta-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.post-side { display: flex; flex-direction: column; gap: 20px; position: sticky; top: 84px; align-self: start; }
.post-side-card { background: var(--white); border: 1px solid var(--line); border-radius: 12px; padding: 20px 22px; }
.post-side-card .eyebrow { font-size: 13px; }
.post-side-links { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.post-side-links a { color: var(--navy); font-weight: 500; font-size: 15px; }
.post-side-links a:hover { color: var(--blue); }
.post-nav { display: flex; justify-content: space-between; gap: 20px; padding: 10px 20px 70px; border-top: 1px solid var(--line); margin-top: 10px; padding-top: 26px; }
.post-nav-link { max-width: 46%; color: var(--navy); font-weight: 500; line-height: 1.35; display: flex; flex-direction: column; gap: 4px; }
.post-nav-link small { color: var(--grey); font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }
.post-nav-link.right { text-align: right; margin-left: auto; }
@media (max-width: 900px) {
  .post-layout { grid-template-columns: 1fr; gap: 30px; }
  .post-side { position: static; }
  .post-head h1 { font-size: 32px; }
  .blog-head h1 { font-size: 36px; }
}

/* ============================== 404 ============================== */
/* The server already pointed missing pages at /404.html, but the file never
   existed, so a missing page returned a bare server error instead. */
.not-found { padding: 120px 0; }
.not-found h1 { font-size: 56px; letter-spacing: -1px; margin-top: 12px; }
.not-found-links { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 30px; }
@media (max-width: 768px) { .not-found { padding: 80px 0; } .not-found h1 { font-size: 36px; } }

/* ============================== Responsive fixes (Sep 2026 audit) ============================== */
/* Slider dots were 8px buttons - far below a usable touch target. The button is
   now a 28px hit area and the visible dot is drawn inside it, so the design is
   unchanged but a thumb can actually land on one. */
.rv-dots, .svc-dots { gap: 0; }
.rv-dot, .svc-dot { width: 28px; height: 28px; background: transparent; display: inline-grid; place-items: center; transform: none; }
.rv-dot::after, .svc-dot::after { content: ""; width: 8px; height: 8px; border-radius: 50%; background: #DCE2E8; transition: background .2s, transform .2s; }
.rv-dot.active, .svc-dot.active { background: transparent; transform: none; }
.rv-dot.active::after, .svc-dot.active::after { background: var(--blue); transform: scale(1.3); }
.section-dark .rv-dot::after { background: rgba(255,255,255,.35); }
.section-dark .rv-dot.active::after { background: var(--white); }

/* The logo could be squeezed narrower than its own shape when the header row
   ran short of space, and the 84px mark crowded the phone number on phones. */
.site-header .logo { flex: none; }
@media (max-width: 480px) {
  .site-header .logo-full { height: 62px; }
  .header-spacer { height: 82px; }
  .site-header .call-number { font-size: 18px; }
}

/* Cloudflare's security check will not render narrower than 300px, so the
   form's 30px side padding pushed the whole card past the edge of a phone
   screen. Tighter padding on small screens gives the widget room to fit. */
.cta-right { min-width: 0; }
@media (max-width: 480px) { .quote-form { padding: 22px 18px; } .cta-right { flex-basis: 100%; } }
@media (max-width: 380px) { .quote-form { padding: 20px 10px; } .quote-form .field-row { flex-direction: column; gap: 0; } }

/* 11px uppercase was below comfortable reading size. */
.call-direct-label { font-size: 12px; }

/* Services submenu inside the phone drawer: eight tiles in three ~100px columns
   could not fit labels like "Maintenance & Repairs", so single long words forced
   the columns wider and the last tiles ran off the screen. */
.mega-item { min-width: 0; }
@media (max-width: 900px) { .mega-item-label { overflow-wrap: anywhere; } }
@media (max-width: 560px) {
  .mega { padding-left: 0; }
  .mega-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .mega-item-label { font-size: 14px; }
}
