/* =========================================================================
   Chaney's Pressure Washing & Soft Wash
   Brand system: Electric Blue #087BFF · Deep Blue #0047B8 · Jet Black #080A0D
                 Bright White #FFFFFF · Chrome Silver #C9D2DC · Soft Ice #DCEEFF
   Headlines: Barlow Condensed ExtraBold · Body: Inter
   ========================================================================= */

/* ---------- Fonts (self-hosted, latin subset) ---------- */
@font-face {
  font-family: 'Barlow Condensed';
  src: url('../fonts/barlow-condensed-800-latin.woff2') format('woff2');
  font-weight: 800; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-var-latin.woff2') format('woff2');
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Tokens ---------- */
:root {
  --electric: #087BFF;
  --deep:     #0047B8;
  --jet:      #080A0D;
  --white:    #FFFFFF;
  --chrome:   #C9D2DC;
  --ice:      #DCEEFF;

  --jet-2:    #0E1218;   /* raised surface on black */
  --jet-3:    #161C25;   /* border on black */
  --ink:      #10151C;   /* body text on light */
  --ink-mid:  #4A5563;   /* secondary text on light */
  --line:     #DCE3EB;   /* hairline on light */

  --font-head: 'Barlow Condensed', 'Arial Narrow', Impact, sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  --wrap: 1180px;
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --pad-y: clamp(3.5rem, 9vw, 6.5rem);
  --radius: 14px;
  --shadow: 0 18px 44px rgba(8, 10, 13, .12);
  --shadow-dark: 0 18px 44px rgba(0, 0, 0, .5);
  --ring: 0 0 0 3px #080A0D, 0 0 0 6px var(--electric);
  --bar-h: 0px; /* height of the sticky mobile bar; set at breakpoint */
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  padding-bottom: var(--bar-h);
  overflow-x: hidden;
}
img, svg { max-width: 100%; }
img { height: auto; display: block; }
a { color: var(--deep); }
h1, h2, h3 {
  font-family: var(--font-head);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: .005em;
  text-transform: uppercase;
  margin: 0;
}
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- Shared layout ---------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }

/* Keep jump-link targets clear of the sticky header */
:where(#top, #services, #gallery, #about, #process, #reviews, #leave-review, #contact) { scroll-margin-top: 88px; }

.center { text-align: center; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ico { width: 1.15em; height: 1.15em; fill: currentColor; flex: none; }

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

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--electric);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--font-head); font-size: 1.15rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .03em; line-height: 1;
  padding: .95rem 1.5rem; border-radius: 10px; border: 2px solid transparent;
  text-decoration: none; cursor: pointer;
  transition: background-color .16s ease, border-color .16s ease, color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.btn:active { transform: translateY(1px); }
.btn .ico { width: 1.05em; height: 1.05em; }

.btn-primary {
  background: var(--deep); color: var(--white);
  border-color: var(--electric);
  box-shadow: 0 0 0 1px rgba(8,123,255,.35), 0 8px 20px rgba(0,71,184,.3);
}
.btn-primary:hover { background: var(--electric); box-shadow: 0 0 0 1px rgba(8,123,255,.5), 0 10px 26px rgba(8,123,255,.4); }

.btn-ghost { background: transparent; color: var(--white); border-color: var(--chrome); }
.btn-ghost:hover { border-color: var(--electric); background: rgba(8,123,255,.14); }

/* ghost button placed on a light background */
.section:not(.section-dark) .btn-ghost,
.section-ice .btn-ghost { color: var(--ink); border-color: #A9B6C6; }
.section:not(.section-dark) .btn-ghost:hover,
.section-ice .btn-ghost:hover { color: var(--deep); border-color: var(--deep); background: rgba(8,123,255,.1); }

.btn-sm { font-size: .95rem; padding: .62rem 1rem; border-radius: 8px; }
.btn-lg { font-size: 1.25rem; padding: 1.05rem 1.75rem; }
.btn-block { width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; }
.center-row { justify-content: center; }

/* ---------- Eyebrow ---------- */
.eyebrow {
  display: flex; align-items: center; gap: .7rem;
  font-family: var(--font-head); font-size: 1.05rem; font-weight: 800;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--electric); margin-bottom: .75rem;
}
.eyebrow-rule { width: 34px; height: 3px; background: var(--electric); border-radius: 2px; }

/* =========================================================================
   HEADER
   ========================================================================= */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(8, 10, 13, .96);
  border-bottom: 1px solid var(--jet-3);
  backdrop-filter: saturate(140%) blur(8px);
}
.site-header.is-stuck { box-shadow: 0 10px 30px rgba(0,0,0,.45); }
.header-inner { display: flex; align-items: center; gap: 1rem; min-height: 68px; }

.brand { display: block; margin-right: auto; line-height: 0; }
.brand img { width: clamp(158px, 30vw, 232px); height: auto; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: none;
  background: transparent; border: 1px solid var(--jet-3); border-radius: 9px;
  color: var(--white); cursor: pointer; padding: 0;
}
.icon-btn:hover { border-color: var(--electric); color: var(--electric); }
.icon-btn .ico { width: 20px; height: 20px; }

