/* ==========================================================================
   AAA — homepage stylesheet.

   Every value here comes from one of the four skills, not from eye:
     colour     .claude/skills/palette-expansion  (Navy & Red, --classic)
     type       .claude/skills/typography-pairing (Space Grotesk / Public Sans / Aleo)
     structure  .claude/skills/layout-system      (containers, spacing, radius)
     pointer    .claude/skills/hover-effects      (durations, lifts, shadows)
   plus design-reference/output-calibration.md, which is the house standard:
   soft corners, things that arrive and answer, round social nodes.

   Two contrast failures the expansion reported are fixed BY PLACEMENT here —
   where a colour is allowed to go — and not by changing a value (brief 3):

     1. --c-caption (#778AA1) is 3.5:1 on white. That clears 3:1 for large text
        and fails 4.5:1 for small. So it is never used below 24px: all small
        print takes --c-muted (6.2:1). It survives on the big numerals only.
     2. --c-border (#E0E0E0) is 1.3:1 on white — decorative, and nowhere near
        the 3:1 a control's edge needs. So a form field's edge takes
        --c-field-edge, which is the mid-dark: exactly the swap
        Archive/prospects/design-questionnaire-web-v2/lib/placement.js makes. No colour
        was altered to achieve either.
   ========================================================================== */

@import url("assets/fonts/fonts.css");

:root {
  /* ---- colour: palette-expansion, Navy & Red, classic ------------------- */
  --c-primary: #23538E;
  --c-dark: #0C1D32;          /* the primary, 65% to black */
  --c-mid: #17365C;           /* the primary, 35% to black */
  --c-accent: #D9253E;
  --c-accent-hover: #B81F42;  /* the accent, 15% darker, 5 degrees cooler */
  --c-highlight: #C6D4E6;
  --c-bg: #FFFFFF;            /* classic: the ground stays neutral */
  --c-alt: #F5F5F5;
  --c-alt-2: #FBFBFB;
  --c-card: #FFFFFF;
  --c-border: #E0E0E0;        /* DECORATIVE ONLY — 1.3:1, never a control's edge */
  --c-field-edge: #17365C;    /* the placement fix: a field edge you can see */
  --c-ink: #0C1016;
  --c-muted: #4A6382;         /* 6.2:1 — every piece of small print */
  --c-caption: #778AA1;       /* 3.5:1 — 24px and up only */
  --c-on-accent: #FFFFFF;     /* 4.9:1 */
  /* the white-on-dark ladder — these exact steps, no others */
  --w-90: rgba(255,255,255,.90);
  --w-60: rgba(255,255,255,.60);
  --w-42: rgba(255,255,255,.42);
  --w-12: rgba(255,255,255,.12);
  --w-07: rgba(255,255,255,.07);

  /* ---- type: typography-pairing ----------------------------------------- */
  --f-display: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
  --f-body: 'Public Sans', 'Segoe UI', system-ui, sans-serif;
  --f-voice: 'Aleo', Georgia, serif;   /* italic only, and never a headline */

  /* ---- structure: layout-system ----------------------------------------- */
  --content-max: 1280px;
  --content-max-text: 768px;
  --pad-x: 24px;
  --sec-y: 96px;
  --space-4: 4px;   --space-8: 8px;    --space-12: 12px;  --space-16: 16px;
  --space-24: 24px; --space-32: 32px;  --space-48: 48px;  --space-64: 64px;
  --space-96: 96px; --space-112: 112px; --space-144: 144px;
  --r-xs: 4px; --r-sm: 8px; --r-md: 12px; --r-lg: 20px; --r-pill: 999px;
  --grid-gap: 24px;

  /* ---- pointer: hover-effects ------------------------------------------- */
  --hover-fast: 200ms;
  --hover-move: 300ms;
  --hover-slow: 500ms;
  --hover-ease: ease-out;
  --c-primary-rgb: 35, 83, 142;
  --shadow-subtle: 0 4px 16px rgba(var(--c-primary-rgb), 0.10);
  --shadow-standard: 0 12px 32px rgba(var(--c-primary-rgb), 0.14);
  --shadow-emphatic: 0 20px 48px rgba(var(--c-primary-rgb), 0.18);
  --shadow-deep: 0 32px 64px rgba(var(--c-primary-rgb), 0.22);
  --focus-ring: 0 0 0 3px rgba(var(--c-primary-rgb), 0.15);

  /* ---- motion: patterns/motion-kit.md ----------------------------------- */
  --m-in: 500ms;
  --m-unmask: 900ms;
  --m-step: 60ms;
  --m-ease: cubic-bezier(.22, .61, .36, 1);
}

