/* ==========================================================================
   TAPERS UNLIMITED & PAINTERS — Design System
   Manchester, NH · Serving NH, VT & MA
   --------------------------------------------------------------------------
   CONTENTS
   01. Tokens (custom properties)
   02. Reset & base
   03. Typography
   04. Decorative primitives (grain, panels, tape, strokes, drips)
   05. Layout helpers
   06. Buttons & labels
   07. Announcement bar
   08. Header & navigation
   09. Hero
   10. Marquee
   11. Section intro
   12. Services grid
   12b. Completed projects
   13. Project gallery + lightbox
   14. Why choose us
   15. Process
   16. Service area
   17. Before & after
   18. Testimonials
   19. Main CTA
   20. Footer
   20f. FAQ (services page)
   21. Contact page
   22. Forms
   23. Motion & reveal
   24. Reduced motion & print
   ========================================================================== */

/* ==========================================================================
   01. TOKENS
   ========================================================================== */

:root {
  /* Brand palette — black, golden yellow, white only. */
  --ink: #000000;
  --gold: #fcbc42;
  --paper: #ffffff;

  /* Supporting neutrals — shadows, borders, surfaces, secondary text only. */
  --gray-050: #f6f5f3;
  --gray-100: #e9e7e2;
  --gray-200: #d5d2cb;
  --gray-400: #8f8b84;
  --gray-600: #57534e;
  --gray-800: #1c1b19;
  --gray-900: #0d0d0c;

  /* Derived brand tints */
  --gold-deep: #e0a52c;
  --gold-soft: rgba(252, 188, 66, 0.16);
  --ink-soft: rgba(0, 0, 0, 0.72);

  /* Warm surface — --gold washed ~28% into --gray-050. Deliberately DARKER than
     --gray-050, not lighter: the white project cards sit on it, and tinting
     toward white would have cost them separation instead of adding it.
     To dial it: ~20% gives #faecd2 (softer), ~35% gives #f7e0b5 (stronger). */
  --paper-warm: #f8e5c1;

  /* Typography */
  --font-display: "Anton", "Arial Narrow", sans-serif;
  --font-condensed: "Barlow Condensed", "Arial Narrow", sans-serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --step--1: clamp(0.82rem, 0.79rem + 0.14vw, 0.9rem);
  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.12rem);
  --step-1: clamp(1.18rem, 1.1rem + 0.4vw, 1.4rem);
  --step-2: clamp(1.45rem, 1.28rem + 0.85vw, 2rem);
  --step-3: clamp(1.9rem, 1.5rem + 2vw, 3rem);
  --step-4: clamp(2.5rem, 1.7rem + 4vw, 4.5rem);
  --step-5: clamp(3rem, 1.6rem + 7vw, 7rem);
  --step-6: clamp(3.6rem, 0.8rem + 12vw, 11rem);

  /* Spacing */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-s: 1rem;
  --space-m: 1.5rem;
  --space-l: 2.25rem;
  --space-xl: 3.5rem;
  --space-2xl: 5rem;
  --space-3xl: clamp(4rem, 2rem + 8vw, 8rem);

  /* Structure */
  --wrap: 1280px;
  --wrap-narrow: 760px;
  --gutter: clamp(1rem, 0.4rem + 2.4vw, 2.5rem);

  --border-w: 3px;
  --border-w-thick: 5px;
  --radius: 2px;
  --radius-pill: 999px;

  /* Hard editorial shadows */
  --shadow-hard: 8px 8px 0 var(--ink);
  --shadow-hard-sm: 4px 4px 0 var(--ink);
  --shadow-hard-gold: 8px 8px 0 var(--gold);
  --shadow-soft: 0 18px 40px -18px rgba(0, 0, 0, 0.55);

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-snap: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast: 160ms;
  --dur: 280ms;
  --dur-slow: 620ms;

  /* Header height is driven by the logo plate, not the nav: the plate is the
     tallest thing in the bar (logo + 7px padding + 2px border, top and bottom).
     Raised from 78px when the logo grew to 48px, to keep ~11px of clearance
     above and below the plate rather than letting it crowd the bar edges. */
  --header-h: 88px;

  /* Stroke colour for outlined text. Dark surfaces flip it to white below. */
  --outline-c: var(--ink);

  /* Paper grain — inline SVG turbulence, no network request. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

/* ==========================================================================
   02. RESET & BASE
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  /* Native smooth anchor scrolling; disabled under prefers-reduced-motion. */
  scroll-behavior: smooth;
}

/* Keep anchor targets clear of the sticky header. */
:target,
section[id] {
  scroll-margin-top: calc(var(--header-h) + var(--space-s));
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Locked while the mobile drawer is open. */
body.is-locked {
  overflow: hidden;
}

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

img {
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

a {
  color: inherit;
}

h1,
h2,
h3,
h4,
p,
figure,
blockquote {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Focus — always visible, never removed. */
:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: var(--radius);
}

.on-dark :focus-visible,
.site-header :focus-visible,
.site-footer :focus-visible {
  outline-color: var(--gold);
}

::selection {
  background: var(--gold);
  color: var(--ink);
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--space-s);
  z-index: 999;
  padding: var(--space-xs) var(--space-m);
  background: var(--gold);
  color: var(--ink);
  border: var(--border-w) solid var(--ink);
  font-family: var(--font-condensed);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
  transition: top var(--dur) var(--ease-out);
}

.skip-link:focus {
  top: var(--space-s);
}

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

/* ==========================================================================
   03. TYPOGRAPHY
   ========================================================================== */

.display,
h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 0.92;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  text-wrap: balance;
}

h1 {
  font-size: var(--step-5);
}

h2 {
  font-size: var(--step-4);
}

h3 {
  font-size: var(--step-2);
}

p {
  text-wrap: pretty;
}

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  max-width: 62ch;
}

.prose {
  max-width: 68ch;
}

/* Eyebrow — small condensed kicker above headings. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-condensed);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1;
}

.eyebrow::before {
  content: "";
  width: 28px;
  height: 3px;
  background: var(--gold);
}

.eyebrow--plain::before {
  display: none;
}

/* Headline word treatments */
.hl-gold {
  color: var(--gold);
}

/* Word sitting on a gold roller stroke.
   Inline rather than absolutely positioned: an absolute stroke needs a
   positioned ancestor, and when it escapes one it lands across body copy. */
.hl-block {
  position: relative;
  display: inline-block;
  padding: 0 0.18em;
  color: var(--ink);
  isolation: isolate;
}

/* The stroke must BLEED PAST the inline box, not inset into it. Headings use
   line-height: 0.92, so the inline box is shorter than the glyphs it holds —
   an inward inset leaves the black word hanging off the gold and, on the dark
   hero sections, unreadable. These negative values keep the stroke behind the
   full cap height at every size. */
.hl-block::before {
  content: "";
  position: absolute;
  inset: -0.1em -0.02em -0.06em;
  z-index: -1;
  background: var(--gold);
  /* Rough, hand-cut paint edge. */
  clip-path: polygon(
    0.6% 6%, 99.4% 0%, 100% 88%, 99% 99%, 40% 96%, 1.5% 100%, 0% 40%
  );
  transform: rotate(-0.7deg);
}

/* Roller nap — fine horizontal streaks across the stroke. */
.hl-block::after {
  content: "";
  position: absolute;
  inset: -0.1em -0.02em -0.06em;
  z-index: -1;
  background-image: repeating-linear-gradient(
    0deg, rgba(255, 255, 255, 0.3) 0 2px, transparent 2px 7px
  );
  mix-blend-mode: soft-light;
  pointer-events: none;
}

/* Outlined (knockout) word.
   The stroke colour must be explicit: `currentColor` would resolve against this
   element's own `color: transparent` and the word would vanish entirely. */
.hl-outline {
  color: transparent;
  -webkit-text-stroke: 2px var(--outline-c);
  paint-order: stroke fill;
}

/* Word with a hand-painted underline stroke.
   `isolation` + z-index keep the stroke behind the letters; without it the
   ::after paints over the baseline and eats into the word. */
.hl-stroke {
  position: relative;
  display: inline-block;
  isolation: isolate;
}

/* Sits behind the word and low enough to read as a brush swipe under it —
   a thin band at the baseline disappears behind heavy display letterforms. */
.hl-stroke::after {
  content: "";
  position: absolute;
  left: -0.05em;
  right: -0.05em;
  bottom: 0.01em;
  height: 0.26em;
  z-index: -1;
  background: var(--gold);
  clip-path: polygon(0 30%, 8% 5%, 30% 22%, 62% 0, 88% 18%, 100% 8%, 100% 74%, 74% 100%, 40% 78%, 12% 96%, 0 72%);
  transform: rotate(-0.5deg);
  transform-origin: left center;
}

/* Rotated word — small tilt for editorial energy. */
.hl-tilt {
  display: inline-block;
  transform: rotate(-2.5deg);
}

/* ==========================================================================
   04. DECORATIVE PRIMITIVES
   ========================================================================== */

/* Paper/compound grain overlay. Applied to dark sections.
   Kept faint on purpose: the blend reaches content that paints below it, so
   anything heavier reads as a grey veil over the photography and headlines
   rather than as texture. */
.grain::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  mix-blend-mode: soft-light;
  opacity: 0.14;
  pointer-events: none;
  z-index: 1;
}

/* Drywall panel seam grid — repeating board joints. */
.panel-grid {
  background-color: var(--gray-050);
  background-image:
    linear-gradient(90deg, var(--gray-200) 1px, transparent 1px),
    linear-gradient(var(--gray-200) 1px, transparent 1px);
  background-size: 96px 96px;
}

.panel-grid--dark {
  background-color: var(--ink);
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, 0.07) 1px, transparent 1px),
    linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px);
  background-size: 96px 96px;
}

/* Joint-tape strip — runs between sections. */
.tape-strip {
  position: relative;
  height: 46px;
  background: var(--gold);
  border-block: var(--border-w) solid var(--ink);
  overflow: hidden;
}