.bars, .bars::before, .bars::after {
  display: block; width: 19px; height: 2px; background: currentColor; border-radius: 2px;
  transition: transform .2s ease, opacity .15s ease;
}
.bars { position: relative; }
.bars::before, .bars::after { content: ''; position: absolute; left: 0; }
.bars::before { top: -6px; }
.bars::after  { top: 6px; }
[aria-expanded="true"] .bars { background: transparent; }
[aria-expanded="true"] .bars::before { transform: translateY(6px) rotate(45deg); }
[aria-expanded="true"] .bars::after  { transform: translateY(-6px) rotate(-45deg); }

/* mobile drawer */
.nav {
  position: fixed; inset: 68px 0 auto 0; z-index: 99;
  background: var(--jet); border-bottom: 1px solid var(--jet-3);
  padding: .5rem var(--gutter) 1.5rem;
  transform: translateY(-115%); visibility: hidden;
  transition: transform .28s cubic-bezier(.4,0,.2,1), visibility .28s;
}
.nav.is-open { transform: translateY(0); visibility: visible; }
.nav-list { display: grid; }
.nav-list a {
  display: block; padding: .95rem .25rem;
  font-family: var(--font-head); font-size: 1.4rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--white); text-decoration: none; border-bottom: 1px solid var(--jet-3);
}
.nav-list a:hover { color: var(--electric); }
.nav-cta { display: grid; gap: .6rem; margin-top: 1.15rem; }
.nav-cta .btn { font-size: 1.1rem; padding: .85rem 1rem; }

.nav-scrim { position: fixed; inset: 0; z-index: 98; background: rgba(8,10,13,.6); }

/* =========================================================================
   HERO
   ========================================================================= */
.hero { position: relative; background: var(--jet); color: var(--white); overflow: hidden; }
/* The hero's only motion lives on these two decorative layers, and it is
   deliberately slow enough that you notice the hero feels alive without ever
   catching it moving. Nothing here touches the h1 or the photo: the photo is
   the LCP element on a page that will be taking paid traffic, so it is left
   strictly alone. Both layers are already scaled up a touch, so drifting them
   can never pull an edge into frame. */
.hero-bg {
  position: absolute; inset: 0;
  background:
    radial-gradient(60% 70% at 78% 34%, rgba(8,123,255,.30), transparent 70%),
    radial-gradient(50% 60% at 6% 92%, rgba(0,71,184,.26), transparent 72%);
  transform: scale(1.08);
  animation: heroDrift 26s ease-in-out infinite;
  will-change: transform;
}
/* faint water arc, drawn not photographed */
.hero-bg::after {
  content: ''; position: absolute; inset: -6%;
  background-image:
    radial-gradient(circle at 50% 140%, transparent 58%, rgba(201,210,220,.07) 58.4%, transparent 59.4%),
    radial-gradient(circle at 50% 150%, transparent 62%, rgba(8,123,255,.10) 62.4%, transparent 63.6%);
  animation: heroArc 34s ease-in-out infinite;
  will-change: transform;
}
/* Offset periods (26s vs 34s) so the two never fall into step and start
   reading as one repeating loop. */
@keyframes heroDrift {
  0%, 100% { transform: scale(1.08) translate3d(0, 0, 0); }
  50%      { transform: scale(1.13) translate3d(-1.6%, 1.2%, 0); }
}
@keyframes heroArc {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
  50%      { transform: translate3d(1.4%, -1%, 0) rotate(1.1deg); }
}
.hero-inner {
  position: relative; z-index: 1;
  display: grid; gap: clamp(2rem, 5vw, 3rem);
  padding-top: clamp(2.75rem, 8vw, 5rem);
  padding-bottom: clamp(4.5rem, 10vw, 7rem);
}
.hero h1 {
  font-size: clamp(2.65rem, 8.4vw, 4.6rem);
  margin-bottom: 1.1rem;
  text-shadow: 0 2px 24px rgba(0,0,0,.5);
}
/* A glint travels across the two headline words every few seconds — light
   catching a wet surface, not a wash. Deliberately NOT the nozzle sweep from
   #leave-review: that gag is the payoff down the page, and spending it up here
   would make the review CTA read as a rerun.

   Guarded by @supports because background-clip:text needs a transparent fill,
   and a browser without it would render the headline invisible. Plain electric
   blue is the fallback and the resting state. */