@media (min-width: 720px)  { :root { --pad-x: 32px; --sec-y: 112px; } }
@media (min-width: 1080px) { :root { --pad-x: 56px; --sec-y: 144px; } }

/* ==========================================================================
   1. Base
   ========================================================================== */

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

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

body {
  margin: 0;
  background-color: var(--c-bg);
  color: var(--c-ink);
  font: 400 16px/1.8 var(--f-body);
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--c-primary); }

:focus-visible {
  outline: 3px solid var(--c-accent);
  outline-offset: 2px;
}

.skip {
  position: absolute; left: var(--space-8); top: -64px; z-index: 60;
  padding: var(--space-12) var(--space-16);
  background-color: var(--c-dark); color: var(--w-90);
  border-radius: var(--r-sm); text-decoration: none;
  transition: top var(--hover-fast) var(--hover-ease);
}
.skip:focus { top: var(--space-8); }

.wrap {
  max-width: var(--content-max);
  margin: 0 auto;
  padding-inline: var(--pad-x);
}
.wrap--text { max-width: var(--content-max-text); }

/* the header is sticky, so an anchor jump has to clear it or it lands with the
   heading already under the bar */
.band, .bleed, .hero { scroll-margin-top: 76px; }

.band { padding-block: var(--sec-y); }
.band--alt { background-color: var(--c-alt); }
.band--alt2 { background-color: var(--c-alt-2); }
.band--dark { background-color: var(--c-dark); color: var(--w-90); }

/* ---- type roles. Zero ALL-CAPS roles on this page: the audit's ceiling is
   10% of text elements, and the two builds that passed it shipped at 0%. ---- */

.h1, .h2, .h3, .h4 { font-family: var(--f-display); margin: 0; }
.h1 { font-weight: 700; font-size: clamp(36px, 5.2vw, 64px); line-height: 1.04; letter-spacing: -0.03em; }
.h2 { font-weight: 700; font-size: clamp(32px, 3.4vw, 52px); line-height: 1.12; letter-spacing: -0.02em; }
.h3 { font-weight: 500; font-size: 20px; line-height: 1.25; letter-spacing: -0.01em; }
.h4 { font-weight: 500; font-size: 16px; line-height: 1.3; letter-spacing: -0.01em; }

.label {
  margin: 0 0 var(--space-8);
  font-weight: 600; font-size: 12px; line-height: 1.4;
  color: var(--c-accent);
}
.band--dark .label, .bleed .label, .on-dark .label, .tile--wide .label { color: var(--c-highlight); }

.lead {
  margin: var(--space-12) 0 0;
  font-size: 20px; line-height: 1.6; color: var(--c-muted);
  max-width: 62ch;
}
.band--dark .lead, .bleed .lead, .on-dark .lead, .tile--wide .lead { color: var(--w-90); }

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

/* the second voice — Aleo, italic, never a headline (register-guide 4) */
.voice {
  font-family: var(--f-voice); font-style: italic; font-weight: 400;
  color: var(--c-muted);
}
.band--dark .voice, .bleed .voice, .on-dark .voice, .tile--wide .voice { color: var(--w-90); }

/* a big decorative numeral: 52px, so --c-caption's 3.5:1 clears the 3:1 floor */
.numeral {
  display: block;
  font-family: var(--f-display); font-weight: 700; font-size: 52px;
  line-height: 1; letter-spacing: -0.03em; color: var(--c-caption);
}
.band--dark .numeral, .bleed .numeral, .on-dark .numeral, .tile--wide .numeral { color: var(--c-highlight); }

.head { margin-bottom: var(--space-48); max-width: 68ch; }
.head--mid { margin-bottom: var(--space-32); }