.tape-strip::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Perforated joint-tape mesh. */
  background-image:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.22) 0 2px, transparent 2px 9px),
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.22) 0 2px, transparent 2px 9px);
}

/* Construction measurement rule — ticks like a tape measure. */
.measure-rule {
  height: 26px;
  background-image: repeating-linear-gradient(90deg, var(--ink) 0 2px, transparent 2px 24px);
  background-position: bottom;
  background-repeat: repeat-x;
  background-size: 24px 12px;
  border-bottom: var(--border-w) solid var(--ink);
}

.on-dark .measure-rule {
  background-image: repeating-linear-gradient(90deg, var(--gold) 0 2px, transparent 2px 24px);
  border-bottom-color: var(--gold);
}

/* Paint drip edge — hangs off the bottom of a block. */
.drips {
  position: relative;
}

.drips::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -22px;
  height: 24px;
  background: inherit;
  /* Irregular drip tongues of varying length. */
  clip-path: polygon(
    0 0, 100% 0, 100% 18%,
    96% 18%, 95% 62%, 93% 18%,
    84% 18%, 83% 88%, 81% 18%,
    70% 18%, 69% 44%, 67% 18%,
    54% 18%, 53% 74%, 51% 18%,
    38% 18%, 37% 38%, 35% 18%,
    24% 18%, 23% 82%, 21% 18%,
    11% 18%, 10% 50%, 8% 18%,
    0 18%
  );
  pointer-events: none;
}

/* Paint splatter dots, used sparingly at transitions. */
.splatter {
  position: absolute;
  pointer-events: none;
  color: var(--gold);
}

/* Masking-tape sticker label.
   The colour is set explicitly, never inherited: this label always sits on a
   gold or white plate, so on a dark section inherited white text would be
   invisible on the paper variant and low-contrast on the gold one. */
.tape-label {
  display: inline-block;
  padding: var(--space-3xs) var(--space-s);
  background: var(--gold);
  color: var(--ink);
  border: 2px solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  font-family: var(--font-condensed);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transform: rotate(-2deg);
}

.tape-label--paper {
  background: var(--paper);
}

/* Rotated sticker badge — circular seal.
   Colour is explicit for the same reason as .tape-label: the seal is always
   gold, so inherited white text on the dark hero would fail contrast. */
.badge-seal {
  display: grid;
  place-content: center;
  width: 118px;
  height: 118px;
  padding: var(--space-2xs);
  border-radius: 50%;
  background: var(--gold);
  color: var(--ink);
  border: var(--border-w) solid var(--ink);
  font-family: var(--font-display);
  font-size: 0.82rem;
  line-height: 1.05;
  text-align: center;
  text-transform: uppercase;
  transform: rotate(-9deg);
  box-shadow: var(--shadow-hard-sm);
}

/* Four-point spark/star. */
.spark {
  display: inline-block;
  width: 1em;
  height: 1em;
  background: currentColor;
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
}

/* Oversized ghost word behind content. */
.ghost-word {
  position: absolute;
  font-family: var(--font-display);
  font-size: var(--step-6);
  line-height: 0.8;
  text-transform: uppercase;
  color: transparent;
  -webkit-text-stroke: 2px rgba(0, 0, 0, 0.08);
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  z-index: 0;
}

.on-dark .ghost-word {
  -webkit-text-stroke-color: rgba(255, 255, 255, 0.07);
}

/* Hand-drawn arrow. */
.arrow-hand {
  color: var(--gold);
  width: 68px;
  height: auto;
}

/* ==========================================================================
   05. LAYOUT HELPERS
   ========================================================================== */

.wrap {
  width: min(100% - (var(--gutter) * 2), var(--wrap));
  margin-inline: auto;
}

.wrap--narrow {
  width: min(100% - (var(--gutter) * 2), var(--wrap-narrow));
  margin-inline: auto;
}

.section {
  position: relative;
  padding-block: var(--space-3xl);
  overflow: clip;
}

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

/* Dark surfaces: white text, and outlined words stroke white to match. */
.on-dark,
.hero,
.gallery,
.process,
.cta,
.site-header,
.site-footer,
.page-hero,
.intro__aside,
.form-aside {
  --outline-c: var(--paper);
}

.on-dark {
  background: var(--ink);
  color: var(--paper);
}

.on-dark .lede,
.on-dark p {
  color: var(--gray-200);
}

.on-gold {
  background: var(--gold);
  color: var(--ink);
}

.stack > * + * {
  margin-top: var(--space-s);
}

.stack-l > * + * {
  margin-top: var(--space-l);
}

.section-head {
  position: relative;
  z-index: 2;
  max-width: min(100%, 760px);
}

.section-head .lede {
  margin-top: var(--space-m);
}

/* ==========================================================================
   06. BUTTONS & LABELS
   ========================================================================== */

.btn {
  --btn-bg: var(--gold);
  --btn-fg: var(--ink);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-height: 52px;
  padding: var(--space-xs) var(--space-l);
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: var(--border-w) solid var(--ink);
  border-radius: var(--radius);
  box-shadow: var(--shadow-hard-sm);
  font-family: var(--font-condensed);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur) var(--ease-snap),
    box-shadow var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out);
}

.btn:hover,
.btn:focus-visible {
  transform: translate(-3px, -3px);
  box-shadow: 7px 7px 0 var(--ink);
}

.btn:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--ink);
}

/* Black contractor-label button. */
.btn--ink {
  --btn-bg: var(--ink);
  --btn-fg: var(--paper);
  border-color: var(--ink);
}

.btn--ink:hover,
.btn--ink:focus-visible {
  --btn-bg: var(--gray-800);
  box-shadow: 7px 7px 0 var(--gold);
}

/* Outlined button for dark backgrounds. */
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--paper);
  border-color: var(--paper);
  box-shadow: 4px 4px 0 var(--gold);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
  --btn-bg: var(--paper);
  --btn-fg: var(--ink);
  box-shadow: 7px 7px 0 var(--gold);
}

.btn--white {
  --btn-bg: var(--paper);
  --btn-fg: var(--ink);
}

.btn--lg {
  min-height: 62px;
  padding-inline: var(--space-xl);
  font-size: 1.2rem;
}

.btn__icon {
  width: 1.15em;
  height: 1.15em;
  flex: none;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: center;
}

/* ==========================================================================
   07. ANNOUNCEMENT BAR
   ========================================================================== */

.announce {
  position: relative;
  background: var(--gold);
  color: var(--ink);
  border-bottom: var(--border-w) solid var(--ink);
  overflow: hidden;
}

.announce__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  min-height: 42px;
  padding: var(--space-3xs) var(--gutter);
  font-family: var(--font-condensed);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
}

/* Pulsing job-site marker dot. */
.announce__dot {
  position: relative;
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--ink);
}

.announce__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--ink);
  animation: ping 2.4s var(--ease-out) infinite;
}

@keyframes ping {
  0% { transform: scale(1); opacity: 0.9; }
  70%, 100% { transform: scale(3.2); opacity: 0; }
}

.announce__sep {
  opacity: 0.55;
}

/* On narrow screens the full bar wraps to multiple lines and pushes the hero
   down, so the secondary claim drops away and the primary message stays. */
@media (max-width: 900px) {
  .announce__inner {
    font-size: 0.8rem;
    letter-spacing: 0.06em;
  }

  .announce__sep,
  .announce__extra {
    display: none;
  }
}

/* ==========================================================================
   08. HEADER & NAVIGATION
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  border-bottom: 3px solid transparent;
  transition: background-color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

/* Scrolled state — border appears, shadow deepens, height reduces. */
.site-header.is-stuck {
  background: rgba(0, 0, 0, 0.96);
  backdrop-filter: blur(8px);
  border-bottom-color: var(--gold);
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.8);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  min-height: var(--header-h);
  padding-inline: var(--gutter);
  width: min(100%, calc(var(--wrap) + var(--gutter) * 2));
  margin-inline: auto;
  transition: min-height var(--dur) var(--ease-out);
}

.site-header.is-stuck .site-header__inner {
  min-height: 72px;
}

/* Logo lockup — the real logo art sits on a white plate so it reads on black. */
.brand {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  text-decoration: none;
  flex: none;
}

.brand__plate {
  display: grid;
  place-items: center;
  padding: 7px 10px;
  background: var(--paper);
  border: 2px solid var(--ink);
  box-shadow: 3px 3px 0 var(--gold);
  transition: transform var(--dur) var(--ease-snap), box-shadow var(--dur) var(--ease-out);
}

.brand:hover .brand__plate,
.brand:focus-visible .brand__plate {
  transform: translate(-2px, -2px) rotate(-1deg);
  box-shadow: 5px 5px 0 var(--gold);
}

/* Sized by height, never width — the logo art is 549x198 (~2.77:1), so height
   is what has to clear the header bar and width follows from it. */
.brand__img {
  width: auto;
  height: 48px;
  transition: height var(--dur) var(--ease-out);
}

/* The scrolled state still steps down, just from a taller start. Keep the two
   heights in proportion, or the logo appears to jump rather than settle. */
.site-header.is-stuck .brand__img {
  height: 38px;
}

/* Primary navigation */
.nav {
  margin-left: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.4vw, 1.6rem);
}

.nav__link {
  position: relative;
  display: inline-block;
  padding: var(--space-2xs) 2px;
  font-family: var(--font-condensed);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  transition: color var(--dur) var(--ease-out);
}

/* Gold stroke wipes in from the left on hover. */
.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 4px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}

.nav__link:hover,
.nav__link:focus-visible {
  color: var(--gold);
}

.nav__link:hover::after,
.nav__link:focus-visible::after,
.nav__link[aria-current="page"]::after {
  transform: scaleX(1);
}

.nav__link[aria-current="page"] {
  color: var(--gold);
}

.nav__cta {
  margin-left: var(--space-xs);
}

.site-header .btn {
  min-height: 46px;
  padding-inline: var(--space-m);
  font-size: 0.95rem;
  box-shadow: 3px 3px 0 var(--gold);
  border-color: var(--paper);
}