.hero h1 .hl { color: var(--electric); }

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero h1 .hl {
    /* THREE layers, painted back to front. The last one is a SOLID sheet of
       electric blue covering the whole box, and it is the safety net: because
       something always covers every glyph, no combination of the moving layers
       above it can leave a letter unpainted. background-clip:text fails
       destructively — an uncovered glyph paints nothing and disappears — and an
       earlier version of this lost the first six letters of "Pressure" that
       way. The base layer makes that failure mode impossible rather than
       merely avoided.

       The two bands above it travel in OPPOSITE directions and meet near the
       middle of the phrase, so the highlight builds to one bright crossing and
       separates again — light moving over a wet surface, rather than a single
       flat wipe. */
    background-image:
      linear-gradient(100deg, transparent 38%, rgba(255,255,255,.62) 50%, transparent 62%),
      linear-gradient(78deg,  transparent 34%, rgba(168,211,255,.55) 50%, transparent 66%),
      linear-gradient(var(--electric), var(--electric));
    background-size: 300% 100%, 250% 100%, 100% 100%;
    background-position: 100% 0, 0% 0, 0 0;
    background-repeat: repeat, repeat, repeat;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    animation: hlGlint 9s ease-in-out 1.6s infinite;
  }
}
/* The pass happens in the first 40%, then the phrase rests as solid blue for
   the rest of the cycle. Something moving permanently on top of the most
   important sentence on the site is a distraction, not a flourish. */
@keyframes hlGlint {
  0%        { background-position: 100% 0, 0% 0, 0 0; }
  40%, 100% { background-position: 0% 0, 100% 0, 0 0; }
}
.hero-lead {
  font-size: clamp(1.06rem, 3.2vw, 1.28rem); font-weight: 600;
  color: var(--white); margin-bottom: .4rem;
  border-left: 3px solid var(--electric); padding-left: .85rem;
}
.hero-sub { font-size: clamp(1rem, 3vw, 1.12rem); color: var(--chrome); margin-bottom: 1.5rem; }

.pill-row { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: 1.9rem; }
.pill {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .9rem; font-weight: 600; color: var(--white);
  background: rgba(255,255,255,.05); border: 1px solid var(--jet-3);
  border-radius: 100px; padding: .5rem .95rem;
}
.pill .ico { color: var(--electric); width: 1.05rem; height: 1.05rem; }

.hero-visual { display: flex; justify-content: center; }
.hero-emblem { width: min(100%, 420px); filter: drop-shadow(0 22px 50px rgba(0,0,0,.7)); }

/* Hero job photo. Chrome hairline + deep shadow keeps it feeling deliberate
   against the dark hero rather than pasted on. */
.hero-shot {
  position: relative; margin: 0; width: min(100%, 440px);
  border-radius: var(--radius); overflow: hidden;
  border: 1px solid rgba(201,210,220,.35);
  box-shadow: 0 26px 60px rgba(0,0,0,.6);
}
.hero-shot img { display: block; width: 100%; height: auto; }
.hero-shot-cap {
  position: absolute; inset: auto 0 0 0;
  display: flex; align-items: center; gap: .5rem;
  padding: 1.6rem .95rem .8rem;
  font-size: .84rem; font-weight: 600; color: var(--white);
  background: linear-gradient(to top, rgba(8,10,13,.92), rgba(8,10,13,0));
}
.hero-shot-cap .ico { width: 1rem; height: 1rem; color: var(--electric); flex: none; }

.wave { display: block; width: 100%; height: clamp(40px, 6vw, 76px); margin-top: -1px; fill: var(--white); position: relative; z-index: 1; }

/* =========================================================================
   TRUST BAR
   ========================================================================= */
.trustbar { background: var(--white); padding-bottom: clamp(1rem, 3vw, 1.5rem); }
.trust-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: .75rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--ice); padding: 1.1rem;
}
.trust-grid li { display: flex; align-items: center; gap: .7rem; }
.trust-grid .ico { width: 1.9rem; height: 1.9rem; color: var(--deep); }
.trust-grid span { display: grid; font-size: .85rem; line-height: 1.3; color: var(--ink-mid); }
.trust-grid strong {
  font-family: var(--font-head); font-size: 1.15rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .01em; color: var(--ink);
}

/* =========================================================================
   SECTIONS
   ========================================================================= */
.section { padding-block: var(--pad-y); }
.section-ice { background: var(--ice); }
.section-dark { background: var(--jet); color: var(--white); }
.section-dark h2, .section-dark h3 { color: var(--white); }
.section-dark p { color: var(--chrome); }

.section-head { max-width: 62ch; margin-bottom: clamp(2rem, 5vw, 3rem); }
.section-head h2 { font-size: clamp(2.05rem, 6vw, 3.05rem); }
.section-intro { margin-top: 1rem; color: var(--ink-mid); font-size: 1.03rem; }
.section-dark .section-intro { color: var(--chrome); }
.section-intro strong { color: var(--ink); }
.section-dark .section-intro strong { color: var(--white); }
.section-foot { margin-top: 2rem; color: var(--ink-mid); }

/* ---------- Service cards ---------- */
.card-grid { display: grid; gap: 1rem; }
.card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.6rem 1.4rem;
  border-top: 4px solid var(--electric);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.card-ico { width: 2.4rem; height: 2.4rem; fill: var(--deep); margin-bottom: .85rem; }
