/* ==========================================================================
   LIGHTSTREAM ROOFING — one-page site
   ---------------------------------------------------------------------------
   Concept: "The Roofline". One pitch angle (~7°) is the visual system for the
   whole page: section transitions, image masks, card notches and the header
   underline all use it. Behind everything sits a single fixed "sky" layer whose
   gradient is driven by scroll position (storm -> clearing -> daylight).

   Mobile-first throughout: every layout starts as a single column and gains
   structure at min-width breakpoints. Type and spacing scale fluidly with
   clamp() rather than stepping at breakpoints.

   Contents
     01  Tokens
     02  Reset & base
     03  Typography & shared blocks
     04  Buttons
     05  Sky, scroll progress, angled section system
     06  Header, nav, mobile menu
     07  Hero
     08  Company introduction
     09  Services grid
     10  Why choose us
     11  Process steps
     12  Homeowner band
     13  Testimonials
     14  FAQ accordion
     15  Contact
     16  Footer
     17  Privacy modal
     18  Sticky mobile action bar
     19  Reveal utilities
     20  Reduced motion
   ========================================================================== */


/* ==========================================================================
   01  TOKENS
   ========================================================================== */
:root {
  /* --- Palette --- */
  --charcoal:    #16191D;   /* primary dark / storm */
  --slate:       #242A31;   /* surfaces */
  --deep:        #123A63;   /* brand blue */
  --sky-blue:    #2E6FA8;   /* sky accent */
  --orange:      #F26522;   /* CTAs, highlights — used sparingly */
  --white:       #FFFFFF;
  --off:         #F5F7FA;
  --muted-dark:  #A7B0BB;   /* 8.0:1 on charcoal */
  --muted-light: #55606C;   /* 6.9:1 on off-white */

  /* Accessibility note ------------------------------------------------------
     #F26522 on white is 3.15:1 — below AA for body copy. Orange is therefore
     only used on dark surfaces (5.6:1 on charcoal), as a fill, or at display
     sizes. Text sitting ON an orange fill is charcoal, not white (5.6:1).
     ------------------------------------------------------------------------ */

  /* --- The pitch ---
     The diagonal rises over --pitch-run and then runs flat, like a roof slope
     meeting a ridge. Running it across the FULL viewport was the mistake: a
     true 7° angle over 1440px of width forces a 173px rise, and because both
     ends of a band must clear that rise, it opened a ~400px void between
     sections with nothing in it but a hairline.
     Capping the run keeps the angle genuinely 7.1° (rise = run x 0.125) while
     holding the rise near 80px on desktop. */
  --pitch-run:  clamp(210px, 44vw, 640px);
  --slope:      calc(var(--pitch-run) * 0.125);

  /* Local variants. Cards use a *partial* notch so the true 7° angle survives
     without eating the card: 25px of rise over 200px of run is tan⁻¹(0.125)
     = 7.1°, identical to the section pitch. */
  --notch:      200px;
  --notch-rise: 25px;
  --mask-rise:  clamp(18px, 4vw, 56px);

  /* --- Type --- */
  --font-head: "Archivo", "Arial Narrow", system-ui, sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  --fs-hero: clamp(2.5rem, 7.6vw, 5.5rem);
  --fs-h2:   clamp(1.8rem, 4.2vw, 3.2rem);
  --fs-h3:   clamp(1.2rem, 2.2vw, 1.6rem);
  --fs-h4:   clamp(1.02rem, 1.6vw, 1.18rem);
  --fs-lead: clamp(1.0625rem, 1.35vw, 1.25rem);
  --fs-body: 1.0625rem;
  --fs-sm:   0.9375rem;
  --fs-xs:   0.8125rem;

  /* --- Header ---
     The bar owns a solid band at the top of the page rather than floating
     transparently over the hero. --header-h is reserved on <body> so nothing
     is ever covered; --header-h-stuck is the condensed height after scrolling. */
  --header-h:       88px;
  --header-h-stuck: 68px;

  /* --- Space & motion --- */
  --shell:   1240px;
  --gutter:  clamp(1.15rem, 4vw, 2.5rem);
  /* Guaranteed clearance between a section's content and its slice edges.
     The pitched bands add --slope on top of this at both ends (see .pitch), so
     the content-to-content gap works out to slope + 2 x sec-pad. */
  --sec-pad: clamp(3.5rem, 5.4vw, 5.5rem);

  --ease:    cubic-bezier(.22, .61, .36, 1);
  --ease-io: cubic-bezier(.4, 0, .2, 1);
  --t-fast:  200ms;
  --t-mid:   360ms;
  --t-slow:  560ms;

  --radius:  4px;   /* deliberately tight — the angles do the shaping */
}

@media (max-width: 640px) {
  :root { --notch: 120px; --notch-rise: 15px; }
}