.site-header.is-stuck .btn {
  box-shadow: 4px 4px 0 var(--paper);
  background: var(--gold);
  border-color: var(--gold);
}

.site-header .btn:hover,
.site-header .btn:focus-visible {
  box-shadow: 6px 6px 0 var(--paper);
  transform: translate(-2px, -2px);
}

/* Mobile toggle */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-left: auto;
  padding: 0;
  background: transparent;
  border: 2px solid var(--paper);
  border-radius: var(--radius);
  cursor: pointer;
}

.nav-toggle__bars {
  position: relative;
  display: block;
  width: 22px;
  height: 2px;
  background: var(--paper);
  transition: background-color var(--dur-fast) var(--ease-out);
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 22px;
  height: 2px;
  background: var(--paper);
  transition: transform var(--dur) var(--ease-out), top var(--dur) var(--ease-out);
}

.nav-toggle__bars::before { top: -7px; }
.nav-toggle__bars::after { top: 7px; }

.nav-toggle[aria-expanded="true"] {
  background: var(--gold);
  border-color: var(--gold);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars {
  background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  top: 0;
  background: var(--ink);
  transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  top: 0;
  background: var(--ink);
  transform: rotate(-45deg);
}

/* Mobile drawer */
.nav-drawer {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: 99;
  width: min(88vw, 400px);
  padding: calc(var(--header-h) + var(--space-xl)) var(--space-l) var(--space-l);
  background: var(--ink);
  border-left: var(--border-w) solid var(--gold);
  transform: translateX(101%);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* No `visibility` transition — it would flip at the midpoint and leave the
     drawer unfocusable on open. The `inert` attribute keeps the closed drawer
     out of the tab order instead. */
  transition: transform var(--dur-slow) var(--ease-out);
}

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

.nav-drawer__list > li + li {
  margin-top: var(--space-2xs);
}

.nav-drawer__link {
  display: block;
  padding: var(--space-xs) 0;
  font-family: var(--font-display);
  font-size: var(--step-2);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  border-bottom: 2px solid rgba(255, 255, 255, 0.12);
  transition: color var(--dur) var(--ease-out), padding-left var(--dur) var(--ease-out);
}

.nav-drawer__link:hover,
.nav-drawer__link:focus-visible {
  color: var(--gold);
  padding-left: var(--space-xs);
}

.nav-drawer__cta {
  margin-top: var(--space-l);
  width: 100%;
}

.nav-drawer__phone {
  margin-top: var(--space-m);
  display: block;
  font-family: var(--font-condensed);
  font-size: var(--step-1);
  font-weight: 700;
  color: var(--gold);
  text-decoration: none;
}

.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 98;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.nav-scrim[hidden] {
  display: none;
}

.nav-scrim.is-open {
  opacity: 1;
}

@media (max-width: 1080px) {
  .nav,
  .site-header > .site-header__inner > .btn {
    display: none;
  }

  .nav-toggle {
    display: flex;
  }
}

@media (min-width: 1081px) {
  .nav-drawer,
  .nav-scrim {
    display: none;
  }
}

/* ==========================================================================
   09. HERO
   ========================================================================== */

.hero {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  overflow: clip;
  padding-block: clamp(3rem, 1.5rem + 6vw, 6rem) clamp(4rem, 2rem + 6vw, 7rem);
}

.hero__bg {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 110px 110px;
  mask-image: radial-gradient(120% 90% at 20% 20%, #000 25%, transparent 78%);
}

.hero__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: center;
}

.hero__eyebrow {
  color: var(--gold);
}

/* The headline runs long, so it gets its own tighter scale rather than
   --step-5, which is tuned for short display lines. */
.hero__title {
  position: relative;
  margin-top: var(--space-m);
  font-size: clamp(2.1rem, 1.15rem + 3.1vw, 4rem);
  z-index: 2;
}

.hero__copy {
  margin-top: var(--space-m);
  max-width: 54ch;
  color: var(--gray-200);
}

.hero__actions {
  margin-top: var(--space-l);
}

/* Trust chips under the CTAs. */
.hero__trust {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-s);
  margin-top: var(--space-l);
  padding-top: var(--space-m);
  border-top: 2px solid rgba(255, 255, 255, 0.16);
}

.trust-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-condensed);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--paper);
}

.trust-chip .spark {
  width: 0.8em;
  height: 0.8em;
  color: var(--gold);
  flex: none;
}

/* Hero media — layered photo frame. */
.hero__media {
  position: relative;
}

.hero__frame {
  position: relative;
  z-index: 2;
  border: var(--border-w-thick) solid var(--paper);
  box-shadow: 14px 14px 0 var(--gold);
  overflow: hidden;
  aspect-ratio: 4 / 3;
}

.hero__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Offset gold panel behind the photo. */
.hero__panel {
  position: absolute;
  inset: auto -28px -30px 40px;
  height: 62%;
  background: var(--gold);
  border: var(--border-w) solid var(--paper);
  transform: rotate(-2.5deg);
  z-index: 1;
}

/* Years badge stuck to the frame. */
.hero__badge {
  position: absolute;
  top: -30px;
  left: -30px;
  z-index: 3;
}

.hero__badge strong {
  display: block;
  font-size: 1.9rem;
  line-height: 1;
}

/* Taping-knife silhouette decorative shape. */
.knife {
  position: absolute;
  z-index: 1;
  color: var(--gold);
  opacity: 0.5;
  pointer-events: none;
}

.hero__knife {
  right: -70px;
  top: -50px;
  width: 190px;
  transform: rotate(18deg);
}

/* Phone block under hero media. */
.hero__phone {
  position: relative;
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-top: var(--space-l);
  padding: var(--space-2xs) var(--space-m);
  background: var(--paper);
  color: var(--ink);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  font-family: var(--font-display);
  font-size: var(--step-1);
  text-decoration: none;
  transform: rotate(-1.5deg);
  transition: transform var(--dur) var(--ease-snap);
}

.hero__phone:hover,
.hero__phone:focus-visible {
  transform: rotate(-1.5deg) translate(-3px, -3px);
}

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

  .hero__media {
    order: -1;
  }

  .hero__knife {
    display: none;
  }

  .hero__badge {
    width: 96px;
    height: 96px;
    top: -22px;
    left: -14px;
  }
}

/* ==========================================================================
   10. MARQUEE
   ========================================================================== */

.marquee {
  position: relative;
  display: flex;
  overflow: hidden;
  padding-block: var(--space-xs);
  background: var(--gold);
  border-block: var(--border-w) solid var(--ink);
  user-select: none;
}

.marquee--ink {
  background: var(--ink);
  border-color: var(--gold);
}

.marquee__track {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--space-m);
  padding-right: var(--space-m);
  min-width: max-content;
  animation: marquee-scroll 42s linear infinite;
}

.marquee:hover .marquee__track {
  animation-play-state: paused;
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-m);
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 0.9rem + 1vw, 1.75rem);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--ink);
}

.marquee--ink .marquee__item {
  color: var(--paper);
}

.marquee--ink .marquee__item:nth-child(even) {
  color: var(--gold);
}

.marquee__item .spark {
  width: 0.5em;
  height: 0.5em;
  flex: none;
}

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

/* ==========================================================================
   11. SECTION INTRO
   ========================================================================== */

.intro {
  position: relative;
  background: var(--paper);
}

.intro__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: end;
}

.intro__ghost {
  top: -2.2rem;
  right: -2rem;
}

.intro__title {
  font-size: var(--step-4);
}

.intro__aside {
  padding: var(--space-l);
  background: var(--ink);
  color: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-gold);
}

.intro__aside p {
  color: var(--gray-200);
}

.intro__aside .tape-label {
  margin-bottom: var(--space-s);
}

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

/* ==========================================================================
   12. SERVICES GRID
   ========================================================================== */

.services {
  position: relative;
  background: var(--gray-050);
  background-image:
    linear-gradient(90deg, var(--gray-200) 1px, transparent 1px),
    linear-gradient(var(--gray-200) 1px, transparent 1px);
  background-size: 96px 96px;
}

/* Warm variant of the panel-grid surface, used only by the homepage Completed
   Projects section. `.services` is shared with about.html and services.html, so
   the tint has to live on a modifier or those two warm up with it.
   Single-class modifier relying on source order, matching `.panel-grid--dark`
   after `.panel-grid` — it must stay below `.services`. Only the colour is
   overridden; the seam grid `background-image` is inherited unchanged. */
.services--warm {
  background-color: var(--paper-warm);
}

.services__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-m);
  margin-bottom: var(--space-xl);
}

.services__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
  gap: var(--space-m);
}

/* Service card styled as a drywall panel.
   Currently unused: the home page runs the Completed Projects grid (12b) where
   this grid used to sit. Kept so the services grid can be restored as-is. */
.service-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 300px;
  padding: var(--space-l);
  background: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--dur) var(--ease-snap),
    box-shadow var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out);
}

/* Gold panel wipes up from the bottom on hover. */
.service-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--gold);
  transform: translateY(101%);
  transition: transform var(--dur-slow) var(--ease-out);
}

.service-card:hover,
.service-card:focus-within {
  transform: translate(-4px, -6px);
  box-shadow: 10px 12px 0 var(--ink);
}

.service-card:hover::before,
.service-card:focus-within::before {
  transform: translateY(0);
}

/* Oversized outlined number. */
.service-card__num {
  font-family: var(--font-display);
  font-size: 3.4rem;
  line-height: 0.85;
  color: transparent;
  -webkit-text-stroke: 2px var(--ink);
  transition: color var(--dur) var(--ease-out);
}

.service-card:hover .service-card__num,
.service-card:focus-within .service-card__num {
  color: var(--paper);
  -webkit-text-stroke-color: var(--ink);
}

.service-card__icon {
  position: absolute;
  top: var(--space-l);
  right: var(--space-l);
  width: 44px;
  height: 44px;
  color: var(--gold);
  transition: color var(--dur) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}

.service-card:hover .service-card__icon,
.service-card:focus-within .service-card__icon {
  color: var(--ink);
  transform: rotate(-8deg) scale(1.08);
}