.card h3 { font-size: 1.5rem; margin-bottom: .5rem; }
.card p { color: var(--ink-mid); font-size: .97rem; }
.section-ice .card { border-color: #C4D8EE; }

/* ---------- Before & After ---------- */
.gallery { display: grid; gap: 1.35rem; }
/* While only one project is live, don't leave a dead column beside it.
   Self-correcting: uncomment another tile in index.html and the grid goes
   back to two columns on its own, with no CSS change needed. */
.gallery:has(> .ba-card:only-child) {
  grid-template-columns: minmax(0, 46rem);
  justify-content: center;
}
.ba-card {
  margin: 0; background: var(--white); border: 1px solid #C4D8EE;
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
}
.ba-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; background: var(--chrome); }
.ba-shot { position: relative; background: var(--jet); }
.ba-shot img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.ba-tag {
  position: absolute; top: .6rem; left: .6rem;
  font-family: var(--font-head); font-size: .92rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .08em; color: var(--white);
  padding: .3rem .65rem; border-radius: 6px;
}
.ba-before { background: var(--deep); }
.ba-after  { background: var(--electric); }
.ba-card figcaption {
  display: flex; align-items: baseline; gap: .65rem; flex-wrap: wrap;
  padding: .95rem 1.1rem; font-weight: 600; color: var(--ink);
}
.ba-type {
  font-family: var(--font-head); font-size: .82rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--deep); border: 1px solid currentColor; border-radius: 5px; padding: .1rem .45rem;
}

/* =========================================================================
   RECENT WORK — single job photos, square tiles so mixed camera
   orientations still line up on a grid
   ========================================================================= */
.recent { margin-top: 3.25rem; padding-top: 2.75rem; border-top: 1px solid #C4D8EE; }
.recent-head {
  font-family: var(--font-head); font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.4rem, 4.5vw, 1.9rem); letter-spacing: .01em; color: var(--ink);
}
.recent-intro { margin-top: .7rem; max-width: 62ch; color: var(--ink-mid); font-size: 1rem; }

.recent-grid {
  list-style: none; margin: 1.9rem 0 0; padding: 0;
  display: grid; gap: 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.recent-item figure {
  margin: 0; height: 100%; background: var(--white);
  border: 1px solid #C4D8EE; border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow);
}
.recent-item img {
  display: block; width: 100%; aspect-ratio: 1 / 1;
  object-fit: cover; background: var(--jet);
}
.recent-item figcaption {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  padding: .85rem .95rem; font-size: .93rem; font-weight: 600; color: var(--ink);
}
.recent-type {
  font-family: var(--font-head); font-size: .75rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--deep);
  border: 1px solid currentColor; border-radius: 5px; padding: .1rem .4rem;
}

/* Residential photo closing the Why Chaney's section */
.why-shot {
  margin: 2.75rem 0 0; border-radius: var(--radius); overflow: hidden;
  border: 1px solid rgba(201,210,220,.28); box-shadow: 0 20px 46px rgba(0,0,0,.5);
}
.why-shot img { display: block; width: 100%; height: auto; }
.why-shot figcaption {
  padding: .85rem 1.1rem; font-size: .9rem; color: var(--chrome);
  background: rgba(255,255,255,.05);
}

/* placeholder / disclosure note */
.note {
  margin-top: 1.5rem; padding: .9rem 1.1rem;
  border-left: 4px solid var(--electric); background: rgba(8,123,255,.07);
  border-radius: 0 8px 8px 0; font-size: .92rem; color: var(--ink-mid);
}
.note strong { color: var(--ink); }

/* ---------- Why choose ---------- */
.why-grid { display: grid; gap: 1.35rem; }
.why-grid li { display: flex; gap: .9rem; align-items: flex-start; }
.why-grid .ico { width: 1.6rem; height: 1.6rem; color: var(--electric); margin-top: .15rem; }
.why-grid h3 { font-size: 1.32rem; margin-bottom: .25rem; }
.why-grid p { font-size: .97rem; }

/* ---------- Process ---------- */
.steps { display: grid; gap: 1.15rem; counter-reset: step; }
.step {
  position: relative; background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.9rem 1.4rem 1.5rem;
}
.step-num {
  position: absolute; top: -1.1rem; left: 1.3rem;
  display: grid; place-items: center; width: 2.6rem; height: 2.6rem;
  font-family: var(--font-head); font-size: 1.5rem; font-weight: 800;
  color: var(--white); background: var(--deep);
  border: 2px solid var(--electric); border-radius: 50%;
}
.step h3 { font-size: 1.42rem; margin: .35rem 0 .4rem; }
.step p { color: var(--ink-mid); font-size: .97rem; }

/* ---------- Reviews ----------
   Cards sit on the dark section, and the count of real reviews is whatever it
   is — five today. So this is a MASONRY (CSS multi-column), not a grid: an odd
   number of cards flows naturally instead of stranding one alone on a row, and
   the wildly different review lengths pack without leaving holes. Adding or
   removing a review needs no layout change. */