/* ==========================================================================
   2. Buttons and links
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-8);
  padding: 14px var(--space-24);
  min-height: 48px;
  border: 0; border-radius: var(--r-sm);
  background-color: var(--c-accent); color: var(--c-on-accent);
  font: 600 14px/1.2 var(--f-body);
  text-align: center; text-decoration: none; cursor: pointer;
  transition: background-color var(--hover-fast) var(--hover-ease),
              transform var(--hover-fast) var(--hover-ease);
}
@media (hover: hover) {
  .btn:hover { background-color: var(--c-accent-hover); transform: translateY(-1px); }
}

.btn--ghost {
  background-color: transparent;
  color: var(--c-primary);
  box-shadow: inset 0 0 0 2px var(--c-primary);
  transition: background-color var(--hover-fast) var(--hover-ease),
              color var(--hover-fast) var(--hover-ease);
}
@media (hover: hover) {
  .btn--ghost:hover { background-color: var(--c-primary); color: #FFFFFF; }
}
.band--dark .btn--ghost, .on-dark .btn--ghost, .bleed .btn--ghost, .hero__words .btn--ghost {
  color: #FFFFFF; box-shadow: inset 0 0 0 2px var(--w-42);
}
@media (hover: hover) {
  .band--dark .btn--ghost:hover, .on-dark .btn--ghost:hover, .bleed .btn--ghost:hover,
  .hero__words .btn--ghost:hover {
    background-color: #FFFFFF; color: var(--c-dark);
  }
}

.tl {
  color: var(--c-primary); font-weight: 600;
  text-underline-offset: 3px;
  transition: color var(--hover-fast) var(--hover-ease);
}
@media (hover: hover) { .tl:hover { color: var(--c-accent); } }

/* ==========================================================================
   3. Header
   ========================================================================== */

.hd {
  position: sticky; top: 0; z-index: 40;
  background-color: var(--c-bg);
  transition: box-shadow var(--hover-fast) var(--hover-ease);
}
.hd.is-stuck { box-shadow: var(--shadow-standard); }

.hd__in {
  display: flex; align-items: center; gap: var(--space-16);
  max-width: var(--content-max); margin: 0 auto;
  padding: var(--space-12) var(--pad-x);
  min-height: 64px;
}
.hd__logo { display: block; margin-right: auto; }
.hd__logo img { width: 104px; }

.hd__nav { display: none; gap: var(--space-24); }
.hd__nav a {
  color: var(--c-muted); font-weight: 500; font-size: 14px; text-decoration: none;
  transition: color var(--hover-fast) var(--hover-ease);
}
@media (hover: hover) { .hd__nav a:hover { color: var(--c-ink); } }

.hd__call {
  display: none; align-items: center; gap: var(--space-8);
  color: var(--c-ink); font-weight: 600; font-size: 14px; text-decoration: none;
  transition: color var(--hover-fast) var(--hover-ease);
}
@media (hover: hover) { .hd__call:hover { color: var(--c-primary); } }

@media (min-width: 960px) {
  .hd__nav { display: flex; }
  .hd__call { display: inline-flex; }
  .menu { display: none; }
}

.menu > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; min-height: 44px;
  padding-inline: var(--space-12);
  border-radius: var(--r-sm);
  font-weight: 600; font-size: 14px; color: var(--c-ink);
  transition: color var(--hover-fast) var(--hover-ease);
}
.menu > summary::-webkit-details-marker { display: none; }
@media (hover: hover) { .menu > summary:hover { color: var(--c-primary); } }
.menu__panel {
  position: absolute; left: 0; right: 0;
  display: grid; gap: var(--space-4);
  padding: var(--space-16) var(--pad-x) var(--space-24);
  background-color: var(--c-bg);
  box-shadow: var(--shadow-standard);
}
.menu__panel a {
  padding: var(--space-12) 0; color: var(--c-ink);
  font-weight: 500; text-decoration: none;
  transition: color var(--hover-fast) var(--hover-ease);
}
@media (hover: hover) { .menu__panel a:hover { color: var(--c-primary); } }

/* ==========================================================================
   4. Hero — photograph as the ground, the quote form over it
   ========================================================================== */

/* One grid cell, three layers: the photograph, the drawn bay, the words and the
   form. The photograph is stretched by the cell rather than sizing it, so the
   hero is as tall as its content at every width and the form never has to be
   absolutely positioned over a picture it might outgrow. */
