/* ============================================================================
   Hollow Reach Marine Construction — spec landing page (FICTIONAL BRAND)
   ----------------------------------------------------------------------------
   ONE stylesheet, ONE font file, no framework, no build step. That is the point:
   this build is priced low, so it has to be cheap to maintain by hand. Anyone
   who can read CSS can re-skin it from the token block below.

   This page is a DE-BRANDED fork of a cold spec build made for a real marine
   contractor. Every one of that company's identifiers came out, and the colour
   went with them: the original palette was sampled from that company's own logo
   artwork, so keeping it would have carried their brand onto a fiction.

   The replacement is a pine-and-brass scheme owing nothing to the source. The
   accent is declared TWICE, because one accent cannot serve both grounds: the
   copper carries text on the linen and fails on the dark ground, and the brass
   does the reverse.

   MEASURED, all against the grounds actually used here (WCAG AA needs 4.5:1 for
   body text and 3:1 for large text and UI):
     #12332E pine    white on it 13.65:1   — the dark ground and the body ink
     #1C4A42 pine-2  white on it  9.96:1   — lifted panels on the dark ground
     #3A4A46 body    8.44:1 on linen
     #56655F muted   5.54:1 on linen, 5.03:1 on the band
     #8A4B12 copper  6.13:1 on linen, 5.56:1 on the band, white on it 6.78:1
     #E8B54A brass   7.24:1 on the pine ground
   No rule downstream hard-codes a colour, so swapping these tokens re-skins the
   whole page for the next marine contractor.
   ========================================================================== */