.rating-summary {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: .5rem; margin-bottom: clamp(2rem, 5vw, 2.75rem);
}
.rating-score {
  font-family: var(--font-head); font-weight: 800; line-height: .9;
  font-size: clamp(4rem, 13vw, 6.5rem); color: var(--white);
  text-shadow: 0 0 30px rgba(8,123,255,.5);
}
.rating-count { color: var(--chrome); font-size: .98rem; }
.rating-summary .btn { margin-top: .6rem; }

.stars { display: inline-flex; gap: .18em; }
.star { width: 1em; height: 1em; fill: var(--electric); flex: none; }
.stars-lg { font-size: 1.9rem; gap: .12em; }

/* Stars wash in one at a time. Resting state is LIT, so no JavaScript means a
   fully lit rating rather than a blank row — main.js adds .is-dim to arm it. */
.stars-lg .star { opacity: 1; transform: none; }
.rating-summary.is-dim .stars-lg .star { opacity: .18; transform: scale(.72); }
.rating-summary.is-lit .stars-lg .star {
  animation: starPop .45s cubic-bezier(.2,1.5,.4,1) forwards;
}
.rating-summary.is-lit .stars-lg .star:nth-child(1) { animation-delay: .05s; }
.rating-summary.is-lit .stars-lg .star:nth-child(2) { animation-delay: .17s; }
.rating-summary.is-lit .stars-lg .star:nth-child(3) { animation-delay: .29s; }
.rating-summary.is-lit .stars-lg .star:nth-child(4) { animation-delay: .41s; }
.rating-summary.is-lit .stars-lg .star:nth-child(5) { animation-delay: .53s; }
@keyframes starPop {
  from { opacity: .18; transform: scale(.72); }
  60%  { opacity: 1; transform: scale(1.18); }
  to   { opacity: 1; transform: scale(1); }
}

.review-masonry { columns: 1; column-gap: 1.1rem; }
.review {
  break-inside: avoid; -webkit-column-break-inside: avoid;
  margin-bottom: 1.1rem;
  position: relative; overflow: hidden;
  background: var(--jet-2); border: 1px solid var(--jet-3);
  border-radius: var(--radius); padding: 1.5rem 1.4rem;
  transition: border-color .25s ease, transform .25s ease;
}
.review:hover { border-color: var(--electric); transform: translateY(-3px); }

/* A sheen crossing the card on hover — light catching a surface that has just
   been washed. Decorative only, and it never intercepts the pointer. */
.review::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgba(220,238,255,.16) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform .7s ease;
}
.review:hover::after { transform: translateX(120%); }

.quote-mark { width: 1.9rem; height: 1.9rem; fill: var(--electric); opacity: .65; margin-bottom: .6rem; }
.review-text { font-size: 1.02rem; color: var(--chrome); }
.review-meta {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-top: 1rem; font-family: var(--font-head); font-size: .95rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--white);
}
.review-meta .stars { font-size: .95rem; }

/* =========================================================================
   QUOTE FORM
   ========================================================================= */
.quote-wrap { display: grid; gap: clamp(2rem, 5vw, 3.25rem); align-items: start; }
.quote-intro h2 { font-size: clamp(2.05rem, 6vw, 2.9rem); margin-bottom: .9rem; }
.quote-intro > p { margin-bottom: 1.1rem; }
.phone-link {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--font-head); font-size: clamp(1.7rem, 5vw, 2.15rem); font-weight: 800;
  color: var(--white); text-decoration: none; letter-spacing: .01em;
}
.phone-link span { color: var(--chrome); }
.phone-link .ico { color: var(--electric); width: 1.5rem; height: 1.5rem; }
.phone-link:hover { color: var(--electric); }
/* Deliberately much quieter than .phone-link above it — the form and the phone
   are the routes to a booked job; this is the catch-all for everything else. */
.quote-email { margin-top: 1.1rem; font-size: .95rem; color: var(--chrome); max-width: 40ch; }
.email-link {
  display: inline-flex; align-items: center; gap: .4rem;
  margin-top: .3rem; color: var(--white); text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,.35);
  overflow-wrap: anywhere;   /* the address is long; never let it widen the column */
}
.email-link .ico { color: var(--electric); width: 1.05rem; height: 1.05rem; }
.email-link:hover { color: var(--electric); border-bottom-color: var(--electric); }

.quote-facts { margin-top: 1.4rem; display: grid; gap: .55rem; }
.quote-facts li {
  position: relative; padding-left: 1.5rem; font-size: .95rem; color: var(--chrome);
}
.quote-facts li::before {
  content: ''; position: absolute; left: 0; top: .5rem;
  width: .6rem; height: .6rem; background: var(--electric); border-radius: 2px; transform: rotate(45deg);
}

.quote-form {
  background: var(--jet-2); border: 1px solid var(--jet-3); border-radius: var(--radius);
  padding: clamp(1.35rem, 4vw, 2rem); box-shadow: var(--shadow-dark);
}
.field { margin-bottom: 1.05rem; border: 0; padding: 0; min-width: 0; }
.field-row { display: grid; gap: 1.05rem; }
.field label, .field legend {
  display: block; padding: 0; margin-bottom: .4rem;
  font-size: .9rem; font-weight: 600; color: var(--white);
}
.req { color: var(--electric); }
.opt { color: var(--chrome); font-weight: 400; }

