/* ==========================================================================
   Schroeder's Expert Wall Inc. - Stylesheet (v3 / logo-coordinated)
   Palette derived from brand mark: charcoal, steel, navy, controlled red
   ========================================================================== */

:root {
  /* Surface tokens */
  --bg: #f6f7f9;
  --bg-warm: #f3f0ea;
  --bg-alt: #eceff3;
  --bg-dark: #131820;
  --bg-deeper: #0c1015;
  --surface: #ffffff;
  --surface-2: #fafbfc;

  /* Text tokens */
  --text: #161b22;
  --text-soft: #2a3340;
  --text-muted: #5b6573;
  --text-inverse: #f6f7f9;

  /* Brand tokens */
  --primary: #1f3a6e;
  --primary-dark: #152a52;
  --primary-soft: #e7ecf3;
  --accent: #c8202c;
  --accent-dark: #9d1820;
  --accent-soft: #fbe7e9;
  --steel: #6b7785;
  --steel-light: #9ba5b3;
  --steel-soft: #dde1e7;

  /* Lines */
  --border: #e2e5ea;
  --border-strong: #c4c9d2;

  /* States */
  --success: #2f7a52;
  --warn: #b35900;

  /* Spacing */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;

  /* Radii */
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 16px;
  --radius-xl: 22px;
  --radius-pill: 999px;

  /* Shadows (cooler, premium) */
  --shadow-xs: 0 1px 2px rgba(22, 27, 34, 0.06);
  --shadow-sm: 0 2px 8px rgba(22, 27, 34, 0.06), 0 1px 2px rgba(22, 27, 34, 0.04);
  --shadow: 0 8px 24px rgba(22, 27, 34, 0.08), 0 2px 6px rgba(22, 27, 34, 0.04);
  --shadow-lg: 0 24px 48px rgba(22, 27, 34, 0.14), 0 4px 12px rgba(22, 27, 34, 0.06);
  --shadow-ring: 0 0 0 1px var(--border), 0 8px 24px rgba(22, 27, 34, 0.06);

  /* Type */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --font-display: "Manrope", "Inter", -apple-system, BlinkMacSystemFont,
    "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Layout */
  --container: 1200px;
  --container-narrow: 880px;
  --header-h: 84px;
}

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

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

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "ss01", "cv11";
}

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

a {
  color: var(--primary);
  text-decoration: none;
  transition: color 0.15s ease;
}

a:hover {
  color: var(--accent);
}

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

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 var(--space-4);
  color: var(--text);
}

h1 {
  font-size: clamp(2.3rem, 5vw, 3.8rem);
  letter-spacing: -0.03em;
  font-weight: 800;
}

h2 {
  font-size: clamp(1.8rem, 3.2vw, 2.6rem);
  letter-spacing: -0.025em;
}

h3 {
  font-size: clamp(1.15rem, 1.6vw, 1.35rem);
  letter-spacing: -0.015em;
  font-weight: 700;
}

h4 {
  font-size: 1rem;
  font-weight: 600;
}

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

ul,
ol {
  padding-left: 1.2rem;
  margin: 0 0 var(--space-4);
}

li {
  margin-bottom: var(--space-2);
}

li::marker {
  color: var(--accent);
}

.lead {
  font-size: 1.18rem;
  color: var(--text-soft);
  max-width: 60ch;
  line-height: 1.55;
}

.muted {
  color: var(--text-muted);
}

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

.container-narrow {
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

section {
  padding-block: var(--space-9);
}

.section-tight {
  padding-block: var(--space-7);
}

.section-alt {
  background: var(--bg-alt);
}

/* Blueprint background — architectural/planning themed section.
   The PNG is applied at full strength (no image opacity reduction).
   A near-transparent white radial sits ONLY over the empty center so
   heading/card text stays crisp while the corner blueprints show fully. */
.section-blueprint {
  position: relative;
  background-color: var(--bg-alt);
  background-image:
    radial-gradient(ellipse 70% 60% at center, rgba(255, 255, 255, 0.45) 0%, rgba(255, 255, 255, 0) 60%),
    url("../opt/how-it-works.jpg");
  background-size: cover, cover;
  background-position: center center, center center;
  background-repeat: no-repeat, no-repeat;
}

.section-dark {
  background: var(--bg-dark);
  color: var(--text-inverse);
}

.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4,
.trust-band h1,
.trust-band h2,
.trust-band h3,
.trust-band h4 {
  color: var(--text-inverse);
}

.section-dark .muted {
  color: rgba(246, 247, 249, 0.7);
}

.section-dark a {
  color: var(--text-inverse);
}

.eyebrow {
  display: inline-block;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}

.section-dark .eyebrow {
  color: var(--accent);
}

.eyebrow-rule {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: var(--space-3);
}

.eyebrow-rule::before {
  content: "";
  width: 28px;
  height: 2px;
  background: var(--accent);
  display: inline-block;
}

.section-header {
  max-width: 60ch;
  margin: 0 auto var(--space-7);
  text-align: center;
}

.section-header .eyebrow-rule {
  justify-content: center;
}

.text-center {
  text-align: center;
}

.divider {
  height: 1px;
  background: var(--border);
  margin: var(--space-7) 0;
  border: 0;
}

.rule-red {
  width: 56px;
  height: 3px;
  background: var(--accent);
  border: 0;
  margin: 0 0 var(--space-5);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.95rem 1.5rem;
  font-family: var(--font-sans);
  font-size: 0.98rem;
  font-weight: 600;
  line-height: 1;
  border: 1.5px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease,
    box-shadow 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  white-space: nowrap;
  letter-spacing: -0.005em;
}

.btn:hover {
  transform: translateY(-1px);
}

.btn-primary {
  background: var(--primary);
  color: var(--text-inverse);
  box-shadow: var(--shadow-sm);
}

.btn-primary:hover {
  background: var(--primary-dark);
  color: var(--text-inverse);
  box-shadow: var(--shadow);
}

.btn-accent {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 6px 16px rgba(200, 32, 44, 0.18), 0 2px 4px rgba(200, 32, 44, 0.12);
}

.btn-accent:hover {
  background: var(--accent-dark);
  color: #fff;
  box-shadow: 0 12px 24px rgba(200, 32, 44, 0.24), 0 4px 8px rgba(200, 32, 44, 0.14);
}

.btn-dark {
  background: var(--bg-dark);
  color: var(--text-inverse);
  box-shadow: var(--shadow-sm);
}

.btn-dark:hover {
  background: var(--bg-deeper);
  color: var(--text-inverse);
  box-shadow: var(--shadow);
}

/* Light-surface secondary CTA: navy text + navy-tinted border reads as
   intentional brand styling, not a default gray box. Hover fills navy. */
.btn-outline {
  background: transparent;
  color: var(--primary);
  border-color: var(--border-strong);
}

.btn-outline:hover {
  background: var(--primary);
  color: var(--text-inverse);
  border-color: var(--primary);
}

/* Dark-surface secondary CTA (glass): the four dark contexts on the site —
   .section-dark, .cta-banner, .trust-band, .site-footer. White text + icon
   and a soft white border are ALWAYS legible before hover; a faint translucent
   fill gives the premium glass look. Hover brightens the fill to solid white
   and switches text to navy — it enhances the button, it does not reveal it.
   (Fixes the previously near-invisible #161b22-on-dark phone CTAs globally.) */
.section-dark .btn-outline,
.cta-banner .btn-outline,
.trust-band .btn-outline,
.site-footer .btn-outline {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-inverse);
  border-color: rgba(246, 247, 249, 0.5);
}

.section-dark .btn-outline:hover,
.cta-banner .btn-outline:hover,
.trust-band .btn-outline:hover,
.site-footer .btn-outline:hover {
  background: var(--text-inverse);
  color: var(--primary);
  border-color: var(--text-inverse);
}

.btn-lg {
  padding: 1.05rem 1.8rem;
  font-size: 1rem;
}

.btn-block {
  width: 100%;
}

.icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.site-header.is-scrolled {
  border-bottom-color: var(--border);
  box-shadow: 0 4px 16px rgba(22, 27, 34, 0.04);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  height: var(--header-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.brand img {
  height: 56px;
  width: auto;
}

.brand-locality {
  display: none;
  flex-direction: column;
  font-family: var(--font-display);
  line-height: 1.05;
}

.brand-locality strong {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.brand-locality span {
  font-size: 0.7rem;
  color: var(--steel);
  letter-spacing: 0.04em;
}

@media (min-width: 1024px) {
  .brand-locality {
    display: flex;
    border-left: 1px solid var(--border);
    padding-left: var(--space-3);
  }
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.nav-list {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-list a {
  color: var(--text);
  font-weight: 500;
  font-size: 0.95rem;
  padding: var(--space-2) 0;
  position: relative;
  letter-spacing: -0.005em;
}

.nav-list a:hover,
.nav-list a[aria-current="page"] {
  color: var(--primary);
}

.nav-list a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

.nav-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--accent);
  color: #fff !important;
  padding: 0.7rem 1.15rem;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.9rem;
  box-shadow: 0 4px 12px rgba(200, 32, 44, 0.18);
  letter-spacing: -0.005em;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.nav-cta:hover {
  background: var(--accent-dark);
  color: #fff !important;
  transform: translateY(-1px);
  box-shadow: 0 8px 16px rgba(200, 32, 44, 0.24);
}

.nav-cta svg {
  width: 16px;
  height: 16px;
}

.nav-toggle {
  display: none;
  background: none;
  border: 0;
  width: 44px;
  height: 44px;
  padding: 0;
  cursor: pointer;
  color: var(--text);
}

.nav-toggle svg {
  width: 26px;
  height: 26px;
  margin: auto;
}

@media (max-width: 880px) {
  :root {
    --header-h: 72px;
  }

  .brand img {
    height: 44px;
  }

  .nav-toggle {
    display: grid;
    place-items: center;
  }

  .nav {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-5);
    gap: var(--space-4);
    transform: translateY(-110%);
    transition: transform 0.25s ease;
    box-shadow: var(--shadow);
  }

  .nav.is-open {
    transform: translateY(0);
  }

  .nav-list {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  .nav-list a {
    padding: var(--space-3) 0;
    border-bottom: 1px solid var(--border);
    font-size: 1.05rem;
    font-weight: 500;
  }

  .nav-cta {
    justify-content: center;
    padding: 0.95rem 1.2rem;
    font-size: 1rem;
  }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding-block: clamp(var(--space-7), 8vw, var(--space-10)) var(--space-9);
  background:
    radial-gradient(900px 500px at 100% -10%, rgba(31, 58, 110, 0.08), transparent 60%),
    radial-gradient(700px 400px at -10% 110%, rgba(200, 32, 44, 0.05), transparent 60%),
    var(--bg);
  overflow: hidden;
  border-bottom: 1px solid var(--border);
}

/* ==========================================================================
   HOMEPAGE HERO — finished-interior photo as the full-bleed background.
   The room IS the hero; the copy sits on top, anchored left. No card, frame,
   or contained image — the photo fills the section edge to edge.
   ========================================================================== */
.hero--home {
  display: flex;
  align-items: center;
  min-height: clamp(620px, 82vh, 820px);
  padding-block: var(--space-8);
  background-image:
    image-set(
      url("../homepage-background.webp") type("image/webp"),
      url("../Homepage Background.png") type("image/png")
    );
  background-size: cover;
  background-position: center right;
  background-repeat: no-repeat;
  background-color: var(--bg);
}

/* Readability layer: a strong white wash on the left for the copy, dissolving
   to near-clear on the right so the fireplace, coved ceiling, and open floor
   stay visible behind and around the headline. */
.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.97) 0%,
    rgba(255, 255, 255, 0.90) 32%,
    rgba(255, 255, 255, 0.58) 58%,
    rgba(255, 255, 255, 0.12) 100%
  );
}

.hero-grid--home {
  position: relative;
  z-index: 2; /* copy sits above the overlay + photo */
}

.hero-content {
  max-width: 50%;
  min-width: min(100%, 30rem);
}

/* Tablet: widen the copy column and even out the overlay so text stays legible
   as the room compresses. */
@media (max-width: 1100px) {
  .hero-content { max-width: 64%; }
  .hero-overlay {
    background: linear-gradient(
      90deg,
      rgba(255, 255, 255, 0.97) 0%,
      rgba(255, 255, 255, 0.92) 45%,
      rgba(255, 255, 255, 0.68) 72%,
      rgba(255, 255, 255, 0.30) 100%
    );
  }
}

/* Mobile: the photo reads as a soft full-bleed backdrop; the overlay becomes a
   near-solid vertical wash so the stacked copy stays crisp on a small screen. */
@media (max-width: 760px) {
  .hero--home {
    min-height: 0;
    padding-block: clamp(var(--space-7), 12vw, var(--space-9));
    background-position: center center;
  }
  .hero-content { max-width: 100%; }
  .hero-overlay {
    background: linear-gradient(
      180deg,
      rgba(255, 255, 255, 0.95) 0%,
      rgba(255, 255, 255, 0.90) 60%,
      rgba(255, 255, 255, 0.82) 100%
    );
  }
}

/* ==========================================================================
   HOMEPAGE HERO — branded edge accent (red + blue vertical lines).
   Decorative only: a pseudo-element pinned to the far-left edge of the hero,
   painted above the white readability wash (z-index:2, same as the copy) but
   the copy is later in the DOM so it always stays on top. The source art
   (assets/RED BLUE LINES.png) is transparent except for the two lines, which
   sit at image-x 25..149 of 1568 (a ~1.6% transparent left margin). We scale
   the art with background-size and nudge it left with background-position so
   the red line lands flush against the page edge, then clip the element width
   to the blue line's right edge. .hero has overflow:hidden, so this can never
   create horizontal scroll, and the rule is scoped to .hero--home (index.html
   only) so no other page is affected.
   ========================================================================== */
.hero--home::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40px;
  z-index: 2;
  pointer-events: none;
  background-image: url("../RED%20BLUE%20LINES.png");
  background-repeat: no-repeat;
  background-position: -8px top;   /* crop the art's transparent left margin */
  background-size: 506px 100%;     /* vertical stretch is invisible on solid lines */
}