/* ==========================================================================
   02  RESET & BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Offset anchor targets so the condensed header never covers a heading. */
  scroll-padding-top: calc(var(--header-h-stuck) + 1.5rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  /* Reserve the header's band so the fixed bar never sits over page content. */
  padding-top: var(--header-h);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.72;
  color: var(--off);
  background: var(--charcoal);          /* fallback beneath the sky layer */
  /* Angled and parallax layers must never scroll the page sideways.
     `clip` is preferred (no scroll container); `hidden` covers Safari < 16. */
  overflow-x: hidden;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

img, svg, iframe { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.022em;
  margin: 0 0 .6em;
  text-wrap: balance;
}

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

button, input, select, textarea { font: inherit; color: inherit; }

/* Visible, high-contrast focus on every interactive element. */
:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
  border-radius: 2px;
}
.on-light :focus-visible { outline-color: var(--deep); }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: fixed; top: -100px; left: 12px; z-index: 300;
  background: var(--orange); color: var(--charcoal);
  font-family: var(--font-head); font-weight: 800;
  padding: .75rem 1.25rem; text-decoration: none;
  transition: top var(--t-fast) var(--ease);
}
.skip-link:focus { top: 12px; }

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


/* ==========================================================================
   03  TYPOGRAPHY & SHARED BLOCKS
   ========================================================================== */
.h2 { font-size: var(--fs-h2); font-weight: 900; letter-spacing: -0.03em; }
.h3 { font-size: var(--fs-h3); font-weight: 800; }
.h4 { font-size: var(--fs-h4); font-weight: 700; letter-spacing: -0.01em; }

.lead { font-size: var(--fs-lead); max-width: 62ch; }
.muted { color: var(--muted-dark); }
.on-light .muted { color: var(--muted-light); }
.accent { color: var(--orange); }

/* Eyebrow with a roofline glyph beside it.
   The label is off-white on dark rather than orange: at 13px it counts as
   small text for WCAG, and orange over the translucent mid-page surfaces sits
   too close to the 4.5:1 floor. The glyph stays orange — decorative, so it
   carries the accent without carrying the contrast burden. */
.eyebrow {
  display: inline-flex; align-items: center; gap: .7rem;
  font-family: var(--font-head);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--off);
  margin-bottom: 1rem;
}
.eyebrow::after {
  content: "";
  width: 46px; height: 10px;
  background: var(--orange);
  clip-path: polygon(0 100%, 50% 0, 100% 100%, 50% 42%);
}
.on-light .eyebrow { color: var(--deep); }

.sec-head { max-width: 68ch; margin-bottom: clamp(2.5rem, 5vw, 4rem); }

/* Centred CTA that closes a section */
.sec-cta { margin-top: clamp(2.5rem, 5vw, 3.5rem); display: flex; justify-content: center; }

/* Inline text CTA with an animated roofline underline */
.link-cta {
  display: inline-block;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: var(--fs-sm);
  color: var(--orange);
  text-decoration: none;
  padding-bottom: 3px;
  background-image: linear-gradient(var(--orange), var(--orange));
  background-size: 0% 2px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size var(--t-mid) var(--ease);
}
.link-cta::after { content: " →"; }
.link-cta:hover, .link-cta:focus-visible { background-size: 100% 2px; }
.on-light .link-cta {
  color: var(--deep);
  background-image: linear-gradient(var(--deep), var(--deep));
}


/* ==========================================================================
   04  BUTTONS
   ========================================================================== */
.btn {
  --btn-shift-x: 0px; --btn-shift-y: 0px;
  display: inline-flex; align-items: center; justify-content: center;
  gap: .5rem;
  font-family: var(--font-head);
  font-weight: 800;
  font-size: var(--fs-sm);
  line-height: 1;
  padding: 1rem 1.6rem;
  min-height: 44px;              /* comfortable touch target on every variant */
  border: 2px solid transparent;
  border-radius: var(--radius);
  text-decoration: none;
  cursor: pointer;
  text-align: center;
  transform: translate3d(var(--btn-shift-x), var(--btn-shift-y), 0);
  transition:
    transform var(--t-fast) var(--ease),
    background-color var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease);
}
.btn--lg { padding: 1.15rem 2rem; font-size: 1rem; }
.btn--sm { padding: .72rem 1.1rem; font-size: var(--fs-xs); }
.btn--block { display: flex; width: 100%; }