.field input[type="text"], .field input[type="tel"], .field input[type="email"],
.field select, .field textarea, .field input[type="file"] {
  width: 100%; font: inherit; font-size: 1rem; color: var(--white);
  background: var(--jet); border: 1px solid #232B37; border-radius: 9px;
  padding: .8rem .9rem;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field textarea { resize: vertical; min-height: 6.5rem; }
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%23C9D2DC' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center; background-size: 12px;
  padding-right: 2.6rem;
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: #33404F; }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--electric); box-shadow: 0 0 0 3px rgba(8,123,255,.28); outline: none;
}
.field input::placeholder, .field textarea::placeholder { color: #6C7A8B; }
.field input[type="file"] { padding: .62rem .7rem; color: var(--chrome); font-size: .92rem; }
.field input[type="file"]::file-selector-button {
  font: inherit; font-weight: 600; margin-right: .8rem; cursor: pointer;
  background: var(--jet-3); color: var(--white); border: 0; border-radius: 6px; padding: .45rem .8rem;
}
.field input[type="file"]::file-selector-button:hover { background: var(--deep); }

.choice-row { display: flex; flex-wrap: wrap; gap: .55rem; }
.choice { position: relative; margin: 0; }
.choice input { position: absolute; opacity: 0; width: 0; height: 0; }
.choice span {
  display: inline-block; cursor: pointer; font-size: .95rem; font-weight: 500;
  color: var(--chrome); background: var(--jet); border: 1px solid #232B37;
  border-radius: 100px; padding: .58rem 1.1rem;
  transition: border-color .15s, color .15s, background-color .15s;
}
.choice span:hover { border-color: #3E4B5C; color: var(--white); }
.choice input:checked + span {
  background: var(--deep); border-color: var(--electric); color: var(--white);
}
.choice input:focus-visible + span { outline: 3px solid var(--electric); outline-offset: 3px; }

.hint { font-size: .84rem; color: #8A96A6; margin-top: .4rem; }
.err { font-size: .86rem; font-weight: 500; color: #FF8A8A; margin-top: .4rem; }
.field [aria-invalid="true"] { border-color: #FF6B6B; }
.field [aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(255,107,107,.28); }

.form-note { margin-top: 1rem; font-size: .84rem; color: #8A96A6; }
.form-note a { color: var(--chrome); }
.form-status {
  margin-top: 1rem; padding: .85rem 1rem; border-radius: 9px; font-size: .93rem;
  background: rgba(255,107,107,.12); border: 1px solid rgba(255,107,107,.4); color: #FFC9C9;
}
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

#quoteSubmit.is-busy { opacity: .7; pointer-events: none; }

.quote-success {
  background: var(--jet-2); border: 1px solid var(--electric); border-radius: var(--radius);
  padding: clamp(1.6rem, 5vw, 2.5rem); box-shadow: var(--shadow-dark);
}
.quote-success .success-ico { width: 3rem; height: 3rem; fill: var(--electric); margin-bottom: .9rem; }
.quote-success h2 { font-size: clamp(1.8rem, 5vw, 2.35rem); margin-bottom: .8rem; }
.quote-success p { margin-bottom: .7rem; }
.quote-success a { color: var(--electric); font-weight: 600; }
/* Photo-by-text ask — set apart so it is not skimmed past. */
.quote-success .success-photos {
  margin-block: 1.1rem; padding: .9rem 1.1rem;
  background: rgba(8,123,255,.1); border-left: 3px solid var(--electric);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.quote-success .success-photos strong { color: var(--white); }

/* =========================================================================
   FINAL CTA
   ========================================================================= */
.final-cta {
  background: var(--deep);
  background-image: radial-gradient(80% 120% at 50% 0%, rgba(8,123,255,.55), transparent 70%);
  color: var(--white); text-align: center; padding-block: clamp(3rem, 8vw, 4.75rem);
  border-top: 3px solid var(--electric);
}
.final-cta h2 { font-size: clamp(2.15rem, 6.5vw, 3.4rem); margin-bottom: .85rem; }
.final-cta p { max-width: 54ch; margin: 0 auto 1.9rem; color: #E6F0FF; }
.final-cta .btn-primary { background: var(--white); color: var(--deep); border-color: var(--white); box-shadow: 0 8px 24px rgba(0,0,0,.28); }
.final-cta .btn-primary:hover { background: var(--ice); color: var(--jet); border-color: var(--ice); }
.final-cta .btn-ghost { color: var(--white); border-color: rgba(255,255,255,.65); }
.final-cta .btn-ghost:hover { background: rgba(255,255,255,.14); border-color: var(--white); }

/* =========================================================================
   LEAVE A REVIEW  — the pressure-washed headline
   -------------------------------------------------------------------------
   Two copies of the same word sit exactly on top of each other. The dirty one
   is always painted; the clean one shows only through #washMask, whose rect
   slides left to right. The wand slides on the identical keyframes, so the
   nozzle stays glued to the wet edge.

   The RESTING state below is the CLEAN, finished one. That is deliberate — if
   JavaScript never runs, the visitor reads the word normally. main.js adds
   .is-armed to dirty it and .is-washing to run the sweep.
   ========================================================================= */
.wash-head { max-width: 46ch; margin-inline: auto; text-align: center; }
.wash-head .eyebrow { justify-content: center; }

.wash-card {
  display: block;
  max-width: 900px;
  margin: 0 auto;
  padding: clamp(.75rem, 2.5vw, 1.5rem) clamp(.75rem, 2.5vw, 1.75rem) clamp(1.25rem, 3vw, 1.75rem);
  background: var(--jet-2);
  background-image: radial-gradient(120% 100% at 50% 0%, rgba(8,123,255,.22), transparent 70%);
  border: 1px solid var(--jet-3);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  text-align: center;
  text-decoration: none;
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.wash-card:hover { border-color: var(--electric); transform: translateY(-2px); box-shadow: 0 22px 50px rgba(8,10,13,.22); }
.wash-card:focus-visible { outline: none; box-shadow: var(--ring); }

/* The type is set on the <svg> itself, not on the <text>. Both copies of the
   word are <use> clones, and a selector cannot reach inside a use shadow tree
   — but font properties inherit into it, so they have to come from above. */
.wash-art {
  display: block; width: 100%; height: auto;
  font-family: var(--font-head);
  font-size: 118px;
  font-weight: 800;
  letter-spacing: 3px;
}
.wash-dirty { fill: #39424F; }
.wash-clean { fill: var(--white); filter: drop-shadow(0 0 16px rgba(8,123,255,.75)); }

.wash-mask-rect, .wash-wand { transform: translateX(1160px); }
.wash-art.is-armed .wash-mask-rect,
.wash-art.is-armed .wash-wand { transform: translateX(0); }
.wash-art.is-washing .wash-mask-rect,
.wash-art.is-washing .wash-wand {
  animation: washSweep 2.5s cubic-bezier(.36,.06,.28,1) .15s forwards;
  will-change: transform;
}
@keyframes washSweep { from { transform: translateX(0); } to { transform: translateX(1160px); } }

/* The spray flickers only while the wand is actually travelling. */
.wash-art.is-washing .wash-spray { animation: washSpit .16s steps(2, end) infinite; }
@keyframes washSpit { from { opacity: .78; } to { opacity: 1; } }

.wash-btn {
  display: inline-flex; align-items: center; gap: .55rem;
  margin-top: .5rem; padding: 1.05rem 1.75rem;
  font-family: var(--font-head); font-size: 1.25rem; text-transform: uppercase;
  letter-spacing: .03em; line-height: 1;
  color: var(--white); background: var(--deep);
  border: 2px solid var(--deep); border-radius: 999px;
  transition: background .2s ease, border-color .2s ease;
}
.wash-card:hover .wash-btn { background: var(--electric); border-color: var(--electric); }

.wash-note { margin-top: 1rem; text-align: center; font-size: .9rem; color: var(--ink-mid); }

/* On a phone the word is only ~330px wide, so give it more of the frame. */
@media (max-width: 600px) {
  .wash-art { font-size: 128px; }
  .wash-btn { font-size: 1.05rem; padding: .9rem 1.25rem; }
}

/* Reduced motion: no sweep at all. The global rule already collapses the
   duration, and because the animation fills forwards that lands on the clean
   end state — but state it outright rather than leaning on a side effect. */
@media (prefers-reduced-motion: reduce) {
  /* Hero goes completely still. The global rule collapses the duration, but an
     infinite animation is exactly the case where that is not enough — say it. */
  .hero-bg, .hero-bg::after { animation: none; }
  .hero h1 .hl {
    animation: none;
    background-image: none;
    -webkit-text-fill-color: var(--electric);
    color: var(--electric);
  }

  /* Stars stay lit and still. The global rule already collapses the duration,
     but say it outright rather than leaning on a side effect. */
  .rating-summary.is-dim .stars-lg .star,
  .rating-summary.is-lit .stars-lg .star { opacity: 1; transform: none; animation: none; }
  .review::after { display: none; }

  .wash-art.is-armed .wash-mask-rect,
  .wash-art.is-armed .wash-wand,
  .wash-art.is-washing .wash-mask-rect,
  .wash-art.is-washing .wash-wand { transform: translateX(1160px); animation: none; }
  .wash-art.is-washing .wash-spray { animation: none; }
}

/* =========================================================================
   FOOTER
   ========================================================================= */
.site-footer { background: var(--jet); color: var(--chrome); padding-top: clamp(2.75rem, 7vw, 4rem); }
.footer-inner { display: grid; gap: 2rem; }
.footer-brand img { width: 220px; margin-bottom: 1rem; }
.footer-tag {
  font-family: var(--font-head); font-size: 1.12rem; text-transform: uppercase;
  letter-spacing: .02em; color: var(--white); max-width: 26ch;
}
.footer-col h2 {
  font-size: 1.15rem; letter-spacing: .1em; color: var(--white); margin-bottom: .85rem;
}
.footer-col ul { display: grid; gap: .5rem; font-size: .93rem; }
.footer-col a { color: var(--chrome); text-decoration: none; }
.footer-col a:hover { color: var(--electric); text-decoration: underline; }
.footer-phone { font-family: var(--font-head); font-size: 1.45rem; color: var(--white) !important; letter-spacing: .01em; }
.footer-phone:hover { color: var(--electric) !important; }
/* Long enough to blow out the narrow footer column on a phone if left alone. */
.footer-email { overflow-wrap: anywhere; }
.social { display: flex; gap: .6rem; margin-top: 1rem; }
.social a {
  display: grid; place-items: center; width: 42px; height: 42px;
  border: 1px solid var(--jet-3); border-radius: 9px; color: var(--chrome);
}
.social a:hover { border-color: var(--electric); color: var(--electric); background: rgba(8,123,255,.1); }
.social .ico { width: 20px; height: 20px; }

.footer-bottom {
  display: flex; flex-wrap: wrap; gap: .6rem 1.5rem; justify-content: space-between;
  margin-top: clamp(2rem, 5vw, 3rem); padding-block: 1.35rem;
  border-top: 1px solid var(--jet-3); font-size: .85rem;
}
.footer-bottom a { color: var(--chrome); }

/* =========================================================================
   STICKY MOBILE BAR
   ========================================================================= */
.mobile-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 95;
  display: grid; grid-template-columns: 1fr 1.35fr; gap: .6rem;
  padding: .6rem var(--gutter) calc(.6rem + env(safe-area-inset-bottom));
  background: rgba(8,10,13,.97); border-top: 1px solid var(--jet-3);
  backdrop-filter: blur(8px);
}
.mobile-bar .btn { font-size: 1.05rem; padding: .8rem .5rem; }

/* =========================================================================
   BREAKPOINTS
   ========================================================================= */
@media (min-width: 560px) {
  .field-row { grid-template-columns: 1fr 1fr; }
  .card-grid, .steps, .gallery { grid-template-columns: repeat(2, 1fr); }
  .review-masonry { columns: 2; }
  .why-grid { grid-template-columns: repeat(2, 1fr); gap: 1.6rem 2rem; }
}

@media (min-width: 780px) {
  .trust-grid { grid-template-columns: repeat(4, 1fr); padding: 1.4rem 1.25rem; }
  .steps { grid-template-columns: repeat(3, 1fr); }
  .review-masonry { columns: 3; }
  .hero-inner { grid-template-columns: 1.1fr .9fr; align-items: center; }
  .hero-emblem { width: min(100%, 460px); }
  .footer-inner { grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 2.5rem; }
}

@media (min-width: 900px) {
  .card-grid { grid-template-columns: repeat(3, 1fr); gap: 1.35rem; }
  .gallery { gap: 1.75rem; }
  .quote-wrap { grid-template-columns: .85fr 1.15fr; }
  .quote-intro { position: sticky; top: 100px; }
}

/* Desktop navigation — drawer becomes an inline bar */
@media (min-width: 1000px) {
  .nav {
    position: static; transform: none; visibility: visible;
    display: flex; align-items: center; gap: 1.75rem;
    background: transparent; border: 0; padding: 0; inset: auto;
  }
  .nav-list { display: flex; gap: 1.4rem; }
  .nav-list a {
    padding: .35rem 0; border: 0; font-size: 1.06rem; letter-spacing: .05em;
    border-bottom: 2px solid transparent;
  }
  .nav-list a:hover { border-bottom-color: var(--electric); }
  .nav-cta { display: flex; gap: .6rem; margin: 0; }
  .nav-toggle, .header-call, .nav-scrim { display: none; }
  .mobile-bar { display: none; }
  body { padding-bottom: 0; }
}

@media (max-width: 999px) {
  :root { --bar-h: 74px; }
  .nav-call { display: none; }
}

/* Very small phones */
@media (max-width: 380px) {
  .btn-lg { font-size: 1.12rem; padding: .95rem 1.15rem; }
  .btn-row .btn { width: 100%; }
}

/* Users who prefer more contrast */
@media (prefers-contrast: more) {
  .card, .step, .review, .ba-card { border-color: var(--ink); }
  .section-intro, .card p, .step p, .review-text { color: var(--ink); }
}

@media print {
  .site-header, .mobile-bar, .hero-bg, .wave, .nav { display: none !important; }
  body { color: #000; background: #fff; padding: 0; }
  .section-dark, .hero, .final-cta, .site-footer { background: #fff !important; color: #000 !important; }
  .section-dark h2, .section-dark h3, .section-dark p, .hero * , .final-cta * { color: #000 !important; }
}
