/* ==========================================================================
   Caridi Painting & Finishing — stylesheet
   One file, no framework, no build step.

   Contents
   01. Tokens
   02. Reset & base
   03. Layout helpers
   04. Buttons & links
   05. Header / nav
   06. Hero + before/after slider
   07. Color chip strip
   08. Services
   09. Work gallery + lightbox
   10. Process
   11. Reviews
   12. Service area
   13. FAQ
   14. Estimate form
   15. Footer + mobile call bar
   16. Utility pages (404, thanks)
   17. Motion & print
   ========================================================================== */

/* 01. Tokens ------------------------------------------------------------- */
:root {
  /* Brand — sampled straight off the truck lettering.
     green-500 / navy-800 are the exact vinyl colors. The darker green-700 is
     used wherever white text sits on top of it, so it clears WCAG AA. */
  --green-700: #177a00;
  --green-500: #1c9000;
  --green-400: #5bc52e;
  --green-050: #eaf5e5;

  --navy-900: #0b1130;
  --navy-800: #141c4a;
  --navy-700: #24306b;
  --navy-050: #e8ebf4;

  /* Neutrals read cool, like primed drywall — not cream. */
  --paper: #eef1f5;
  --paper-2: #e3e8ef;
  --white: #ffffff;
  --ink: #12151c;
  --muted: #545c6a;
  --line: #d3d9e2;

  /* Colors pulled from actual Caridi projects (see tools/assets.py). */
  --job-navy: #30425e;
  --job-green: #35666e;
  --job-bronze: #5b554a;
  --job-white: #d1d8d6;
  --job-brick: #7e5442;

  /* Elevation. Three stacked layers each — a hairline contact shadow, a short
     ambient one and a long soft one — so a lifted surface reads as sitting in
     the light rather than having a grey blur pasted under it. Tinted navy, not
     black, so shadows sit in the same colour world as everything else. */
  --shadow-sm:
    0 1px 1px rgba(11, 17, 48, .04),
    0 2px 6px rgba(11, 17, 48, .05);
  --shadow-md:
    0 1px 1px rgba(11, 17, 48, .04),
    0 4px 10px rgba(11, 17, 48, .06),
    0 14px 30px rgba(11, 17, 48, .09);
  --shadow-lg:
    0 1px 2px rgba(11, 17, 48, .05),
    0 8px 20px rgba(11, 17, 48, .08),
    0 30px 60px rgba(11, 17, 48, .14);

  /* One radius family. The old 4px next to 10px read as two unrelated systems. */
  --radius-xs: 4px;
  --radius: 8px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-pill: 999px;

  /* Atmosphere: a barely-there wash used behind the hero and the navy blocks so
     large flat fills pick up some depth. Kept in tokens so the angle and the
     stop positions stay consistent wherever they are reused. */
  --wash-light:
    radial-gradient(70rem 40rem at 15% -10%, rgba(28, 144, 0, .06), transparent 60%),
    radial-gradient(55rem 35rem at 100% 0%, rgba(36, 48, 107, .07), transparent 62%);
  /* Both stops are anchored above the top edge, so a navy block fades back to
     flat --navy-800 by its foot. That lets one navy section butt straight up
     against another without a bright seam across the join. */
  --wash-navy:
    radial-gradient(60rem 38rem at 10% -25%, rgba(91, 197, 46, .11), transparent 60%),
    radial-gradient(75rem 45rem at 100% -15%, rgba(36, 48, 107, .60), transparent 62%);

  --container: 1180px;
  --gutter: clamp(1.15rem, 4vw, 2.5rem);
  --section-y: clamp(3.75rem, 8vw, 6.5rem);

  /* Type */
  --font-display: "Instrument Serif", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --font-label: "Cinzel", "Trajan Pro", Georgia, serif;
  --font-body: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --t-xs: .78rem;
  --t-sm: .9rem;
  --t-base: 1.0625rem;
  --t-md: 1.15rem;
  --t-lg: clamp(1.2rem, 1.6vw, 1.4rem);
  --t-h3: clamp(1.3rem, 2.2vw, 1.6rem);
  --t-h2: clamp(1.95rem, 4.2vw, 2.9rem);
  --t-h1: clamp(2.5rem, 6.4vw, 4.35rem);

  color-scheme: light;
}

/* 02. Reset & base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-base);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  margin: 0 0 .5em;
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -.015em;
  color: var(--navy-800);
  text-wrap: balance;
}

/* Display sizes need tighter tracking than text sizes — the same -.015em that
   looks right at 1.3rem looks loose at 4rem. */
h1 { font-size: var(--t-h1); letter-spacing: -.028em; }
h2 { font-size: var(--t-h2); letter-spacing: -.022em; }
h3 { font-size: var(--t-h3); line-height: 1.15; }
h4 { font-size: var(--t-md); font-family: var(--font-body); font-weight: 700; line-height: 1.35; letter-spacing: 0; }

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