@font-face {
  font-family: 'Hanken Grotesk';
  src: url('../assets/fonts/hanken-grotesk-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* grounds */
  --ground:      #F6F3EE;   /* warm linen — the page */
  --ground-2:    #EDE8E0;   /* one step down, for banded sections */
  --ink:         #12332E;   /* deep pine — body text AND the dark ground */
  --ink-2:       #1C4A42;   /* pine, one step up — lifted panels on the dark ground */
  --body:        #3A4A46;   /* body copy on the light ground — 8.1:1 */
  --muted:       #56655F;   /* captions, meta — 5.4:1, small text still passes */
  --line:        rgba(11, 38, 33, 0.14);
  --line-soft:   rgba(11, 38, 33, 0.07);

  /* accent — their own inks. See the header note. */
  --accent:         #8A4B12;   /* text on the LIGHT ground: 6.13:1 on #F6F3EE */
  --accent-on-dark: #E8B54A;   /* text on the PINE  ground: 7.24:1 on #12332E */
  --accent-fill:    #9A5410;   /* deeper copper, for fills: white on it 5.75:1 */
  --accent-soft:    rgba(138, 75, 18, 0.10);

  /* type scale — clamped, so there are no breakpoint-specific font sizes */
  --h1:   clamp(2.35rem, 1.30rem + 4.4vw, 5.1rem);
  --h2:   clamp(1.85rem, 1.28rem + 2.3vw, 3.1rem);
  --h3:   clamp(1.15rem, 1.02rem + 0.5vw, 1.4rem);
  --lead: clamp(1.05rem, 0.98rem + 0.4vw, 1.28rem);

  --wrap:      1200px;
  --wrap-text: 760px;
  --gut:       clamp(20px, 5vw, 56px);
  --header-h:  74px;

  --radius: 3px;   /* almost square. Marine work is not soft. */
  --shadow: 0 18px 40px -22px rgba(18, 51, 46, 0.45);
}

/* Dark sections re-declare the tokens, so the same components invert without
   a single `.dark &` override anywhere below.

   THE VALUES BELOW ARE LITERAL ON PURPOSE. Writing `--ground: var(--ink)` here
   does NOT reach the navy defined on :root — a var() resolves against the
   element's OWN computed value of that property, and this block redefines
   --ink two lines later. It silently produced #F2F6F8 text on an #F2F6F8
   ground: a 1.0:1 ratio, and the section read as blank rather than as broken.
   Never reference a token that the same block reassigns. */
.on-dark,
.site-footer {
  --ground:    #12332E;   /* deep pine */
  --ground-2:  #1C4A42;   /* pine, one step up */
  --ink:       #FFFFFF;   /* 15.1:1 */
  --body:      #C3D0E0;   /*  9.7:1 */
  --muted:     #93A5BC;   /*  6.0:1 */
  --line:      rgba(255, 255, 255, 0.18);
  --line-soft: rgba(255, 255, 255, 0.09);
  --accent:    #E8B54A;   /*  7.24:1 — the brass. The copper only manages 2.0 here. */
  --accent-soft: rgba(232, 181, 74, 0.14);
}

/* ---------------------------------------------------------------- reset --- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ground);
  color: var(--body);
  font-family: 'Hanken Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
button { font: inherit; }

h1, h2, h3, h4 {
  color: var(--ink);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.028em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}
h1 { font-size: var(--h1); font-weight: 800; }
h2 { font-size: var(--h2); }
h3 { font-size: var(--h3); line-height: 1.25; letter-spacing: -0.015em; }
p  { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--ink); color: #fff; padding: 10px 16px; border-radius: var(--radius);
  transition: top .2s;
}
.skip-link:focus { top: 12px; }

:where(a, button, summary, input, textarea, select):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* --------------------------------------------------------------- layout --- */
.wrap { width: min(var(--wrap), 100%); margin-inline: auto; padding-inline: var(--gut); }

.section {
  background: var(--ground);
  color: var(--body);
  padding-block: clamp(64px, 9vw, 118px);
  position: relative;
}
.section--band { background: var(--ground-2); }
.section--tight { padding-block: clamp(44px, 6vw, 76px); }

.eyebrow {
  display: flex; align-items: center; gap: 12px;
  font-size: 12px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 18px;
}
.eyebrow::before {
  content: ""; width: 28px; height: 2px; background: currentColor; flex: none;
}

/* On the pine ground the eyebrow WORDS go near-white and only the rule stays brass:
   at 12px the lifted red clears 4.5:1 by 0.04, which is not a margin worth shipping. */
.on-dark .eyebrow { color: var(--ink); }
.on-dark .eyebrow::before { background: var(--accent-on-dark); }

.section__head { max-width: var(--wrap-text); margin-bottom: clamp(36px, 5vw, 60px); }
.section__head p { font-size: var(--lead); }
.lead { font-size: var(--lead); color: var(--body); }

/* --------------------------------------------------------------- header --- */
.site-header {
  position: fixed; inset: 0 0 auto; z-index: 100;
  height: var(--header-h);
  display: flex; align-items: center;
  transition: background-color .3s ease, box-shadow .3s ease, border-color .3s ease;
  border-bottom: 1px solid transparent;
}
.site-header__bar {
  display: flex; align-items: center; gap: 20px; width: 100%;
}
.site-header__brand {
  display: flex; align-items: center; gap: 11px;
  text-decoration: none; color: #fff; margin-right: auto;
  transition: color .3s ease;
}
/* ------------------------------------------------------------------ logo --
   Their OWN artwork, from their Facebook profile picture — the only copy on the
   public web. Facebook's square avatar crop cuts the excavator's bucket off the
   left and the CONSTRUCTION bar off the right, so it reads "CONS". Shipping it
   cropped is Ben's call and it is the right one: their real mark beats a redraw.

   The artwork is flat ink on solid white with the excavator stacked ABOVE the
   wordmark, roughly 1.27:1. Two consequences:
     - It needs a white plaque. Keyed transparent, its navy would vanish into a
       dark waterfront photograph in the header.
     - At any sane header height the wordmark lands under ~10px, so the
       company name sits beside it as ordinary text. That text is not a redrawn
       wordmark; it is the site's own face, doing the legibility the shrunken
       artwork cannot. It also gives the header something a screen reader and a
       crawler can read. */
.site-header__logo {
  display: flex; align-items: center; justify-content: center;
  flex: none;
  background: #fff;
  border-radius: var(--radius);
  padding: 5px 8px;
  box-shadow: 0 1px 0 rgba(18, 51, 46,.10);
}
.site-header__logo img { height: 46px; width: auto; display: block; }

.brand-name {
  display: grid; line-height: 1.12;
}
.brand-name b {
  font-size: 16px; font-weight: 800; letter-spacing: -0.018em;
  color: var(--brand-ink); white-space: nowrap;
}
.brand-name span {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.20em;
  text-transform: uppercase; color: var(--brand-sub);
}

.site-header            { --brand-ink: #ffffff; --brand-sub: rgba(255,255,255,.76); }
.site-header.is-stuck   { --brand-ink: var(--ink); --brand-sub: var(--muted); }
.site-footer            { --brand-ink: #ffffff; --brand-sub: rgba(255,255,255,.72); }

.foot-brand .site-header__logo { padding: 7px 11px; }
.foot-brand .site-header__logo img { height: 58px; }
.foot-brand .foot-lockup { display: flex; align-items: center; gap: 13px; margin-bottom: 18px; }
.foot-brand .brand-name b { font-size: 18px; }

.nav { display: flex; align-items: center; gap: 28px; }
/* :not(.btn) is load-bearing. The call button lives inside the nav, and
   `.site-header.is-stuck .nav a` (0,2,1) outranks `.btn--primary` (0,1,0), so
   without this the button quietly took navy text on its red fill — 3.01:1 —
   and dropped from 700 to 500 weight. It only misbehaved after scrolling,
   which is most of the page. */
.nav a:not(.btn) {
  color: #fff; text-decoration: none; font-size: 15px; font-weight: 500;
  opacity: .88; transition: opacity .2s, color .3s ease;
}
.nav a:not(.btn):hover { opacity: 1; }

/* Scrolled: the bar solidifies and every ink token flips to the dark-on-light set. */
.site-header.is-stuck {
  background: var(--ground);
  border-bottom-color: var(--line-soft);
  box-shadow: 0 10px 30px -24px rgba(18, 51, 46, .6);
}
.site-header.is-stuck .site-header__brand,
.site-header.is-stuck .nav a:not(.btn) { color: var(--ink); }

.nav-toggle {
  display: none; width: 42px; height: 42px; padding: 0;
  background: none; border: 1px solid rgba(255,255,255,.34); border-radius: var(--radius);
  color: #fff; cursor: pointer;
}
.site-header.is-stuck .nav-toggle { color: var(--ink); border-color: var(--line); }
.nav-toggle svg { margin: auto; }

/* --------------------------------------------------------------- buttons -- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 15px 26px;
  font-size: 15px; font-weight: 700; letter-spacing: 0.015em;
  text-decoration: none; border: 1px solid transparent; border-radius: var(--radius);
  cursor: pointer; white-space: nowrap;
  transition: background-color .2s, border-color .2s, color .2s, transform .2s;
}
.btn:hover { transform: translateY(-1px); }
.btn--primary { background: var(--accent-fill); color: #fff; }
.btn--primary:hover { background: #AE1A0F; }
/* On navy the fill stays the DEEP red — white on it measures 6.95:1, where the
   lifted red would only reach 4.35:1. */
.on-dark .btn--primary { background: var(--accent-fill); color: #fff; }
.on-dark .btn--primary:hover { background: #AE1A0F; }
.btn--ghost { border-color: currentColor; color: var(--ink); background: transparent; }
.btn--ghost:hover { background: var(--ink); color: var(--ground); }
.btn--on-photo { border-color: rgba(255,255,255,.5); color: #fff; }
.btn--on-photo:hover { background: #fff; color: var(--ink); border-color: #fff; }
.btn--sm { padding: 11px 18px; font-size: 14px; }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* ------------------------------------------------------------------ hero -- */
.hero {
  position: relative;
  min-height: min(94vh, 860px);
  display: flex; align-items: flex-end;
  padding-top: calc(var(--header-h) + 40px);
  padding-bottom: clamp(48px, 7vw, 88px);
  background: var(--ink);
  overflow: hidden;
}
.hero__media { position: absolute; inset: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
/* THE SCRIM IS MEASURED, NOT EYEBALLED. No computed style can judge white text
   over a photograph, so tools/check_hero_contrast.py composites these exact
   gradients over the real hero file — applying object-fit:cover per viewport,
   because each width shows a different slice — and checks every pixel of the
   region the text actually occupies, measured off the DOM with a Range.

   The previous values were tuned against a hero whose middle band was dark
   trees. This photograph has a bright cirrus sky exactly where the headline
   sits: they left 28.6% of the desktop copy area and 43.7% of the mobile one
   below 4.5:1, worst case 1.36:1. White on cloud.

   Measured with the values below: desktop 6.97:1 worst, mobile 5.31:1 worst,
   nothing below AA at either width. Re-run that script after ANY hero change. */
.hero__media::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to bottom,
      rgba(18, 51, 46,.64) 0%,
      rgba(18, 51, 46,.58) 10%,
      rgba(18, 51, 46,.72) 50%,
      rgba(18, 51, 46,.91) 85%,
      rgba(18, 51, 46,.96) 100%);
}
/* On anything wide enough for the copy to sit in the left two-thirds, a second
   pass darkens that side only, so the sky stays open on the right. Below this
   width the text spans nearly the full hero and the vertical scrim carries it
   alone — which is why the vertical one has to pass on its own. */
@media (min-width: 861px) {
  .hero__media::before {
    content: "";
    position: absolute; inset: 0; z-index: 1;
    background:
      linear-gradient(to right,
        rgba(18, 51, 46,.60) 0%,
        rgba(18, 51, 46,.36) 58%,
        rgba(18, 51, 46,0) 94%);
  }
}
.hero__inner { position: relative; z-index: 2; width: 100%; }
.hero__copy { max-width: 940px; }
.hero .eyebrow { color: #fff; opacity: .9; }
.hero h1 { color: #fff; margin-bottom: 0.42em; }
.hero__sub {
  font-size: var(--lead); color: rgba(255,255,255,.9);
  max-width: 620px; margin-bottom: 30px;
}
.hero .btn-row { margin-bottom: 34px; }

.hero__facts {
  display: flex; flex-wrap: wrap; gap: 10px 34px;
  padding-top: 22px; border-top: 1px solid rgba(255,255,255,.22);
  list-style: none; margin: 0; padding-left: 0;
}
.hero__facts li {
  display: flex; align-items: center; gap: 9px;
  color: #fff; font-size: 14px; font-weight: 600; letter-spacing: .01em;
}
.hero__facts svg { flex: none; color: var(--accent-on-dark); }

/* ------------------------------------------------------------- services --- */
.cards {
  display: grid; gap: clamp(14px, 1.6vw, 22px);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.card {
  background: var(--ground);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: border-color .25s, transform .25s, box-shadow .25s;
}
.section--band .card { background: var(--ground); }
.card:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: var(--shadow); }
.card__media { aspect-ratio: 3 / 2; background: var(--ground-2); overflow: hidden; }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.card:hover .card__media img { transform: scale(1.04); }
.card__body { padding: 22px 24px 26px; }
.card__body h3 { margin-bottom: 8px; }
.card__body p { font-size: 15.5px; margin: 0; color: var(--body); }

/* ------------------------------------------------------------------ work -- */
.gallery {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.gallery figure { margin: 0; position: relative; overflow: hidden; border-radius: var(--radius); }
.gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; transition: transform .6s ease; }
.gallery figure:hover img { transform: scale(1.05); }
.gallery figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: 26px 16px 13px;
  background: linear-gradient(to top, rgba(18, 51, 46,.92) 35%, rgba(18, 51, 46,.55) 70%, transparent);
  color: #fff; font-size: 13px; font-weight: 600; letter-spacing: .02em;
  /* Text over a photograph cannot be proven legible by a contrast calculation,
     because the thing behind it changes per pixel. The shadow is the cheap
     insurance a measurement cannot provide. */
  text-shadow: 0 1px 3px rgba(18, 51, 46,.9);
}
/* Five photographs, not six: that is how many distinct jobs are on their public
   page, and padding it out by showing one twice would be the first dishonest
   thing here. An explicit 3-column grid with the first tile double-height lands
   5 items cleanly; auto-fit left a ragged row. */
@media (min-width: 900px) {
  .gallery--tall { grid-template-columns: repeat(3, 1fr); }
  .gallery--tall figure:first-child { grid-row: span 2; }
  .gallery--tall figure:first-child img { height: 100%; aspect-ratio: auto; }
}

/* An honest empty state. Used where the fictional build had invented content. */
.empty-state {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: clamp(30px, 5vw, 54px);
  text-align: center;
  color: var(--muted);
  background: var(--ground-2);
}
.empty-state strong { display: block; color: var(--ink); font-size: var(--h3); margin-bottom: 8px; }
.empty-state p { max-width: 46ch; margin-inline: auto; font-size: 15.5px; }

/* ----------------------------------------------------------------- split -- */
.split {
  display: grid; gap: clamp(30px, 5vw, 68px);
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  align-items: center;
}
.split__media img { border-radius: var(--radius); width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.split__body { max-width: 60ch; }

/* --------------------------------------------------------------- process -- */
.steps { display: grid; gap: 2px; background: var(--line-soft); border-block: 1px solid var(--line-soft); }
.step {
  background: var(--ground); padding: 26px clamp(18px, 3vw, 34px);
  display: grid; grid-template-columns: 62px 1fr; gap: 6px 22px; align-items: start;
}
.step__num {
  font-size: 13px; font-weight: 800; letter-spacing: .12em;
  color: var(--accent); padding-top: 5px;
}
.step h3 { margin-bottom: 6px; }
.step p { grid-column: 2; font-size: 15.5px; margin: 0; }

/* ----------------------------------------------------------- service area - */
.area {
  display: grid; gap: clamp(30px, 5vw, 60px);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  align-items: start;
}
.town-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 0;
}
.town-list li {
  padding: 11px 0; border-bottom: 1px solid var(--line-soft);
  font-size: 15.5px; font-weight: 600; color: var(--ink);
  display: flex; align-items: center; gap: 10px;
}
.town-list li::before {
  content: ""; width: 5px; height: 5px; flex: none;
  background: var(--accent); border-radius: 50%;
}
.map-frame {
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
  aspect-ratio: 4 / 3; background: var(--ground-2);
}
.map-frame iframe { width: 100%; height: 100%; border: 0; display: block; }

/* --------------------------------------------------------------- reviews -- */
.quotes { display: grid; gap: clamp(14px, 1.6vw, 22px); grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
.quote {
  background: var(--ground); border: 1px solid var(--line-soft);
  border-radius: var(--radius); padding: 28px 26px;
  display: flex; flex-direction: column; gap: 14px;
}
.quote blockquote { margin: 0; font-size: 16.5px; color: var(--ink); line-height: 1.6; }
.quote figcaption { font-size: 13.5px; color: var(--muted); margin-top: auto; }
.quote figcaption b { color: var(--ink); font-weight: 700; display: block; font-size: 14.5px; }
.stars { color: var(--accent); font-size: 14px; letter-spacing: .14em; }

/* ONE review exists for this company, so it is set as a statement rather than
   dropped into a card grid built for six. A lone bordered box in a 1200px band
   reads as a gap where the other five should be; centred with the mark above
   it reads as a choice. There is no star row anywhere on this page, because
   the Google profile carries no rating to show. */
.solo-quote { max-width: 780px; margin-inline: auto; text-align: center; }
.solo-quote__mark {
  font-size: 76px; line-height: .6; color: var(--accent);
  font-weight: 800; display: block; margin-bottom: 12px;
}
.solo-quote blockquote {
  margin: 0 0 24px;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.5rem);
  line-height: 1.22; letter-spacing: -0.025em; font-weight: 700;
  color: var(--ink); text-wrap: balance;
}
.solo-quote figcaption { font-size: 14.5px; color: var(--muted); }
.solo-quote figcaption b {
  display: block; color: var(--ink); font-size: 16px; font-weight: 700;
  margin-bottom: 3px;
}

/* ------------------------------------------------------------------ faqs -- */
.faqs { max-width: 860px; border-top: 1px solid var(--line-soft); }
.faqs details { border-bottom: 1px solid var(--line-soft); }
.faqs summary {
  list-style: none; cursor: pointer; padding: 22px 44px 22px 0; position: relative;
  font-size: var(--h3); font-weight: 700; color: var(--ink); line-height: 1.3;
  letter-spacing: -0.012em;
}
.faqs summary::-webkit-details-marker { display: none; }
.faqs summary::after {
  content: ""; position: absolute; right: 6px; top: 50%;
  width: 11px; height: 11px; margin-top: -7px;
  border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(45deg); transition: transform .25s;
}
.faqs details[open] summary::after { transform: rotate(-135deg); margin-top: -3px; }
.faqs details > div { padding: 0 44px 24px 0; font-size: 16px; max-width: 68ch; }

/* --------------------------------------------------------------- contact --
   There is no form. Ben's call, and it is the right one for this trade: a
   waterfront owner with a washing-out bank picks up the phone, and a form with
   no backend behind it is worse than no form at all. */
.contact-grid {
  display: grid; gap: clamp(30px, 5vw, 64px);
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
  align-items: start;
}
.reach { display: grid; gap: 14px; align-content: start; }

.reach__call {
  display: flex; align-items: center; gap: 18px;
  padding: 24px 26px;
  background: var(--accent-fill); color: #fff;
  border-radius: var(--radius); text-decoration: none;
  transition: background-color .2s, transform .2s;
}
.reach__call:hover { background: #AE1A0F; transform: translateY(-2px); }
.reach__call svg { flex: none; }
.reach__call span { display: grid; line-height: 1.2; }
.reach__call b {
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  opacity: .85;
}
.reach__call strong {
  font-size: clamp(1.5rem, 1.2rem + 1.3vw, 2.1rem); font-weight: 800;
  letter-spacing: -0.02em; margin: 4px 0 3px;
}
.reach__call em { font-style: normal; font-size: 13.5px; opacity: .88; }

.reach__row {
  display: flex; align-items: center; gap: 14px;
  padding: 17px 20px;
  border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink); text-decoration: none;
  transition: border-color .2s, background-color .2s;
  overflow-wrap: anywhere;
}
.reach__row:hover { border-color: var(--accent); background: var(--accent-soft); }
.reach__row svg { flex: none; color: var(--accent); }
.reach__row span { display: grid; font-size: 15.5px; line-height: 1.35; }
.reach__row b {
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 3px;
}

.socials { display: flex; flex-wrap: wrap; gap: 10px; }
.socials a {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 13px 20px;
  border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink); text-decoration: none;
  font-size: 15px; font-weight: 600;
  transition: border-color .2s, background-color .2s;
}
.socials a:hover { border-color: var(--accent); background: var(--accent-soft); }
.socials svg { color: var(--accent); }

.contact-card { display: grid; gap: 22px; }
.contact-row { display: flex; gap: 14px; align-items: flex-start; }
.contact-row svg { flex: none; color: var(--accent); margin-top: 3px; }
.contact-row b { display: block; color: var(--ink); font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 3px; }
.contact-row a { color: var(--ink); text-decoration: none; font-size: 18px; font-weight: 600; }
.contact-row a:hover { color: var(--accent); }
.contact-row p { margin: 0; font-size: 16px; color: var(--ink); }

/* ----------------------------------------------------------------- footer - */
.site-footer { background: var(--ground); color: var(--body); padding-block: clamp(48px, 6vw, 76px) 0; }
.foot-grid {
  display: grid; gap: 34px clamp(24px, 4vw, 60px);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  padding-bottom: 44px;
}
.foot-grid h4 { font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); font-weight: 700; margin-bottom: 14px; }
.foot-grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.foot-grid a { color: var(--body); text-decoration: none; font-size: 15px; }
.foot-grid a:hover { color: var(--accent); }
.foot-brand p { font-size: 15px; max-width: 34ch; }
.foot-bottom {
  border-top: 1px solid var(--line-soft); padding-block: 22px 30px;
  display: flex; flex-wrap: wrap; gap: 10px 24px; justify-content: space-between;
  font-size: 13px; color: var(--muted);
}
.foot-bottom a { color: var(--muted); }

/* Sticky call bar — phones only. A contractor's site lives or dies on the tap. */
.call-bar {
  position: fixed; inset: auto 0 0 0; z-index: 90;
  display: none; gap: 1px;
  background: var(--line);
  box-shadow: 0 -8px 26px -18px rgba(18, 51, 46,.8);
}
.call-bar a {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 15px 10px; text-decoration: none;
  font-size: 15px; font-weight: 700;
  background: var(--ink); color: #fff;
}
.call-bar a.is-primary { background: var(--accent-fill); color: #fff; }

/* ---------------------------------------------------------------- motion -- */
.rv { opacity: 0; transform: translateY(18px); transition: opacity .7s ease, transform .7s cubic-bezier(.22,.61,.36,1); }
.rv.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; transition: none; }
  .card, .gallery img, .btn { transition: none !important; }
}

/* ------------------------------------------------------------ responsive -- */
@media (max-width: 860px) {
  .nav {
    position: fixed; inset: var(--header-h) 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--ground); border-bottom: 1px solid var(--line);
    padding: 6px 0 14px;
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity .22s, transform .22s;
  }
  .nav.is-open { opacity: 1; transform: none; pointer-events: auto; }
  .nav a:not(.btn) { color: var(--ink); padding: 14px var(--gut); font-size: 17px; opacity: 1; }
  .nav .btn { margin: 10px var(--gut) 0; }
  .nav-toggle { display: flex; }
  .site-header:has(.nav.is-open) { background: var(--ground); }
  .site-header:has(.nav.is-open) .site-header__brand,
  .site-header:has(.nav.is-open) .nav-toggle { color: var(--ink); }
  .site-header:has(.nav.is-open) { --brand-ink: var(--ink); --brand-sub: var(--muted); }
  .site-header:has(.nav.is-open) .nav-toggle { border-color: var(--line); }

  .call-bar { display: flex; }
  body { padding-bottom: 54px; }
  .hero { min-height: 640px; }
  .hero__facts { gap: 8px 22px; }
  .step { grid-template-columns: 1fr; }
  .step p { grid-column: 1; }
  .step__num { padding-top: 0; }
}

/* ------------------------------------------------------------- waterline --
   The one piece of ornament on the page, and it is 12 lines: a hairline wave
   that sits on the seam between two sections. It is the only thing here that
   says "water" without spending a photograph on it, and it inherits --line so
   it inverts with the section like everything else. */
.section--wave { padding-top: calc(clamp(64px, 9vw, 118px) + 22px); }
.section--wave::before {
  content: "";
  position: absolute; inset: 0 0 auto 0; height: 12px;
  background-repeat: repeat-x;
  background-size: 76px 12px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='76' height='12' viewBox='0 0 76 12'%3E%3Cpath d='M0 8c9.5 0 9.5-4 19-4s9.5 4 19 4 9.5-4 19-4 9.5 4 19 4' fill='none' stroke='%2312332E' stroke-opacity='.22' stroke-width='1.4'/%3E%3C/svg%3E");
}
.on-dark.section--wave::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='76' height='12' viewBox='0 0 76 12'%3E%3Cpath d='M0 8c9.5 0 9.5-4 19-4s9.5 4 19 4 9.5-4 19-4 9.5 4 19 4' fill='none' stroke='%23E8B54A' stroke-opacity='.5' stroke-width='1.4'/%3E%3C/svg%3E");
}

/* ============================================================================
   DE-BRAND ADDITIONS
   Three things the source build did not need. The logo slot used to hold a
   raster <img> of a real company's mark; it now holds an inline SVG, which has
   to be sized and coloured explicitly because the old rule only ever targeted
   img. The map frame held a Google embed of a real street address and is gone,
   so the grid cell it occupied needs a panel to sit in. And the page carries a
   visible fictional-company notice, which has to read as a notice rather than
   as body copy.
   ========================================================================== */

.site-header__logo svg { height: 46px; width: auto; display: block; color: var(--ink); }
.foot-brand .site-header__logo svg { height: 58px; }

.area-note {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--ground-2); padding: 26px 28px; align-self: start;
}
.area-note h3 { margin: 0 0 10px; font-size: 18px; letter-spacing: -0.01em; }
.area-note p { margin: 0 0 12px; font-size: 15.5px; color: var(--body); }
.area-note p:last-child { margin-bottom: 0; }

.demo-inline {
  margin-top: 22px; padding: 15px 17px;
  border-left: 3px solid var(--accent);
  background: rgba(138, 75, 18, 0.06);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 15px; color: var(--body);
}
.demo-inline strong { color: var(--ink); }