@media (max-width: 760px) {
  /* Slimmer than the 24px container padding so the lines never sit under the
     stacked mobile copy. */
  .hero--home::before {
    width: 22px;
    background-position: -4px top;
    background-size: 278px 100%;
  }
}

.hero-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0.45rem 1rem;
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--text-soft);
  margin-bottom: var(--space-5);
  box-shadow: var(--shadow-xs);
}

.hero-tag .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px rgba(47, 122, 82, 0.18);
}

.hero h1 {
  margin-bottom: var(--space-4);
  text-wrap: balance;
}

.hero h1 .accent {
  color: var(--accent);
}

.hero-sub {
  font-size: 1.18rem;
  color: var(--text-soft);
  margin-bottom: var(--space-6);
  max-width: 54ch;
  line-height: 1.55;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.trust-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.trust-pills li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 0.42rem 0.85rem;
  border-radius: var(--radius-pill);
  margin: 0;
  box-shadow: var(--shadow-xs);
}

.trust-pills svg {
  width: 14px;
  height: 14px;
  color: var(--accent);
}

/* ---------- Cards & service grid ---------- */
.grid {
  display: grid;
  gap: var(--space-5);
}

.grid-2 {
  grid-template-columns: repeat(2, 1fr);
}

.grid-3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid-4 {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 880px) {
  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 600px) and (max-width: 880px) {
  .grid-3,
  .grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-xs);
  transition: transform 0.18s ease, box-shadow 0.18s ease,
    border-color 0.18s ease;
}

.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
  border-color: var(--border-strong);
}

.service-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
  overflow: hidden;
}

.service-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}

.service-card:hover::before {
  transform: scaleX(1);
}

.service-card .icon-wrap {
  width: 52px;
  height: 52px;
  border-radius: 12px;
  background: var(--primary-soft);
  color: var(--primary);
  display: grid;
  place-items: center;
  margin-bottom: var(--space-5);
}

.service-card .icon-wrap svg {
  width: 26px;
  height: 26px;
}

.service-card h3 {
  margin-bottom: var(--space-3);
  font-size: 1.25rem;
}

.service-card p {
  color: var(--text-muted);
  margin-bottom: var(--space-5);
  flex-grow: 1;
}

.service-card .card-link {
  font-weight: 600;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.95rem;
  letter-spacing: -0.005em;
}

.service-card .card-link:hover {
  color: var(--accent);
  gap: var(--space-3);
}

.service-card .card-link svg {
  width: 14px;
  height: 14px;
  transition: transform 0.18s ease;
}

.service-card:hover .card-link svg {
  transform: translateX(3px);
}

/* ---------- Feature / benefits ---------- */
.feature {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  height: 100%;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.feature:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs);
}

.feature .feature-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

.feature .feature-icon svg {
  width: 22px;
  height: 22px;
}

.feature h3 {
  font-size: 1.08rem;
  margin-bottom: var(--space-2);
  font-weight: 700;
}

.feature p {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0;
  line-height: 1.55;
}

/* ---------- Process / steps ---------- */
.process {
  counter-reset: step;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-5);
}

@media (max-width: 880px) {
  .process {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 600px) and (max-width: 880px) {
  .process {
    grid-template-columns: repeat(2, 1fr);
  }
}

.step {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  position: relative;
  counter-increment: step;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.step:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs);
}

.step::before {
  content: "0" counter(step);
  font-family: var(--font-display);
  font-size: 2.2rem;
  font-weight: 800;
  color: var(--accent);
  display: block;
  margin-bottom: var(--space-3);
  line-height: 1;
  letter-spacing: -0.04em;
}

.step h3 {
  font-size: 1.1rem;
  margin-bottom: var(--space-2);
}

.step p {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0;
}

/* ---------- Project type grid (chips/tiles) ---------- */
.project-types {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  list-style: none;
  padding: 0;
  margin: 0;
}

@media (max-width: 880px) {
  .project-types {
    grid-template-columns: 1fr 1fr;
  }
}

.project-types li {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-weight: 500;
  color: var(--text);
  margin: 0;
  transition: border-color 0.18s ease, transform 0.18s ease;
}

.project-types li:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}

.project-types li svg {
  width: 18px;
  height: 18px;
  color: var(--accent);
  flex-shrink: 0;
}

/* ---------- Testimonials / Proof Wall ----------
   Three tiers: header rating object, featured spotlight (testimonial +
   project case study), and a variable-height masonry review wall. All depth
   and motion is transform/opacity only and disabled under reduced-motion. */
.proof {
  /* gold review-star token (distinct from the red CTA accent) */
  --star: #e0a32e;
  /* lift the limewash material a touch so the section reads more premium */
  --texture-opacity: 0.18;
}

.proof .stars,
.proof-rating-stars {
  display: inline-flex;
  gap: 2px;
  color: var(--star);
}

/* Tier 1 - header rating object */
.proof-rating {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-2) var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-xs);
}

.proof-rating-stars svg { width: 18px; height: 18px; }

.proof-rating-text {
  font-size: 0.95rem;
  color: var(--text-muted);
}

.proof-rating-text strong {
  color: var(--text);
  font-weight: 700;
}

/* Shared context / category chip */
.proof-chip {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--primary);
  background: var(--primary-soft);
  border-radius: var(--radius-pill);
  padding: 0.32rem 0.7rem;
}

.proof-chip-cat {
  color: var(--steel);
  background: var(--steel-soft);
  margin-bottom: var(--space-3);
}

/* ---------- Tier 2: premium review rail (slow marquee) ----------
   Every card carries equal weight. On pointer devices the track drifts
   slowly and pauses on hover/focus. Under reduced-motion and on touch /
   small screens it degrades to a swipe-friendly scroll-snap rail with no
   auto-motion, and the duplicate loop set is hidden. CSS-only. */
.review-rail {
  position: relative;
  margin: 0 0 var(--space-7);
  overflow: hidden;
  /* feather both edges so cards drift in and out softly */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.review-track {
  display: flex;
  align-items: center;
  width: max-content;
  animation: review-marquee 80s linear infinite;
  will-change: transform;
}

.review-rail:hover .review-track,
.review-rail:focus-within .review-track {
  animation-play-state: paused;
}

@keyframes review-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ---------- Review card (equal weight, off-white, faint plaster) ---------- */
.review-card {
  position: relative;
  flex: 0 0 auto;
  width: 340px;
  margin-right: var(--space-5);
  display: flex;
  flex-direction: column;
  padding: var(--space-6);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition:
    transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.22s ease,
    border-color 0.22s ease;
}

/* Drywall/plaster texture comes from the shared .has-card-texture system
   (knockdown finish + white readability scrim), so .review-card is added to
   that selector group below rather than re-implementing it here. */

/* organic, non-robotic size variation */
.review-card--sm { width: 300px; }
.review-card--lg { width: 392px; }

.review-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow);
  border-color: var(--border-strong);
}

.review-card .stars {
  margin-bottom: var(--space-3);
}

.review-card .stars svg {
  width: 18px;
  height: 18px;
}

.review-card blockquote {
  font-size: 1.02rem;
  line-height: 1.6;
  color: var(--text);
  margin: 0 0 var(--space-5);
  flex-grow: 1;
}

.review-card cite {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-style: normal;
  font-weight: 600;
  color: var(--text);
  font-size: 0.95rem;
}

.review-card .avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--primary);
  color: var(--text-inverse);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
  flex-shrink: 0;
}

/* Tier 3 - CTA row */
.proof-cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-7);
}

/* ---------- Review rail: touch / small screens = swipe rail ----------
   No auto-motion on small screens; users scroll/swipe instead. */
@media (max-width: 700px) {
  .review-rail {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .review-rail::-webkit-scrollbar {
    height: 0;
  }
  .review-track {
    width: max-content;
    animation: none;
  }
  .review-card {
    scroll-snap-align: center;
  }
  /* drop the duplicate loop set; only the real reviews remain to swipe */
  .review-track > [aria-hidden="true"] {
    display: none;
  }
  .review-card,
  .review-card--sm,
  .review-card--lg {
    width: min(82vw, 340px);
  }
}

/* Mobile CTA: full-width stacked buttons */
@media (max-width: 600px) {
  .proof-cta .btn {
    flex: 1 1 100%;
    justify-content: center;
  }
}

/* ---------- Review rail: reduced motion = static swipe rail ---------- */
@media (prefers-reduced-motion: reduce) {
  .review-rail {
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .review-rail::-webkit-scrollbar {
    height: 0;
  }
  .review-track {
    animation: none;
  }
  .review-track > [aria-hidden="true"] {
    display: none;
  }
  .review-card,
  .review-card:hover {
    transition: none;
    transform: none;
  }
}

/* ---------- Service area ---------- */
.area-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  list-style: none;
  padding: 0;
  margin: 0;
}

@media (max-width: 880px) {
  .area-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

.area-list li {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
  font-weight: 600;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: 0.95rem;
}

.area-list svg {
  width: 16px;
  height: 16px;
  color: var(--accent);
  flex-shrink: 0;
}

/* ---------- Trust band ---------- */
.trust-band {
  background: var(--bg-dark);
  color: var(--text-inverse);
  position: relative;
  overflow: hidden;
}

.trust-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(700px 400px at 100% 0%, rgba(31, 58, 110, 0.55), transparent 60%),
    radial-gradient(500px 300px at 0% 100%, rgba(200, 32, 44, 0.18), transparent 60%);
  pointer-events: none;
}

.trust-band > .container {
  position: relative;
  z-index: 1;
}

.trust-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-5);
  margin-top: var(--space-7);
  padding-top: var(--space-7);
  border-top: 1px solid rgba(246, 247, 249, 0.12);
}

@media (max-width: 880px) {
  .trust-stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

.trust-stat .num {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 2.6rem);
  font-weight: 800;
  color: var(--text-inverse);
  line-height: 1.05;
  margin-bottom: var(--space-2);
  letter-spacing: -0.03em;
}

.trust-stat .num em {
  color: var(--accent);
  font-style: normal;
}

.trust-stat .lbl {
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(246, 247, 249, 0.65);
  font-weight: 600;
}

/* ---------- CTA banner ---------- */
.cta-banner {
  background: var(--bg-dark);
  color: var(--text-inverse);
  border-radius: var(--radius-xl);
  padding: var(--space-8) var(--space-7);
  text-align: center;
  position: relative;
  overflow: hidden;
}

.cta-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(700px 320px at 100% -20%, rgba(31, 58, 110, 0.6), transparent 60%),
    radial-gradient(500px 320px at 0% 120%, rgba(200, 32, 44, 0.18), transparent 60%);
  pointer-events: none;
}

.cta-banner > * {
  position: relative;
  z-index: 1;
}

.cta-banner h2 {
  color: var(--text-inverse);
  margin-bottom: var(--space-3);
  text-wrap: balance;
}

.cta-banner p {
  color: rgba(246, 247, 249, 0.82);
  max-width: 50ch;
  margin: 0 auto var(--space-6);
  font-size: 1.08rem;
}

.cta-banner .hero-actions {
  justify-content: center;
  margin: 0;
}