ul, ol { margin: 0 0 1.1em; padding-left: 1.15em; }
li { margin-bottom: .4em; }

strong { font-weight: 700; }

hr { border: 0; border-top: 1px solid var(--line); margin: 2.5rem 0; }

::selection { background: var(--green-400); color: var(--navy-900); }

:focus-visible {
  outline: 3px solid var(--green-700);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute;
  left: 1rem;
  top: -100px;
  z-index: 200;
  padding: .7rem 1.1rem;
  background: var(--navy-800);
  color: var(--white);
  font-weight: 600;
  border-radius: var(--radius);
  transition: top .15s ease;
}
.skip-link:focus { top: 1rem; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* 03. Layout helpers ----------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section--paper2 { background: var(--paper-2); }
.section--white { background: var(--white); }
/* The wash keeps a full-bleed navy block from reading as one flat rectangle.
   Both stops stay at or below the base navy in luminance, so text contrast on
   this section can never come out worse than the tested --navy-800 pairing. */
.section--navy {
  position: relative;
  background-color: var(--navy-800);
  background-image: var(--wash-navy);
  color: #dfe4f0;
}
.section--navy h2, .section--navy h3 { color: var(--white); }

/* Small caps label, set with a short leading rule. The rule gives the label
   something to sit against so it reads as a deliberate mark rather than a line
   of stray capitals. Tracking is .13em, not .2em — at 12px the wider setting
   pushed this onto two ragged lines on a phone. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin-bottom: 1.1rem;
  font-family: var(--font-label);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: .13em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--green-700);
  text-wrap: balance;
}
.eyebrow::before {
  content: "";
  flex: none;
  width: 1.6rem;
  height: 2px;
  border-radius: var(--radius-pill);
  background: currentColor;
  opacity: .55;
}
.section--navy .eyebrow { color: var(--green-400); }

.section-head { max-width: 46rem; margin-bottom: clamp(2rem, 4vw, 3.25rem); }
.section-head p { font-size: var(--t-lg); color: var(--muted); line-height: 1.5; }
.section--navy .section-head p { color: #b9c2da; }

.lede { font-size: var(--t-lg); line-height: 1.55; color: var(--muted); }

/* Section mark. Two weights of the brand green rather than one flat bar, which
   gives it a direction and stops it reading as a stray rectangle. */
.rule {
  width: 56px; height: 5px;
  margin-bottom: 1.5rem;
  background: linear-gradient(90deg, var(--green-700), var(--green-400));
  border-radius: var(--radius-pill);
}
.section--navy .rule { background: linear-gradient(90deg, var(--green-400), var(--green-500)); }

/* 04. Buttons & links ---------------------------------------------------- */
a { color: var(--green-700); text-underline-offset: .18em; text-decoration-thickness: 1px; }
a:hover { color: var(--navy-800); }
.section--navy a { color: var(--green-400); }
.section--navy a:hover { color: var(--white); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .95rem 1.6rem;
  border: 2px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--t-base);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: .01em;
  text-decoration: none;
  cursor: pointer;
  transition: transform .12s ease, background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); transition-duration: .05s; }

/* The primary button carries a soft coloured glow rather than a neutral grey
   shadow, so the lift on hover looks lit from the button's own colour. */
.btn--primary {
  background: linear-gradient(180deg, var(--green-500), var(--green-700));
  border-color: var(--green-700);
  color: var(--white);
  box-shadow: 0 1px 1px rgba(11,17,48,.06), 0 4px 12px rgba(23,122,0,.22);
}
.btn--primary:hover {
  background: linear-gradient(180deg, #21a300, #16700a);
  border-color: #12630a;
  color: var(--white);
  box-shadow: 0 2px 4px rgba(11,17,48,.08), 0 10px 24px rgba(23,122,0,.30);
}

.btn--navy { background: var(--navy-800); border-color: var(--navy-800); color: var(--white); }
.btn--navy:hover { background: var(--navy-700); border-color: var(--navy-700); color: var(--white); }

.btn--outline { background: transparent; border-color: var(--navy-800); color: var(--navy-800); }
.btn--outline:hover { background: var(--navy-800); color: var(--white); }

.btn--ghost-light { background: transparent; border-color: rgba(255,255,255,.45); color: var(--white); }
.btn--ghost-light:hover { background: var(--white); border-color: var(--white); color: var(--navy-800); }

.btn--outline:hover { box-shadow: var(--shadow-md); }

.btn--lg { padding: 1.1rem 2rem; font-size: var(--t-md); }
.btn--block { width: 100%; }

.btn svg { width: 1.05em; height: 1.05em; flex: none; }

.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-weight: 700;
  font-size: var(--t-sm);
  letter-spacing: .01em;
  text-decoration: none;
}
.arrow-link::after { content: "→"; transition: transform .15s ease; }
.arrow-link:hover::after { transform: translateX(3px); }