.service-card__title {
  margin-top: var(--space-m);
  font-size: var(--step-2);
}

.service-card__body {
  margin-top: var(--space-2xs);
  font-size: 0.96rem;
  line-height: 1.6;
  color: var(--gray-600);
  transition: color var(--dur) var(--ease-out);
}

.service-card:hover .service-card__body,
.service-card:focus-within .service-card__body {
  color: var(--ink);
}

/* Board seam line at the card foot. */
.service-card__seam {
  margin-top: auto;
  padding-top: var(--space-m);
  border-top: 2px dashed var(--gray-200);
  font-family: var(--font-condensed);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gray-400);
  transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}

.service-card:hover .service-card__seam,
.service-card:focus-within .service-card__seam {
  color: var(--ink);
  border-top-color: var(--ink);
}

/* ==========================================================================
   12b. COMPLETED PROJECTS
   --------------------------------------------------------------------------
   Sits on the warm `.services--warm` variant of the panel-grid surface (section
   12) and reuses `.services__head`.

   Each photo tile reuses the gallery's `.shot` button so the existing lightbox
   picks it up with no JS change. `.shot` is drawn for the dark gallery, though
   — white border, gold hover shadow, height: 100% — so every override below is
   scoped as `.project-card .shot`. That is one class heavier than the base
   rules, which keeps it winning regardless of source order (section 13 defines
   `.shot` *after* this block).
   ========================================================================== */

/* 340px rather than 300px: nine projects land as a clean 3 × 3 at full width,
   where a four-column track would leave a single orphan card on the last row. */
.projects__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: var(--space-m);
}

.project-card {
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  transition: transform var(--dur) var(--ease-snap),
    box-shadow var(--dur) var(--ease-out);
}

.project-card:hover,
.project-card:focus-within {
  transform: translate(-4px, -6px);
  box-shadow: 10px 12px 0 var(--ink);
}

/* Fixed ratio so portrait and landscape source photos still line up in a row.
   The card owns the border, so the tile only draws the seam beneath itself. */
.project-card .shot,
.project-card__plate {
  aspect-ratio: 4 / 3;
  flex: none;
  border: 0;
  border-bottom: var(--border-w) solid var(--ink);
}

.project-card .shot {
  height: auto;
}

/* The whole card already lifts on hover; a second lift on the button inside
   would slide the photo out from under its own frame. */
.project-card .shot:hover,
.project-card .shot:focus-visible {
  transform: none;
  box-shadow: none;
}

/* Stand-in plate for a project with no photo yet — a drywall panel rather
   than an unrelated stock image. Currently unused (every project has a photo);
   kept for the next one that arrives without one. */
.project-card__plate {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-s);
  background-color: var(--gray-050);
  background-image:
    linear-gradient(90deg, var(--gray-200) 1px, transparent 1px),
    linear-gradient(var(--gray-200) 1px, transparent 1px);
  background-size: 48px 48px;
}

.project-card__plate-icon {
  width: 56px;
  height: 56px;
  color: var(--gray-400);
}

.project-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--space-m) var(--space-l) var(--space-l);
}

/* Outlined job number, matching the service cards it replaced. Currently unused
   — the 01–10 numbers were removed from the markup — but kept so the cards can
   be renumbered without rebuilding the style. If it is reinstated, put back the
   `margin-top` on .project-card__title below; that gap existed to clear this. */
.project-card__num {
  font-family: var(--font-display);
  font-size: 2.4rem;
  line-height: 0.85;
  color: transparent;
  -webkit-text-stroke: 2px var(--gray-200);
  transition: -webkit-text-stroke-color var(--dur) var(--ease-out);
}

.project-card:hover .project-card__num,
.project-card:focus-within .project-card__num {
  -webkit-text-stroke-color: var(--gold-deep);
}

/* The margin-bottom is the floor for the gap below. `.project-card__addr` is
   pushed down by an auto margin, which collapses to nothing on a two-line
   title and leaves the seam rule cutting into the second line. */
.project-card__title {
  margin-bottom: var(--space-m);
  font-size: var(--step-2);
}

/* Pushed to the foot so addresses line up across a row of uneven titles. */
.project-card__addr {
  margin-top: auto;
  padding-top: var(--space-m);
  border-top: 2px dashed var(--gray-200);
  font-family: var(--font-condensed);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.03em;
  color: var(--gray-600);
  transition: color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out);
}

.project-card:hover .project-card__addr,
.project-card:focus-within .project-card__addr {
  color: var(--ink);
  border-top-color: var(--ink);
}

/* Featured card — photo beside the plate rather than above it, spanning the
   whole track so the last row reads as a deliberate close instead of an
   orphan. The photo has no aspect-ratio here: it stretches to whatever the
   text column needs, with a floor so a short address cannot collapse it. */
.project-card--wide {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}

.project-card--wide .shot {
  aspect-ratio: auto;
  min-height: 320px;
  border-bottom: 0;
  border-right: var(--border-w) solid var(--ink);
}

.project-card--wide .project-card__body {
  justify-content: center;
  padding: var(--space-xl) var(--space-2xl) var(--space-xl) var(--space-xl);
}

/* The address stops being a foot rule when the body is vertically centred. */
.project-card--wide .project-card__addr {
  margin-top: 0;
}

/* `align-self` keeps the sticker at its own width — a grid/flex child would
   otherwise stretch the tape across the whole plate. */
.project-card__tag {
  align-self: start;
  margin-bottom: var(--space-m);
}

@media (max-width: 900px) {
  .project-card--wide {
    grid-template-columns: 1fr;
  }

  .project-card--wide .shot {
    aspect-ratio: 4 / 3;
    min-height: 0;
    border-right: 0;
    border-bottom: var(--border-w) solid var(--ink);
  }

  .project-card--wide .project-card__body {
    padding: var(--space-m) var(--space-l) var(--space-l);
  }
}

.projects__foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: center;
  margin-top: var(--space-xl);
}

/* ==========================================================================
   13. PROJECT GALLERY + LIGHTBOX
   ========================================================================== */

.gallery {
  position: relative;
  background: var(--ink);
  color: var(--paper);
}

/* `ch` is misleadingly narrow for a condensed display face, so this headline
   is capped in px to keep it to two or three lines. */
.gallery__head {
  position: relative;
  z-index: 2;
  margin-bottom: var(--space-xl);
  max-width: min(100%, 940px);
}

/* Editorial collage — deliberately uneven proportions.
   12 tracks, not 6, so a row can hold the 6+3+3 split that 6 tracks cannot.
   See the notes above the cell rules below — the row structure has three
   constraints that are easy to break by accident. */
.gallery__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--space-s);
}

/* Each grid cell carries the collage placement; the button inside fills it. */
.gallery__grid > li {
  display: flex;
  min-width: 0;
}

.shot {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  background: var(--gray-900);
  border: var(--border-w) solid var(--paper);
  overflow: hidden;
  cursor: pointer;
  transition: transform var(--dur) var(--ease-snap), box-shadow var(--dur) var(--ease-out);
}

.shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out), filter var(--dur) var(--ease-out);
}

.shot:hover,
.shot:focus-visible {
  transform: translate(-3px, -4px);
  box-shadow: 10px 12px 0 var(--gold);
  z-index: 3;
}

.shot:hover img,
.shot:focus-visible img {
  transform: scale(1.06);
}

/* Hover overlay label. */
.shot__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: var(--space-s);
  background: linear-gradient(to top, rgba(0, 0, 0, 0.86) 0%, rgba(0, 0, 0, 0.1) 55%, transparent 100%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.shot:hover .shot__overlay,
.shot:focus-visible .shot__overlay {
  opacity: 1;
}

.shot__label {
  display: inline-block;
  padding: var(--space-3xs) var(--space-xs);
  background: var(--gold);
  color: var(--ink);
  border: 2px solid var(--ink);
  font-family: var(--font-condensed);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transform: translateY(8px);
  transition: transform var(--dur) var(--ease-snap);
}

.shot:hover .shot__label,
.shot:focus-visible .shot__label {
  transform: translateY(0);
}

/* Collage placement — deliberately uneven spans and proportions. */
/* `.cell--lead` and `.cell--paint` are named rather than lettered: a–f are the
   original collage slots in visual order, so a letter landing out of sequence
   would read as a mistake — `.cell--g` sitting first, or sitting ahead of
   `.cell--f`, both do. 16/7 is within a hair of the lead photo's native
   1400×614, so it seats with effectively no crop.

   Every row sums to 12:
     lead(12) | a(6)+b(3)+c(3) | d(4)+e(4)+paint(4) | f(12).

   Three things about this row structure are load-bearing.

   1. `.cell--a` has NO aspect-ratio. A grid item with one is sized by that
      ratio and does not stretch, so when it was 16/9 beside a 3/4 portrait it
      came out 78px shorter than its own row and left a black hole in the
      collage — these tiles sit on `.gallery`, which is dark, so a short item
      reads as a void rather than as whitespace. With no ratio it has no
      intrinsic height, the row is sized by the two portraits beside it, and
      `align-items: normal` stretches it to fill. It is then exactly flush at
      every viewport width, with no magic number to re-tune when the wrap
      changes. The photo is 1.62:1 landing in roughly 1.54:1, so it loses ~5%
      off the sides — less than the ~9% the old 16/9 slot took off the top and
      bottom.

   2. Tiles sharing a row must share a ratio. Same row, same width, so any
      difference in ratio leaves one of them short and opens the same kind of
      hole. Hence b and c are both 3/4, and d, e and paint are all 4/5. Change
      one and you change its whole row.

   3. The split follows DOM order — there is no `order` property anywhere here,
      deliberately. Below 860px the collage drops to two columns and pairs up as
      lead | a | b+c | d+e | paint | f, every row full, purely because that is
      the source order. Reordering visually would desync the tab order from the
      reading order across eight focusable image buttons. */
.cell--lead { grid-column: span 12; aspect-ratio: 16 / 7; }
.cell--a { grid-column: span 6; }
.cell--b { grid-column: span 3; aspect-ratio: 3 / 4; }
.cell--c { grid-column: span 3; aspect-ratio: 3 / 4; }
.cell--d { grid-column: span 4; aspect-ratio: 4 / 5; }
.cell--e { grid-column: span 4; aspect-ratio: 4 / 5; }
.cell--paint { grid-column: span 4; aspect-ratio: 4 / 5; }
.cell--f { grid-column: span 12; aspect-ratio: 21 / 7; }

/* This band holds the hero photo, which is 1.65:1 going into a 3:1 slot — a
   centred crop would keep the sky and cut the taping knife off at the bottom.
   Anchoring to the bottom keeps the whole crew member, helmet to knife. */
.cell--f img {
  object-position: center bottom;
}

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

  /* `.cell--paint` joins the full-width band here rather than the 2-up group
     above: it is the fifth portrait tile, and five in a two-column grid strand
     the last one beside an empty cell. Its photo is a 3:4 that centre-crops to
     16:10 with the whole crew member, roller and pole still in frame, so the
     band costs it nothing and no object-position tuning is needed. */
  .cell--lead,
  .cell--a,
  .cell--f,
  .cell--paint {
    grid-column: span 2;
    aspect-ratio: 16 / 10;
  }

  .cell--b,
  .cell--c,
  .cell--d,
  .cell--e {
    grid-column: span 1;
    aspect-ratio: 4 / 5;
  }
}