/* Primary — charcoal on orange keeps the label at 5.6:1 (AA). */
.btn--primary { background: var(--orange); color: var(--charcoal); }
.btn--primary:hover { background: #FF7A3D; box-shadow: 0 10px 26px -10px rgba(242,101,34,.75); }

.btn--outline { border-color: rgba(245,247,250,.5); color: var(--off); background: transparent; }
.btn--outline:hover { border-color: var(--off); background: rgba(245,247,250,.1); }

.btn--ghost { border-color: rgba(245,247,250,.35); color: var(--off); background: transparent; }
.btn--ghost:hover { background: rgba(245,247,250,.1); }

.btn--dark { background: var(--charcoal); color: var(--white); }
.btn--dark:hover { background: #000; }

/* Tactile press state (the mobile counterpart of the desktop magnetic pull) */
.btn:active { transform: translate3d(var(--btn-shift-x), var(--btn-shift-y), 0) scale(.97); }


/* ==========================================================================
   05  SKY, SCROLL PROGRESS, ANGLED SECTION SYSTEM
   ========================================================================== */
.sky {
  position: fixed; inset: 0; z-index: -2;
  --sky-top: #0E0F11;
  --sky-bot: #1C1E22;
  background: linear-gradient(170deg, var(--sky-top) 0%, var(--sky-bot) 100%);
  will-change: background;
}
/* Neutral depth only. These radials used to be rgba(46,111,168,.28) and
   rgba(18,58,99,.30) — because the layer is fixed, that top-right blue glow
   sat permanently over the hero and gave it a navy cast. White at low alpha
   keeps the same sense of depth with no colour. */
.sky__haze {
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 60% at 70% 8%,  rgba(255,255,255,.05), transparent 60%),
    radial-gradient(90%  50% at 12% 95%, rgba(255,255,255,.035), transparent 65%);
}

.progress {
  position: fixed; top: 0; left: 0; right: 0; z-index: 120;
  height: 6px; pointer-events: none;
}
.progress__svg { width: 100%; height: 6px; }
.progress__track,
.progress__line {
  fill: none; stroke-width: 4; stroke-linecap: butt; vector-effect: non-scaling-stroke;
}
.progress__track { stroke: rgba(245,247,250,.14); }
.progress__line  { stroke: var(--orange); }

/* --- The pitched section system ------------------------------------------
   Every band after the hero pulls itself up over the previous one and cuts a
   diagonal top edge at the shared angle. Surfaces are translucent so the sky
   keeps flowing behind them — the pitch reads as an edge in the tint. */
.pitch {
  position: relative;
  z-index: 1;
  margin-top: calc(var(--slope) * -1);
  /* Both ends must clear the slope, not just the top.
     The diagonal starts at y=slope on the left and y=0 on the right, so this
     section's own cut steals up to `slope` of top space on the left — and the
     NEXT section (pulled up by -slope, cutting from y=0 on the right) steals
     the same amount of bottom space on the right. Padding only one end left
     the bottom-right clearance negative, letting the following slice bite into
     this section's content. Adding --slope to both keeps the guaranteed
     clearance at --sec-pad on every edge and makes the band read as balanced. */
  padding-top: calc(var(--slope) + var(--sec-pad));
  padding-bottom: calc(var(--slope) + var(--sec-pad));
  /* Slope up over --pitch-run, then flat ridge to the right edge. */
  clip-path: polygon(0 var(--slope), var(--pitch-run) 0, 100% 0, 100% 100%, 0 100%);
}
/* Hairline of light riding the pitch — the "depth" edge. Traces the same
   slope-then-ridge profile and returns 3px below it. */
.pitch::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: calc(var(--slope) + 3px);
  background: rgba(245,247,250,.22);
  clip-path: polygon(0 var(--slope), var(--pitch-run) 0, 100% 0,
                     100% 3px, var(--pitch-run) 3px, 0 calc(var(--slope) + 3px));
  pointer-events: none;
}

/* Section surfaces — progressively lighter as the sky clears.
   Opacity is deliberately high (>=.80): these are translucent, so the
   effective background of every label shifts as the sky brightens. At lower
   opacity the mid-page sections drifted toward bright blue and small text
   fell under 4.5:1. */
/* Adjacent bands alternate lighter/darker. Without this the pitched edge had
   nothing to separate — two near-identical darks meeting at a diagonal read as
   a stray hairline in an empty band rather than a deliberate cut. */
.intro        { background: rgba(31, 37, 45, .82); }   /* lighter slate */
.services     { background: rgba(13, 16, 20, .88); }   /* darker          */
.why          { background: rgba(20, 45, 73, .86); }   /* lighter, blue   */
.process      { background: rgba(13, 16, 20, .90); }   /* darker          */
.testimonials { background: rgba(246,248,251, .94); }  /* near white       */
.faq          { background: rgba(219,227,238, .97); }  /* cool grey step   */
.contact      { background: rgba(248,250,252, .98); }  /* near white       */
.footer       { background: var(--charcoal); }

.on-light { color: var(--charcoal); }
.testimonials::before, .faq::before, .contact::before { background: rgba(18,58,99,.22); }

/* --- Angled image masks --------------------------------------------------- */
.anglemask {
  margin: 0;
  overflow: hidden;
  clip-path: polygon(0 var(--mask-rise), 100% 0,
                     100% calc(100% - var(--mask-rise)), 0 100%);
}
.anglemask--r {
  clip-path: polygon(0 0, 100% var(--mask-rise),
                     100% 100%, 0 calc(100% - var(--mask-rise)));
}
.anglemask img { width: 100%; height: 100%; object-fit: cover; }


/* ==========================================================================
   06  HEADER, NAV, MOBILE MENU
   ========================================================================== */
/* Solid at every scroll position. It previously started transparent and sat
   directly on top of the hero; now it holds its own band (reserved by the
   body's padding-top) so it never overlaps the hero. */
.header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 110;
  background: var(--charcoal);
  transition: box-shadow var(--t-mid) var(--ease);
}
.header__inner {
  display: flex; align-items: center; gap: 1.25rem;
  min-height: var(--header-h);
  transition: min-height var(--t-mid) var(--ease);
}
/* The roofline underline is permanent brand furniture, not a scroll state. */
.header::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: linear-gradient(90deg, var(--orange) 0 33%, rgba(242,101,34,.15) 33%);
}
/* Scrolled: condense and lift off the page. */
.header.is-stuck { box-shadow: 0 10px 30px -18px rgba(0,0,0,.9); }
.header.is-stuck .header__inner { min-height: var(--header-h-stuck); }