/* 05. Header / nav ------------------------------------------------------- */
.topbar {
  background: var(--navy-900);
  color: #b8c1dc;
  font-size: var(--t-xs);
  letter-spacing: .02em;
}
.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 38px;
  padding-block: .35rem;
}
.topbar p { margin: 0; }
.topbar strong { color: var(--white); font-weight: 600; }
.topbar__right { display: flex; gap: 1.35rem; }
@media (max-width: 720px) { .topbar__right { display: none; } }

.site-header {
  position: sticky;
  top: 0;
  z-index: 90;
  background: rgba(255, 255, 255, .88);
  backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .2s ease, background-color .2s ease;
}
/* Once the page has moved under it, the bar earns a shadow. Driven by the
   sentinel that main.js already toggles for the nav; falls back to no shadow. */
.site-header[data-stuck="true"] {
  background: rgba(255, 255, 255, .95);
  box-shadow: 0 1px 0 rgba(11,17,48,.05), 0 6px 20px rgba(11,17,48,.08);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 78px;
  padding-block: .6rem;
}
.brand { flex: none; order: 1; line-height: 0; }
.brand img { width: clamp(158px, 22vw, 210px); }

.nav { order: 2; margin-left: auto; }
.nav ul { display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2rem); margin: 0; padding: 0; list-style: none; }
.nav li { margin: 0; }
.nav a {
  display: block;
  padding: .35rem 0;
  color: var(--navy-800);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: .02em;
  text-decoration: none;
  border-bottom: 2px solid transparent;
}
.nav a:hover { border-bottom-color: var(--green-500); }
.nav a[aria-current="page"] { border-bottom-color: var(--navy-800); }

.header-cta { flex: none; order: 3; }
.nav-toggle { display: none; }

@media (max-width: 900px) {
  .site-header__inner { min-height: 66px; gap: .75rem; }
  .header-cta .btn { padding: .7rem 1rem; font-size: var(--t-sm); }
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    order: 3;
    width: 44px; height: 44px;
    margin-left: auto;
    padding: 0;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--navy-800);
    cursor: pointer;
  }
  .nav {
    order: 4;
    width: 100%;
    margin-left: 0;
    display: none;
    border-top: 1px solid var(--line);
  }
  .nav[data-open="true"] { display: block; }
  .nav ul { flex-direction: column; align-items: stretch; gap: 0; padding-block: .5rem; }
  .nav a { padding: .85rem .25rem; border-bottom: 1px solid var(--line); }
  .nav li:last-child a { border-bottom: 0; }
  .nav a:hover, .nav a[aria-current="page"] { border-bottom-color: var(--line); color: var(--green-700); }
  .header-cta { margin-left: auto; order: 2; }
}
@media (max-width: 420px) {
  .header-cta .btn span { display: none; }
}

/* 06. Hero + before/after slider ----------------------------------------- */
.hero {
  position: relative;
  background: var(--white);
  background-image: var(--wash-light);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
/* The five job colours, banded along the foot of the hero like a fan deck.
   Kept as hard stops — it is a colour card, not a gradient. */
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 6px;
  background: linear-gradient(90deg,
    var(--job-navy) 0 20%, var(--job-green) 20% 40%, var(--job-bronze) 40% 60%,
    var(--job-brick) 60% 80%, var(--green-500) 80% 100%);
}
.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  padding-block: clamp(2.75rem, 6vw, 5.25rem);
}
.hero h1 { margin-bottom: .35em; text-wrap: balance; }
.hero h1 em { font-style: italic; color: var(--green-700); }
.hero__lede { font-size: var(--t-lg); color: var(--muted); max-width: 34rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 1.9rem; }

/* Proof strip. A two-column grid rather than a wrapping flex row so the four
   claims line up in a block instead of raggedly reflowing, and each one gets a
   figure/label pairing instead of a run-on sentence with a dot in front. */
.trust {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.25rem 1.5rem;
  margin-top: 2.1rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  list-style: none;
  padding-left: 0;
}
.trust li {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  margin: 0;
  font-size: var(--t-md);
  font-weight: 700;
  line-height: 1.15;
  color: var(--navy-800);
  letter-spacing: -.01em;
}
.trust span {
  font-size: var(--t-xs);
  font-weight: 500;
  line-height: 1.3;
  color: var(--muted);
  letter-spacing: .01em;
}

@media (max-width: 900px) {
  .hero__inner { grid-template-columns: 1fr; gap: 2.25rem; }
}
@media (max-width: 560px) {
  /* Both hero buttons go full width so they read as one stacked pair rather
     than two differently-sized shapes. */
  .hero__actions { gap: .65rem; }
  .hero__actions .btn { flex: 1 1 100%; }
  .trust { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem 1rem; }
}