@media (max-width: 880px) {
  .cta-banner {
    padding: var(--space-7) var(--space-5);
  }
}

/* ---------- Brand watermark (Schroeder's circular icon accent) ----------
   Decorative ghost mark for dark accent surfaces. Anchored to the top-right
   corner so it sits inside the existing navy radial glow, sized large but
   held at low opacity so it reads as atmosphere — never a pasted-on logo.
   Pinned behind content (z-index:0) so it can never reduce readability or
   overlap stats/CTAs. Purely decorative: aria-hidden in markup. */
.brand-mark {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}

/* Homepage "Why Schroeder's" band — the watermark is pulled inward over the
   right-hand metrics so it anchors the right half of the section and sits
   above/behind the "Free Honest Estimates" stat instead of floating in the
   corner. Anchored by `bottom` (ties it to the stats row) and a container-aware
   `right` (the mark's right edge tracks the centered content edge, so it stays
   put across desktop widths and never clips against the section's
   overflow:hidden). Stays a decorative background layer at z-index:0 — copy is
   always on top. position/z-index repeated here so this rule beats the later,
   equal-weight `.has-plaster > *` rule that would otherwise force
   position:relative and drop the mark into the flow. */
.trust-band .brand-mark {
  position: absolute;
  z-index: 0;
  top: auto;
  bottom: 2rem;
  right: max(1.5rem, calc((100vw - var(--container)) / 2));
  width: clamp(250px, 38vw, 475px);
  aspect-ratio: 1 / 1;
  opacity: 0.15;
  filter: saturate(0.85) drop-shadow(0 24px 48px rgba(0, 0, 0, 0.4));
  /* Fade the lower third toward transparent so the stats row it overlaps
     ("Free Honest Estimates") stays fully legible — opacity is reduced only
     in the overlapping area, the size is preserved. */
  -webkit-mask-image: linear-gradient(to bottom, #000 56%, transparent 90%);
  mask-image: linear-gradient(to bottom, #000 56%, transparent 90%);
}

/* Tablet: slightly reduce the inward offset — sit nearer the right edge. */
@media (max-width: 880px) {
  .trust-band .brand-mark {
    width: clamp(200px, 40vw, 290px);
    right: 0;
    bottom: 1.5rem;
    opacity: 0.1;
  }
}

/* Mobile: return to a small corner watermark so it never crowds the
   full-width copy; very low opacity keeps text the clear priority. */
@media (max-width: 600px) {
  .trust-band .brand-mark {
    width: clamp(130px, 42vw, 170px);
    top: 0.75rem;
    bottom: auto;
    right: 0;
    opacity: 0.07;
  }
}

/* Final CTA banner (shared site-wide) — decorative watermark moved out of the
   top-right corner into the open right-side area beside the centered copy.
   Vertically centered and pinned behind content (z-index:0, pointer-events:none
   inherited from .brand-mark). position:absolute keeps it out of flow so it can
   never change the banner's height, padding, button alignment, or text wrapping.
   Opacity matches the prior corner mark so readability is unchanged. */
.cta-banner .brand-mark {
  position: absolute;
  z-index: 0;
  top: 50%;
  right: clamp(1.5rem, 5vw, 4rem);
  transform: translateY(-50%);
  width: clamp(160px, 22vw, 300px);
  aspect-ratio: 1 / 1;
  opacity: 0.08;
}

/* Tablet & mobile: the centered copy spans nearly the full width, so there is
   no open right-side gutter. Drop the mark to dead-center behind the content
   and hold it very faint so it reads as atmosphere and never crowds the text. */
@media (max-width: 880px) {
  .cta-banner .brand-mark {
    top: 50%;
    right: 50%;
    transform: translate(50%, -50%);
    width: clamp(180px, 55vw, 260px);
    opacity: 0.05;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .brand-mark {
    transition: opacity 0.6s ease;
  }
}

/* ---------- Compact mid-page trust CTA ---------- */
.trust-cta {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
  box-shadow: var(--shadow-xs);
}

.trust-cta strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--text);
  margin-bottom: var(--space-1);
  letter-spacing: -0.015em;
}

.trust-cta span {
  color: var(--text-muted);
  font-size: 0.96rem;
}

.trust-cta .actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

@media (max-width: 720px) {
  .trust-cta {
    grid-template-columns: 1fr;
  }
}

/* ---------- Page header ---------- */
.page-header {
  background:
    radial-gradient(900px 400px at 90% -10%, rgba(31, 58, 110, 0.06), transparent 60%),
    var(--bg);
  padding-block: var(--space-9) var(--space-7);
  border-bottom: 1px solid var(--border-strong);
  /* Gradient fade on the bottom edge (replaces the former ::after line so the
     texture system can use ::after for its readability scrim). */
  border-image: linear-gradient(90deg, transparent, var(--border-strong), transparent) 1;
  position: relative;
  overflow: hidden;
  /* Own stacking context so the decorative left-edge lines (.hero-edge-lines)
     resolve predictably on plain heroes too (the .has-texture variants already
     isolate). No visual/layout effect on existing content. */
  isolation: isolate;
}

.page-header-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--space-8);
  align-items: center;
}

@media (max-width: 880px) {
  .page-header-grid {
    grid-template-columns: 1fr;
    gap: var(--space-6);
  }
}

/* Hero image fill — scoped to Drywall, Ceilings & Painting page headers.
   Lets the right-side hero photo fill the full height of its grid cell on
   desktop while the base .photo-frame img rules keep object-fit: cover.
   Mobile (single column) keeps the .ratio-4-3 aspect behavior unchanged. */
@media (min-width: 881px) {
  .page-header-grid--hero-fill {
    align-items: stretch;
  }
  .page-header-grid--hero-fill > div:last-child {
    display: flex;
  }
  .page-header-grid--hero-fill > div:last-child > .photo-frame {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
  }
}

.page-header h1 .accent {
  color: var(--accent);
}

.page-header .breadcrumbs {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: var(--space-4);
}

.page-header .breadcrumbs a {
  color: var(--text-muted);
}

.page-header .breadcrumbs a:hover {
  color: var(--primary);
}

/* ---------- Content layout ---------- */
.content-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: var(--space-8);
  align-items: start;
}

@media (max-width: 880px) {
  .content-grid {
    grid-template-columns: 1fr;
  }
}

.content h2 {
  margin-top: var(--space-7);
}

.content h2:first-child {
  margin-top: 0;
}

.aside {
  position: sticky;
  top: calc(var(--header-h) + var(--space-4));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-xs);
}

.aside h3 {
  font-size: 1.15rem;
  margin-bottom: var(--space-3);
}

.aside p {
  color: var(--text-muted);
  font-size: 0.95rem;
}

.aside .btn {
  width: 100%;
  margin-top: var(--space-3);
}

.aside ul {
  list-style: none;
  padding: 0;
  margin: var(--space-4) 0 0;
  border-top: 1px solid var(--border);
  padding-top: var(--space-4);
}

.aside ul li {
  font-size: 0.93rem;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--text);
  margin-bottom: var(--space-2);
}

.aside ul li svg {
  width: 16px;
  height: 16px;
  color: var(--accent);
  flex-shrink: 0;
}

.aside .placeholder {
  margin-bottom: var(--space-4);
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
}

/* ---------- FAQ ---------- */
.faq {
  display: grid;
  gap: var(--space-3);
  max-width: 820px;
  margin-inline: auto;
}

.faq details {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.faq details[open] {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs);
}

.faq summary {
  font-weight: 600;
  font-size: 1.02rem;
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  color: var(--text);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "";
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c8202c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><line x1='12' y1='5' x2='12' y2='19'/><line x1='5' y1='12' x2='19' y2='12'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  transition: transform 0.2s ease;
}

.faq details[open] summary::after {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c8202c' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><line x1='5' y1='12' x2='19' y2='12'/></svg>");
}

.faq details > p,
.faq details > div {
  margin-top: var(--space-3);
  color: var(--text-muted);
}

/* ---------- Form ---------- */
.form {
  display: grid;
  gap: var(--space-4);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

@media (max-width: 600px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}

.field label {
  display: block;
  font-weight: 600;
  font-size: 0.88rem;
  margin-bottom: var(--space-2);
  color: var(--text);
}

.field label .field-opt {
  font-weight: 400;
  color: var(--text-muted);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--text);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 4px rgba(31, 58, 110, 0.12);
}

.field textarea {
  min-height: 140px;
  resize: vertical;
}

.field .hint {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: var(--space-2);
}

/* ---------- Contact info card ---------- */
.contact-cards {
  display: grid;
  gap: var(--space-3);
}

.contact-line {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.contact-line:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-xs);
}

.contact-line .ic {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: var(--primary-soft);
  color: var(--primary);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

.contact-line .ic svg {
  width: 20px;
  height: 20px;
}

.contact-line strong {
  display: block;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-muted);
  margin-bottom: 2px;
  font-weight: 700;
}

.contact-line a,
.contact-line span {
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--text);
  word-break: break-word;
}

.contact-line a:hover {
  color: var(--accent);
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--bg-deeper);
  color: rgba(246, 247, 249, 0.78);
  padding-block: var(--space-8) var(--space-5);
  position: relative;
  overflow: hidden;
}

.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(800px 400px at 0% 0%, rgba(31, 58, 110, 0.18), transparent 60%);
  pointer-events: none;
}

.site-footer > .container {
  position: relative;
  z-index: 1;
}

.footer-top {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-5);
  align-items: center;
  padding-bottom: var(--space-7);
  margin-bottom: var(--space-7);
  border-bottom: 1px solid rgba(246, 247, 249, 0.1);
}

.footer-top h2 {
  color: var(--text-inverse);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  margin: 0;
  max-width: 26ch;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.footer-top .actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
}

@media (max-width: 720px) {
  .footer-top {
    grid-template-columns: 1fr;
  }
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1.2fr;
  gap: var(--space-7);
  margin-bottom: var(--space-7);
}

@media (max-width: 880px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 600px) {
  .footer-grid {
    grid-template-columns: 1fr;
  }
}

.footer-grid h4 {
  color: var(--text-inverse);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: var(--space-4);
  font-weight: 700;
}

.footer-grid ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.footer-grid li {
  margin-bottom: var(--space-2);
}

.footer-grid a {
  color: rgba(246, 247, 249, 0.78);
  font-size: 0.95rem;
}

.footer-grid a:hover {
  color: var(--accent);
}

.footer-brand {
  display: block;
}

.footer-brand .logo-tile {
  display: inline-block;
  background: var(--surface);
  padding: var(--space-3);
  border-radius: var(--radius);
  margin-bottom: var(--space-4);
  box-shadow: var(--shadow-sm);
}

.footer-brand .logo-tile img {
  height: 64px;
  width: auto;
}

.footer-brand p {
  color: rgba(246, 247, 249, 0.65);
  font-size: 0.95rem;
  margin: 0;
  max-width: 32ch;
}

.footer-bottom {
  border-top: 1px solid rgba(246, 247, 249, 0.1);
  padding-top: var(--space-5);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  font-size: 0.85rem;
  color: rgba(246, 247, 249, 0.55);
}

.footer-bottom .badges {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  align-items: center;
}

.footer-bottom .dot-sep::before {
  content: "•";
  margin-right: var(--space-3);
  color: var(--accent);
}

/* ---------- Sticky mobile CTA ---------- */
.mobile-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: none;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-top: 1px solid var(--border);
  box-shadow: 0 -8px 24px rgba(22, 27, 34, 0.08);
  padding: var(--space-3) var(--space-4);
  gap: var(--space-3);
  padding-bottom: max(var(--space-3), env(safe-area-inset-bottom));
}

.mobile-cta .btn {
  flex: 1;
  padding: 0.85rem 1rem;
  font-size: 0.95rem;
  border-radius: var(--radius);
}

@media (max-width: 880px) {
  .mobile-cta {
    display: flex;
  }

  body {
    padding-bottom: 84px;
  }
}

/* ---------- Premium image placeholder ---------- */
.placeholder {
  position: relative;
  aspect-ratio: 4 / 3;
  background:
    linear-gradient(135deg, #f8fafc 0%, #e8eaef 60%, #d4d8df 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: grid;
  place-items: center;
  color: var(--text-muted);
  isolation: isolate;
  box-shadow: var(--shadow-xs);
}

/* Subtle blueprint grid */
.placeholder::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(31, 58, 110, 0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(31, 58, 110, 0.06) 1px, transparent 1px);
  background-size: 32px 32px;
  background-position: -1px -1px;
  pointer-events: none;
  opacity: 0.65;
}

.placeholder::after {
  content: "";
  position: absolute;
  inset: 14px;
  border: 1px solid var(--steel-soft);
  border-radius: calc(var(--radius-lg) - 8px);
  pointer-events: none;
}