/* --- Brand wordmark --- */
.brand {
  display: inline-flex; align-items: center; gap: .7rem;
  text-decoration: none; color: var(--white);
  margin-right: auto;
}
.brand__mark { width: 34px; height: 20px; color: var(--orange); flex: none; }
.brand__text { display: grid; line-height: 1; }
.brand__name {
  font-family: var(--font-head); font-weight: 900;
  font-size: clamp(1.08rem, 4vw, 1.28rem);
  letter-spacing: -0.035em;
  text-transform: uppercase;
}
.brand__sub {
  font-family: var(--font-head); font-weight: 600;
  font-size: clamp(.58rem, 2vw, .66rem);
  letter-spacing: .42em;
  text-transform: uppercase;
  color: var(--muted-dark);
  margin-top: 3px;
}
.brand--inv .brand__name { color: var(--white); }

/* --- Desktop nav --- */
.nav { display: none; }
.nav__list { display: flex; align-items: center; gap: clamp(.85rem, 1.7vw, 1.7rem); }
.nav__link {
  position: relative;
  font-family: var(--font-head);
  font-weight: 700; font-size: var(--fs-sm);
  color: var(--off); text-decoration: none;
  padding: .4rem 0;
  white-space: nowrap;
  transition: color var(--t-fast) var(--ease);
}
.nav__link::after {
  content: ""; position: absolute; left: 0; bottom: -2px;
  width: 100%; height: 8px;
  background: var(--orange);
  clip-path: polygon(0 100%, 50% 0, 100% 100%);
  opacity: 0; transform: translateY(4px);
  transition: opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.nav__link:hover, .nav__link.is-active { color: var(--white); }
.nav__link.is-active::after { opacity: 1; transform: translateY(0); }

.header__actions { display: none; align-items: center; gap: 1rem; }
.header__phone {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-head); font-weight: 700;
  font-size: var(--fs-sm); color: var(--white);
  text-decoration: none; white-space: nowrap;
}
.header__phone:hover { color: var(--orange); }
.icon { width: 17px; height: 17px; flex: none; }

/* --- Burger --- */
.burger {
  width: 46px; height: 46px; flex: none;
  display: grid; place-content: center; gap: 6px;
  background: transparent; border: 0; cursor: pointer; padding: 0;
}
.burger__bar {
  display: block; width: 26px; height: 2px; background: var(--white);
  transition: transform var(--t-mid) var(--ease), opacity var(--t-fast) var(--ease);
}
.burger[aria-expanded="true"] .burger__bar:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.burger[aria-expanded="true"] .burger__bar:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] .burger__bar:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* --- Full-screen mobile menu --- */
.mmenu { position: fixed; inset: 0; z-index: 105; }
.mmenu[hidden] { display: none; }
.mmenu__panel {
  position: absolute; inset: 0;
  background: var(--charcoal);
  padding: 110px var(--gutter) calc(2rem + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 1.5rem;
  overflow-y: auto;
  transform: translateY(-16px); opacity: 0;
  transition: transform var(--t-mid) var(--ease), opacity var(--t-mid) var(--ease);
}
.mmenu.is-open .mmenu__panel { transform: translateY(0); opacity: 1; }
.mmenu__nav ul { display: grid; gap: .1rem; }
.mmenu__nav a {
  display: block;
  font-family: var(--font-head); font-weight: 800;
  font-size: clamp(1.35rem, 6vw, 2rem);
  letter-spacing: -0.03em;
  color: var(--white); text-decoration: none;
  padding: .5rem 0;
  border-bottom: 1px solid rgba(245,247,250,.1);
}
.mmenu__nav a:hover { color: var(--orange); }
.mmenu__foot { display: grid; gap: .75rem; margin-top: auto; padding-top: 1.5rem; }
.mmenu__addr { color: var(--muted-dark); font-size: var(--fs-sm); text-align: center; margin: .5rem 0 0; }

body.is-locked { overflow: hidden; }

@media (min-width: 1100px) {
  .nav, .header__actions { display: flex; }
  .burger { display: none; }
}


/* ==========================================================================
   07  HERO
   ========================================================================== */
.hero {
  position: relative;
  /* The header owns its own band now, so the hero fills what's left of the
     viewport and no longer needs 140px of padding to duck underneath it. */
  min-height: calc(100svh - var(--header-h));
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(2.5rem, 6vw, 4.5rem) 0 clamp(5rem, 12vw, 8rem);
  overflow: hidden;
  isolation: isolate;
}

.hero__scene { position: absolute; inset: -6% 0 0; z-index: -1; }
.hero__layer { position: absolute; inset: 0; will-change: transform; }

.hero__layer--mid {
  top: auto; bottom: 0; height: 74%;
  clip-path: polygon(0 var(--slope), var(--pitch-run) 0, 100% 0, 100% 100%, 0 100%);
}
.hero__photo {
  width: 100%; height: 100%; object-fit: cover;
  object-position: 50% 55%;
  opacity: .38;
  filter: grayscale(.3) contrast(1.06);
}
.hero__layer--mid::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg,
              rgba(13,15,18,.72) 0%, rgba(13,15,18,.42) 40%, rgba(13,15,18,.92) 100%);
}

.hero__ridge { position: absolute; left: -2%; bottom: 0; width: 104%; }
.hero__ridge--far  { height: clamp(120px, 22vw, 260px); }
/* Neutral slate, not the brand blue — this silhouette is a depth layer, and
   filling it #123A63 was a second source of the hero's navy cast. */