/* Before / after slider */
.ba {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  background: var(--paper-2);
  touch-action: pan-y;
  --pos: 50%;
}
.ba__frame { position: relative; display: block; }
.ba__frame picture { display: block; }
.ba__frame img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.ba__before {
  position: absolute;
  inset: 0;
  clip-path: inset(0 calc(100% - var(--pos)) 0 0);
}
.ba__before picture { position: absolute; inset: 0; }
.ba__before img { width: 100%; height: 100%; }
.ba__divider {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--pos);
  width: 3px;
  margin-left: -1.5px;
  background: var(--white);
  box-shadow: 0 0 0 1px rgba(11,17,48,.25);
  pointer-events: none;
}
.ba__grip {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  background: var(--white);
  border-radius: 50%;
  box-shadow: var(--shadow-md);
  font-size: 15px;
  font-weight: 700;
  color: var(--navy-800);
  letter-spacing: -.08em;
}
.ba__frame { cursor: ew-resize; }
/* The range stays in the DOM as the keyboard and screen-reader control — it is
   still focusable and still fires `input` on arrow keys — but it no longer takes
   pointer events. Dragging is handled on .ba in main.js instead. Leaving the
   native input to handle touch did not work: iOS only drags a range when the
   gesture starts on the thumb, which here is an invisible 56px band, and any
   vertical component let the browser claim the swipe as a scroll. */
.ba__range {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  margin: 0;
  opacity: 0;
  pointer-events: none;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
.ba__range::-webkit-slider-thumb { -webkit-appearance: none; width: 56px; height: 100%; }
.ba__range::-moz-range-thumb { width: 56px; height: 100%; border: 0; background: transparent; }
.ba__range:focus-visible + .ba__divider { background: var(--green-400); box-shadow: 0 0 0 3px rgba(91,197,46,.6); }

.ba__tag {
  position: absolute;
  top: .85rem;
  padding: .32rem .7rem;
  background: rgba(11, 17, 48, .78);
  color: var(--white);
  font-family: var(--font-label);
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  border-radius: 2px;
  pointer-events: none;
}
.ba__tag--before { left: .85rem; }
.ba__tag--after { right: .85rem; }

.ba__readout {
  position: absolute;
  left: .85rem;
  bottom: .85rem;
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .5rem .85rem .5rem .55rem;
  background: rgba(255, 255, 255, .95);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  pointer-events: none;
}
.ba__swatch { width: 30px; height: 30px; border-radius: 3px; border: 1px solid rgba(11,17,48,.18); flex: none; transition: background-color .18s ease; }
.ba__readout-text { line-height: 1.15; }
.ba__readout-name { display: block; font-size: var(--t-sm); font-weight: 700; color: var(--navy-800); }
.ba__readout-hex { display: block; font-size: .72rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--muted); letter-spacing: .04em; }

.ba-caption {
  margin-top: .9rem;
  font-size: var(--t-sm);
  color: var(--muted);
}

/* 07. Color chip strip -------------------------------------------------- */
.chips { background: var(--white); border-block: 1px solid var(--line); }
.chips__inner { display: grid; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3rem); align-items: center; padding-block: clamp(2rem, 4vw, 2.75rem); }
.chips__intro p { margin: 0; font-size: var(--t-sm); color: var(--muted); }
.chips__intro .eyebrow { margin-bottom: .5rem; }
.chips__list { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .85rem; margin: 0; padding: 0; list-style: none; }
.chip { margin: 0; }

/* Each chip is a physical paint sample: a tall swatch with a slight sheen down
   it and a dark inner hairline, so a pale colour still has an edge against the
   white card instead of dissolving into it. */
.chip__swatch {
  display: block;
  height: clamp(64px, 8vw, 88px);
  border-radius: var(--radius);
  background-image: linear-gradient(160deg, rgba(255,255,255,.16), rgba(0,0,0,.09));
  box-shadow:
    inset 0 0 0 1px rgba(11,17,48,.13),
    0 1px 2px rgba(11,17,48,.06),
    0 6px 14px rgba(11,17,48,.07);
}
.chip__body { padding: .6rem .1rem 0; }
.chip__name { display: block; font-size: var(--t-sm); font-weight: 700; color: var(--navy-800); line-height: 1.2; }
.chip__hex { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .7rem; letter-spacing: .04em; color: var(--muted); }
.chip__note { display: block; font-size: .74rem; color: var(--muted); margin-top: .25rem; }

