/* =====================================================================
   cerpabuilds.com — landing page components

   Surface: Decide/Learn. One idea per section, hero is justified here
   (it is the conversion page for a homeowner). Composition is NOT the
   generic centered-hero + three-equal-cards default: the hero is a
   split (copy left / contact rail right), and the service pillars are
   a ruled list rather than floating tiles.
   ===================================================================== */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: 1.65;
  color: var(--body);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }
a { color: var(--navy-mid); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  line-height: 1.15;
  margin: 0 0 var(--sp-3);
  font-weight: 600;
  text-wrap: balance;
}
h1 { font-size: var(--step-hero); letter-spacing: -0.02em; }
h2 { font-size: var(--step-h2); letter-spacing: -0.01em; }
h3 { font-size: var(--step-h3); font-family: var(--font-body); font-weight: 600; }

p { margin: 0 0 var(--sp-4); }

:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* -- Layout helpers ------------------------------------------------ */
.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--sp-5); }
.wrap-narrow { max-width: var(--wrap-narrow); }
.section { padding: var(--sp-8) 0; }
.section--alt { background: var(--surface-alt); }
.section--warm { background: var(--surface-warm); }
.section--navy { background: var(--navy); color: rgba(255,255,255,0.82); }
.section--navy h2, .section--navy h3 { color: #fff; }
.section--navy a { color: #fff; }

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: var(--sp-3);
  display: block;
}
.eyebrow--muted { color: var(--muted); }

.lead { font-size: var(--step-lead); color: var(--muted); line-height: 1.55; }
.section--navy .lead { color: rgba(255,255,255,0.7); }

/* =====================================================================
   Top bar — brand + phone. Sticky, minimal.
   ===================================================================== */
.topbar {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255,255,255,0.96);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.topbar__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); min-height: 68px;
}
.brand {
  display: flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-display); font-size: 1.3rem; font-weight: 600;
  color: var(--navy); text-decoration: none; letter-spacing: -0.01em;
}
/* The real logo (downloaded from cerpaconstruction.com) rather than a
   re-typeset wordmark. Intrinsic ratio 2694x1176; the width/height
   attributes on the <img> reserve the space so the bar does not jump. */
.brand__logo { width: 180px; height: auto; display: block; }
.brand__logo--light { width: 200px; }
.brand span { font-family: var(--font-body); font-size: 0.7rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }

.topbar__phone {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-weight: 600; color: var(--navy); text-decoration: none;
  font-size: 1.02rem; white-space: nowrap;
}
.topbar__phone svg { width: 18px; height: 18px; stroke: var(--orange); flex: none; }
@media (max-width: 560px) { .brand span { display: none; } }

/* =====================================================================
   Hero — split: promise on the left, contact rail on the right.
   ===================================================================== */
.hero { padding: var(--sp-8) 0 var(--sp-7); background: var(--surface); }
.hero__grid {
  display: grid; gap: var(--sp-7);
  grid-template-columns: minmax(0, 1.25fr) minmax(320px, 0.85fr);
  align-items: start;
}
@media (max-width: 900px) { .hero__grid { grid-template-columns: 1fr; gap: var(--sp-6); } }

.hero h1 em { font-style: normal; color: var(--orange); }
.hero__proof {
  margin-top: var(--sp-5); padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: var(--sp-5) var(--sp-6);
}
.hero__proof div { min-width: 130px; }
.hero__proof dt { font-size: 0.76rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; margin-bottom: 2px; }
.hero__proof dd { margin: 0; font-family: var(--font-display); font-size: 1.28rem;
  color: var(--ink); font-weight: 600; }

/* -- Accessibility helpers ---------------------------------------- */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--navy); color: #fff; padding: 12px 20px;
  border-radius: 0 0 var(--r-md) 0; font-weight: 600; text-decoration: none;
}
.skip-link:focus { left: 0; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* =====================================================================
   Hero actions — inline pair that wraps on narrow screens.
   ===================================================================== */
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }

.section--warm ul[style] a {
  display: inline-block; padding: 0.6rem 1.1rem; border: 1px solid var(--line);
  border-radius: var(--r-pill); background: var(--surface); font-weight: 600;
  text-decoration: none; color: var(--navy); transition: border-color .16s ease, background .16s ease;
}
.section--warm ul[style] a:hover { border-color: var(--orange); background: #fff8ef; }
.section--warm ul[style] { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .75rem; }

/* -- Contact rail (the conversion block) ---------------------------- */
.rail {
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-md);
}
.rail h2 { font-size: 1.4rem; margin-bottom: var(--sp-2); }
.rail__note { font-size: 0.9rem; color: var(--muted); margin-bottom: var(--sp-4); }

.choice { margin-bottom: var(--sp-4); }
.choice__label {
  display: block; font-weight: 600; font-size: 0.92rem;
  color: var(--ink); margin-bottom: var(--sp-2);
}
.choice__label .req { color: var(--orange); margin-left: 3px; }

.contact-list { list-style: none; margin: 0; padding: 0; }
.contact-list li { margin-bottom: var(--sp-2); }
.contact-list label {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); border: 1px solid var(--line);
  border-radius: var(--r-md); cursor: pointer; background: var(--surface);
  font-size: 0.95rem; font-weight: 500; color: var(--ink);
  transition: border-color 0.16s ease, background 0.16s ease, box-shadow 0.16s ease;
  min-height: 48px;
}
.contact-list label:hover { border-color: var(--navy-mid); }
.contact-list input { position: absolute; opacity: 0; pointer-events: none; }
.contact-list input:checked + label {
  border-color: var(--orange); background: #fff8ef;
  box-shadow: 0 0 0 1px var(--orange) inset;
}
.contact-list input:focus-visible + label { outline: 3px solid var(--orange); outline-offset: 2px; }
.contact-list svg { width: 19px; height: 19px; flex: none; stroke: var(--navy-mid); }
.contact-list .hint {
  display: block; font-size: 0.78rem; font-weight: 400;
  color: var(--muted); margin-top: 2px;
}

/* -- Conditional fields ------------------------------------------- */
/* Neither the phone nor the email field is shown until a contact method
   is picked — an empty form should not ask for a number nobody has
   committed to giving yet. */
.phone-note {
  display: none; margin: var(--sp-3) 0 var(--sp-2);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  background: #fff8ef; border-left: 3px solid var(--orange);
  font-size: 0.86rem; color: #7a4a00; line-height: 1.5;
}
.phone-note.is-visible { display: block; }
.phone-field, .email-field { display: none; }
.phone-field.is-visible { display: block; }
.email-field.is-visible { display: block; }

.field { margin-bottom: var(--sp-4); }

/* "Add details" disclosure — keeps the rail short enough that the CTA
   button sits above the fold instead of below it. */