.placeholder-content {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: var(--space-5);
  max-width: 80%;
}

.placeholder-icon {
  width: 60px;
  height: 60px;
  margin: 0 auto var(--space-4);
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface);
  color: var(--primary);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-sm);
}

.placeholder-icon svg {
  width: 26px;
  height: 26px;
}

.placeholder-label {
  display: inline-block;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-2);
  padding: 0.32rem 0.7rem;
  background: var(--surface);
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
}

.placeholder-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  color: var(--text);
  margin: 0;
  line-height: 1.4;
  letter-spacing: -0.01em;
}

.placeholder-square {
  aspect-ratio: 1 / 1;
}

.placeholder-wide {
  aspect-ratio: 16 / 10;
}

.placeholder-tall {
  aspect-ratio: 4 / 5;
}

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--primary);
  color: var(--text-inverse);
  padding: var(--space-3) var(--space-4);
  z-index: 100;
  border-radius: 0 0 var(--radius) 0;
  font-weight: 600;
}

.skip-link:focus {
  left: 0;
  color: var(--text-inverse);
}

/* ---------- Misc ---------- */
.checklist {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-5);
}

.checklist li {
  position: relative;
  padding-left: 2rem;
  margin-bottom: var(--space-3);
}

.checklist li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.35rem;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent-soft);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23c8202c' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
}

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

/* ==========================================================================
   v4 - Premium photo pass
   - Photo card / gallery treatment
   - Before/After comparison slider (vanilla JS)
   - Photo collage hero
   ========================================================================== */

/* ---------- Photo wrapper that replaces page-header placeholders ---------- */
.photo-frame {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--bg-alt);
  border: 1px solid var(--border);
}
.photo-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.photo-frame.ratio-4-3 { aspect-ratio: 4 / 3; }
.photo-frame.ratio-16-10 { aspect-ratio: 16 / 10; }
.photo-frame.ratio-3-4 { aspect-ratio: 3 / 4; }
.photo-frame.ratio-1-1 { aspect-ratio: 1 / 1; }
.photo-frame.ratio-4-5 { aspect-ratio: 4 / 5; }

/* Premium tag overlay used over photos */
.photo-tag {
  position: absolute;
  top: 14px;
  left: 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(20, 32, 46, 0.88);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.35rem 0.75rem;
  border-radius: var(--radius-pill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 2;
}
.photo-tag::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* ---------- Painting hero: blue painter's-tape frame ----------
   The hero photo is "masked off" with real blue painter's tape the way a
   painter preps a wall. The tape image (assets/img/painter-tape-frame.png)
   is a transparent-center overlay cropped tight to the tape, so it becomes
   the framing mechanism around the photo — not a card border.

   Geometry comes from the source asset (cropped to the tape, 938 x 871):
     container aspect-ratio       = 938 / 871
     tape INNER opening edges     = L 10.4%  R 11.6%  T 8.9%  B 9.9% (from sides)
   The photo lives in an overflow:hidden mask whose edges are pulled a few %
   PAST the inner opening, i.e. UNDER the tape band. The tape overlay then sits
   on top of those edges, so the tape — not the photo rectangle — defines the
   visible image. No photo pixels can appear outside the tape opening. */
.painting-image-frame {
  position: relative;
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
  aspect-ratio: 938 / 871;
  /* slight organic tilt only. The "mounted on the wall" shadow lives on
     .tape-overlay (below) so it traces the TAPE alpha, not this container's
     bounding box. A filter here would trace the union of all children —
     including the opaque .tape-image-mask rectangle — and cast a square
     shadow halo (the old "faint box" artifact). */
  transform: rotate(-1.15deg);
}

/* Interior mask = the actual visible image area. Edges sit ~3% inside the
   tape band (i.e. the photo tucks under the tape, which overlaps on top). */
.painting-image-frame .tape-image-mask {
  position: absolute;
  top: 6%;
  bottom: 7%;
  left: 7.5%;
  right: 8.5%;
  overflow: hidden;
  border-radius: 2px; /* just softens hard corner pixels under the tape */
  /* faint seat shadow inside the opening so the photo reads as recessed */
  box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.18);
  z-index: 1;
}
.painting-image-frame .tape-image-mask .hero-photo {
  width: 100%;
  height: 100%;
  object-fit: cover; /* fills the opening, crops wide/tall photos, never distorts */
  object-position: center;
  display: block;
}

.painting-image-frame .tape-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* native ratio matches the container, so contain fills it with no distortion */
  object-fit: contain;
  display: block;
  pointer-events: none;
  background: none; /* never paint a box behind the tape */
  /* Both shadows trace THIS image's alpha (the tape silhouette): a tiny lift
     so the tape reads as raised off the photo, plus the soft "mounted on the
     wall" shadow that used to live on the parent container. Because they hang
     off the tape's torn edges instead of a rectangle, there is no square. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.28))
    drop-shadow(0 18px 28px rgba(20, 32, 46, 0.22));
  z-index: 2;
}

/* Give the painting hero photo a little more room than the default split */
@media (min-width: 881px) {
  .page-header-grid--painting {
    grid-template-columns: 1.3fr 1fr;
  }
  .page-header-grid--painting > div:last-child {
    display: flex;
    justify-content: center;
  }
}

/* Mobile / tablet: drop the tilt so rotated corners + tape shadow never
   crop or trigger horizontal overflow, and keep the frame comfortably sized */
@media (max-width: 880px) {
  .painting-image-frame {
    max-width: 460px;
    transform: rotate(-0.6deg);
  }
  /* Keep the mount shadow on the tape silhouette at this breakpoint too,
     just a touch softer — never on the parent (would re-create the box). */
  .painting-image-frame .tape-overlay {
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.26))
      drop-shadow(0 12px 20px rgba(20, 32, 46, 0.18));
  }
}

@media (max-width: 520px) {
  .painting-image-frame {
    max-width: 100%;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .painting-image-frame {
    transform: none;
  }
}

/* ---------- Drywall hero: "Level 5 finish" drywall-mud frame ----------
   Same overlay mechanic as the painting tape frame above. The hero photo
   sits in the open center of a real joint-compound frame (assets/drywall-
   frame.png) — a transparent-center PNG that also carries the taping knife
   and "LEVEL 5 FINISH" placard. The photo lives in an overflow:hidden mask
   whose edges tuck a few % UNDER the mud band; the frame PNG sits on top, so
   the mud — not the photo rectangle — defines the visible image. No photo
   pixels can appear outside the opening, and the transparent margins let the
   section texture show through (no white box).

   Geometry from the trimmed asset (1511 x 1023, aspect 1.477):
     mud-band OUTER edges   L 27% R 11% T 7%  B 5%
     opening INNER edges    L 33% R 19% T 25% B 13%
   The knife juts into the upper-right of the opening and the placard hangs
   into the top — both are part of the opaque overlay, so the photo safely
   tucks beneath them. The mask insets below sit between the outer and inner
   edges on every side, i.e. a few % under the mud band. */
.drywall-image-frame {
  position: relative;
  width: 100%;
  max-width: 620px;
  margin-inline: auto;
  aspect-ratio: 1511 / 1023;
  /* gentle organic tilt only; the mount shadow lives on the overlay (below)
     so it traces the mud silhouette, not this container's bounding box. */
  transform: rotate(-0.8deg);
}

/* Interior mask = the actual visible image area, tucked under the mud band. */
.drywall-image-frame .drywall-frame-mask {
  position: absolute;
  top: 21%;
  right: 16%;
  bottom: 10.5%;
  left: 30%;
  overflow: hidden;
  border-radius: 2px; /* softens hard corner pixels under the mud */
  box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.18);
  z-index: 1;
}
.drywall-image-frame .drywall-frame-mask .hero-photo {
  width: 100%;
  height: 100%;
  object-fit: cover; /* fills the opening, crops wide/tall photos, never distorts */
  object-position: center;
  display: block;
}

.drywall-image-frame .drywall-frame-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* native ratio matches the container, so contain fills it with no distortion */
  object-fit: contain;
  display: block;
  pointer-events: none;
  background: none; /* never paint a box behind the mud */
  /* shadows trace THIS image's alpha (the mud silhouette): a tiny lift plus a
     soft "mounted on the wall" shadow. No rectangle, so no square halo. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.25))
    drop-shadow(0 18px 28px rgba(20, 32, 46, 0.2));
  z-index: 2;
}

/* Desktop: give the frame a touch more room and center it in its grid cell */
@media (min-width: 881px) {
  .page-header-grid--drywall {
    grid-template-columns: 1.25fr 1fr;
  }
  .page-header-grid--drywall > div:last-child {
    display: flex;
    justify-content: center;
  }
}

/* Full desktop (≥1100px): make the mud frame read as a large, premium hero
   feature WITHOUT it participating in document flow. The grid columns stay at
   the 1.25fr / 1fr split above (text column unchanged), and the frame's layout
   box stays at its track size — so the row height, headline rhythm, CTA row,
   badges and trust bar are all unaffected. The enlargement is applied purely
   as a transform, which is composited AFTER layout: the frame paints ~40%
   bigger (≈483px → ≈676px box), anchored on its own box, growing into the right
   gutter and the section's vertical padding rather than into the text. This
   brings the visible photo opening up to roughly the painting hero's presence
   (the mud band's wide LEFT margin is transparent, so center-scaling grows the
   transparent edge — not the visible mud — toward the text gap, keeping the
   text column clear). It is fully visible at ≥1300px; below that only the
   extreme knife tip / right border bleeds a few px past the viewport, which
   .page-header's overflow:hidden clips so there is never a horizontal
   scrollbar. The photo inside scales in lockstep (it is part of the
   transformed element). */
@media (min-width: 1100px) {
  /* let the scaled frame paint outside its grid cell; the cell keeps its track
     size so layout is untouched */
  .page-header-grid--drywall > div:last-child {
    overflow: visible;
  }
  .drywall-image-frame {
    transform: rotate(-0.8deg) scale(1.4);
    transform-origin: center center;
  }
}

@media (min-width: 1100px) and (prefers-reduced-motion: reduce) {
  .drywall-image-frame {
    transform: scale(1.4);
  }
}

/* Mobile / tablet: drop the tilt so rotated corners + shadow never crop or
   trigger horizontal overflow, and keep the frame comfortably sized */
@media (max-width: 880px) {
  .drywall-image-frame {
    max-width: 520px;
    transform: rotate(-0.5deg);
  }
  .drywall-image-frame .drywall-frame-overlay {
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.24))
      drop-shadow(0 12px 20px rgba(20, 32, 46, 0.16));
  }
}

@media (max-width: 520px) {
  .drywall-image-frame {
    max-width: 100%;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .drywall-image-frame {
    transform: none;
  }
}

/* ---------- Ceiling hero: architect's blueprint-drawing frame ----------
   Same overlay mechanic as the painting tape frame and drywall mud frame above.
   The hero photo sits in the open center of a blueprint frame
   (assets/Blueprint Frame.png) — a transparent-center PNG whose drawn border is
   the framing for this "plan". The photo lives in an overflow:hidden mask whose
   edges tuck a few % UNDER the border band; the frame PNG sits on top, so the
   blueprint border — not the photo rectangle — defines the visible image. No
   photo pixels can appear outside the opening, and the transparent margins let
   the section's blueprint background show through (no white box).

   Geometry from the asset (1536 x 1024, aspect 1.5):
     opening INNER edges    L 23.6%  R 23.8%  T 16.5%  B 13.4%
     border band            ~28px (~1.8%) wide on each side
   The mask insets below sit ~1% INSIDE those inner edges, i.e. a hair under the
   border line, so the photo edge always reads beneath the drawn frame. */
.ceiling-image-frame {
  position: relative;
  width: 100%;
  max-width: 600px;
  margin-inline: auto;
  aspect-ratio: 1536 / 1024;
}

/* Interior mask = the actual visible image area, tucked under the border band. */
.ceiling-image-frame .blueprint-frame-mask {
  position: absolute;
  top: 15.5%;
  right: 22.7%;
  bottom: 12.4%;
  left: 22.7%;
  overflow: hidden;
  border-radius: 2px; /* softens hard corner pixels under the border line */
  box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.16);
  z-index: 1;
}
.ceiling-image-frame .blueprint-frame-mask .hero-photo {
  width: 100%;
  height: 100%;
  object-fit: cover; /* fills the opening, crops wide/tall photos, never distorts */
  object-position: center;
  display: block;
}