.hero { display: grid; background-color: var(--c-dark); }

.hero__ph { grid-area: 1 / 1; position: relative; min-height: 58vh; overflow: hidden; }
.hero__ph picture { display: block; height: 100%; }
.hero__ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* the scrim is at full depth from the first frame. Fading it in over 900ms
   leaves the headline on the raw picture for most of a second, which passes a
   contrast audit and fails a human (motion-kit.md 2). */
/* Two gradients, not one: darkest at the bottom where the headline sits and
   along the left where it runs, and near-clear at the top right so the
   photograph is still a photograph. */
.hero__ph::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(12,29,50,.90) 0%, rgba(12,29,50,.56) 48%, rgba(12,29,50,.30) 100%),
    linear-gradient(to right, rgba(12,29,50,.60) 0%, rgba(12,29,50,.12) 60%, rgba(12,29,50,0) 100%);
}

/* the drawn device: a scaffold elevation over the photograph, once, large */
.hero__bay {
  grid-area: 1 / 1; z-index: 1;
  display: grid; place-items: start end;
  padding: var(--space-24) var(--pad-x);
  color: #FFFFFF; opacity: .16; pointer-events: none;
}
.hero__bay img { width: min(44vw, 440px); height: auto; }

.hero__in {
  grid-area: 1 / 1; z-index: 2; position: relative;
  display: grid; align-content: end; gap: var(--space-32);
  width: 100%; max-width: var(--content-max); margin-inline: auto;
  padding: var(--space-48) var(--pad-x);
}
.hero .h1 { color: #FFFFFF; max-width: 15ch; }
.hero__sub { margin-top: var(--space-16); color: var(--w-90); font-size: 18px; max-width: 46ch; }
.hero__foot { display: flex; flex-wrap: wrap; gap: var(--space-12); margin-top: var(--space-32); }

/* the quote card. layout-system 4a: --r-lg is for a card that hangs over an
   edge, which is what this does at 1080 and up. */
.quote {
  background-color: var(--c-card);
  border-radius: var(--r-lg);
  padding: var(--space-24);
  box-shadow: var(--shadow-deep);
}
.quote .h3 { margin-bottom: var(--space-4); }
.quote__note { margin-top: var(--space-4); font-size: 14px; color: var(--c-muted); }

/* Below 1080 the words sit in the middle of a tall hero rather than at its
   foot, so a bottom-weighted scrim leaves the headline on the sky — measured at
   2.30:1. The phone gets a flatter, deeper one. */
@media (max-width: 1079px) {
  .hero__ph::after {
    background: linear-gradient(to top,
      rgba(12,29,50,.95) 0%, rgba(12,29,50,.86) 46%, rgba(12,29,50,.74) 100%);
  }
}

@media (min-width: 1080px) {
  .hero__ph { min-height: 84vh; }
  .hero__in {
    grid-template-columns: minmax(0, 1fr) 420px;
    gap: var(--space-64);
    align-content: normal; align-items: end;
    padding-block: var(--space-64);
  }
  .hero__card { grid-column: 2; align-self: center; }
}

/* ---- the two routes. AAA serve homeowners AND trade, which pull opposite
   ways, so the page asks once rather than splitting the difference. ---- */
.routes {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-8);
  margin-bottom: var(--space-16);
}
.routes button {
  min-height: 44px; padding: var(--space-8) var(--space-12);
  border: 0; border-radius: var(--r-pill);
  background-color: var(--c-alt); color: var(--c-muted);
  font: 600 14px/1.2 var(--f-body); cursor: pointer;
  transition: background-color var(--hover-fast) var(--hover-ease),
              color var(--hover-fast) var(--hover-ease);
}
.routes button[aria-pressed="true"] { background-color: var(--c-primary); color: #FFFFFF; }
@media (hover: hover) {
  .routes button:hover { color: var(--c-ink); }
  .routes button[aria-pressed="true"]:hover { background-color: var(--c-mid); color: #FFFFFF; }
}

.fields { display: grid; gap: var(--space-12); }
.fields--2 { grid-template-columns: 1fr 1fr; }
.field { display: grid; gap: var(--space-4); align-content: start; }
.field > span { font-weight: 600; font-size: 12px; color: var(--c-muted); }
.field input, .field select, .field textarea {
  width: 100%; min-height: 44px; padding: 10px var(--space-12);
  border: 1px solid var(--c-field-edge);   /* the placement fix — see the file header */
  border-radius: var(--r-sm);
  background-color: var(--c-card); color: var(--c-ink);
  font: 400 16px/1.4 var(--f-body);
  transition: border-color var(--hover-fast) var(--hover-ease),
              box-shadow var(--hover-fast) var(--hover-ease);
}
.field textarea { min-height: 76px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--c-primary); box-shadow: var(--focus-ring);
}
.field input::placeholder, .field textarea::placeholder { color: var(--c-muted); opacity: 1; }

.quote .btn { width: 100%; margin-top: var(--space-16); }
.quote__ps { margin-top: var(--space-12); font-size: 13px; color: var(--c-muted); }

/* the honeypot: in the document for bots, out of sight and out of the tab order for people */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* a field's error: the message under it, and its edge in the accent. The accent
   is 4.9:1 on white, so it carries small text without a darker token. */
.field__err { min-height: 0; font-size: 12px; line-height: 1.4; color: var(--c-accent-hover); }
.field__err:empty { display: none; }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] {
  border-color: var(--c-accent-hover);
}