/* Lightbox */
/* The `hidden` attribute (toggled in main.js) is what removes the lightbox
   from the page. Deliberately no `visibility` transition: a transitioned
   visibility flips at the midpoint, leaving the dialog unfocusable for half
   the animation, which breaks the opening focus move for keyboard users. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background: rgba(0, 0, 0, 0.94);
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

.lightbox[hidden] {
  display: none;
}

.lightbox.is-open {
  opacity: 1;
}

.lightbox__figure {
  position: relative;
  max-width: min(1100px, 100%);
  margin: 0;
}

.lightbox__img {
  width: 100%;
  max-height: 76vh;
  object-fit: contain;
  border: var(--border-w) solid var(--paper);
  background: var(--gray-900);
}

.lightbox__caption {
  margin-top: var(--space-s);
  font-family: var(--font-condensed);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
  text-align: center;
}

.lightbox__btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  background: var(--gold);
  color: var(--ink);
  border: var(--border-w) solid var(--ink);
  cursor: pointer;
  transition: transform var(--dur) var(--ease-snap);
}

.lightbox__btn:hover {
  transform: translateY(-50%) scale(1.08);
}

.lightbox__btn--prev { left: -26px; }
.lightbox__btn--next { right: -26px; }

.lightbox__close {
  position: absolute;
  top: -60px;
  right: 0;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  background: var(--paper);
  color: var(--ink);
  border: var(--border-w) solid var(--ink);
  cursor: pointer;
  transition: transform var(--dur) var(--ease-snap), background-color var(--dur) var(--ease-out);
}

.lightbox__close:hover {
  background: var(--gold);
  transform: rotate(90deg);
}

@media (max-width: 720px) {
  .lightbox__btn--prev { left: 0; }
  .lightbox__btn--next { right: 0; }
}

/* ==========================================================================
   14. WHY CHOOSE US
   ========================================================================== */

.why {
  position: relative;
  background: var(--paper);
}

.why__ghost {
  top: 1rem;
  left: -3rem;
}

.why__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: start;
}

.why__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-s);
}

.why-item {
  position: relative;
  padding: var(--space-m);
  background: var(--paper);
  border: var(--border-w) solid var(--ink);
  transition: transform var(--dur) var(--ease-snap), box-shadow var(--dur) var(--ease-out);
}

.why-item:nth-child(odd) {
  box-shadow: var(--shadow-hard-sm);
}

.why-item:nth-child(even) {
  box-shadow: 4px 4px 0 var(--gold);
}

.why-item:hover {
  transform: translate(-3px, -3px);
  box-shadow: 8px 8px 0 var(--gold);
}

.why-item:nth-child(even):hover {
  box-shadow: 8px 8px 0 var(--ink);
}

.why-item__icon {
  width: 42px;
  height: 42px;
  color: var(--ink);
  background: var(--gold);
  border: 2px solid var(--ink);
  padding: 6px;
}

.why-item__title {
  margin-top: var(--space-s);
  font-family: var(--font-condensed);
  font-size: 1.28rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.15;
}

.why-item__body {
  margin-top: var(--space-3xs);
  font-size: 0.94rem;
  line-height: 1.55;
  color: var(--gray-600);
}

.why__aside .badge-seal {
  margin-bottom: var(--space-m);
}

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

/* ==========================================================================
   15. PROCESS
   ========================================================================== */

.process {
  position: relative;
  background: var(--ink);
  color: var(--paper);
}

.process__head {
  position: relative;
  z-index: 2;
  margin-bottom: var(--space-2xl);
  max-width: min(100%, 820px);
}

.process__track {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-m);
}

/* Taped measurement path connecting the steps. */
.process__track::before {
  content: "";
  position: absolute;
  top: 34px;
  left: 6%;
  right: 6%;
  height: 4px;
  background-image: repeating-linear-gradient(90deg, var(--gold) 0 14px, transparent 14px 26px);
}

/* Top padding must clear the 68px number badge plus breathing room, or the
   badge lands on top of the title. */
.step {
  position: relative;
  padding-top: 92px;
}

.step__num {
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  background: var(--gold);
  color: var(--ink);
  border: var(--border-w) solid var(--ink);
  box-shadow: 0 0 0 4px var(--ink);
  font-family: var(--font-display);
  font-size: 1.6rem;
  transition: transform var(--dur) var(--ease-snap);
}

.step:hover .step__num {
  transform: rotate(-8deg) scale(1.06);
}

.step__title {
  font-family: var(--font-display);
  font-size: var(--step-1);
  text-transform: uppercase;
  line-height: 1.05;
}

.step__body {
  margin-top: var(--space-2xs);
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--gray-200);
}

@media (max-width: 900px) {
  .process__track {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }

  /* Path turns vertical on small screens. */
  .process__track::before {
    top: 0;
    bottom: 0;
    left: 33px;
    right: auto;
    width: 4px;
    height: auto;
    background-image: repeating-linear-gradient(180deg, var(--gold) 0 14px, transparent 14px 26px);
  }

  .step {
    padding-top: 0;
    padding-left: 96px;
    min-height: 68px;
  }
}

/* ==========================================================================
   16. SERVICE AREA
   ========================================================================== */

.area {
  position: relative;
  background: var(--gold);
  color: var(--ink);
  overflow: clip;
}

/* Three children — copy, map, state tiles — in source order copy → map → tiles,
   which is the order they stack in on mobile. Desktop rebuilds the two-column
   look by placing them explicitly: copy and tiles stack in column 1, the map
   spans both rows in column 2.

   Row gap is set separately from the column gutter. The column gutter wants to
   be generous; the vertical rhythm does not, and letting the 4rem gutter double
   as the row gap pushed the tiles too far off the copy above them. */
.area__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  column-gap: clamp(2rem, 1rem + 4vw, 4rem);
  row-gap: var(--space-l);
  align-items: center;
}

.area__copy {
  grid-column: 1;
  grid-row: 1;
}

.area__states {
  grid-column: 1;
  grid-row: 2;
}

.area__photo {
  grid-column: 2;
  grid-row: 1 / span 2;
}

/* Oversized state abbreviations. */
.area__states {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
}

.state {
  position: relative;
  display: grid;
  place-items: center;
  flex: 1 1 150px;
  aspect-ratio: 1;
  background: var(--ink);
  color: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  overflow: hidden;
  transition: transform var(--dur) var(--ease-snap), background-color var(--dur) var(--ease-out);
}

.state:hover {
  transform: translate(-4px, -4px) rotate(-1.5deg);
  background: var(--paper);
  color: var(--ink);
}

.state__abbr {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 1.6rem + 3.4vw, 4.4rem);
  line-height: 0.85;
  transition: color var(--dur) var(--ease-out);
}

.state:hover .state__abbr {
  color: var(--ink);
}

.state__name {
  margin-top: var(--space-3xs);
  font-family: var(--font-condensed);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

.state:hover .state__name {
  color: var(--gray-600);
}

/* 4:3 because this frame holds the New England service-area graphic, which is a
   native 4:3 with the map running nearly its full height. At the previous 16:9
   `object-fit: cover` took ~12% off the top and clipped northern Maine. */
.area__photo {
  position: relative;
  border: var(--border-w-thick) solid var(--ink);
  box-shadow: var(--shadow-hard);
  overflow: hidden;
  aspect-ratio: 4 / 3;
}

/* No grayscale/contrast filter here. It was tuned to settle a photograph into
   the gold section; on the brand graphic it mutes the gold map against its black
   field, which is the one thing the graphic is made of. Put it back if this
   frame ever returns to holding photography. */
.area__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.area__photo figcaption {
  position: absolute;
  left: 0;
  bottom: 0;
  padding: var(--space-2xs) var(--space-s);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-condensed);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Single column: drop the explicit placement so the three children fall back to
   source order — copy, then the map, then the state tiles. */
@media (max-width: 900px) {
  .area__inner {
    grid-template-columns: 1fr;
  }

  .area__copy,
  .area__states,
  .area__photo {
    grid-column: auto;
    grid-row: auto;
  }
}

/* ==========================================================================
   17. BEFORE & AFTER
   ========================================================================== */

.ba {
  position: relative;
  background: var(--paper);
}

.ba__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: clamp(2rem, 1rem + 4vw, 3.5rem);
  align-items: center;
}

.ba__frame {
  position: relative;
  aspect-ratio: 16 / 10;
  border: var(--border-w-thick) solid var(--ink);
  box-shadow: var(--shadow-hard-gold);
  overflow: hidden;
  user-select: none;
  touch-action: pan-y;
}

.ba__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The "after" image is revealed to the right of the handle. */
.ba__after {
  clip-path: inset(0 0 0 var(--ba-pos, 50%));
}