.hero__ridge--far  path { fill: rgba(58,60,63,.55); }
.hero__ridge--near { height: clamp(150px, 26vw, 300px); }
.hero__ridge--near path { fill: rgba(11,13,16,.94); }

.hero__body { position: relative; z-index: 2; }
.hero__title {
  font-size: var(--fs-hero);
  font-weight: 900;
  letter-spacing: -0.045em;
  line-height: .98;
  text-transform: uppercase;
  margin-bottom: 1.5rem;
  /* Headroom over the longest line ("Affordable Roofing."), so the three
     deliberate breaks survive a webfont failing to load and the wider
     fallback face taking over. */
  max-width: 20ch;
}
.hero__title-line { display: block; }
.hero__title-line--accent { color: var(--orange); }
.hero__sub {
  font-size: var(--fs-lead);
  color: #DCE3EB;
  max-width: 58ch;
  margin-bottom: 2.2rem;
}
.hero__cta { display: flex; flex-wrap: wrap; gap: .85rem; }

.scroll-cue {
  position: absolute; z-index: 2;
  left: 50%;
  /* The next band is pulled up by --slope. Now that the diagonal flattens at
     --pitch-run — which is left of centre — the cue sits under the flat ridge,
     so it has to clear the full slope rather than half of it. */
  bottom: calc(var(--slope) + 2.25rem);
  transform: translateX(-50%);
  width: 26px; height: 42px;
  display: grid; place-items: start center;
}
.scroll-cue__rail {
  width: 24px; height: 40px; border: 2px solid rgba(245,247,250,.4);
  border-radius: 14px; display: grid; justify-items: center; padding-top: 7px;
}
.scroll-cue__dot {
  width: 3px; height: 8px; border-radius: 2px; background: var(--orange);
  animation: cue 2.2s var(--ease-io) infinite;
}
@keyframes cue {
  0%, 100% { transform: translateY(0);    opacity: 1; }
  55%      { transform: translateY(12px); opacity: .2; }
}
@media (max-width: 900px) { .scroll-cue { display: none; } }


/* ==========================================================================
   08  COMPANY INTRODUCTION
   ========================================================================== */
.intro__grid { display: grid; gap: clamp(2.5rem, 6vw, 4.5rem); align-items: center; }
.intro__media > .anglemask { aspect-ratio: 4 / 5; }
.intro__copy .lead { margin-bottom: 1.2rem; }