.quote__msg { margin-top: var(--space-12); font-size: 14px; color: var(--c-accent-hover); }
.quote__msg:empty { display: none; }

.quote .btn:disabled { opacity: .65; cursor: progress; }
@media (hover: hover) { .quote .btn:disabled:hover { transform: none; background-color: var(--c-accent); } }

/* the confirmation that takes the form's place; focused on arrival so a screen
   reader lands on it */
.quote__done { padding: var(--space-16) 0; }
.quote__done:focus { outline: none; }
.quote__done p { color: var(--c-muted); font-size: 15px; }
.quote__local { font-family: var(--f-voice); font-style: italic; font-size: 14px; }

/* ==========================================================================
   5. Tiles — the layout: everything as a grid of boxes
   ========================================================================== */

.tiles { display: grid; gap: var(--grid-gap); grid-template-columns: 1fr; }
@media (min-width: 640px)  { .tiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .tiles { grid-template-columns: repeat(3, 1fr); } }

.tile {
  padding: var(--space-32);
  background-color: var(--c-card);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-subtle);
}
.tile p { color: var(--c-muted); font-size: 15px; }
.band--alt .tile { box-shadow: var(--shadow-standard); }

/* the featured box the grid layout is built around (layout type 6: "often one
   large featured box over smaller ones") */