.ba__tag {
  position: absolute;
  top: var(--space-s);
  z-index: 4;
  padding: var(--space-3xs) var(--space-xs);
  border: 2px solid var(--ink);
  font-family: var(--font-condensed);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  pointer-events: none;
}

.ba__tag--before {
  left: var(--space-s);
  background: var(--paper);
  color: var(--ink);
}

.ba__tag--after {
  right: var(--space-s);
  background: var(--gold);
  color: var(--ink);
}

/* Divider line + grab handle. */
.ba__divider {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--ba-pos, 50%);
  z-index: 5;
  width: 4px;
  margin-left: -2px;
  background: var(--gold);
  box-shadow: 0 0 0 2px var(--ink);
  pointer-events: none;
}

.ba__handle {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  transform: translate(-50%, -50%);
  background: var(--gold);
  color: var(--ink);
  border: var(--border-w) solid var(--ink);
  border-radius: 50%;
  transition: transform var(--dur) var(--ease-snap);
}

.ba__frame:hover .ba__handle {
  transform: translate(-50%, -50%) scale(1.1);
}

.ba__handle svg {
  width: 24px;
  height: 24px;
}

/* The real control — a native range input laid over the frame.
   Kept transparent but fully focusable and keyboard-operable. */
.ba__range {
  position: absolute;
  inset: 0;
  z-index: 6;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  appearance: none;
  -webkit-appearance: none;
  cursor: ew-resize;
}

.ba__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: transparent;
  cursor: ew-resize;
}

.ba__range::-moz-range-thumb {
  width: 54px;
  height: 54px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: ew-resize;
}

.ba__range::-moz-range-track {
  background: transparent;
}

.ba__range:focus-visible {
  outline: 4px solid var(--gold);
  outline-offset: 4px;
}

.ba__note {
  margin-top: var(--space-s);
  font-size: 0.85rem;
  color: var(--gray-600);
}

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

/* ==========================================================================
   18. TESTIMONIALS
   ========================================================================== */

.quotes {
  position: relative;
  background: var(--gray-050);
  background-image:
    linear-gradient(90deg, var(--gray-200) 1px, transparent 1px),
    linear-gradient(var(--gray-200) 1px, transparent 1px);
  background-size: 96px 96px;
}

.quotes__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr));
  gap: var(--space-m);
  margin-top: var(--space-xl);
}

.quote {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--space-l);
  background: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  transition: transform var(--dur) var(--ease-snap), box-shadow var(--dur) var(--ease-out);
}

.quote:nth-child(2) {
  transform: rotate(-1deg);
}

.quote:nth-child(3) {
  transform: rotate(0.8deg);
}

.quote:hover {
  transform: translate(-3px, -4px) rotate(0deg);
  box-shadow: 9px 10px 0 var(--gold);
}

.quote__mark {
  font-family: var(--font-display);
  font-size: 3.6rem;
  line-height: 0.6;
  color: var(--gold);
  -webkit-text-stroke: 2px var(--ink);
}

.quote__body {
  margin-top: var(--space-s);
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--gray-600);
  font-style: italic;
}

.quote__meta {
  margin-top: auto;
  padding-top: var(--space-m);
  border-top: 2px dashed var(--gray-200);
}

.quote__label {
  font-family: var(--font-condensed);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-400);
}

/* ==========================================================================
   19. MAIN CTA
   ========================================================================== */

.cta {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  overflow: clip;
}

/* Rotated gold slab layered behind the CTA content. */
.cta__slab {
  position: absolute;
  inset: 12% -10% 12% 42%;
  background: var(--gold);
  transform: rotate(-4deg);
  z-index: 1;
  opacity: 0.95;
}

.cta__slab::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.22) 0 3px, transparent 3px 9px);
  mix-blend-mode: soft-light;
}

.cta__inner {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: center;
}

.cta__title {
  font-size: var(--step-4);
}

.cta__copy {
  margin-top: var(--space-m);
  max-width: 46ch;
  color: var(--gray-200);
}

.cta__actions {
  margin-top: var(--space-l);
}

/* Paint bucket panel. */
.cta__panel {
  position: relative;
  padding: var(--space-l);
  background: var(--paper);
  color: var(--ink);
  border: var(--border-w-thick) solid var(--ink);
  box-shadow: var(--shadow-hard);
  transform: rotate(1.5deg);
}

.cta__panel-icon {
  width: 64px;
  height: 64px;
  color: var(--ink);
}

.cta__panel-title {
  margin-top: var(--space-s);
  font-family: var(--font-display);
  font-size: var(--step-2);
  text-transform: uppercase;
  line-height: 1;
}

.cta__panel-phone {
  display: inline-block;
  margin-top: var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--ink);
  text-decoration: none;
  border-bottom: 4px solid var(--gold);
  transition: border-color var(--dur) var(--ease-out);
}

.cta__panel-phone:hover {
  border-bottom-color: var(--ink);
}

.cta__panel-note {
  margin-top: var(--space-2xs);
  font-size: 0.88rem;
  color: var(--gray-600);
}

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

  .cta__slab {
    inset: 0;
    opacity: 0.14;
  }
}

/* ==========================================================================
   20. FOOTER
   ========================================================================== */

.site-footer {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  padding-top: var(--space-2xl);
  overflow: clip;
}

.footer__ghost {
  bottom: -1.5rem;
  left: 50%;
  transform: translateX(-50%);
}

.footer__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  gap: var(--space-l);
  padding-bottom: var(--space-2xl);
}

.footer__brand-plate {
  display: inline-block;
  padding: var(--space-2xs) var(--space-s);
  background: var(--paper);
  border: var(--border-w) solid var(--paper);
  box-shadow: 5px 5px 0 var(--gold);
}

/* Larger than the header lockup on purpose: the footer plate has a whole grid
   column to sit in, with no nav competing for the width. */
.footer__brand-plate img {
  width: auto;
  height: 64px;
}

.footer__statement {
  margin-top: var(--space-m);
  max-width: 40ch;
  font-size: 0.96rem;
  color: var(--gray-200);
}

.footer__badges {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  margin-top: var(--space-m);
}

.footer__union {
  width: 62px;
  height: 62px;
  border: 2px solid var(--gold);
  border-radius: 50%;
  background: var(--paper);
}

.footer__union-text {
  font-family: var(--font-condensed);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold);
  line-height: 1.3;
}

.footer__heading {
  font-family: var(--font-condensed);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  padding-bottom: var(--space-2xs);
  border-bottom: 2px solid rgba(255, 255, 255, 0.16);
  margin-bottom: var(--space-s);
}

.footer__list > li + li {
  margin-top: var(--space-2xs);
}

.footer__link {
  display: inline-block;
  font-size: 0.95rem;
  color: var(--gray-200);
  text-decoration: none;
  transition: color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}

.footer__link:hover,
.footer__link:focus-visible {
  color: var(--gold);
  transform: translateX(4px);
}

.footer__contact-item {
  display: block;
  font-size: 0.95rem;
  color: var(--gray-200);
  text-decoration: none;
}

.footer__phone {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--paper);
  text-decoration: none;
  line-height: 1;
  transition: color var(--dur) var(--ease-out);
}

.footer__phone:hover {
  color: var(--gold);
}

.footer__cta {
  margin-top: var(--space-m);
}

.footer__social {
  display: flex;
  gap: var(--space-2xs);
  margin-top: var(--space-m);
}

.social-btn {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  background: transparent;
  color: var(--paper);
  border: 2px solid var(--gray-600);
  transition: background-color var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-snap);
}

.social-btn svg {
  width: 22px;
  height: 22px;
}

.social-btn:hover,
.social-btn:focus-visible {
  background: var(--gold);
  color: var(--ink);
  border-color: var(--gold);
  transform: translateY(-4px) rotate(-4deg);
}

.footer__bar {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding-block: var(--space-m);
  border-top: 2px solid rgba(255, 255, 255, 0.16);
  font-size: 0.85rem;
  color: var(--gray-400);
}

.footer__bar-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
}

.footer__bar a {
  color: var(--gray-400);
  text-decoration: none;
  transition: color var(--dur) var(--ease-out);
}

.footer__bar a:hover {
  color: var(--gold);
}

/* Business hours component — hidden until real hours are configured in main.js. */
.hours[hidden] {
  display: none;
}

.hours__status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-condensed);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.hours__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gray-400);
  flex: none;
}

/* Status is never carried by colour alone — the text label states it too. */
.hours__status[data-state="open"] .hours__dot { background: var(--gold); }
.hours__status[data-state="closed"] .hours__dot { background: var(--gray-600); }

.hours__list {
  margin-top: var(--space-2xs);
  font-size: 0.88rem;
  color: var(--gray-200);
}

.hours__row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-s);
  padding: 2px 0;
}

.hours__row[data-today="true"] {
  color: var(--gold);
  font-weight: 700;
}

.hours__fallback {
  font-size: 0.95rem;
  color: var(--gray-200);
}

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

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

/* ==========================================================================
   20b. SERVICE TRACKS (services page)
   --------------------------------------------------------------------------
   The two ways the business is hired: hourly repair work and contract work.
   Presented as two opposing slabs — light vs dark — rather than a flat grid.
   ========================================================================== */

.tracks {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-l);
}

.track {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: clamp(1.25rem, 0.7rem + 2vw, 2.25rem);
  border: var(--border-w-thick) solid var(--ink);
  overflow: hidden;
  isolation: isolate;
}

.track--hourly {
  background: var(--paper);
  color: var(--ink);
  box-shadow: var(--shadow-hard);
}

.track--contract {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
  box-shadow: 12px 12px 0 var(--gold);
  --outline-c: var(--paper);
}

.track--contract .track__body {
  color: var(--gray-200);
}

/* Oversized outlined track number, bled off the top-right corner. */
.track__num {
  position: absolute;
  top: -0.18em;
  right: 0.06em;
  z-index: -1;
  font-family: var(--font-display);
  font-size: clamp(6rem, 3rem + 9vw, 11rem);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 2px var(--outline-c);
  opacity: 0.16;
  pointer-events: none;
  user-select: none;
}