.ceiling-image-frame .blueprint-frame-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* native ratio matches the container, so contain fills it with no distortion */
  object-fit: contain;
  display: block;
  pointer-events: none; /* purely decorative — never blocks clicks or layout */
  background: none; /* never paint a box behind the blueprint lines */
  /* a soft "drawing on the desk" shadow that traces the frame's alpha, not a
     rectangle, so there is no square halo */
  filter: drop-shadow(0 10px 22px rgba(20, 32, 46, 0.16));
  z-index: 2;
}

/* Desktop: center the frame in its grid cell. Columns stay at the default
   page-header-grid split (1.4fr / 1fr) so the left hero text is unmoved. */
@media (min-width: 881px) {
  .page-header-grid--ceiling > div:last-child {
    display: flex;
    justify-content: center;
  }
}

/* Full desktop (≥1100px): scale the blueprint frame up to match the painting
   hero's on-screen presence — same post-layout transform mechanic as the
   drywall mud frame above. The blueprint frame had NO desktop scale, so its
   photo opening read far smaller than painting's tight tape frame (~247px vs
   ~397px visible). The columns and the frame's layout box are untouched, so the
   headline, lead, CTA row, trust pills and trust bar do not move; only the
   painted frame grows. The blueprint border's wide
   transparent margins mean center-scaling grows the transparent edge toward the
   text gap, not the drawn border, so the text column stays clear; any right-edge
   bleed past the viewport is clipped by .page-header's overflow:hidden, so there
   is never a horizontal scrollbar.

   The scale below is the only knob for the image composition's on-screen size.
   It was bumped from 1.4 → 1.75 to enlarge the photo + blueprint frame + its
   drop-shadow as one unit by ~25% (1.4 × 1.25 = 1.75). Because this is a
   transform on a layer whose layout box keeps its track size, the enlargement
   reads as the artwork expanding within its visual area — nothing else on the
   page moves. */
@media (min-width: 1100px) {
  /* let the scaled frame paint outside its grid cell; the cell keeps its track
     size so layout is untouched */
  .page-header-grid--ceiling > div:last-child {
    overflow: visible;
  }
  .ceiling-image-frame {
    transform: scale(1.75);
    transform-origin: center center;
  }
}

/* Mobile / tablet: keep the frame comfortably sized; the mask + overlay are
   both percentage-based, so the photo and frame stay locked together at every
   width and there is no horizontal overflow. */
@media (max-width: 880px) {
  .ceiling-image-frame {
    max-width: 520px;
  }
}

@media (max-width: 520px) {
  .ceiling-image-frame {
    max-width: 100%;
  }
}

/* ---------- Painting hero background (painting page only) ---------- */
/* Decorative navy paint-roller photo behind the painting hero. It sits on the
   section's own background, so it stays below the drywall texture layer, the
   scrim and every piece of content — including the tape-frame photo, which
   keeps reading on top with the navy framing it. A left-to-right light wash
   keeps the headline, lead and CTAs fully readable while the navy and roller
   resolve on the right / top-right. */
.page-header.painting-hero {
  background:
    linear-gradient(
      100deg,
      var(--bg) 0%,
      rgba(246, 247, 249, 0.94) 26%,
      rgba(246, 247, 249, 0.6) 44%,
      rgba(246, 247, 249, 0) 62%
    ),
    url("../opt/painting-background.jpg") right top / cover no-repeat,
    radial-gradient(900px 400px at 90% -10%, rgba(31, 58, 110, 0.06), transparent 60%),
    var(--bg);
  /* The wash above handles readability, so drop the texture scrim that would
     otherwise mute the navy. The drywall texture layer itself stays. */
  --texture-scrim: transparent;
}

/* Tablet / stacked layout: the text stacks above the tape frame, so anchor the
   navy low-right and lay a vertical wash over the top to keep the headline and
   CTAs clean and clear of the roller. */
@media (max-width: 880px) {
  .page-header.painting-hero {
    background:
      linear-gradient(
        to bottom,
        var(--bg) 0%,
        rgba(246, 247, 249, 0.92) 34%,
        rgba(246, 247, 249, 0.45) 58%,
        rgba(246, 247, 249, 0) 80%
      ),
      url("../opt/painting-background.jpg") right bottom / cover no-repeat,
      var(--bg);
  }
}

/* Phone: hold the paint to the very bottom behind the tape frame and fade it
   further so it never crowds the headline. */
@media (max-width: 520px) {
  .page-header.painting-hero {
    background:
      linear-gradient(
        to bottom,
        var(--bg) 0%,
        rgba(246, 247, 249, 0.9) 48%,
        rgba(246, 247, 249, 0.45) 72%,
        rgba(246, 247, 249, 0.12) 100%
      ),
      url("../opt/painting-background.jpg") center bottom / cover no-repeat,
      var(--bg);
  }
}

/* ---------- DIY hero ----------
   Subtle paper / clipboard texture sits behind the hero, anchored right so the
   clipboard detail falls mostly behind and to the right of the coaching photo.
   A left-anchored wash keeps the headline, lead, and CTAs highly readable. */
.page-header.diy-hero {
  background:
    linear-gradient(
      100deg,
      var(--bg) 0%,
      rgba(246, 247, 249, 0.94) 30%,
      rgba(246, 247, 249, 0.58) 50%,
      rgba(246, 247, 249, 0) 68%
    ),
    url("../diy-background.webp") right center / cover no-repeat,
    radial-gradient(900px 400px at 90% -10%, rgba(31, 58, 110, 0.05), transparent 60%),
    var(--bg);
  /* The wash handles readability; drop the texture scrim. The smooth-drywall
     texture layer itself stays for a touch of surface detail. */
  --texture-scrim: transparent;
}

/* Keep the worker finishing the ceiling and the ceiling action in frame if the
   card opening crops the portrait photo (favor right + upper). */
.diy-hero-photo img {
  object-position: 60% 38%;
}

/* Tablet / stacked: photo drops below the text. Anchor the paper low-right
   behind the card and wash from the top so the headline stays clean. */
@media (max-width: 880px) {
  .page-header.diy-hero {
    background:
      linear-gradient(
        to bottom,
        var(--bg) 0%,
        rgba(246, 247, 249, 0.92) 32%,
        rgba(246, 247, 249, 0.5) 60%,
        rgba(246, 247, 249, 0) 82%
      ),
      url("../diy-background.webp") right bottom / cover no-repeat,
      var(--bg);
  }
}

/* Phone: hold the texture low and fade it further so mobile never feels busy. */
@media (max-width: 520px) {
  .page-header.diy-hero {
    background:
      linear-gradient(
        to bottom,
        var(--bg) 0%,
        rgba(246, 247, 249, 0.95) 46%,
        rgba(246, 247, 249, 0.6) 74%,
        rgba(246, 247, 249, 0.18) 100%
      ),
      url("../diy-background.webp") center bottom / cover no-repeat,
      var(--bg);
  }
}

/* ---------- Ceiling hero background (ceilings page only) ----------
   A faint architect's blueprint (assets/Ceiling Background.png) laid behind the
   ceiling hero like a ceiling plan on the desk: dimension lines down the left
   and bottom edges, light annotations, and a vaulted-ceiling framing sketch in
   the top-right. It is anchored right/top so that sketch resolves behind the
   hero photo card and reads as the plan for it. The blueprint itself is the
   hero texture here (no wood-plank layer — it would compete with the fine
   pencil lines), so this is a plain .page-header with no .has-texture machinery.
   A left-to-right white wash keeps the headline, lead, badges and CTAs fully
   legible while the right side and clean center stay crisp. */
.page-header.ceiling-hero {
  background:
    linear-gradient(
      100deg,
      var(--bg) 0%,
      rgba(246, 247, 249, 0.95) 22%,
      rgba(246, 247, 249, 0.7) 40%,
      rgba(246, 247, 249, 0.28) 58%,
      rgba(246, 247, 249, 0) 74%
    ),
    url("../opt/ceiling-background.jpg") right top / cover no-repeat,
    radial-gradient(900px 400px at 90% -10%, rgba(31, 58, 110, 0.06), transparent 60%),
    var(--bg);
}

/* Tablet / stacked layout: the copy stacks above the photo card, so lay the
   wash top-to-bottom — headline and CTAs stay clean while the vaulted sketch
   keeps its top-right anchor and softens toward the content below. */
@media (max-width: 880px) {
  .page-header.ceiling-hero {
    background:
      linear-gradient(
        to bottom,
        var(--bg) 0%,
        rgba(246, 247, 249, 0.92) 30%,
        rgba(246, 247, 249, 0.52) 56%,
        rgba(246, 247, 249, 0.12) 82%
      ),
      url("../opt/ceiling-background.jpg") right top / cover no-repeat,
      radial-gradient(900px 400px at 90% -10%, rgba(31, 58, 110, 0.06), transparent 60%),
      var(--bg);
  }
}

/* Phone: simplify. Fade the blueprint further so it reads as a quiet hint in
   the top-right corner and never crowds the stacked headline or CTAs. */
@media (max-width: 520px) {
  .page-header.ceiling-hero {
    background:
      linear-gradient(
        to bottom,
        var(--bg) 0%,
        rgba(246, 247, 249, 0.9) 46%,
        rgba(246, 247, 249, 0.62) 74%,
        rgba(246, 247, 249, 0.34) 100%
      ),
      url("../opt/ceiling-background.jpg") right top / cover no-repeat,
      var(--bg);
  }
}

/* ---------- Photo cards (replaces gallery card placeholders) ---------- */
.photo-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* Fill the full height of the (stretched) grid cell so every card in a row
     ends at the same bottom edge regardless of text length. */
  height: 100%;
  transition: transform 0.2s ease, box-shadow 0.2s ease,
    border-color 0.2s ease;
}
.photo-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
  border-color: var(--border-strong);
}
.photo-card .photo-frame {
  border: 0;
  border-radius: 0;
  border-bottom: 1px solid var(--border);
  box-shadow: none;
  /* Keep the image section at a consistent aspect ratio across cards —
     never let the flex column compress it to absorb extra height. */
  flex-shrink: 0;
}
.photo-card-body {
  padding: var(--space-5) var(--space-5) var(--space-6);
  /* Grow to absorb the extra height of taller cards in the row, so shorter
     cards have no white gap below their text. The textured ::after overlay
     (inset:0) grows with it, keeping the fill seamless to the bottom edge. */
  flex: 1 1 auto;
}
.photo-card-body .gallery-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-2);
}
.photo-card-body .gallery-tag::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
.photo-card-body h3 {
  font-size: 1.1rem;
  margin-bottom: var(--space-2);
}
.photo-card-body p {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0;
}

/* ---------- Editorial photo strip (process / dual photos) ---------- */
.photo-strip {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 880px) {
  .photo-strip { grid-template-columns: 1fr; }
}
@media (min-width: 600px) and (max-width: 880px) {
  .photo-strip { grid-template-columns: repeat(2, 1fr); }
}

/* ---------- Diagonal texture showcase (gallery reveal) ----------
   Gallery-reveal model: the card is a FIXED-size frame holding three
   full-height image layers, each pinned to a stable box so the photos
   never move or rescale. Two angled divider lines (the ::before/::after)
   sit on top at --d1/--d2. Hover/focus only slides --d1/--d2, so the
   only thing that travels is the white diagonal lines — revealing a bit
   more of one image and a bit less of its neighbours. --d1/--d2 are
   registered with @property so they interpolate smoothly and every
   clip-path / label that reads them glides in lockstep. */
@property --d1 {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 33.333%;
}
@property --d2 {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 66.667%;
}
.diag-showcase {
  --slant: 52px;          /* diagonal angle: top/bottom horizontal offset */
  --gap: 16px;            /* width of the white divider line */
  --sh: calc(var(--slant) / 2);
  --gh: calc(var(--gap) / 2);
  --d1: 33.333%;          /* left/centre divider centre */
  --d2: 66.667%;          /* centre/right divider centre */
  position: relative;
  aspect-ratio: 5 / 2;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow);
  background: var(--bg);
  transition: --d1 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    --d2 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
/* the two sliding white divider lines, drawn over the images so the panel
   hit-areas can tile edge-to-edge (no dead zone = no hover flicker) */
.diag-showcase::before,
.diag-showcase::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background: var(--bg);
}
.diag-showcase::before {
  clip-path: polygon(
    calc(var(--d1) + var(--sh) - var(--gh)) 0,
    calc(var(--d1) + var(--sh) + var(--gh)) 0,
    calc(var(--d1) - var(--sh) + var(--gh)) 100%,
    calc(var(--d1) - var(--sh) - var(--gh)) 100%
  );
}
.diag-showcase::after {
  clip-path: polygon(
    calc(var(--d2) + var(--sh) - var(--gh)) 0,
    calc(var(--d2) + var(--sh) + var(--gh)) 0,
    calc(var(--d2) - var(--sh) + var(--gh)) 100%,
    calc(var(--d2) - var(--sh) - var(--gh)) 100%
  );
}
.diag-panel {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--bg-alt);
  cursor: pointer;
}
/* each panel is the full frame, clipped to its angled band; bands meet at
   the divider centre line so the pointer never lands in a gap */