@media (max-width: 800px) {
  .chips__inner { grid-template-columns: 1fr; }
  /* Five chips across a phone left each one about 60px wide with the names
     colliding. Scroll them instead, at full size — the fifth sample sitting
     half-cut at the right edge is what says there is more to swipe to.
     Deliberately no negative-margin bleed here: the strip starts on the same
     line as the text above it, which matters more than running to the edge. */
  .chips__list {
    display: flex;
    gap: .75rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .chips__list::-webkit-scrollbar { display: none; }
  .chip { flex: 0 0 9.5rem; scroll-snap-align: start; }
  .chip__note { display: block; }
}

/* 07b. About ------------------------------------------------------------- */
.about { display: grid; grid-template-columns: minmax(0, 18rem) minmax(0, 1fr); gap: clamp(1.75rem, 4vw, 3.5rem); align-items: start; }
.about__intro h2 { margin-bottom: 1.1rem; }
.about__credits { display: flex; flex-direction: column; gap: .55rem; margin: 0; padding: 0; list-style: none; }
.about__credits li {
  position: relative;
  margin: 0;
  padding-left: 1.4rem;
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--navy-800);
  line-height: 1.35;
}
.about__credits li::before {
  content: "";
  position: absolute;
  left: 0; top: .45em;
  width: 8px; height: 8px;
  background: var(--green-500);
  border-radius: 50%;
}
/* Decal photos. The two decals are different shapes, so each sits in a frame of
   a fixed height and is contained inside it — that lines them up on a common
   baseline instead of letting the tall BBB sticker tower over the Angi one. */
.about__badges { display: flex; flex-wrap: wrap; gap: 1rem; margin: 1.75rem 0 0; padding: 0; list-style: none; }
.badge { margin: 0; }
.badge__link { display: block; text-decoration: none; color: inherit; }
.badge__frame {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 8rem;
  height: 8rem;
  padding: .5rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
/* display:contents makes the <img> itself the flex item, so its max-height
   resolves against the frame instead of against an auto-height <picture>. */
.badge__frame picture { display: contents; }
.badge__frame img { max-width: 100%; max-height: 100%; width: auto; height: auto; min-height: 0; }
.badge__link:hover .badge__frame { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: #c2cad8; }
.badge__caption {
  display: block;
  max-width: 8rem;
  margin-top: .45rem;
  font-size: .72rem;
  line-height: 1.3;
  color: var(--muted);
}
.badge__link:hover .badge__caption { color: var(--green-700); }

.about__body > * + * { margin-top: 1rem; }
.about__body p { max-width: 40rem; }
.about__sign { font-size: var(--t-sm); color: var(--muted); }
.about__sign strong { color: var(--ink); }
@media (max-width: 800px) {
  .about { grid-template-columns: 1fr; }
  .about__credits { flex-direction: row; flex-wrap: wrap; column-gap: 1.25rem; }
}

/* 08. Services ----------------------------------------------------------- */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr)); gap: clamp(1rem, 2vw, 1.5rem); }

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.75rem 1.6rem 1.6rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
/* The accent bar is the service's own colour. It stays a hairline at rest and
   thickens on hover, so the card answers the pointer without moving anything
   the eye is trying to read. */
.card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: var(--accent, var(--green-500));
  transition: height .18s ease;
}
/* A soft tint of the accent bleeds down from the top edge on hover. */
.card::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 40%;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: linear-gradient(180deg, var(--accent, var(--green-500)), transparent);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s ease;
}
.card > * { position: relative; }
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: #c6cedc; }
.card:hover::before { height: 7px; }
.card:hover::after { opacity: .07; }
.card h3 { margin-bottom: .5rem; }
.card p { color: var(--muted); font-size: var(--t-sm); line-height: 1.6; }
.card ul { margin: 0 0 1.25rem; padding-left: 1.1rem; font-size: var(--t-sm); color: var(--muted); }
.card ul li::marker { color: var(--green-500); }
.card .arrow-link { margin-top: auto; }

/* 09. Work gallery + lightbox -------------------------------------------- */
.work-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); gap: clamp(.85rem, 1.6vw, 1.25rem); }
.work-item {
  position: relative;
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--paper-2);
  box-shadow: var(--shadow-sm);
}
.work-item button {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  color: inherit;
  text-align: left;
}
.work-item:hover { box-shadow: var(--shadow-md); }
.work-item picture { display: block; }
.work-item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; transition: transform .5s cubic-bezier(.2,.7,.3,1); }
.work-item:hover img { transform: scale(1.045); }
/* A two-stop scrim: most of the darkening happens in the bottom third where the
   text actually sits, so the photo above it is not needlessly dimmed. */