.track__tag {
  align-self: flex-start;
  margin-bottom: var(--space-s);
}

.track__title {
  font-size: var(--step-3);
  line-height: 0.95;
}

.track__body {
  margin-top: var(--space-s);
  color: var(--gray-600);
  font-size: 0.98rem;
  line-height: 1.6;
}

.track__photo {
  position: relative;
  margin: var(--space-m) 0;
  border: var(--border-w) solid currentColor;
  aspect-ratio: 16 / 8;
  overflow: hidden;
}

.track__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.track__label {
  font-family: var(--font-condensed);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gray-400);
  margin-bottom: var(--space-2xs);
}

.track--contract .track__label {
  color: var(--gold);
}

/* Checklist of what each track covers. */
.track__list {
  display: grid;
  gap: 2px;
}

.track__list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2xs);
  padding: var(--space-2xs) 0;
  border-bottom: 2px dashed var(--gray-200);
  font-family: var(--font-condensed);
  font-size: 1.08rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  line-height: 1.25;
}

.track--contract .track__list li {
  border-bottom-color: rgba(255, 255, 255, 0.16);
}

.track__check {
  width: 20px;
  height: 20px;
  flex: none;
  margin-top: 0.15em;
  padding: 2px;
  background: var(--gold);
  color: var(--ink);
  border: 2px solid var(--ink);
}

.track--contract .track__check {
  border-color: var(--gold);
}

.track__foot {
  margin-top: auto;
  padding-top: var(--space-m);
}

.track__note {
  margin-bottom: var(--space-s);
  font-size: 0.92rem;
  font-style: italic;
  color: var(--gray-600);
}

.track--contract .track__note {
  color: var(--gray-200);
}

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

  .track--contract {
    box-shadow: 8px 8px 0 var(--gold);
  }
}

/* ==========================================================================
   20c. CREDENTIALS LIST (about page)
   --------------------------------------------------------------------------
   The "why choose us" reasons as numbered editorial rows separated by
   measurement rules — a deliberately different treatment from the card grids
   used on the homepage and services page.
   ========================================================================== */

.creds {
  position: relative;
  z-index: 2;
  display: grid;
}

.cred {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1rem, 0.5rem + 2vw, 2.5rem);
  align-items: start;
  padding-block: var(--space-l);
  border-top: 2px dashed var(--gray-200);
  transition: background-color var(--dur) var(--ease-out);
}

.cred:last-child {
  border-bottom: 2px dashed var(--gray-200);
}

.cred:hover {
  background: var(--gold-soft);
}

.cred__num {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 1.6rem + 3vw, 4.5rem);
  line-height: 0.8;
  color: transparent;
  -webkit-text-stroke: 2px var(--ink);
  transition: color var(--dur) var(--ease-out);
}

.cred:hover .cred__num {
  color: var(--gold);
}

.cred__title {
  font-size: var(--step-2);
  line-height: 1;
}

.cred__body {
  margin-top: var(--space-2xs);
  max-width: 60ch;
  color: var(--gray-600);
  font-size: 0.98rem;
  line-height: 1.6;
}

@media (max-width: 620px) {
  .cred {
    grid-template-columns: 1fr;
    gap: var(--space-2xs);
  }
}

/* ==========================================================================
   20d. PULL QUOTE
   ========================================================================== */

/* Condensed rather than the display face, and sentence case: this quote is a
   full sentence, and in oversized uppercase Anton it runs many lines and
   out-shouts the heading it is meant to support. */
.pull {
  position: relative;
  z-index: 2;
  margin: 0;
  padding: var(--space-s) 0 var(--space-s) clamp(1rem, 0.5rem + 2vw, 1.75rem);
  border-left: 8px solid var(--gold);
  font-family: var(--font-condensed);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.28;
  letter-spacing: 0.01em;
  text-wrap: pretty;
}

.pull__cite {
  display: block;
  margin-top: var(--space-s);
  font-family: var(--font-condensed);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-style: normal;
  color: var(--gray-400);
}

.on-dark .pull__cite {
  color: var(--gold);
}

/* ==========================================================================
   20e. MISSION PANEL (about page)
   ========================================================================== */

.mission {
  position: relative;
  background: var(--gold);
  color: var(--ink);
  overflow: clip;
}

.mission__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: center;
}

/* Oversized knife silhouette bleeding off the edge. */
.mission__knife {
  position: absolute;
  right: -60px;
  bottom: -70px;
  width: clamp(220px, 30vw, 420px);
  color: var(--ink);
  opacity: 0.08;
  transform: rotate(-12deg);
  pointer-events: none;
  z-index: 1;
}

.mission__card {
  padding: var(--space-l);
  background: var(--paper);
  border: var(--border-w-thick) solid var(--ink);
  box-shadow: var(--shadow-hard);
  transform: rotate(-1deg);
}

.mission__card p + p {
  margin-top: var(--space-s);
}

/* The four confirmed service lines, linked through to the services page. */
.svc-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin-top: var(--space-m);
}

.svc-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: var(--space-2xs) var(--space-m);
  background: var(--ink);
  color: var(--paper);
  border: 2px solid var(--ink);
  font-family: var(--font-condensed);
  font-size: 0.98rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  transition: transform var(--dur) var(--ease-snap),
    background-color var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

.svc-chip:hover,
.svc-chip:focus-visible {
  background: var(--paper);
  color: var(--ink);
  transform: translate(-3px, -3px);
  box-shadow: 5px 5px 0 var(--ink);
}

.svc-chip .spark {
  width: 0.7em;
  height: 0.7em;
  flex: none;
  color: var(--gold);
}

.svc-chip:hover .spark {
  color: var(--gold-deep);
}

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

/* ==========================================================================
   20f. FAQ (services page)
   --------------------------------------------------------------------------
   Native <details>/<summary>, not a JS accordion: it opens by keyboard for
   free, it prints and it degrades with scripting off, and — the reason it
   matters here — the answer text is in the DOM whether or not the panel is
   open, which is what the FAQPage structured data on this page claims and
   what a crawler or an AI assistant actually reads.
   ========================================================================== */

.faq {
  background: var(--gray-050);
}

.faq__list {
  position: relative;
  z-index: 2;
  margin-top: var(--space-xl);
  display: grid;
  gap: var(--space-s);
}

.faq__item {
  background: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  transition: box-shadow var(--dur) var(--ease-out);
}

.faq__item[open] {
  box-shadow: 8px 8px 0 var(--gold);
}

/* `list-item` is the default display for summary and paints a disclosure
   triangle next to the custom marker; both prefixes are needed for Safari. */
.faq__q {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-m);
  font-family: var(--font-condensed);
  font-size: var(--step-1);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: 0.01em;
  /* Sentence case, unlike the other condensed headings on the site. Those are
     short labels — "Superior Workmanship" — where uppercase reads as a label.
     These are full questions of sixty-odd characters, and setting a sentence
     that long in uppercase condensed costs real legibility. */
  cursor: pointer;
  list-style: none;
}

.faq__q::-webkit-details-marker {
  display: none;
}

/* Gold plus/minus plate. The bars are background gradients on the plate itself
   rather than markup, so the glyph never lands in the accessible name of the
   question — a screen reader announces the question and the open/closed state,
   not "plus". One pseudo-element, laid out by the flex row: no absolute
   positioning, which would escape to the nearest positioned ancestor (`.section`)
   and strand the plate in the section corner. */
.faq__q::before {
  content: "";
  flex: none;
  width: 34px;
  height: 34px;
  background:
    linear-gradient(var(--ink) 0 0) center / 16px 3px no-repeat,
    linear-gradient(var(--ink) 0 0) center / 3px 16px no-repeat,
    var(--gold);
  border: 2px solid var(--ink);
  transition: transform var(--dur) var(--ease-snap);
}

/* Drop the vertical bar to leave a minus, and spin as it goes. */
.faq__item[open] .faq__q::before {
  background:
    linear-gradient(var(--ink) 0 0) center / 16px 3px no-repeat,
    var(--gold);
  transform: rotate(180deg);
}

.faq__q:hover {
  background: var(--gold-soft);
}

.faq__a {
  padding: 0 var(--space-m) var(--space-m);
  /* Clears the gold plate so the answer aligns with the question text. */
  padding-left: calc(var(--space-m) + 34px + var(--space-s));
  max-width: 70ch;
  color: var(--gray-600);
}

@media (max-width: 640px) {
  .faq__q {
    font-size: var(--step-0);
  }

  .faq__a {
    padding-left: var(--space-m);
  }
}

/* ==========================================================================
   21. CONTACT PAGE
   ========================================================================== */

.page-hero {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  padding-block: clamp(3rem, 2rem + 4vw, 5rem);
  overflow: clip;
}

.page-hero__grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: center;
}

@media (max-width: 900px) {
  .page-hero__grid {
    grid-template-columns: 1fr;
  }
}

/* Same reasoning as .hero__title — --step-5 is too large for a headline of
   this length and pushes the supporting copy below the fold. */
.page-hero__title {
  margin-top: var(--space-m);
  font-size: clamp(2.3rem, 1.3rem + 3.2vw, 4.4rem);
}

.page-hero__copy {
  margin-top: var(--space-m);
  max-width: 52ch;
  color: var(--gray-200);
}

.page-hero__aside {
  position: relative;
}

/* Stacked contact quick-facts. */
.quick-card {
  padding: var(--space-m);
  background: var(--gold);
  color: var(--ink);
  border: var(--border-w) solid var(--paper);
  box-shadow: var(--shadow-hard-sm);
  transform: rotate(-1.5deg);
}

.quick-card + .quick-card {
  margin-top: var(--space-s);
  background: var(--paper);
  transform: rotate(1deg);
}

.quick-card__label {
  font-family: var(--font-condensed);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.quick-card__value {
  display: block;
  margin-top: var(--space-3xs);
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
}

a.quick-card__value:hover {
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 4px;
}

.breadcrumb {
  position: relative;
  z-index: 2;
  padding-bottom: var(--space-s);
  font-family: var(--font-condensed);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-400);
}