.tile--wide { background-color: var(--c-dark); }
.tile--wide .h3 { color: #FFFFFF; }
/* a dark tile is a dark context: its copy, its form labels and its output line
   all move onto the white ladder, or they sit at 1.5:1 on navy */
.tile--wide p,
.tile--wide .field > span,
.tile--wide .check__out { color: var(--w-90); }
.tile--wide .field input { border-color: var(--w-42); }
@media (min-width: 1080px) { .tile--wide { grid-column: span 2; } }

/* a tile that is entirely a link, and so may lift (hover-effects: a card lifts
   only when the whole card is a link; one that isn't gets no hover, no cursor) */
.tile--link {
  display: block; text-decoration: none; color: inherit;
  transition: transform var(--hover-move) var(--hover-ease),
              box-shadow var(--hover-move) var(--hover-ease);
}
.tile--link .h3 { color: var(--c-ink); }
@media (hover: hover) {
  .tile--link:hover { transform: translateY(-4px); box-shadow: var(--shadow-emphatic); }
}

/* the services grid — denser, so every job is findable without a category */
.svc { display: grid; gap: var(--space-12); grid-template-columns: 1fr; }
@media (min-width: 560px)  { .svc { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .svc { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1200px) { .svc { grid-template-columns: repeat(4, 1fr); } }
.svc__i {
  padding: var(--space-24);
  background-color: var(--c-card);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-subtle);
}
.svc__i .h4 { margin-bottom: var(--space-4); }
.svc__i p { margin: 0; font-size: 14px; line-height: 1.6; color: var(--c-muted); }
.svc__after { margin-top: var(--space-32); }

/* ==========================================================================
   6. Work — a rail of named jobs. No photograph: a stand-in may be the page's
   ground, it may never be presented as AAA's work.
   ========================================================================== */

.rail {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: minmax(240px, 30%);
  gap: var(--grid-gap);
  overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-bottom: var(--space-16);
  /* thinned, not hidden: the buttons are the manual control the calibration
     asks for, and dragging the bar is the other one. Taking it away would
     leave a touch user guessing whether the row moves at all. */
  scrollbar-width: thin;
  scrollbar-color: var(--c-border) transparent;
}
.rail::-webkit-scrollbar { height: 8px; }
.rail::-webkit-scrollbar-track { background: transparent; }
.rail::-webkit-scrollbar-thumb { background: var(--c-border); border-radius: var(--r-pill); }
@media (prefers-reduced-motion: reduce) { .rail { scroll-behavior: auto; } }
@media (max-width: 640px) { .rail { grid-auto-columns: minmax(230px, 76%); } }

.job { scroll-snap-align: start; margin: 0; }
.job__plate {
  display: grid; place-items: center;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  background-color: var(--c-bg);
  box-shadow: var(--shadow-subtle);
  color: var(--c-muted);
  font-family: var(--f-voice); font-style: italic; font-size: 14px;
  text-align: center; padding: var(--space-16);
}
.job__cap { padding-top: var(--space-12); }
.job__meta { margin-top: var(--space-4); font-size: 13px; color: var(--c-muted); }

.rail__ctl { display: flex; gap: var(--space-8); margin-top: var(--space-16); }
.rail__ctl button {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border: 0; border-radius: var(--r-pill);
  background-color: var(--c-primary); color: #FFFFFF; cursor: pointer;
  transition: background-color var(--hover-fast) var(--hover-ease),
              transform var(--hover-fast) var(--hover-ease);
}
/* -1px, not the -2px a round social node takes: check.mjs reads these as
   buttons, and they are — the same filled control as every other button on the
   page, only round. Consistency beats the shape argument. */
@media (hover: hover) {
  .rail__ctl button:hover { background-color: var(--c-mid); transform: translateY(-1px); }
}
.rail__ctl svg { width: 18px; height: 18px; fill: currentColor; }

/* ==========================================================================
   7. Split bands — Who we are, What it costs
   ========================================================================== */

.split { display: grid; gap: var(--space-48); align-items: center; }
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; gap: var(--space-64); }
  .split--flip > :first-child { order: 2; }
}

/* the crew photograph's plate: a designed panel with the drawn bay behind the
   caption, not an empty box. The bay is a mask so it takes the panel's own tint. */
.plate--about {
  position: relative; overflow: hidden;
  aspect-ratio: 7 / 8; font-size: 16px;
  background-color: var(--c-dark); color: var(--w-90);
}
.plate--about::before {
  content: ""; position: absolute; inset: 0;
  background-color: #FFFFFF; opacity: .12;
  -webkit-mask: url(assets/elevation.svg) center / 82% no-repeat;
  mask: url(assets/elevation.svg) center / 82% no-repeat;
}
.plate--about span { position: relative; }

/* a featured box that is one column of a split, not a full-width row */
.split > .tile--wide { grid-column: auto; }

.costs { display: grid; gap: var(--space-24); margin-top: var(--space-32); }
.costs .h4 { margin-bottom: var(--space-4); }
.costs p { margin-top: var(--space-4); font-size: 15px; color: var(--c-muted); }

/* ==========================================================================
   8. Safety — full-bleed photograph with the words on it
   ========================================================================== */

/* Same construction as the hero, and for the same reason: the photograph is
   stretched by the grid cell rather than sizing it, so the band is always as
   tall as its own words. Absolutely positioning the words over a fixed-height
   picture worked at 1440 and put them on the white page below it at 390 — the
   contrast audit measured that as white on white, 1:1. */