.work-item figcaption {
  position: absolute;
  inset: auto 0 0 0;
  padding: 3rem .95rem .9rem;
  background: linear-gradient(to top,
    rgba(9, 14, 40, .92) 0%,
    rgba(9, 14, 40, .70) 32%,
    rgba(9, 14, 40, .22) 66%,
    rgba(9, 14, 40, 0) 100%);
  color: var(--white);
  font-size: var(--t-sm);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -.005em;
  pointer-events: none;
}
.work-item figcaption span { display: block; font-weight: 400; font-size: .78rem; color: #ccd4ea; margin-top: .2rem; }
/* Focus has to be visible on the button inside the clipped, rounded figure. */
.work-item button:focus-visible { outline: 3px solid var(--green-400); outline-offset: -3px; border-radius: var(--radius-lg); }

dialog.lightbox {
  width: min(94vw, 60rem);
  max-width: 94vw;
  padding: 0;
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--navy-900);
  color: var(--white);
  box-shadow: var(--shadow-lg);
}
dialog.lightbox::backdrop { background: rgba(6, 10, 28, .84); }
.lightbox__img { width: 100%; max-height: 76vh; object-fit: contain; background: #05081a; }
.lightbox__bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .85rem 1rem; }
.lightbox__caption { font-size: var(--t-sm); line-height: 1.35; }
.lightbox__caption span { display: block; color: #a9b3d0; font-size: .78rem; }
.lightbox__nav { display: flex; gap: .4rem; flex: none; }
.lightbox__btn {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: var(--radius);
  color: var(--white);
  font-size: 1.1rem;
  cursor: pointer;
}
.lightbox__btn:hover { background: rgba(255,255,255,.2); }

/* 10. Process ------------------------------------------------------------ */
.steps { counter-reset: step; display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
/* A hairline rail runs down the numeral column, from just under each numeral to
   the foot of its own step. Painted as a background on the step rather than a
   fixed-height pseudo-element, so it stretches with however much copy a step
   carries instead of guessing the gap and dangling short. */
.step {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 2rem);
  align-items: start;
  margin: 0;
  padding: 1.75rem 0;
  border-top: 1px solid rgba(255,255,255,.16);
  background-image: linear-gradient(to bottom,
    transparent 0 4.7rem,
    rgba(91,197,46,.40) 4.7rem,
    rgba(255,255,255,.08) 100%);
  background-size: 1px 100%;
  background-position: 1.15rem 0;
  background-repeat: no-repeat;
}
.step:last-child { border-bottom: 1px solid rgba(255,255,255,.16); background-image: none; }
.step__num {
  font-family: var(--font-display);
  font-size: 2.6rem;
  line-height: 1;
  color: var(--green-400);
  letter-spacing: -.03em;
}
.step h3 { margin-bottom: .35rem; }
.step p { margin: 0; color: #b9c2da; font-size: var(--t-sm); line-height: 1.6; max-width: 46rem; }
@media (max-width: 600px) {
  /* Single column on a phone — no gutter left for the rail to run down. */
  .step { grid-template-columns: 1fr; gap: .35rem; background-image: none; }
  .step__num { font-size: 1.7rem; }
}

/* 11. Reviews ------------------------------------------------------------ */
.reviews { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17.5rem), 1fr)); gap: clamp(1rem, 2vw, 1.5rem); }
.review {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .9rem;
  margin: 0;
  padding: 1.7rem 1.6rem 1.6rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 4px solid var(--green-500);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform .16s ease, box-shadow .16s ease;
}
.review:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
/* An oversized quote mark, set very pale in the top corner. It reads as texture
   behind the quotation rather than as a character to be read. */
.review::before {
  content: "\201C";
  position: absolute;
  top: .55rem;
  right: .85rem;
  font-family: var(--font-display);
  font-size: 4.5rem;
  line-height: .8;
  color: var(--green-700);
  opacity: .09;
  pointer-events: none;
}
.review blockquote { position: relative; margin: 0; font-family: var(--font-display); font-size: 1.32rem; line-height: 1.32; color: var(--navy-800); }
.review figcaption { margin-top: auto; font-size: var(--t-sm); color: var(--muted); }
.review figcaption strong { display: block; color: var(--ink); font-size: var(--t-base); }
.stars { color: var(--green-700); letter-spacing: .12em; font-size: .85rem; }

.rating-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem 2.5rem;
  padding: 1.4rem 1.6rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  margin-bottom: 2.25rem;
}
.rating-summary__score { font-family: var(--font-display); font-size: 3rem; line-height: 1; color: var(--navy-800); }
.rating-summary div p { margin: 0; font-size: var(--t-sm); color: var(--muted); }

/* 12. Service area ------------------------------------------------------- */
.area { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: clamp(1.75rem, 4vw, 3.5rem); align-items: start; }
.area__list { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; padding: 0; list-style: none; }
.area__list li { margin: 0; }
.area__list span {
  display: block;
  padding: .45rem .9rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--navy-800);
  box-shadow: var(--shadow-sm);
}
@media (max-width: 800px) { .area { grid-template-columns: 1fr; } }