.diag-panel--left {
  clip-path: polygon(
    0 0,
    calc(var(--d1) + var(--sh)) 0,
    calc(var(--d1) - var(--sh)) 100%,
    0 100%
  );
}
.diag-panel--mid {
  clip-path: polygon(
    calc(var(--d1) + var(--sh)) 0,
    calc(var(--d2) + var(--sh)) 0,
    calc(var(--d2) - var(--sh)) 100%,
    calc(var(--d1) - var(--sh)) 100%
  );
}
.diag-panel--right {
  clip-path: polygon(
    calc(var(--d2) + var(--sh)) 0,
    100% 0,
    100% 100%,
    calc(var(--d2) - var(--sh)) 100%
  );
}
/* Images live in fixed boxes wider than their rest band, so the clip can
   reveal more of the SAME photo without the photo ever moving or resizing. */
.diag-panel img {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
.diag-panel--mid img {
  left: 25%;
}
.diag-panel--right img {
  left: auto;
  right: 0;
}
/* keyboard focus ring sits inside the clipped band so it never bleeds out */
.diag-panel:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -4px;
}
.diag-panel:focus:not(:focus-visible) {
  outline: none;
}
/* ---- Sliding dividers: hover / focus / tap only move --d1 / --d2 -------
   Default = equal thirds. Hovering a panel opens its band ~7% and the two
   neighbours give that back equally, so the dividers glide and the images
   hold still. Gated to the horizontal layout. */
@media (min-width: 881px) {
  .diag-showcase:has(.diag-panel--left:hover),
  .diag-showcase:has(.diag-panel--left:focus-visible),
  .diag-showcase[data-active="left"] {
    --d1: 40%;
    --d2: 70%;
  }
  .diag-showcase:has(.diag-panel--mid:hover),
  .diag-showcase:has(.diag-panel--mid:focus-visible),
  .diag-showcase[data-active="mid"] {
    --d1: 30%;
    --d2: 70%;
  }
  .diag-showcase:has(.diag-panel--right:hover),
  .diag-showcase:has(.diag-panel--right:focus-visible),
  .diag-showcase[data-active="right"] {
    --d1: 30%;
    --d2: 60%;
  }
  /* very subtle lift on the selected image only */
  .diag-panel:hover img,
  .diag-panel:focus-visible img,
  .diag-panel.is-active img {
    transform: scale(1.015);
  }
}
/* bottom scrim keeps the navy label crisp over busy macro texture */
.diag-panel::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 42%;
  background: linear-gradient(to top, rgba(20, 32, 46, 0.55), rgba(20, 32, 46, 0));
  pointer-events: none;
}
.diag-tag {
  position: absolute;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 6;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: calc(100% - 28px);
  background: rgba(20, 32, 46, 0.92);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 0.4rem 0.85rem;
  border-radius: var(--radius-pill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
/* anchor each label to the centre of its VISIBLE band; tracks the divider */
.diag-panel--left  .diag-tag { left: calc(var(--d1) * 0.5); }
.diag-panel--mid   .diag-tag { left: calc((var(--d1) + var(--d2)) * 0.5); }
.diag-panel--right .diag-tag { left: calc((var(--d2) + 100%) * 0.5); }
.diag-tag::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
@media (max-width: 880px) {
  /* stacked cards: drop the layering, dividers, and reveal entirely */
  .diag-showcase {
    position: static;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    aspect-ratio: auto;
    background: transparent;
    border-radius: 0;
    overflow: visible;
    box-shadow: none;
    transition: none;
  }
  .diag-showcase::before,
  .diag-showcase::after {
    display: none;
  }
  .diag-panel,
  .diag-panel--left,
  .diag-panel--mid,
  .diag-panel--right {
    position: relative;
    inset: auto;
    clip-path: none;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
  }
  .diag-panel img,
  .diag-panel--mid img,
  .diag-panel--right img {
    inset: 0;
    left: 0;
    right: auto;
    width: 100%;
    height: 100%;
  }
  .diag-tag,
  .diag-panel--left .diag-tag,
  .diag-panel--mid .diag-tag,
  .diag-panel--right .diag-tag {
    left: 14px;
    bottom: 14px;
    transform: none;
  }
  /* full-width stacked cards: no divider slide, just a tiny tap scale */
  .diag-panel.is-active img {
    transform: scale(1.03);
  }
}
/* Honour reduced-motion: keep the reveal states but remove the easing. */
@media (prefers-reduced-motion: reduce) {
  .diag-showcase,
  .diag-panel img {
    transition: none;
  }
}

/* ---------- Before/After comparison slider ---------- */
.ba {
  --pos: 50%;
  /* Scroll-linked horizontal drift. JS sets --ba-progress in [-1, 1];
     --ba-shift caps the travel (smaller on mobile, 0 for reduced motion). */
  --ba-progress: 0;
  --ba-shift: 32px;
  position: relative;
  aspect-ratio: 4 / 3;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--bg-alt);
  box-shadow: var(--shadow);
  user-select: none;
  touch-action: pan-y;
  isolation: isolate;
  transform: translate3d(calc(var(--ba-progress) * var(--ba-shift)), 0, 0);
  will-change: transform;
}
.ba img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}
.ba .ba-after {
  clip-path: inset(0 0 0 var(--pos));
  -webkit-clip-path: inset(0 0 0 var(--pos));
}
.ba-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  width: 3px;
  background: #fff;
  transform: translateX(-50%);
  cursor: ew-resize;
  border: 0;
  padding: 0;
  z-index: 3;
  box-shadow: 0 0 0 1px rgba(20, 32, 46, 0.25),
    0 6px 18px rgba(20, 32, 46, 0.35);
}
.ba-handle::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 6px 18px rgba(20, 32, 46, 0.35),
    inset 0 0 0 1px rgba(20, 32, 46, 0.06);
}
.ba-handle::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 26px;
  height: 26px;
  z-index: 1;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23161b22' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='9 18 3 12 9 6'/><polyline points='15 6 21 12 15 18'/></svg>");
  background-position: center;
  background-repeat: no-repeat;
  background-size: 22px 22px;
}
.ba-handle:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 4px;
}
.ba-handle:hover::after,
.ba-handle:focus-visible::after {
  box-shadow: 0 8px 24px rgba(20, 32, 46, 0.4),
    inset 0 0 0 2px var(--accent);
}
.ba-label {
  position: absolute;
  top: 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0.38rem 0.85rem;
  background: rgba(20, 32, 46, 0.86);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 2;
  pointer-events: none;
}
.ba-label-before { left: 14px; }
.ba-label-after  { right: 14px; }
.ba-label::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* No-JS / SSR fallback: still readable */
.ba:not([data-ba-ready]) .ba-handle { display: none; }
.ba:not([data-ba-ready]) .ba-after  { clip-path: none; -webkit-clip-path: none; opacity: 0; }

/* Any section hosting a drifting before/after slider clips the X axis so the
   parallax can never produce page-level horizontal scroll. The section is far
   wider than the 820px figure, so the figure's shadow is untouched; Y stays
   visible so nothing above/below is cut off. (.recent-work = homepage,
   .ba-host = ceilings and any future reuse — same logic, no duplication.) */
.recent-work,
.ba-host {
  overflow-x: clip;
}

/* Tighten the section so the slider reads as a featured preview, not a
   full-bleed showpiece. Trim the vertical rhythm without making it cramped. */
.recent-work {
  padding-block: var(--space-7) var(--space-8);
}
.recent-work .section-header {
  margin-bottom: var(--space-6);
}

/* Figure wrapper: keep the comparison intentional and premium, not massive.
   4:3 is retained on purpose — the source photos are square, so a wider
   letterbox would clip the chandelier and floor. Width is capped tighter than
   the column and height is clamped so it never dominates the viewport. */
.ba-figure {
  max-width: 820px;
  margin: 0 auto var(--space-7);
}
.ba-figure .ba {
  max-height: min(540px, 64vh);
}
.ba-figure figcaption {
  max-width: 56ch;
  margin-inline: auto;
}

/* Separate-projects block. These are NOT the same job as the slider above, so
   the label reads "More Completed Work" with a clarifying subline. Centered
   hairline label keeps the rhythm consistent with the rest of the page. */
.ba-projects {
  max-width: 820px;
  margin-inline: auto;
}
.ba-projects-head {
  text-align: center;
  margin-bottom: var(--space-6);
}
.ba-projects-head .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  white-space: nowrap;
}
.ba-projects-head .eyebrow::before,
.ba-projects-head .eyebrow::after {
  content: "";
  width: clamp(28px, 8vw, 64px);
  height: 1px;
  background: var(--border);
}
.ba-projects-sub {
  margin: var(--space-2) 0 0;
  color: var(--text-muted);
  font-size: 0.95rem;
}

/* Gentler horizontal drift once the figure approaches the container width,
   so the travel stays within the gutter (full 32px is reserved for wide
   desktops where the slider has ample side margin). */
@media (max-width: 880px) {
  .ba { --ba-shift: 14px; }
}

/* Respect reduced motion: no scroll-linked movement at all. */
@media (prefers-reduced-motion: reduce) {
  .ba {
    --ba-shift: 0px;
    transform: none;
    will-change: auto;
  }
}

/* ---------- Footer logo tweak so the photo sits cleanly ---------- */
.footer-brand .logo-tile {
  background: #ffffff;
}

/* ==========================================================================
   v5 — Premium polish pass
   Icon sprite usage, scroll reveal, plaster texture, owner card, button sheen,
   section eyebrows, polished focus states, header scroll ramp.
   ========================================================================== */

/* ---------- Icon sprite usage ---------- */
.ic {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
  color: currentColor;
}
.ic-sm { width: 14px; height: 14px; }
.ic-md { width: 22px; height: 22px; }
.ic-lg { width: 28px; height: 28px; }
.ic-xl { width: 36px; height: 36px; }

/* ---------- Subtle plaster texture (for accent surfaces) ---------- */
.has-plaster {
  position: relative;
  isolation: isolate;
}
.has-plaster::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.6;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240' viewBox='0 0 240 240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 0.08  0 0 0 0 0.10  0 0 0 0 0.13  0 0 0 0.08 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 240px 240px;
}
.has-plaster > .container,
.has-plaster > * { position: relative; z-index: 1; }

.section-dark.has-plaster::after,
.trust-band.has-plaster::after,
.cta-banner.has-plaster::after {
  opacity: 0.32;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240' viewBox='0 0 240 240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.12 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* ---------- Material textures (photographic, opt-in per section) ----------
   Subtle, scene-style wall/ceiling textures layered behind a section. Built
   to mirror .has-plaster: a decorative ::before overlay with content lifted
   above it. Every aspect (image, opacity, blend, scrim) is variable-driven so
   sections stay tunable without one-off rules. Use background-size:cover (these
   are photographs, not seamless tiles) and never background-attachment:fixed. */
.has-texture {
  position: relative;
  isolation: isolate;

  /* tunable defaults — light surfaces */
  --texture-img: none;
  --texture-opacity: 0.15;
  --texture-blend: multiply;
  --texture-size: cover;
  --texture-position: center;
  /* readability scrim: a soft wash of the surface color over the texture so
     body copy keeps full contrast. Kept light enough that the material still
     reads through open areas; text contrast is preserved by the low texture
     opacity beneath it. Tuned for light --bg sections. */
  --texture-scrim: linear-gradient(
    to bottom,
    rgba(246, 247, 249, 0.34),
    rgba(246, 247, 249, 0.58)
  );
}

/* Texture layer (sits behind content, above the section background). */
.has-texture::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--texture-img);
  background-size: var(--texture-size);
  background-position: var(--texture-position);
  background-repeat: no-repeat;
  opacity: var(--texture-opacity);
  mix-blend-mode: var(--texture-blend);
}

/* Readability scrim (sits above the texture, below content). */
.has-texture::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--texture-scrim);
}

/* Lift all real content above both decorative layers. */
.has-texture > * {
  position: relative;
  z-index: 1;
}