/* Four emphasis pillars */
.pillars { display: grid; gap: 1.5rem; margin-top: 2.4rem; }
.pillars li { position: relative; padding-left: 2rem; }
.pillars li::before {
  content: ""; position: absolute; left: 0; top: .45em;
  width: 15px; height: 15px; background: var(--orange);
  clip-path: polygon(0 100%, 50% 0, 100% 100%);
}
.pillars h3 {
  font-size: 1.02rem; font-weight: 800; color: var(--white);
  margin-bottom: .25rem;
}
.pillars p { font-size: var(--fs-sm); color: #C6CED8; margin: 0; }

@media (min-width: 620px) { .pillars { grid-template-columns: 1fr 1fr; gap: 1.6rem 2rem; } }
@media (min-width: 960px) { .intro__grid { grid-template-columns: .8fr 1fr; } }


/* ==========================================================================
   09  SERVICES GRID
   ========================================================================== */
.svcgrid { display: grid; gap: 1px; background: rgba(245,247,250,.14); }

.svc {
  background: linear-gradient(180deg, #232A32 0%, #1B2128 100%);
  display: flex; flex-direction: column;
  transition: background var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.svc:hover { background: linear-gradient(180deg, #2A323B 0%, #20272F 100%); }

.svc__media { aspect-ratio: 16 / 10; }
.svc__media img {
  transition: transform var(--t-slow) var(--ease);
}
.svc:hover .svc__media img { transform: scale(1.04); }

.svc__body { padding: clamp(1.3rem, 3vw, 1.8rem); }
.svc__title {
  font-size: clamp(1.1rem, 2.2vw, 1.3rem);
  font-weight: 800; color: var(--white);
  margin-bottom: .55rem;
  position: relative; padding-top: .9rem;
}
.svc__title::before {
  content: ""; position: absolute; top: 0; left: 0;
  width: 34px; height: 5px; background: var(--orange);
  clip-path: polygon(0 100%, 50% 0, 100% 100%);
}
.svc__body p { font-size: var(--fs-sm); color: #C6CED8; margin: 0; }

@media (min-width: 640px)  { .svcgrid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .svcgrid { grid-template-columns: repeat(3, 1fr); } }


/* ==========================================================================
   10  WHY CHOOSE US
   ========================================================================== */
.benefits { display: grid; gap: 1px; background: rgba(245,247,250,.14); }
.benefit {
  background: rgba(16,20,26,.72);
  padding: clamp(1.6rem, 3.5vw, 2.4rem);
}
.benefit__mark {
  display: block; width: 40px; height: 14px; background: var(--orange);
  clip-path: polygon(0 100%, 50% 0, 100% 100%, 50% 46%);
  margin-bottom: 1.1rem;
}
.benefit h3 {
  font-size: 1.14rem; font-weight: 800; color: var(--white);
  margin-bottom: .55rem;
}
.benefit p { font-size: var(--fs-sm); color: #C6CED8; margin: 0; }

@media (min-width: 640px)  { .benefits { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .benefits { grid-template-columns: repeat(4, 1fr); } }


/* ==========================================================================
   11  PROCESS STEPS
   ========================================================================== */
.steps { display: grid; gap: 1.5rem; counter-reset: step; }
.step {
  position: relative;
  background: rgba(26,31,38,.8);
  border-top: 3px solid var(--orange);
  padding: clamp(1.5rem, 3vw, 2rem);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 calc(100% - var(--notch-rise)));
}
.step__num {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  font-family: var(--font-head); font-weight: 900; font-size: 1.15rem;
  color: var(--charcoal); background: var(--orange);
  border-radius: 50%;
  margin-bottom: 1rem;
}
.step__title {
  font-size: 1.1rem; font-weight: 800; color: var(--white);
  margin-bottom: .5rem;
}
.step p { font-size: var(--fs-sm); color: #C6CED8; margin: 0; }

@media (min-width: 640px)  { .steps { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; } }
@media (min-width: 1040px) { .steps { grid-template-columns: repeat(4, 1fr); } }


/* ==========================================================================
   12  HOMEOWNER BAND
   ========================================================================== */
.homeowner {
  position: relative;
  overflow: hidden;
  text-align: center;
  color: var(--white);
  background: var(--deep);
}
.homeowner__bg { position: absolute; inset: 0; z-index: 0; }
.homeowner__bg img {
  width: 100%; height: 100%; object-fit: cover;
  opacity: .3; filter: grayscale(.28);
}
.homeowner::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(150deg, rgba(18,58,99,.90) 0%, rgba(22,25,29,.86) 100%);
}
.homeowner__inner { position: relative; z-index: 1; }
.homeowner__title { margin-bottom: 1.1rem; }
.homeowner__copy {
  font-size: var(--fs-lead); color: #DCE3EB;
  max-width: 62ch; margin-inline: auto; margin-bottom: 2rem;
}
.homeowner__actions {
  display: flex; flex-wrap: wrap; gap: .85rem; justify-content: center;
}


/* ==========================================================================
   13  TESTIMONIALS
   ========================================================================== */
.tgrid { display: grid; gap: 1.25rem; }
.tcard {
  background: var(--white);
  border: 1px solid rgba(18,58,99,.14);
  border-left: 4px solid rgba(18,58,99,.3);
  padding: clamp(1.4rem, 3vw, 1.9rem);
  clip-path: polygon(0 0, 100% var(--notch-rise), 100% 100%, 0 100%);
}
.tcard__mark {
  display: block;
  font-family: var(--font-head); font-weight: 900;
  font-size: 3rem; line-height: .6;
  color: rgba(18,58,99,.22);
  margin-bottom: .75rem;
}
/* Placeholder state — deliberately reads as "not yet filled in" rather than
   imitating a real review. */
.tcard--empty { border-left-style: dashed; }
.tcard__status {
  font-family: var(--font-head); font-weight: 800;
  font-size: var(--fs-sm); letter-spacing: .06em; text-transform: uppercase;
  color: var(--deep);
  margin-bottom: .4rem;
}
.tcard__note { font-size: var(--fs-sm); color: var(--muted-light); margin: 0; }
.tcard__quote { font-size: var(--fs-body); color: var(--charcoal); margin: 0 0 .8rem; font-style: normal; }
.tcard__by {
  font-family: var(--font-head); font-weight: 700;
  font-size: var(--fs-sm); color: var(--muted-light);
}

.tnote {
  margin-top: 2rem; text-align: center;
  font-size: var(--fs-sm); color: var(--muted-light);
}
.tnote a { color: var(--deep); font-weight: 700; }

@media (min-width: 700px)  { .tgrid { grid-template-columns: repeat(3, 1fr); } }


/* ==========================================================================
   14  FAQ ACCORDION
   ========================================================================== */
.acc { max-width: 900px; }
.acc__item {
  border-bottom: 1px solid rgba(18,58,99,.18);
  background: var(--white);
}
.acc__item:first-child {
  border-top: 3px solid var(--orange);
}
.acc__head { margin: 0; }
.acc__btn {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  text-align: left;
  padding: 1.35rem clamp(1rem, 2.5vw, 1.6rem);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease);
}
.acc__btn:hover { background: rgba(18,58,99,.05); }
.acc__btn:focus-visible { outline-offset: -4px; }
.acc__q {
  font-family: var(--font-head); font-weight: 800;
  font-size: clamp(1rem, 2vw, 1.16rem);
  letter-spacing: -0.015em;
  color: var(--charcoal);
}
.acc__chev {
  width: 30px; height: 30px; flex: none;
  border: 2px solid rgba(18,58,99,.3);
  border-radius: 50%;
  position: relative;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.acc__chev::before,
.acc__chev::after {
  content: ""; position: absolute; top: 50%; left: 50%; background: var(--deep);
  transform: translate(-50%, -50%);
  transition: opacity var(--t-fast) var(--ease);
}
.acc__chev::before { width: 12px; height: 2px; }
.acc__chev::after  { width: 2px; height: 12px; }
.acc__btn[aria-expanded="true"] .acc__chev { border-color: var(--orange); background: rgba(242,101,34,.12); }
.acc__btn[aria-expanded="true"] .acc__chev::after { opacity: 0; }

/* Height is animated explicitly from JS (0 -> measured -> auto). The grid
   0fr/1fr technique is avoided here: Safari below 17.4 doesn't interpolate it,
   which would leave panels opening to zero height. Padding stays constant so
   the measured height is correct on the very first open. */
.acc__panel {
  height: 0;
  overflow: hidden;
  transition: height var(--t-mid) var(--ease-io);
}
.acc__inner {
  padding: 0 clamp(1rem, 2.5vw, 1.6rem) 1.6rem;
}
.acc__inner p { font-size: var(--fs-sm); color: var(--muted-light); max-width: 70ch; }
.acc__inner a:not(.link-cta) { color: var(--deep); font-weight: 600; }


/* ==========================================================================
   15  CONTACT
   ========================================================================== */
.contact__grid { display: grid; gap: clamp(2rem, 5vw, 3.5rem); align-items: start; }

.card {
  background: var(--white);
  border: 1px solid rgba(18,58,99,.14);
  box-shadow: 0 30px 70px -46px rgba(18,58,99,.7);
}
.card--form {
  padding: clamp(1.5rem, 4vw, 2.5rem);
  clip-path: polygon(0 var(--notch-rise), var(--notch) 0, 100% 0, 100% 100%, 0 100%);
}

.form { display: grid; gap: 1.1rem; }
.field { display: grid; gap: .4rem; }
.field-row { display: grid; gap: 1.1rem; }
.field label {
  font-family: var(--font-head); font-weight: 700;
  font-size: var(--fs-sm); color: var(--charcoal);
}
.req { color: #A72B15; }

.field input, .field select, .field textarea {
  width: 100%;
  padding: .85rem 1rem;
  border: 2px solid rgba(18,58,99,.24);
  border-radius: var(--radius);
  background: var(--off);
  font-size: var(--fs-sm);
  transition: border-color var(--t-fast) var(--ease);
}
.field textarea { resize: vertical; min-height: 110px; line-height: 1.6; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--deep); }

/* Inline error state — colour is backed by the message text and aria-invalid */
.field input[aria-invalid="true"],
.field select[aria-invalid="true"] { border-color: #C3341A; background: #FDF2EF; }
.field__err {
  margin: 0;
  font-size: var(--fs-xs); font-weight: 600;
  color: #A72B15;                       /* 6.1:1 on white */
}
.field__err::before { content: "▲ "; font-size: .7em; }

.form__note { font-size: var(--fs-xs); color: var(--muted-light); text-align: center; margin: 0; }

.form-success { padding: clamp(2rem, 5vw, 3rem); text-align: center; }
.form-success__mark { width: 62px; height: 62px; margin: 0 auto 1.2rem; color: var(--orange); }
.form-success h3 { color: var(--charcoal); margin-bottom: .6rem; }
.form-success p { color: var(--muted-light); font-size: var(--fs-sm); }
.form-success a { color: var(--deep); font-weight: 700; }

/* --- Info column --- */
.contact__info { display: grid; gap: 1rem; }
.infocard {
  background: var(--white);
  border: 1px solid rgba(18,58,99,.14);
  border-left: 4px solid var(--deep);
  padding: 1.2rem 1.35rem;
  display: grid; gap: .3rem;
  text-decoration: none;
}
.infocard--call, .infocard--mail {
  border-left-color: var(--orange);
  transition: transform var(--t-fast) var(--ease);
}
.infocard--call:hover, .infocard--mail:hover { transform: translateX(3px); }
.infocard__k {
  font-family: var(--font-head); font-weight: 700;
  font-size: var(--fs-xs); letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted-light);
}
.infocard__v {
  font-family: var(--font-head); font-weight: 800;
  font-size: clamp(1.18rem, 2.4vw, 1.45rem);
  letter-spacing: -0.02em;
  color: var(--charcoal);
  font-style: normal;
}
.infocard__v--addr { font-size: clamp(1.02rem, 2vw, 1.15rem); line-height: 1.35; }
/* The email address is long — let it shrink and wrap rather than overflow. */
.infocard__v--mail {
  font-size: clamp(.86rem, 2.6vw, 1.06rem);
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}
.infocard__m { font-size: var(--fs-xs); color: var(--muted-light); }
.infocard .link-cta { margin-top: .5rem; }

.mapembed { aspect-ratio: 16 / 10; background: #DDE4EC; }
.mapembed iframe { width: 100%; height: 100%; border: 0; }

@media (min-width: 560px) { .field-row { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .contact__grid { grid-template-columns: 1.1fr .9fr; } }


/* ==========================================================================
   16  FOOTER
   ========================================================================== */
.footer { color: var(--off); padding-bottom: 2rem; }
.footer__grid { display: grid; gap: 2.5rem; }
.footer__brandcol .brand { margin-bottom: 1.2rem; }
.footer__blurb { font-size: var(--fs-sm); color: var(--muted-dark); max-width: 46ch; }
.footer__h {
  font-family: var(--font-head); font-weight: 800;
  font-size: var(--fs-xs); letter-spacing: .18em; text-transform: uppercase;
  color: var(--white);
  margin-bottom: 1rem;
  padding-bottom: .6rem;
  border-bottom: 1px solid rgba(245,247,250,.16);
}
.footer__nav ul { display: grid; gap: .55rem; }
.footer__nav a, .footer__contact address a {
  font-size: var(--fs-sm); color: var(--muted-dark); text-decoration: none;
}
.footer__nav a:hover, .footer__contact address a:hover { color: var(--orange); }
.footer__contact address { font-style: normal; margin-bottom: 1.2rem; line-height: 1.6; }
.footer__phone {
  font-family: var(--font-head); font-weight: 800;
  font-size: 1.3rem; color: var(--white); text-decoration: none;
  display: inline-block;
}
.footer__phone:hover { color: var(--orange); }
.footer__mail {
  font-size: var(--fs-sm); color: var(--muted-dark); text-decoration: none;
  overflow-wrap: anywhere;
}
.footer__mail:hover { color: var(--orange); }

.footer__bar {
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem;
  justify-content: space-between; align-items: center;
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding-top: 1.5rem;
  border-top: 1px solid rgba(245,247,250,.14);
  font-size: var(--fs-xs);
  color: var(--muted-dark);
}
.footer__bar p { margin: 0; }
.footer__privacy {
  background: none; border: 0; cursor: pointer;
  font-size: var(--fs-xs); color: var(--muted-dark);
  text-decoration: underline; text-underline-offset: 3px;
  /* Padding lifts the hit area to ~44px; the matching negative margin keeps
     the footer bar from growing because of it. */
  padding: .7rem .35rem;
  margin: -.7rem -.35rem;
}
.footer__privacy:hover { color: var(--orange); }
.footer__credit a { color: var(--orange); font-weight: 700; text-decoration: none; }
.footer__credit a:hover { text-decoration: underline; }

@media (min-width: 760px) {
  .footer__grid { grid-template-columns: 2fr 1fr 1.3fr; gap: 3rem; }
}


/* ==========================================================================
   17  PRIVACY MODAL
   ========================================================================== */
.modal {
  width: min(680px, calc(100vw - 2rem));
  max-height: min(84vh, 900px);
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
}
.modal::backdrop { background: rgba(9,11,14,.72); }
.modal__panel {
  background: var(--white);
  color: var(--charcoal);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  max-height: min(84vh, 900px);
  overflow-y: auto;
  position: relative;
  clip-path: polygon(0 var(--notch-rise), var(--notch) 0, 100% 0, 100% 100%, 0 100%);
}
.modal__panel h2 { color: var(--charcoal); margin-bottom: .3rem; padding-top: .6rem; }
.modal__panel h3 {
  font-size: 1rem; font-weight: 800; color: var(--deep);
  margin: 1.5rem 0 .4rem;
}
.modal__panel p { font-size: var(--fs-sm); color: var(--muted-light); }
.modal__panel a { color: var(--deep); font-weight: 600; }
.modal__close {
  position: absolute; top: .6rem; right: .8rem;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  font-size: 1.75rem; line-height: 1;
  background: none; border: 0; cursor: pointer;
  color: var(--muted-light);
}
.modal__close:hover { color: var(--charcoal); }
.modal__disclaimer {
  margin-top: 1.5rem;
  padding: .9rem 1.1rem;
  background: rgba(242,101,34,.09);
  border-left: 4px solid var(--orange);
  font-size: var(--fs-xs) !important;
}
.modal__actions { margin-top: 1.5rem; display: flex; justify-content: flex-end; }


/* ==========================================================================
   18  STICKY MOBILE ACTION BAR
   ========================================================================== */
.actionbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 100;
  display: flex; gap: 1px;
  background: rgba(245,247,250,.2);
  padding-bottom: env(safe-area-inset-bottom);
  transform: translateY(105%);
  transition: transform var(--t-mid) var(--ease);
}
.actionbar.is-visible { transform: translateY(0); }
.actionbar__btn {
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  padding: 1.05rem .5rem;
  font-family: var(--font-head); font-weight: 800;
  font-size: var(--fs-sm);
  text-align: center;
  text-decoration: none;
}
.actionbar__btn--call { background: var(--charcoal); color: var(--white); }
.actionbar__btn--cta  { background: var(--orange);   color: var(--charcoal); }
.actionbar__btn:active { filter: brightness(.9); }

/* Desktop has the header CTA and phone link, so the bar is mobile-only */
@media (min-width: 1100px) { .actionbar { display: none; } }
/* Keep the bar clear of the footer credit on small screens */
@media (max-width: 1099px) { .footer { padding-bottom: 5.5rem; } }


/* ==========================================================================
   19  REVEAL UTILITIES
   ========================================================================== */
/* Only hide content once JS is confirmed present, so a script failure can
   never leave the page blank. */
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
.js .reveal.is-in { opacity: 1; transform: none; }


/* ==========================================================================
   20  REDUCED MOTION
   Static end-states everywhere: no parallax, no scroll-linked colour, no
   pulsing, no reveal offsets.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  .js .reveal { opacity: 1 !important; transform: none !important; }

  /* Freeze the sky on a single legible gradient spanning the same story.
     First stop stays neutral so the hero matches the animated version. */
  .sky {
    background: linear-gradient(170deg, #0E0F11 0%, #1E2126 18%, #123A63 55%, #7FA9CE 100%);
  }

  .scroll-cue__dot { animation: none; opacity: 0; }
  .hero__layer { transform: none !important; }
  .actionbar { transition: none; }
  .svc:hover .svc__media img { transform: none; }
}