/* 13. FAQ ---------------------------------------------------------------- */
.faq { max-width: 52rem; }
.faq details {
  border-bottom: 1px solid var(--line);
  padding: .35rem 0;
  transition: background-color .18s ease;
}
.faq details[open] { background: linear-gradient(180deg, rgba(255,255,255,.7), transparent); }
.faq summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.05rem 0;
  font-size: var(--t-md);
  font-weight: 700;
  color: var(--navy-800);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  flex: none;
  font-family: var(--font-display);
  font-size: 1.6rem;
  line-height: 1;
  color: var(--green-700);
  transition: transform .18s ease;
}
.faq details[open] summary::after { content: "–"; }
.faq summary:hover { color: var(--green-700); }
.faq__answer { padding: 0 0 1.35rem; color: var(--muted); max-width: 46rem; }
.faq__answer p { font-size: var(--t-sm); line-height: 1.65; }

/* 14. Estimate form ------------------------------------------------------ */
.estimate { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: clamp(2rem, 5vw, 4rem); align-items: start; }
@media (max-width: 900px) { .estimate { grid-template-columns: 1fr; } }

.estimate__side ul { list-style: none; padding: 0; margin: 1.5rem 0 0; }
.estimate__side li { display: flex; gap: .7rem; margin-bottom: .85rem; font-size: var(--t-sm); color: #c3cbe2; }
.estimate__side li::before { content: "✓"; color: var(--green-400); font-weight: 700; flex: none; }
.estimate__phone {
  display: inline-flex;
  align-items: center;
  gap: .65rem;
  margin-top: 1.75rem;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.6vw, 2.5rem);
  line-height: 1.1;
  color: var(--white);
  text-decoration: none;
  letter-spacing: -.01em;
  white-space: nowrap;
}
/* Only `.btn svg` was ever given a size, so the icon in this link fell back to
   the default replaced-element box — a 300px-wide phone that shoved the number
   onto three lines. Sized here in em so it tracks the number beside it. */
.estimate__phone svg {
  width: .78em;
  height: .78em;
  flex: none;
  color: var(--green-400);
  stroke-width: 2.2;
}
/* `.section--navy a` (0,1,1) outranked the plain `.estimate__phone` (0,1,0), so
   the number came out green and the hover state changed nothing. Matching that
   specificity puts the number back to white and gives the hover somewhere to go. */
.section--navy a.estimate__phone { color: var(--white); }
.section--navy a.estimate__phone:hover { color: var(--green-400); }

.form-card {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem; }
.field { display: flex; flex-direction: column; gap: .35rem; }
.field--full { grid-column: 1 / -1; }
@media (max-width: 560px) { .form-grid { grid-template-columns: 1fr; } }