.more { margin-bottom: var(--sp-4); }
.more > summary {
  cursor: pointer; list-style: none; font-size: 0.9rem; font-weight: 600;
  color: var(--navy-mid); padding: 10px 0; min-height: 44px;
  display: flex; align-items: center; gap: 6px;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary::after {
  content: ""; width: 7px; height: 7px; margin-left: auto; flex: none;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform 0.2s ease;
}
.more[open] > summary::after { transform: rotate(225deg); }
.more__hint { font-weight: 400; color: var(--muted); font-size: 0.82rem; }
.more__body { padding-top: var(--sp-4); }
.more__body .field:last-child { margin-bottom: 0; }
.field label { display: block; font-weight: 600; font-size: 0.9rem;
  color: var(--ink); margin-bottom: var(--sp-2); }
.field label .req { color: var(--orange); }
.field .opt { font-weight: 400; color: var(--muted); font-size: 0.84rem; }

input[type="text"], input[type="tel"], input[type="email"], input[type="date"], select, textarea {
  width: 100%; padding: 12px var(--sp-4); font: inherit; font-size: 0.97rem;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-md);
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--navy-mid);
  box-shadow: 0 0 0 3px rgba(44,82,130,0.14);
}
input::placeholder, textarea::placeholder { color: #9aa9ba; }
textarea { resize: vertical; min-height: 96px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  width: 100%; min-height: 52px; padding: 14px var(--sp-5);
  font: inherit; font-weight: 600; font-size: 1.02rem;
  border: 1px solid transparent; border-radius: var(--r-md);
  cursor: pointer; text-decoration: none; text-align: center;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.12s ease;
}
.btn:active { transform: translateY(1px); }
/* `.btn` is width:100% on purpose — inside a form a full-width tap target is
   correct on mobile. In running content that same rule makes a CTA stretch
   the entire column. Use .btn--auto for links in prose/sections. */
.btn--auto { width: auto; padding-inline: var(--sp-6); }
.btn--primary { background: var(--orange); color: #fff; }
.btn--primary:hover { background: var(--orange-dark); }
.btn--outline { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn--outline:hover { background: var(--navy); color: #fff; }
.btn--ghost-light { background: rgba(255,255,255,0.08); color: #fff; border-color: rgba(255,255,255,0.4); }
.btn--ghost-light:hover { background: #fff; color: var(--navy); }
.btn[disabled] { opacity: 0.6; cursor: not-allowed; }
.btn .spinner {
  width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.4);
  border-top-color: #fff; border-radius: 50%;
  animation: spin 0.7s linear infinite; display: none;
}
.btn.is-busy .spinner { display: block; }
.btn.is-busy .btn__label { opacity: 0.75; }
@keyframes spin { to { transform: rotate(360deg); } }

.form-status { margin-top: var(--sp-3); font-size: 0.88rem; line-height: 1.5; min-height: 20px; }
.form-status[data-tone="error"] { color: #b42318; }
.form-status[data-tone="ok"] { color: #067647; }
.form-status[data-tone="info"] { color: var(--navy-mid); }

/* =====================================================================
   Pillars — a ruled list, not three equal floating tiles.
   ===================================================================== */
.pillars { list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--sp-5); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.pillar {
  border-top: 2px solid var(--navy); padding-top: var(--sp-4);
}
.pillar:nth-child(2) { border-top-color: var(--navy-mid); }
.pillar:nth-child(3) { border-top-color: var(--orange); }
.pillar h3 { margin-bottom: var(--sp-2); }
.pillar p { margin: 0; color: var(--muted); font-size: 0.97rem; }

.section--navy .pillar { border-top-color: rgba(255,255,255,0.5); }
.section--navy .pillar:nth-child(2) { border-top-color: rgba(255,255,255,0.3); }
.section--navy .pillar:nth-child(3) { border-top-color: var(--orange); }
.section--navy .pillar p { color: rgba(255,255,255,0.7); }

/* -- Steps (numbered, single column on mobile) ----------------------- */
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step;
  display: grid; gap: var(--sp-5); grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.steps li { counter-increment: step; position: relative; padding-left: 3.4rem; }
.steps li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute; left: 0; top: 0;
  font-family: var(--font-display); font-size: 1.6rem; font-weight: 600;
  color: var(--orange); line-height: 1;
}
.steps h3 { font-size: 1.02rem; margin-bottom: var(--sp-1); }
.steps p { margin: 0; font-size: 0.94rem; color: var(--muted); }
.section--navy .steps p { color: rgba(255,255,255,0.7); }

/* -- Definition rows (cost / timeline factors) ----------------------- */
.rows { display: grid; gap: 0; border-top: 1px solid var(--line); }
.rows__item {
  display: grid; grid-template-columns: minmax(180px, 0.9fr) 2fr;
  gap: var(--sp-5); padding: var(--sp-4) 0; border-bottom: 1px solid var(--line);
}
@media (max-width: 640px) { .rows__item { grid-template-columns: 1fr; gap: var(--sp-2); } }
.rows__item dt { font-family: var(--font-display); font-weight: 600; color: var(--ink); font-size: 1.06rem; }
.rows__item dd { margin: 0; }

.note {
  font-size: 0.86rem; color: var(--muted); background: var(--surface-alt);
  border-left: 3px solid var(--line); padding: var(--sp-4); border-radius: 0 var(--r-md) var(--r-md) 0;
}

/* -- FAQ ------------------------------------------------------------ */
.faq { display: grid; gap: var(--sp-3); }
.faq details {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); overflow: hidden;
}
.faq summary {
  cursor: pointer; padding: var(--sp-4); font-weight: 600; color: var(--ink);
  list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  min-height: 48px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; width: 9px; height: 9px; flex: none;
  border-right: 2px solid var(--orange); border-bottom: 2px solid var(--orange);
  transform: rotate(45deg) translateY(-2px); transition: transform 0.2s ease;
}
.faq details[open] summary::after { transform: rotate(225deg) translateY(-2px); }
.faq summary:hover { color: var(--navy-mid); }
.faq__body { padding: 0 var(--sp-4) var(--sp-4); color: var(--muted); font-size: 0.96rem; }
.faq__body p:last-child { margin-bottom: 0; }

/* -- Trust / license strip ------------------------------------------- */
.trust {
  display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-6);
  padding: var(--sp-5) 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.trust div { font-size: 0.9rem; color: var(--muted); }
.trust strong { display: block; color: var(--ink); font-size: 1.02rem; font-family: var(--font-display); }

/* -- Final CTA ------------------------------------------------------ */
.cta-final { background: var(--navy); color: rgba(255,255,255,0.85); padding: var(--sp-8) 0; }
.cta-final h2 { color: #fff; }
.cta-final .lead { color: rgba(255,255,255,0.72); }
.cta-final__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }

/* -- Footer --------------------------------------------------------- */
.footer { background: var(--navy-deep); color: rgba(255,255,255,0.62); padding: var(--sp-7) 0 var(--sp-5); font-size: 0.9rem; }
.footer a { color: #fff; text-decoration: none; }
.footer a:hover { text-decoration: underline; }
.footer__grid { display: grid; gap: var(--sp-5); grid-template-columns: 1.4fr 1fr 1fr; }
@media (max-width: 700px) { .footer__grid { grid-template-columns: 1fr; } }
.footer h4 { color: #fff; font-family: var(--font-body); font-size: 0.8rem;
  letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: var(--sp-3); }
.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.footer__bottom { margin-top: var(--sp-6); padding-top: var(--sp-4); border-top: 1px solid rgba(255,255,255,0.14); font-size: 0.82rem; }
.disclaimer { font-size: 0.78rem; line-height: 1.5; color: rgba(255,255,255,0.45); margin-top: var(--sp-3); }

/* =====================================================================
   Reveal-on-scroll — subtle, opacity + 12px rise. Disabled under
   prefers-reduced-motion (handled by the global rule above).

   IMPORTANT: `.reveal` starts at opacity 0 and is only restored by
   lead.js adding `.is-in`. Any page that uses the class WITHOUT loading
   /assets/lead.js renders its content permanently invisible. Every page
   that emits `class="reveal"` MUST also emit `<script src="/assets/lead.js">
  `. The animation is progressive enhancement and must never be the only
   thing that makes content visible.
   ===================================================================== */
.reveal { opacity: 0; transform: translateY(12px); }
.reveal.is-in { opacity: 1; transform: none; transition: opacity 0.5s ease, transform 0.5s ease; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

/* Inline SVG icons inherit stroke width from their size attribute. */
.icon { fill: none; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.8; }
/* =====================================================================
   Before/after scroll scrub.

   Native CSS scroll-driven animation — no JavaScript. Runs on the
   compositor in Chrome, Firefox and Safari 26.4+.

   The clip-path inset() reveals AREA, not brightness, so the transition
   never reads as a brightness crossfade.

   CRITICAL: the two images must be the same scene at the same angle. Run
   scripts/align-before-after.py on any pair first — raw photos from the
   main site are NOT aligned and produce a visible jump.

   Markup contract:
     <figure class="ba" style="--ba-ar:16/9">
       <img class="ba__before" src="...-before.webp" alt="...">
       <img class="ba__after"  src="...-after.webp"  alt="...">
       <figcaption class="ba__label ba__label--before">Before</figcaption>
       <figcaption class="ba__label ba__label--after">After</figcaption>
     </figure>
   ===================================================================== */
.ba {
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--ba-ar, 16 / 9);
  background: var(--surface-alt);
  border-radius: var(--r-md);
}
.ba__before,
.ba__after {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ba__before { z-index: 1; }
.ba__after {
  z-index: 2;
  clip-path: inset(0 0 0 100%);
  animation: ba-reveal linear both;
  animation-timeline: view();
  animation-range: entry 25% cover 55%;
}
@keyframes ba-reveal {
  from { clip-path: inset(0 0 0 100%); }
  to   { clip-path: inset(0 0 0 0); }
}

.ba__label {
  position: absolute;
  bottom: var(--sp-4);
  z-index: 3;
  margin: 0;
  padding: 0.3rem 0.7rem;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--surface);
  background: rgba(22, 32, 43, 0.72);
  border-radius: var(--r-pill);
  backdrop-filter: blur(6px);
  pointer-events: none;
}
.ba__label--before { left: var(--sp-4); }
.ba__label--after  { right: var(--sp-4); }

/* No scroll-driven animation support: show the finished result outright.
   A static after photo beats a static before photo. */
@supports not (animation-timeline: view()) {
  .ba__after { clip-path: inset(0 0 0 0); }
}

/* Reduced motion: no scrub, show the after frame. Never leave the
   before frame as the only visible one — that misrepresents the work. */
@media (prefers-reduced-motion: reduce) {
  .ba__after {
    animation: none;
    clip-path: inset(0 0 0 0);
  }
}

/* Caption under the figure — the honest note about what is shown. */
.ba-note {
  margin-top: var(--sp-3);
  font-size: 0.85rem;
  color: var(--muted);
}

/* =====================================================================
   Photo strip — real project photos on every service page.

   Every landing page carries at least one image; a page with zero images
   does not convert. `aspect-ratio` + explicit width/height attributes
   reserve the box so the images cannot cause layout shift.
   ===================================================================== */
.shots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-5);
  margin-top: var(--sp-6);
}
.shot {
  margin: 0;
  display: flex;
  flex-direction: column;
}
.shot img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--r-md);
  background: var(--surface-alt);
  box-shadow: var(--shadow-md);
}
.shot figcaption {
  margin-top: var(--sp-3);
  font-size: 0.875rem;
  color: var(--muted);
  line-height: 1.5;
}

/* =====================================================================
   Sticky mobile action bar — mobile only.

   The pages are long and the form is at the bottom. On a phone this is
   the only always-available action. Desktop hides it: the header already
   carries the phone number and a second bar competes with the CTA.

   Hidden entirely from assistive tech duplication via aria-label on the
   region; the links themselves stay focusable and readable.
   ===================================================================== */
.stickybar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: none;
  gap: 1px;
  background: var(--line);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.stickybar__act {
  flex: 1 1 0;
  min-height: 56px;              /* comfortable tap target */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.stickybar__act .icon { width: 20px; height: 20px; }
.stickybar__act--wide {
  flex: 1.4 1 0;
  background: var(--orange);
  color: #fff;
}
/* Only show it where it helps: narrow viewports. */
@media (max-width: 860px) {
  .stickybar { display: flex; }
  /* Keep the last content clear of the bar. */
  .stickybar ~ * { padding-bottom: 0; }
  body { padding-bottom: 58px; }
}
@media (min-width: 861px) {
  .stickybar { display: none; }
}

/* The scrub on a service page sits inside the 1140px wrap. Keep it narrower
   than a full-bleed figure so the wipe reads as a considered editorial object
   rather than a banner, and give it breathing room from the photo strip. */
.work-scrub {
  margin-top: var(--sp-6);
  aspect-ratio: 16 / 9;
  box-shadow: var(--shadow-lg);
}
.work-scrub + .ba-note { margin-top: var(--sp-4); }
@media (max-width: 860px) {
  .work-scrub { aspect-ratio: 4 / 3; }
}

/* =====================================================================
   Hero band — full-bleed project photograph between the hero and the
   service list on the home page.

   Height is capped with clamp() so the photo reads as an editorial
   statement rather than pushing the service cards below the fold. The
   section owns the height and the image fills it with object-fit, which
   keeps the layout stable before the image decodes.
   ===================================================================== */
.heroband {
  width: 100%;
  padding: var(--sp-6) var(--sp-5);
  display: flex;
  justify-content: center;
  background: var(--surface-alt);
}
/* Centred plate, NOT a full-bleed banner. Capping the width is what makes the
   4:3 photograph read as an editorial object: at 420px wide the complete frame
   is 420x315, so nothing is cropped and nothing is empty. Letting it span the
   viewport instead forces a choice — crop ~66% of the frame, or contain it and
   leave ~73% of the band as bare grey. Neither was acceptable. */
.heroband__figure {
  margin: 0;
  width: 100%;
  max-width: 420px;
}
.heroband__figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
}
@media (max-width: 860px) {
  .heroband {
    padding: var(--sp-5) var(--sp-4);
  }
}