.breadcrumb a {
  color: var(--gray-200);
  text-decoration: none;
}

.breadcrumb a:hover {
  color: var(--gold);
}

.breadcrumb li {
  display: inline;
}

.breadcrumb li + li::before {
  content: "/";
  margin: 0 0.5rem;
  color: var(--gold);
}

/* Contact info cards.
   Currently unused: the "Reach Us Directly" section that held them was removed
   from contact.html, and nothing else uses these classes. Kept so the section
   can be pasted back as-is — delete this block if it is gone for good. */
.contact-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-m);
}

.contact-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--space-l);
  background: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-sm);
  transition: transform var(--dur) var(--ease-snap), box-shadow var(--dur) var(--ease-out);
}

.contact-card:hover {
  transform: translate(-4px, -5px);
  box-shadow: 9px 10px 0 var(--gold);
}

.contact-card__icon {
  width: 46px;
  height: 46px;
  padding: 8px;
  background: var(--ink);
  color: var(--gold);
}

.contact-card__title {
  margin-top: var(--space-s);
  font-family: var(--font-condensed);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gray-400);
}

.contact-card__value {
  margin-top: var(--space-3xs);
  font-family: var(--font-display);
  font-size: var(--step-1);
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: anywhere;
}

a.contact-card__value:hover {
  color: var(--gold-deep);
}

.contact-card__note {
  margin-top: var(--space-2xs);
  font-size: 0.9rem;
  color: var(--gray-600);
}

.contact-card__social {
  display: flex;
  gap: var(--space-2xs);
  margin-top: var(--space-s);
}

.contact-card .social-btn {
  border-color: var(--ink);
  color: var(--ink);
}

/* ==========================================================================
   22. FORMS
   ========================================================================== */

.form-section {
  position: relative;
  background: var(--gray-050);
  background-image:
    linear-gradient(90deg, var(--gray-200) 1px, transparent 1px),
    linear-gradient(var(--gray-200) 1px, transparent 1px);
  background-size: 96px 96px;
}

.form-shell {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
  gap: clamp(2rem, 1rem + 4vw, 3.5rem);
  align-items: start;
}

.form-aside {
  position: sticky;
  top: calc(var(--header-h) + var(--space-m));
  padding: var(--space-l);
  background: var(--ink);
  color: var(--paper);
  border: var(--border-w) solid var(--ink);
  box-shadow: var(--shadow-hard-gold);
}

.form-aside p {
  color: var(--gray-200);
  font-size: 0.95rem;
}

.form-aside__list {
  margin-top: var(--space-m);
}

.form-aside__list li {
  display: flex;
  gap: var(--space-2xs);
  padding: var(--space-2xs) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
  font-family: var(--font-condensed);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.form-aside__list .spark {
  color: var(--gold);
  width: 0.7em;
  height: 0.7em;
  margin-top: 0.42em;
  flex: none;
}

.estimate-form {
  padding: clamp(1.25rem, 0.6rem + 2.4vw, 2.5rem);
  background: var(--paper);
  border: var(--border-w-thick) solid var(--ink);
  box-shadow: var(--shadow-hard);
}

.fieldset {
  border: 0;
  padding: 0;
  margin: 0;
}

.fieldset + .fieldset {
  margin-top: var(--space-xl);
}

.fieldset__legend {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  width: 100%;
  padding: 0 0 var(--space-s);
  margin-bottom: var(--space-m);
  border-bottom: var(--border-w) solid var(--ink);
  font-family: var(--font-display);
  font-size: var(--step-1);
  text-transform: uppercase;
}

.fieldset__step {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  background: var(--gold);
  border: 2px solid var(--ink);
  font-size: 0.95rem;
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-m);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.field--full {
  grid-column: 1 / -1;
}

.field__label {
  font-family: var(--font-condensed);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.field__req {
  color: var(--gold-deep);
  margin-left: 2px;
}

.field__hint {
  font-size: 0.82rem;
  color: var(--gray-600);
}

.input,
.select,
.textarea {
  width: 100%;
  min-height: 52px;
  padding: var(--space-2xs) var(--space-s);
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  font-size: 1rem;
  transition: box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}

.textarea {
  min-height: 150px;
  padding-top: var(--space-xs);
  resize: vertical;
  font-family: inherit;
}

.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23000' stroke-width='2' fill='none' stroke-linecap='square'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-s) center;
  background-size: 12px;
  padding-right: var(--space-xl);
  cursor: pointer;
}

.input:focus,
.select:focus,
.textarea:focus {
  outline: 0;
  border-color: var(--ink);
  box-shadow: var(--shadow-hard-sm);
}

.input:focus-visible,
.select:focus-visible,
.textarea:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

/* Invalid state — border + icon + message, never colour alone. */
.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"] {
  border-color: var(--ink);
  border-width: 3px;
  background-color: var(--gold-soft);
}

.field__error {
  display: none;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-condensed);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}

.field__error::before {
  content: "!";
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  flex: none;
  background: var(--ink);
  color: var(--gold);
  border-radius: 50%;
  font-size: 0.72rem;
}

.field__error.is-shown {
  display: flex;
}

/* Radio / checkbox groups styled as paint-swatch chips. */
.choice-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.choice {
  position: relative;
}

.choice input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.choice__face {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 48px;
  padding: var(--space-2xs) var(--space-m);
  background: var(--paper);
  border: 2px solid var(--ink);
  font-family: var(--font-condensed);
  font-size: 0.98rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-snap),
    box-shadow var(--dur) var(--ease-out);
}

.choice__face::before {
  content: "";
  width: 14px;
  height: 14px;
  flex: none;
  border: 2px solid var(--ink);
  background: var(--paper);
  transition: background-color var(--dur) var(--ease-out);
}

.choice input[type="radio"] + .choice__face::before {
  border-radius: 50%;
}

.choice:hover .choice__face {
  transform: translate(-2px, -2px);
  box-shadow: 3px 3px 0 var(--ink);
}

.choice input:checked + .choice__face {
  background: var(--gold);
  box-shadow: 3px 3px 0 var(--ink);
}

.choice input:checked + .choice__face::before {
  background: var(--ink);
}

.choice input:focus-visible + .choice__face {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
}

/* Consent checkbox row. */
.consent {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2xs);
  padding: var(--space-m);
  background: var(--gray-050);
  border: 2px dashed var(--ink);
}

.consent input {
  width: 24px;
  height: 24px;
  margin: 2px 0 0;
  flex: none;
  accent-color: var(--ink);
  cursor: pointer;
}

.consent label {
  font-size: 0.94rem;
  line-height: 1.5;
  cursor: pointer;
}

/* File upload — styled drop plate. */
.upload {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-l);
  background: var(--gray-050);
  border: 3px dashed var(--ink);
  text-align: center;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease-out);
}

.upload:hover,
.upload.is-hover {
  background: var(--gold-soft);
}

.upload input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.upload__icon {
  width: 40px;
  height: 40px;
  color: var(--ink);
}

.upload__title {
  font-family: var(--font-condensed);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.upload__hint {
  font-size: 0.84rem;
  color: var(--gray-600);
}

.upload__files {
  margin-top: var(--space-2xs);
  font-size: 0.86rem;
  font-weight: 600;
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-m);
  margin-top: var(--space-xl);
  padding-top: var(--space-l);
  border-top: var(--border-w) solid var(--ink);
}

.form-actions__note {
  font-size: 0.85rem;
  color: var(--gray-600);
  max-width: 34ch;
}

/* Form-level status region (aria-live). */
.form-status {
  margin-bottom: var(--space-m);
  padding: var(--space-m);
  border: var(--border-w) solid var(--ink);
  background: var(--gold);
}

.form-status[hidden] {
  display: none;
}

.form-status__title {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--step-1);
  text-transform: uppercase;
}

.form-status__body {
  margin-top: var(--space-2xs);
  font-size: 0.94rem;
}

.form-status--error {
  background: var(--paper);
}

/* Success confirmation panel. */
.form-success {
  padding: var(--space-xl) var(--space-l);
  text-align: center;
  background: var(--paper);
  border: var(--border-w-thick) solid var(--ink);
  box-shadow: var(--shadow-hard);
}

.form-success[hidden] {
  display: none;
}

.form-success__seal {
  margin: 0 auto var(--space-m);
}

.form-success__title {
  font-size: var(--step-3);
}

.form-success__body {
  margin: var(--space-s) auto 0;
  max-width: 52ch;
  color: var(--gray-600);
}

.form-success__dev {
  margin: var(--space-m) auto 0;
  max-width: 60ch;
  padding: var(--space-s);
  background: var(--gray-050);
  border: 2px dashed var(--ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem;
  line-height: 1.55;
  text-align: left;
  color: var(--gray-600);
}

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

  .form-aside {
    position: static;
  }
}

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

/* ==========================================================================
   23. MOTION & REVEAL
   ========================================================================== */

/* Scroll-reveal base state, applied by JS only (so no-JS content stays visible). */
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* The roller stroke is deliberately NOT animated in.
   `.hl-block` sets black text that relies on the gold stroke behind it for
   contrast, so sweeping the stroke in would leave the word black-on-black on
   the dark hero sections for the length of the animation. The heading still
   arrives with the section's reveal; the stroke is simply already painted. */

/* ==========================================================================
   24. REDUCED MOTION & PRINT
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  /* Marquee stops entirely rather than snapping. */
  .marquee__track {
    animation: none;
    transform: none;
  }

  .marquee {
    overflow-x: auto;
  }

  .js .reveal {
    opacity: 1;
    transform: none;
  }

  .announce__dot::after {
    animation: none;
  }
}

@media print {
  .site-header,
  .announce,
  .marquee,
  .nav-drawer,
  .nav-scrim,
  .lightbox,
  .cta,
  .ba__range {
    display: none !important;
  }

  body {
    color: #000;
    background: #fff;
  }

  .on-dark,
  .gallery,
  .process,
  .site-footer {
    background: #fff !important;
    color: #000 !important;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
  }
}