.field label { font-size: var(--t-sm); font-weight: 700; color: var(--navy-800); }
.field label .opt { font-weight: 400; color: var(--muted); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: .85rem .9rem;
  font-family: inherit;
  font-size: var(--t-base);
  color: var(--ink);
  background: #fbfcfd;
  border: 1px solid #b9c2d0;
  border-radius: var(--radius);
  box-shadow: inset 0 1px 2px rgba(11,17,48,.05);
  transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: #9aa5b8; }
.field textarea { min-height: 7.5rem; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  background: var(--white);
  border-color: var(--green-700);
  box-shadow: 0 0 0 3px rgba(23, 122, 0, .18);
}
.field input[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"] {
  border-color: #b3261e;
  box-shadow: 0 0 0 3px rgba(179, 38, 30, .14);
}
.field .error { min-height: 1.1rem; font-size: var(--t-xs); font-weight: 600; color: #b3261e; }
.field .error:empty { min-height: 0; }

.form-note { margin-top: 1rem; font-size: var(--t-xs); color: var(--muted); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-status {
  margin-top: 1rem;
  padding: .9rem 1rem;
  border-radius: var(--radius);
  font-size: var(--t-sm);
  font-weight: 600;
}
.form-status[hidden] { display: none; }
.form-status--ok { background: var(--green-050); color: #10570a; border: 1px solid #b7dfa9; }
.form-status--err { background: #fdecea; color: #8c1d18; border: 1px solid #f2b8b5; }

/* 15. Footer + mobile call bar ------------------------------------------- */
/* Darkening-only wash. --green-700 was picked as the lightest green that still
   clears AA against white text, so any stop that lightens it breaks the button
   band — a green-400 glow here dropped white to 4.12:1. Shading toward navy
   instead can only improve contrast, and still gives the band a light source. */
.cta-band {
  position: relative;
  background-color: var(--green-700);
  background-image:
    radial-gradient(48rem 30rem at 100% 120%, rgba(11,17,48,.30), transparent 62%),
    radial-gradient(42rem 26rem at 0% -20%, rgba(11,17,48,.10), transparent 60%);
  color: var(--white);
}
.cta-band__inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1.5rem; padding-block: clamp(2.25rem, 5vw, 3.25rem); }
.cta-band h2 { color: var(--white); margin: 0; max-width: 28ch; }
.cta-band p { margin: .45rem 0 0; color: #dbf3d2; font-size: var(--t-sm); }
.cta-band .btn--ghost-light { border-color: rgba(255,255,255,.75); }

.site-footer {
  background-color: var(--navy-900);
  background-image: radial-gradient(50rem 30rem at 10% 0%, rgba(36,48,107,.45), transparent 62%);
  color: #a7b1cf;
  font-size: var(--t-sm);
}
.site-footer__inner { display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); gap: clamp(1.75rem, 4vw, 3rem); padding-block: clamp(2.75rem, 6vw, 4rem); }
@media (max-width: 860px) { .site-footer__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .site-footer__inner { grid-template-columns: 1fr; } }

.site-footer img { width: 190px; margin-bottom: 1.1rem; }
.site-footer h2 {
  margin-bottom: .9rem;
  font-family: var(--font-label);
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--white);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: .55rem; }
.site-footer a { color: #c3cbe2; text-decoration: none; }
.site-footer a:hover { color: var(--white); text-decoration: underline; }
.site-footer address { font-style: normal; line-height: 1.7; }

.site-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.5rem;
  justify-content: space-between;
  padding-block: 1.15rem;
  border-top: 1px solid rgba(255,255,255,.12);
  font-size: var(--t-xs);
  color: #8a95b8;
}
.site-footer__bottom p { margin: 0; }

.call-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 80;
  display: none;
  gap: .5rem;
  padding: .55rem .75rem calc(.55rem + env(safe-area-inset-bottom));
  background: rgba(255,255,255,.97);
  border-top: 1px solid var(--line);
  box-shadow: 0 -6px 20px rgba(11,17,48,.10);
}
.call-bar .btn { flex: 1; padding: .9rem .75rem; font-size: var(--t-sm); }
@media (max-width: 760px) {
  .call-bar { display: flex; }
  body { padding-bottom: 4.6rem; }
  /* The bar floats over the page, so the last section needs clearance or its
     final line sits underneath it. */
  .site-footer__bottom { padding-bottom: 1.6rem; }
}

/* 16. Utility pages ------------------------------------------------------ */
.page-head { background-color: var(--navy-800); background-image: var(--wash-navy); color: #cdd5ea; }
/* On the contact page a navy section sits directly under the navy page head.
   Two stacked washes put a visible seam across the join, so the second one
   drops its wash and the pair reads as a single field of colour. */
.page-head + .section--navy { background-image: none; }
.page-head__inner { padding-block: clamp(2.75rem, 6vw, 4.5rem); max-width: 48rem; }
.page-head h1 { color: var(--white); margin-bottom: .3em; }
.page-head p { font-size: var(--t-lg); color: #b9c2da; margin: 0; }
.breadcrumbs { margin-bottom: 1.35rem; font-size: var(--t-xs); letter-spacing: .04em; }
.breadcrumbs ol { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; margin: 0; padding: 0; }
.breadcrumbs li { margin: 0; color: #94a0c4; }
.breadcrumbs li + li::before { content: "/"; margin-right: .4rem; color: #5c6892; }
.breadcrumbs a { color: #c3cbe2; text-decoration: none; }
.breadcrumbs a:hover { color: var(--white); text-decoration: underline; }

.prose { max-width: 44rem; }
.prose h2 { margin-top: 2.5rem; }
.prose h3 { margin-top: 1.9rem; }
.prose ul li::marker { color: var(--green-500); }

.split { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4rem); align-items: start; }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; } }

.aside-card {
  padding: 1.5rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 4px solid var(--green-500);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.aside-card h3 { font-size: var(--t-h3); margin-bottom: .6rem; }
.aside-card p { font-size: var(--t-sm); color: var(--muted); }
.aside-card picture { display: block; }
.aside-card img { border-radius: var(--radius); }
.aside-card .btn { margin-top: .4rem; }

.centered { max-width: 40rem; margin-inline: auto; text-align: center; padding-block: clamp(3.5rem, 10vw, 7rem); }
.centered .btn { margin-top: .5rem; }
.centered .hero__actions { justify-content: center; }

/* 17. Motion & print ----------------------------------------------------- */
[data-reveal] { opacity: 0; transform: translateY(14px); }
[data-reveal].is-visible { opacity: 1; transform: none; transition: opacity .55s ease, transform .55s cubic-bezier(.2,.7,.3,1); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
}

@media print {
  .site-header, .call-bar, .cta-band, .nav-toggle, .topbar, dialog { display: none !important; }
  body { background: #fff; color: #000; padding-bottom: 0; }
  .section { padding-block: 1.25rem; }
  a::after { content: " (" attr(href) ")"; font-size: .75em; word-break: break-all; }
}