/* ---------- Page-header brand watermark ----------
   Decorative Schroeder's mark placed in the open right-side gutter of a
   .page-header hero (Contact page). Absolutely positioned inside the relative
   .page-header so it never enters document flow — hero height, text positions,
   container width, and the owner/Steve card are all untouched (no CLS). Sits
   behind content at z-index:0, beneath the .has-texture scrim, so the headline,
   lead copy and card stay fully legible. The header's overflow:hidden clips any
   bleed, so it can never cause a horizontal scrollbar.
   position/z-index/pointer-events are repeated here so this rule beats the
   equal-weight `.has-texture > *` rule above (source order wins) that would
   otherwise force the mark into flow. */
.page-header > .brand-mark {
  position: absolute;
  z-index: 0;
  top: 58%;
  right: max(-3rem, calc((100vw - var(--container)) / 2 - 4rem));
  transform: translateY(-50%);
  width: clamp(525px, 51vw, 720px);
  height: auto;
  aspect-ratio: 1 / 1;
  opacity: 0.1;
  filter: grayscale(100%) drop-shadow(0 0 40px rgba(0, 0, 0, 0.08));
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* Tablet: scale the mark down and tuck it against the right edge. */
@media (max-width: 880px) {
  .page-header > .brand-mark {
    width: clamp(360px, 57vw, 510px);
    right: 0;
    opacity: 0.08;
  }
}

/* Mobile: hide completely so the full-width hero copy is never crowded. */
@media (max-width: 600px) {
  .page-header > .brand-mark {
    display: none;
  }
}

/* ---------- Shared hero edge accent (red + blue vertical lines) ----------
   The same far-left brand lines used on the homepage hero (.hero--home::before)
   applied to every interior page hero (.page-header). The homepage hero has no
   .has-texture machinery so it can use a ::before; interior heroes already use
   ::before (texture) and ::after (scrim), so here the lines are a real, empty,
   aria-hidden element inserted as the first child of each .page-header.

   Same art and exact same metrics as the homepage (40px band on desktop, 22px
   on mobile, red flush to the edge). Absolutely positioned → out of flow, no
   layout shift; .page-header's overflow:hidden clips it, so it can never cause a
   horizontal scrollbar. Stacking is scoped to each hero's model:
     • plain heroes (ceiling): the wash is the section's own background and the
       copy is in normal flow, so the lines sit at z-index:-1 — above the wash,
       below the copy.
     • .has-texture heroes: the copy is lifted to z-index:1 above a z-index:0
       scrim, so the lines rise to z-index:1 (above the scrim) and the copy,
       being later in source order, paints over them. */
.page-header > .hero-edge-lines {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40px;
  z-index: -1;
  pointer-events: none;
  background-image: url("../RED%20BLUE%20LINES.png");
  background-repeat: no-repeat;
  background-position: -8px top;   /* crop the art's transparent left margin */
  background-size: 506px 100%;     /* vertical stretch is invisible on solid lines */
}

.page-header.has-texture > .hero-edge-lines {
  z-index: 1;                      /* clear the readability scrim, stay under copy */
}

@media (max-width: 760px) {
  /* Slimmer than the 24px container padding so the lines never sit under the
     stacked mobile copy — matches the homepage mobile treatment. */
  .page-header > .hero-edge-lines {
    width: 22px;
    background-position: -4px top;
    background-size: 278px 100%;
  }
}

/* Dark accent surfaces (.trust-band / .cta-banner / .section-dark): switch the
   blend to overlay and drop the light scrim — the dark surface already carries
   contrast, so we only let the texture catch the light subtly. */
.has-texture.on-dark {
  --texture-opacity: 0.14;
  --texture-blend: soft-light;
  --texture-scrim: linear-gradient(
    to bottom,
    rgba(12, 16, 21, 0.12),
    rgba(12, 16, 21, 0.28)
  );
}

/* Warm surfaces (.section-warm) get a warm-tinted scrim to match --bg-warm. */
.has-texture.on-warm {
  --texture-scrim: linear-gradient(
    to bottom,
    rgba(243, 240, 234, 0.38),
    rgba(243, 240, 234, 0.62)
  );
}

/* Per-texture image bindings (responsive default = desktop variant). */
.texture-smooth-drywall { --texture-img: url("../img/textures/smooth-drywall.webp"); }
.texture-level5         { --texture-img: url("../img/textures/level5.webp"); }
.texture-venetian       { --texture-img: url("../img/textures/venetian.webp"); }
.texture-limewash       { --texture-img: url("../img/textures/limewash.webp"); }
.texture-knockdown      { --texture-img: url("../img/textures/knockdown.webp"); }
.texture-painted-planks { --texture-img: url("../img/textures/painted-planks.webp"); }
.texture-timber         { --texture-img: url("../img/textures/timber.webp"); }

/* Knockdown is a deliberate drywall accent — let it read a touch stronger. */
.texture-knockdown { --texture-opacity: 0.17; }

/* Timber is the dramatic ceiling showcase; on a light section it needs a hair
   more presence than the flat finishes to register as real material. */
.texture-timber { --texture-opacity: 0.17; }

/* Heroes / page headers stay deliberately soft — the headline and hero photo
   carry these, so the texture is a whisper, not a surface. */
.hero.has-texture,
.page-header.has-texture { --texture-opacity: 0.1; }

/* Mobile: swap to the lighter 800px variants and ease opacity for readability
   on small, text-dense screens. */
@media (max-width: 600px) {
  .texture-smooth-drywall { --texture-img: url("../img/textures/smooth-drywall-sm.webp"); }
  .texture-level5         { --texture-img: url("../img/textures/level5-sm.webp"); }
  .texture-venetian       { --texture-img: url("../img/textures/venetian-sm.webp"); }
  .texture-limewash       { --texture-img: url("../img/textures/limewash-sm.webp"); }
  .texture-knockdown      { --texture-img: url("../img/textures/knockdown-sm.webp"); }
  .texture-painted-planks { --texture-img: url("../img/textures/painted-planks-sm.webp"); }
  .texture-timber         { --texture-img: url("../img/textures/timber-sm.webp"); }

  /* Ease opacity and firm up the scrim slightly for dense small-screen text. */
  .has-texture {
    --texture-opacity: 0.12;
    --texture-scrim: linear-gradient(
      to bottom,
      rgba(246, 247, 249, 0.42),
      rgba(246, 247, 249, 0.66)
    );
  }
  .has-texture.on-warm {
    --texture-scrim: linear-gradient(
      to bottom,
      rgba(243, 240, 234, 0.46),
      rgba(243, 240, 234, 0.7)
    );
  }
  .has-texture.on-dark { --texture-opacity: 0.13; }
  .texture-knockdown { --texture-opacity: 0.14; }
  .texture-timber { --texture-opacity: 0.14; }
}

/* ---------- Textured cards (finished-wall-sample treatment) ----------
   Opt-in, reusable. Turns a card/list-tile surface into a subtle material
   sample: the texture sits in ::after at z-index -1 (above the card's own
   background, below all content) so text never needs lifting, and a white
   scrim is layered over the texture so copy stays clean. Reuses the same
   --texture-img bindings as the section system (.texture-knockdown etc.),
   which inherit, so an ancestor (e.g. the list <ul>) can set the image once.
   Card surfaces are smaller than sections, so the texture reads stronger
   here by design while remaining clean. Border / radius / shadow / hover
   on the underlying .card / .project-types li are untouched. */
.has-card-texture,
.service-card,
.step,
.feature,
.review-card,
.owner-card,
.contact-line,
.photo-card-body,
.project-types li {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  /* white veil strength over the texture — higher = cleaner/softer */
  --card-scrim: 0.7;
  --card-texture-size: cover;
  --card-texture-position: center;
  /* Default finish: subtle knockdown drywall texture (self-contained, and
     overrides any section-level --texture-img that would inherit in). */
  --texture-img: url("../img/textures/knockdown.webp");
}

.has-card-texture::after,
.service-card::after,
.step::after,
.feature::after,
.review-card::after,
.owner-card::after,
.contact-line::after,
.photo-card-body::after,
.project-types li::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(
      rgba(255, 255, 255, var(--card-scrim)),
      rgba(255, 255, 255, var(--card-scrim))
    ),
    var(--texture-img, none);
  background-repeat: no-repeat, no-repeat;
  background-size: cover, var(--card-texture-size);
  background-position: center, var(--card-texture-position);
}

/* Mobile: lighter image variants are already swapped by the section media
   query (same .texture-* classes); just soften the veil a touch less so the
   smaller card still reads as material. */
@media (max-width: 600px) {
  .has-card-texture,
  .service-card,
  .step,
  .feature,
  .review-card,
  .owner-card,
  .contact-line,
  .photo-card-body,
  .project-types li {
    --card-scrim: 0.72;
    /* lighter knockdown variant to match the default on small screens */
    --texture-img: url("../img/textures/knockdown-sm.webp");
  }
}

/* Respect reduced-data preferences — drop the decorative texture download. */
@media (prefers-reduced-data: reduce) {
  .has-texture::before,
  .has-card-texture::after,
  .service-card::after,
  .step::after,
  .feature::after,
  .review-card::after,
  .owner-card::after,
  .contact-line::after,
  .photo-card-body::after,
  .project-types li::after { background-image: none; }
}

/* ---------- Scroll reveal ---------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 520ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}
[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}
[data-reveal-stagger] > * {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 520ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
}
[data-reveal-stagger].is-revealed > * {
  opacity: 1;
  transform: none;
}
[data-reveal-stagger].is-revealed > *:nth-child(1) { transition-delay: 0ms; }
[data-reveal-stagger].is-revealed > *:nth-child(2) { transition-delay: 70ms; }
[data-reveal-stagger].is-revealed > *:nth-child(3) { transition-delay: 140ms; }
[data-reveal-stagger].is-revealed > *:nth-child(4) { transition-delay: 210ms; }
[data-reveal-stagger].is-revealed > *:nth-child(5) { transition-delay: 280ms; }
[data-reveal-stagger].is-revealed > *:nth-child(6) { transition-delay: 350ms; }
[data-reveal-stagger].is-revealed > *:nth-child(7) { transition-delay: 420ms; }
[data-reveal-stagger].is-revealed > *:nth-child(8) { transition-delay: 490ms; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  [data-reveal-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ---------- Hero entrance ---------- */
@keyframes sew-hero-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
.hero h1,
.hero .hero-sub,
.hero .hero-tag,
.hero .hero-actions,
.hero .trust-pills {
  animation: sew-hero-rise 700ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.hero .hero-tag        { animation-delay: 40ms; }
.hero h1               { animation-delay: 90ms; }
.hero .hero-sub        { animation-delay: 150ms; }
.hero .hero-actions    { animation-delay: 210ms; }
.hero .trust-pills     { animation-delay: 270ms; }

@media (prefers-reduced-motion: reduce) {
  .hero h1, .hero .hero-sub, .hero .hero-tag,
  .hero .hero-actions, .hero .trust-pills {
    animation: none;
  }
}

/* ---------- Button sheen microinteraction ---------- */
.btn {
  position: relative;
  overflow: hidden;
}
.btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: -120%;
  width: 60%;
  height: 100%;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255, 255, 255, 0.14) 40%,
    rgba(255, 255, 255, 0.22) 50%,
    rgba(255, 255, 255, 0.14) 60%,
    transparent 100%
  );
  transform: skewX(-18deg);
  transition: left 600ms ease;
  pointer-events: none;
}
.btn:hover::after { left: 130%; }
.btn-outline::after {
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(22, 27, 34, 0.06) 40%,
    rgba(22, 27, 34, 0.10) 50%,
    rgba(22, 27, 34, 0.06) 60%,
    transparent 100%
  );
}
@media (prefers-reduced-motion: reduce) {
  .btn::after { display: none; }
}

/* ---------- Header polish: brand mark glow + scroll ramp ---------- */
.site-header.is-scrolled {
  background: rgba(255, 255, 255, 0.96);
}
.site-header.is-scrolled-deep {
  box-shadow: 0 8px 28px rgba(22, 27, 34, 0.07);
}
.brand img {
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.brand:hover img {
  transform: rotate(-3deg) scale(1.04);
}

/* ---------- Service card: refined ---------- */
.service-card {
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.22s cubic-bezier(0.22, 1, 0.36, 1),
              border-color 0.22s ease;
}
.service-card:hover .icon-wrap {
  background: var(--primary);
  color: #fff;
}
.service-card .icon-wrap {
  transition: background 0.22s ease, color 0.22s ease, transform 0.22s ease;
}
.service-card:hover .icon-wrap {
  transform: scale(1.06);
}

/* ---------- Improved focus rings ---------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}
.btn:focus-visible {
  outline-color: var(--accent);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px rgba(200, 32, 44, 0.18);
}

/* ---------- Section corner rule (premium eyebrow on dark sections) ---------- */
.section-dark .eyebrow-rule::before,
.trust-band .eyebrow-rule::before,
.cta-banner .eyebrow-rule::before {
  background: var(--accent);
}

/* ---------- Trust strip refinement (used on every page below hero) ---------- */
.trust-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
  align-items: center;
  justify-content: center;
  padding: var(--space-5) var(--space-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}
.trust-strip-bare {
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: var(--space-3) 0;
}
.trust-strip-item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-soft);
  white-space: nowrap;
}
.trust-strip-item .ic {
  width: 20px;
  height: 20px;
  color: var(--accent);
  flex-shrink: 0;
}
.trust-strip-sep {
  width: 1px;
  height: 22px;
  background: var(--border);
  flex-shrink: 0;
}
@media (max-width: 720px) {
  .trust-strip-sep { display: none; }
  .trust-strip { gap: var(--space-3); }
}