.bleed {
  display: grid; position: relative; overflow: hidden;
  background-color: var(--c-dark); color: var(--w-90);
}
.bleed > :first-child { grid-area: 1 / 1; position: relative; min-height: 460px; overflow: hidden; }
.bleed picture { display: block; height: 100%; }
.bleed img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.bleed::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right,
    rgba(12,29,50,.96) 0%, rgba(12,29,50,.92) 52%, rgba(12,29,50,.62) 100%);
}
.bleed__in {
  grid-area: 1 / 1; position: relative; z-index: 1;
  display: grid; align-content: center;
  width: 100%; max-width: var(--content-max); margin-inline: auto;
  padding: var(--space-64) var(--pad-x);
}
.bleed .h2, .bleed .h4 { color: #FFFFFF; }

/* the same band mirrored — gradient and words on the right. The audit's
   "vary how sections open": two full-bleed photographs that open the same way
   are one template used twice. */
.bleed--right::after {
  background: linear-gradient(to left,
    rgba(12,29,50,.96) 0%, rgba(12,29,50,.92) 52%, rgba(12,29,50,.62) 100%);
}
.bleed__in--narrow { justify-items: end; }
.bleed__in--narrow > div { max-width: 620px; }
@media (max-width: 899px) {
  .bleed::after, .bleed--right::after {
    background: linear-gradient(to top,
      rgba(12,29,50,.96) 0%, rgba(12,29,50,.92) 60%, rgba(12,29,50,.86) 100%);
  }
  .bleed__in--narrow { justify-items: stretch; }
}

.safety { display: grid; gap: var(--space-24); margin-top: var(--space-32); max-width: 760px; }
@media (min-width: 720px) { .safety { grid-template-columns: 1fr 1fr; gap: var(--space-32); } }
.safety p { margin-top: var(--space-4); color: var(--w-90); font-size: 15px; }

/* ==========================================================================
   9. Small parts — what customers say, hours, areas, questions, contact
   ========================================================================== */

.say {
  padding: var(--space-32);
  background-color: var(--c-card); border-radius: var(--r-md);
  box-shadow: var(--shadow-subtle);
}
.say__q {
  display: block;
  font-family: var(--f-display); font-weight: 700; font-size: 52px; line-height: .8;
  color: var(--c-caption);
}
.say__t {
  margin-top: var(--space-16); font-size: 17px; line-height: 1.6;
  font-family: var(--f-voice); font-style: italic; color: var(--c-ink);
}
.say__who { margin-top: var(--space-16); font-size: 13px; color: var(--c-muted); }

.hours { margin: var(--space-24) 0 0; display: grid; grid-template-columns: 1fr auto; gap: var(--space-12) var(--space-24); }
.hours dt { color: var(--c-muted); font-size: 15px; }
.hours dd { margin: 0; font-size: 15px; text-align: right; }

.check { display: flex; flex-wrap: wrap; gap: var(--space-12); margin-top: var(--space-24); }
.check .field { flex: 1 1 220px; }
.check .btn { align-self: end; }
.check__out { margin-top: var(--space-16); font-size: 15px; color: var(--c-muted); }

.qa {
  border-radius: var(--r-md); background-color: var(--c-card);
  box-shadow: var(--shadow-subtle); margin-top: var(--space-12);
}
.qa > summary {
  list-style: none; cursor: pointer;
  padding: var(--space-24);
  font-family: var(--f-display); font-weight: 500; font-size: 18px;
  transition: color var(--hover-fast) var(--hover-ease);
}
.qa > summary::-webkit-details-marker { display: none; }
@media (hover: hover) { .qa > summary:hover { color: var(--c-primary); } }
.qa__a { padding: 0 var(--space-24) var(--space-24); color: var(--c-muted); font-size: 15px; }
.qa__a p:first-child { margin-top: 0; }

.ways { display: grid; gap: var(--space-32); }
@media (min-width: 720px) { .ways { grid-template-columns: repeat(3, 1fr); } }
.way .h4 { margin-bottom: var(--space-4); }
.way p { margin-top: var(--space-4); font-size: 15px; color: var(--c-muted); }
.way .btn { margin-top: var(--space-16); }

/* ==========================================================================
   10. Social nodes — patterns/social-nodes.md
   ========================================================================== */

.socials__row { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 12px; }
.node {
  display: grid; place-items: center;
  width: 44px; height: 44px;
  border: 0; border-radius: var(--r-pill);
  background-color: var(--c-accent); color: var(--c-on-accent);
  cursor: pointer;
  transition: background-color var(--hover-fast) var(--hover-ease),
              transform var(--hover-fast) var(--hover-ease);
}
.node svg { width: 20px; height: 20px; display: block; fill: currentColor; }
@media (hover: hover) {
  .node:hover { background-color: var(--c-accent-hover); transform: translateY(-2px); }
}
/* on a dark band the nodes read as holes punched in it, and the contrast works
   without touching the palette */
.on-dark .node { background-color: var(--w-12); color: #FFFFFF; }
@media (hover: hover) {
  .on-dark .node:hover { background-color: rgba(255,255,255,.22); transform: translateY(-2px); }
}
.socials__note { margin-top: var(--space-12); font-size: 13px; color: var(--w-90); }

/* ==========================================================================
   11. Footer and the one example notice
   ========================================================================== */

.notice {
  margin: 0; padding: var(--space-12) var(--pad-x);
  background-color: var(--c-mid); color: var(--w-90);
  font-size: 14px; text-align: center;
}
.notice a { color: #FFFFFF; }

.foot { background-color: var(--c-dark); color: var(--w-90); padding-block: var(--space-64) var(--space-32); }
.foot__top { display: grid; gap: var(--space-48); }
@media (min-width: 900px) { .foot__top { grid-template-columns: 1.2fr 1fr 1fr; } }
.foot__logo img { width: 128px; }
.foot__h { margin: 0 0 var(--space-12); font-family: var(--f-display); font-weight: 500; font-size: 16px; color: #FFFFFF; }
.foot p { color: var(--w-90); font-size: 14px; }
.foot p a { color: #FFFFFF; text-underline-offset: 3px; }
.foot__links { display: flex; flex-wrap: wrap; gap: var(--space-24); margin-top: var(--space-48); }
.foot__links a {
  color: var(--w-60); font-size: 14px; text-decoration: none;
  transition: color var(--hover-fast) var(--hover-ease);
}
@media (hover: hover) { .foot__links a:hover { color: var(--w-90); } }
.foot__small { margin-top: var(--space-24); color: var(--w-60); font-size: 13px; }

/* ==========================================================================
   12. Entrance motion — patterns/motion-kit.md. Three behaviours on this page:
   rise, stagger, unmask. One per band, each once.

   Every hidden state is behind .js, which the <head> sets on the first line.
   With the script blocked nothing on this page is ever invisible.
   ========================================================================== */

.js [data-in] { opacity: 0; }
.js [data-in].is-in { opacity: 1; }

.js [data-in="rise"] {
  transform: translateY(16px);
  transition: opacity var(--m-in) var(--m-ease), transform var(--m-in) var(--m-ease);
}
.js [data-in="rise"].is-in { transform: none; }

.js [data-in="stagger"] { opacity: 1; }
.js [data-in="stagger"] > * {
  opacity: 0; transform: translateY(16px);
  transition: opacity var(--m-in) var(--m-ease), transform var(--m-in) var(--m-ease);
}
.js [data-in="stagger"].is-in > * { opacity: 1; transform: none; }
.js [data-in="stagger"].is-in > :nth-child(2) { transition-delay: calc(var(--m-step) * 1); }
.js [data-in="stagger"].is-in > :nth-child(3) { transition-delay: calc(var(--m-step) * 2); }
.js [data-in="stagger"].is-in > :nth-child(4) { transition-delay: calc(var(--m-step) * 3); }
.js [data-in="stagger"].is-in > :nth-child(5) { transition-delay: calc(var(--m-step) * 4); }
.js [data-in="stagger"].is-in > :nth-child(6) { transition-delay: calc(var(--m-step) * 5); }
/* past six they arrive together — a seventh delay is a queue, not a stagger */

/* the FRAME is observed, never the image: an element clipped to zero area by
   its own transform is invisible to an IntersectionObserver (found in v9) */
.js [data-in="unmask"] { opacity: 1; }
.js [data-in="unmask"] img { transform: scale(1.06); transition: transform var(--m-unmask) var(--m-ease); }
.js [data-in="unmask"].is-in img { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js [data-in], .js [data-in] > *, .js [data-in] img {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
  .btn:hover, .tile--link:hover, .node:hover,
  .rail__ctl button:hover { transform: none; }
}