/* ---------- Owner card (contact page / hero accent) ---------- */
.owner-card {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}
.owner-card .owner-mark {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--primary);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.owner-card .owner-mark .ic { width: 28px; height: 28px; }
.owner-card .owner-text strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--text);
  letter-spacing: -0.01em;
}
.owner-card .owner-text span {
  display: block;
  font-size: 0.92rem;
  color: var(--text-muted);
  margin-top: 2px;
}

/* ---------- Refined feature icon (uses sprite) ---------- */
.feature .feature-icon .ic {
  width: 22px;
  height: 22px;
}

/* ---------- Refined project type chips with sprite ---------- */
.project-types li .ic {
  width: 18px;
  height: 18px;
  color: var(--accent);
}

/* ---------- Service area chips: ensure single-line, refined ---------- */
.area-list li .ic {
  width: 16px;
  height: 16px;
  color: var(--accent);
}

/* ---------- Trust band stat number sheen ---------- */
.trust-stat .num em {
  display: inline-block;
}

/* ---------- Photo card: refined motion ---------- */
.photo-card .photo-frame img {
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.photo-card:hover .photo-frame img {
  transform: scale(1.035);
}

/* ---------- Photo frame zoom on hover (subtle) ---------- */
.photo-frame {
  overflow: hidden;
}
.photo-frame img {
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- FAQ refinement: sprite chevron + smoother open ---------- */
.faq summary::after {
  content: none; /* we'll use inline sprite icons via .faq-toggle */
}
.faq summary .faq-toggle {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  transition: transform 0.22s ease, background 0.22s ease;
}
.faq summary .faq-toggle .ic { width: 14px; height: 14px; }
.faq details[open] summary .faq-toggle {
  transform: rotate(180deg);
  background: var(--accent);
  color: #fff;
}
.faq summary .faq-toggle .ic-minus { display: none; }
.faq details[open] summary .faq-toggle .ic-plus  { display: none; }
.faq details[open] summary .faq-toggle .ic-minus { display: inline-block; transform: rotate(180deg); }

/* Animated open */
.faq details {
  overflow: hidden;
}
.faq details > *:not(summary) {
  animation: sew-fade-in 260ms ease both;
}
@keyframes sew-fade-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .faq details > *:not(summary) { animation: none; }
}

/* ---------- Mobile menu: cleaner transition + icon swap ---------- */
.nav-toggle .ic-close { display: none; }
.nav-toggle[aria-expanded="true"] .ic-menu { display: none; }
.nav-toggle[aria-expanded="true"] .ic-close { display: inline-block; }

@media (max-width: 880px) {
  .nav {
    transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.22s ease;
    opacity: 0;
    pointer-events: none;
  }
  .nav.is-open {
    opacity: 1;
    pointer-events: auto;
  }
}

/* ---------- Mobile CTA: gradient top edge for premium feel ---------- */
.mobile-cta::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -16px;
  height: 16px;
  background: linear-gradient(to top, rgba(22, 27, 34, 0.05), transparent);
  pointer-events: none;
}

/* ---------- Section "wall corner" motif: subtle CSS divider ---------- */
.section-divider {
  position: relative;
  height: 1px;
  background: var(--border);
  max-width: var(--container);
  margin: 0 auto;
}
.section-divider::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -3px;
  transform: translateX(-50%);
  width: 7px;
  height: 7px;
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 0 4px var(--bg);
}

/* ---------- Eyebrow tag with icon variant ---------- */
.eyebrow-tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0.4rem 0.8rem;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.eyebrow-tag .ic { width: 14px; height: 14px; }

/* ---------- Polished section eyebrow rule on dark surfaces ---------- */
.section-dark .eyebrow,
.trust-band .eyebrow,
.cta-banner .eyebrow {
  color: #ff5d68;
}

/* (Former .page-header::after accent line is now drawn via border-image on
   .page-header itself, freeing ::after for the .has-texture readability scrim.) */

/* ---------- Visible-anchor jump fix under sticky header ---------- */
[id]:not(body) { scroll-margin-top: calc(var(--header-h) + 16px); }

/* ==========================================================================
   v6 — Owner proof band ("Meet the Owner")
   Puts a real face and the branded van on the homepage so "owner-operated"
   reads as proof, not a claim. Warm editorial surface to break the cool palette.
   ========================================================================== */

.section-warm {
  background: var(--bg-warm);
  border-block: 1px solid rgba(22, 27, 34, 0.05);
  overflow: hidden; /* clip the left-mounted van cutout so it can't cause horizontal scroll */
}

.owner-band {
  display: grid;
  grid-template-columns: 0.92fr 1fr;
  gap: var(--space-8);
  align-items: center;
}

@media (max-width: 880px) {
  .owner-band {
    grid-template-columns: 1fr;
    gap: var(--space-7);
  }
}

.owner-band-visual {
  position: relative;
}

.owner-band-visual .photo-frame {
  box-shadow: var(--shadow-lg);
}

.owner-band-van {
  margin-top: var(--space-4);
}

/* On desktop the van becomes a layered inset off the portrait corner. */
@media (min-width: 881px) {
  .owner-band-van {
    position: absolute;
    right: calc(-1 * var(--space-6));
    bottom: calc(-1 * var(--space-5));
    width: 60%;
    margin-top: 0;
    border: 5px solid var(--bg-warm);
    box-shadow: var(--shadow-lg);
  }
}

.owner-band-copy h2 {
  text-wrap: balance;
}

.owner-band-copy .lead {
  color: var(--text-soft);
  margin-bottom: var(--space-5);
}

.owner-band-copy .checklist {
  margin-bottom: var(--space-6);
}

.owner-band-copy .checklist li {
  font-weight: 500;
  color: var(--text-soft);
}

/* ==========================================================================
   Edge-mounted service-van cutout (Meet the Owner)
   The van is a transparent WebP cutout mounted flush to the viewport edge as a
   large standalone visual — NO card, frame, border, or background box.
   object-fit: contain keeps the van undistorted; a horizontal translate pushes
   the front past the edge so only the back ~2/3 reads.
   ========================================================================== */

/* ---- MEET THE OWNER: van enters from the LEFT edge (faces left) ---- */
.owner-band--van {
  display: block; /* drop the 2-col grid; copy floats to the right */
  position: relative;
}
.owner-band--van .owner-band-copy {
  max-width: 540px;
  margin-left: auto; /* push copy into the right column */
}

.owner-van-stage {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 56vw;
  max-width: 940px;
  z-index: 1;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}

.owner-van-cutout {
  width: 100%;
  height: auto;
  max-height: 80%;
  object-fit: contain;
  object-position: left center;
  /* push the front of the van past the left viewport edge -> ~2/3 visible */
  transform: translateX(-12%);
  filter: drop-shadow(0 22px 32px rgba(16, 22, 30, 0.14));
}

/* ---- Tablet: shrink the van + push it farther right so it never crushes copy ---- */
@media (max-width: 1100px) and (min-width: 881px) {
  .owner-van-stage { width: 50vw; }
  .owner-van-cutout { transform: translateX(-17%); }
}

/* ---- Mobile (<=880): stack cleanly, van becomes a full-width visual ---- */
@media (max-width: 880px) {
  .owner-van-stage {
    position: static;
    width: auto;
    max-width: none;
    margin-top: var(--space-6);
    justify-content: center;
    overflow: hidden; /* clip any edge bleed -> no horizontal scroll */
  }
  .owner-van-cutout {
    position: static;
    width: 100%;
    max-height: none;
    transform: none;
    object-position: center;
  }
  .owner-band--van .owner-band-copy {
    max-width: none;
    margin-left: 0;
  }
}

/* ---------- Contact form: honeypot + inline status ---------- */
/* Honeypot kept in the DOM (and the layout) but hidden from people. Bots that
   fill every field trip it; real visitors never see it. */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-status {
  margin: 0 0 var(--space-4);
  padding: 0.85rem 1rem;
  border-radius: var(--radius-sm, 0.6rem);
  font-size: 0.95rem;
  line-height: 1.4;
  border: 1px solid transparent;
}
.form-status[hidden] { display: none; }
.form-status.is-success {
  color: #0f5132;
  background: #d1e7dd;
  border-color: #badbcc;
}
.form-status.is-error {
  color: #842029;
  background: #f8d7da;
  border-color: #f5c2c7;
}

/* Field-level invalid hint set by the submit handler. */
.form .field input.is-invalid,
.form .field textarea.is-invalid {
  border-color: #dc3545;
  outline-color: #dc3545;
}

/* ==========================================================================
   v7 — Mobile premium polish pass (2026)
   Surgical, mobile-scoped refinements. Every rule below is gated to small
   screens (or to ≥881px for the one desktop-only helper), so the desktop
   layout that already exists is completely untouched. Addresses, in order:
   contact-page grid overflow, over-tall section rhythm, ragged hero CTAs,
   trust-strip pyramid wrap, hero copy scale, and the sticky CTA safe area.
   ========================================================================== */

/* ---- Contact page two-column helper --------------------------------------
   The contact info / form layout wants an even 50/50 split on desktop. That
   used to be an INLINE `grid-template-columns:1fr 1fr` on .content-grid, which
   (being inline) beat the responsive `@media(max-width:880px){…:1fr}` rule and
   forced two columns on phones — pushing the entire estimate form off-screen
   with horizontal scroll. Moving the desktop split into this class lets the
   base mobile-first single column win on small screens again. */
@media (min-width: 881px) {
  .content-grid--even { grid-template-columns: 1fr 1fr; }
}

/* ---- Mobile section rhythm ------------------------------------------------
   The 6rem (--space-9) block padding reads as large dead gaps on a phone.
   Tighten the vertical rhythm so sections feel intentional, not empty, while
   keeping comfortable breathing room. */
@media (max-width: 600px) {
  section { padding-block: var(--space-7); }          /* 3rem (was 6rem) */
  .section-tight { padding-block: var(--space-6); }    /* 2rem */
  .page-header { padding-block: var(--space-6) var(--space-6); }
  .section-header { margin-bottom: var(--space-6); }
  .cta-banner { padding: var(--space-7) var(--space-5); }
}

/* ---- Hero / CTA action rows ----------------------------------------------
   On phones the primary + secondary buttons stacked at different auto widths,
   reading as two unrelated pills. Stack them full-width and equal so they form
   one intentional, thumb-friendly CTA pair. Covers every .hero-actions row
   (homepage hero, page-header heroes, cta-banner, owner band, contact) plus the
   footer and mid-page trust-CTA action clusters. */
@media (max-width: 600px) {
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; }
  .footer-top .actions .btn,
  .trust-cta .actions .btn { flex: 1 1 100%; }
}

/* ---- Trust strip ---------------------------------------------------------
   The centered flex-wrap formed an uneven pyramid on phones (one item, then
   two, then one…). Switch to a tidy left-aligned two-up grid so it reads as a
   deliberate proof row. */
@media (max-width: 600px) {
  .trust-strip {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3) var(--space-4);
    justify-items: start;
    padding: var(--space-5);
  }
  .trust-strip-item { font-size: 0.82rem; white-space: normal; }
  .trust-strip-sep { display: none; }
}

/* ---- Hero copy on the smallest screens -----------------------------------
   Keep the headline confident but stop it overflowing toward the edges, and
   ease the long sub-paragraph a touch so the hero feels composed at 320–390px. */
@media (max-width: 400px) {
  .hero h1 { font-size: clamp(2.05rem, 8.5vw, 2.45rem); }
  .hero-sub,
  .page-header .lead { font-size: 1.05rem; }
}

/* ---- Sticky mobile CTA ----------------------------------------------------
   Reserve space for the bar plus the device safe-area (home indicator) so it
   never covers page content, and give the two buttons a consistent comfortable
   tap target. */
@media (max-width: 880px) {
  body { padding-bottom: calc(74px + env(safe-area-inset-bottom)); }
  .mobile-cta .btn { min-height: 48px; }
}
