@charset "utf-8";
/* ===========================================================================
   Service One Automotive
   ---------------------------------------------------------------------------
   The page is a printed workshop manual. Dark is reserved for instruments.

   Warm paper for everything you read. Near-black for the things that behave
   like instruments: the header, the hero drawing, the process track, the
   booking terminal, the footer. Moving between them should feel like the
   workshop lights going down and coming back up.

   Red is a warning lamp, not decoration. It appears on the call to action, on
   focus, on the live component in the drawing, and once as a sweep line during
   the boot sequence. Nowhere else.

   Contrast ratios in the comments below are computed, not estimated.
   validate.py recomputes them from these exact values on every build.
   =========================================================================== */

@import url("geometry.css");

/* --- Fonts ---------------------------------------------------------------
   Self-hosted, latin subset, variable. Archivo carries a real width axis,
   which is what makes the headings technical rather than merely bold. Nothing
   is fetched from a third party at runtime.
   ------------------------------------------------------------------------- */

@font-face {
  font-family: "Archivo";
  src: url("/assets/fonts/archivo-latin-var.woff2") format("woff2");
  font-weight: 400 800;
  font-stretch: 75% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/jetbrainsmono-latin-var.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- Tokens --------------------------------------------------------------- */

:root {
  /* Surfaces */
  --paper: #f3f0e9;
  --paper-2: #eae5db;
  --paper-3: #e1dbcd;
  --dark: #0a0c0e;
  --dark-2: #111517;
  --dark-3: #191e21;

  /* Ink */
  --ink: #15181b;          /* 15.9:1 on paper */
  --ink-mute: #4e565e;     /*  6.5:1 on paper */
  --rule: #d8d2c5;         /* printed rules, decorative only */
  --line: #77818b;         /*  3.6:1 on paper: linework and large text only */

  /* On dark */
  --on-dark: #f3f0e9;      /* 17.4:1 on dark */
  --on-dark-mute: #9aa4ae; /*  7.7:1 on dark */
  --on-dark-dim: #7d8792;  /*  5.4:1 on dark */
  --dark-rule: #262d32;

  /* The one red */
  --red: #d4150c;          /*  4.7:1 on paper */
  --red-dark: #ff4032;     /*  5.6:1 on dark */
  --red-ink: #ffffff;

  /* Type */
  --f-sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --f-mono: "JetBrains Mono", ui-monospace, "SF Mono", SFMono-Regular, Consolas,
    "Liberation Mono", monospace;

  /* Motion. Mechanical: travel, settle, click into place. Never the default
     ease, which is what makes a page feel like a template. */
  --e-settle: cubic-bezier(0.16, 0.84, 0.28, 1);      /* decisive finish */
  --e-latch: cubic-bezier(0.2, 1.5, 0.35, 1);         /* small overshoot, hard stop */
  --e-out: cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast: 140ms;
  --t-mid: 260ms;
  --t-slow: 520ms;

  /* Rhythm */
  --gut: clamp(1rem, 4vw, 2.5rem);
  --wrap: 1220px;
  --wrap-narrow: 720px;
  --sec-y: clamp(3.5rem, 8vw, 7rem);

  --focus: var(--red);
}

/* --- Reset ---------------------------------------------------------------- */

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

html {
  overflow-x: hidden;
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
  /* Deliberately NOT smooth here. A deep link like /#services would otherwise
     animate the page down from the top on arrival, which delays the content
     the visitor asked for and leaves everything measuring the wrong scroll
     position while it glides. Smooth is switched on after load, so in-page
     anchor clicks still ease and the initial jump is instant. */
  scroll-behavior: auto;
}
html.ready { scroll-behavior: smooth; }

body {
  overflow-x: hidden;
  overflow-x: clip;
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.62;
  font-variation-settings: "wdth" 100;
  -webkit-font-smoothing: antialiased;
  font-synthesis-weight: none;
}

/* Fine grain on paper. One fixed layer, composited, never repainted. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.4;
  background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'>\
<filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/>\
<feColorMatrix type='saturate' values='0'/></filter>\
<rect width='160' height='160' filter='url(%23n)' opacity='0.16'/></svg>");
  mix-blend-mode: multiply;
}

body > * { position: relative; z-index: 1; }

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

h1, h2, h3, h4 { margin: 0; text-wrap: balance; }
p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }
ul, ol { margin: 0; padding: 0; }
address { font-style: normal; }
button { font: inherit; color: inherit; }

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

/* --- Focus ---------------------------------------------------------------
   Two rings so the marker survives both surfaces. The dark ring reads on
   paper, the paper ring reads on near-black, and the red is constant.
   ------------------------------------------------------------------------- */

:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--red);
  outline-offset: 3px;
  border-radius: 2px;
}
.surface-dark :focus-visible,
.hdr :focus-visible,
.ftr :focus-visible {
  outline-color: var(--red-dark);
  box-shadow: 0 0 0 6px rgba(255, 64, 50, 0.18);
}

.skip {
  position: absolute; left: var(--gut); top: -100px; z-index: 200;
  background: var(--red); color: var(--red-ink);
  padding: 0.75rem 1.1rem; font-weight: 700; text-decoration: none;
  transition: top var(--t-fast) var(--e-settle);
}
.skip:focus { top: 0.6rem; }

main:focus { outline: none; }

/* --- Surfaces ------------------------------------------------------------- */

.surface-dark {
  background: var(--dark);
  color: var(--on-dark);
  position: relative;
  isolation: isolate;
}

/* Subtle scanlines. Dark panels only, never on paper. */
.surface-dark::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.5;
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(243, 240, 233, 0.028) 0 1px,
    transparent 1px 3px
  );
}

.surface-dark h1, .surface-dark h2, .surface-dark h3 { color: var(--on-dark); }
.surface-dark p { color: var(--on-dark-mute); }

/* --- Layout --------------------------------------------------------------- */

.wrap {
  width: min(100% - (var(--gut) * 2), var(--wrap));
  margin-inline: auto;
  min-width: 0;
}
/* The narrow text column lines up with the page heading rather than centring
   under it. A centred 720px column inside a left-aligned 1220px wrap put the
   body copy 238px to the right of its own h1, which read as two different
   pages stacked. A consistent left margin is also the printed-manual look the
   rest of the site is built on. */
/* The narrow text column starts at the same left edge as the page heading
   rather than centring under it.

   The cap goes on the CONTENT, not on the wrap. Capping the wrap and centring
   it put the body copy 238px right of its own h1, which read as two pages
   stacked; capping the wrap and left-aligning it flung the copy to x=0. This
   keeps the wrap exactly where every other wrap on the page is and narrows
   what sits inside it. */
.wrap-narrow {
  max-width: none;
  margin-inline: auto;
}
.wrap-narrow > * { max-width: var(--wrap-narrow); }

/* Only TOP LEVEL sections carry the big rhythm. Without the child combinator
   this also hit every nested <section> (each prose block, each signs list),
   giving them 112px of padding above and below and blowing the page apart. */
main > section { padding-block: var(--sec-y); }

/* Two sections on the same surface, back to back, do not need the full gap;
   the rhythm exists to mark a change of surface. */
.phero + section { padding-top: clamp(1.8rem, 3.5vw, 3rem); }
.hero { padding-block: clamp(2.5rem, 6vw, 4.5rem) 0; }

/* --- Type ----------------------------------------------------------------
   Headings run on Archivo's width axis, pulled in to 88 so they read as
   technical rather than as a default grotesque, set tight and large.
   ------------------------------------------------------------------------- */

.hero-h, .phero-h, .rule-h, .step-h, .jobcard-h,
.scard-name, .acard h2, .prose-sec h2, .prose-sec h3, .faq-h, .emph-name {
  font-variation-settings: "wdth" 88;
  letter-spacing: -0.022em;
  line-height: 1.02;
}

.hero-h {
  font-size: clamp(2.6rem, 8.4vw, 6rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  display: block;
  text-transform: uppercase;
}
.hero-h .hh-1, .hero-h .hh-2 { display: block; }
.hero-h .hh-2 { color: var(--on-dark-mute); }

.phero-h {
  font-size: clamp(2.05rem, 5.6vw, 3.55rem);
  font-weight: 800;
  letter-spacing: -0.032em;
  max-width: 19ch;
}

.rule-h {
  font-size: clamp(1.45rem, 3vw, 2.1rem);
  font-weight: 750;
  padding-top: 1.05rem;
  position: relative;
  max-width: 24ch;
}

/* Headings are introduced by a rule that draws in, not by a fade-up. */
.rule-h::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  height: 2px;
  width: 100%;
  max-width: 7.5rem;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-slow) var(--e-settle);
}
.surface-dark .rule-h::before { background: var(--red-dark); }
.in .rule-h::before, .rule-h.in::before { transform: scaleX(1); }

/* A ruled heading used on its own, outside .prose-sec, still needs air under
   it. Adjacent-sibling margins collapse, so this does not double up where
   .prose-sec h2 already sets a bottom margin. */
.rule-h + p, .rule-h + ul, .rule-h + ol, .rule-h + address { margin-top: 1.05rem; }

.kicker {
  font-family: var(--f-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0 0 0.9rem;
}
.surface-dark .kicker { color: var(--on-dark-dim); }

.mono-label {
  font-family: var(--f-mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
.surface-dark .mono-label, .ftr .mono-label { color: var(--on-dark-dim); }

.sec-lede {
  font-size: clamp(1.02rem, 1.6vw, 1.2rem);
  color: var(--ink-mute);
  max-width: 56ch;
  margin-top: 1rem;
}
.surface-dark .sec-lede { color: var(--on-dark-mute); }

.phero-lede {
  font-size: clamp(1.1rem, 2vw, 1.35rem);
  color: var(--ink-mute);
  max-width: 48ch;
  margin-top: 1.1rem;
}

/* --- Links and buttons ---------------------------------------------------- */

a { color: inherit; }

.lnk {
  color: var(--ink);
  text-decoration: none;
  font-weight: 650;
  border-bottom: 2px solid var(--red);
  padding-bottom: 1px;
  transition: color var(--t-fast) var(--e-out);
}
.lnk:hover { color: var(--red); }
.surface-dark .lnk, .ftr .lnk { color: var(--on-dark); border-bottom-color: var(--red-dark); }
.surface-dark .lnk:hover { color: var(--red-dark); }

.tel {
  color: inherit;
  font-family: var(--f-mono);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  white-space: nowrap;
}
.tel:hover { color: var(--red); }
.surface-dark .tel:hover, .ftr .tel:hover { color: var(--red-dark); }

.btn {
  --btn-y: 0.78rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: var(--btn-y) 1.35rem;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.005em;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: 2px;
  cursor: pointer;
  text-align: center;
  transition:
    transform var(--t-fast) var(--e-latch),
    background-color var(--t-fast) var(--e-out),
    border-color var(--t-fast) var(--e-out),
    color var(--t-fast) var(--e-out);
}
.btn-lg { --btn-y: 1rem; font-size: 1.02rem; padding-inline: 1.7rem; }

.btn-red {
  background: var(--red);
  color: var(--red-ink);
  border-color: var(--red);
}
.surface-dark .btn-red, .ftr .btn-red, .hdr .btn-red {
  background: var(--red-dark);
  border-color: var(--red-dark);
  color: #160300;
}
.btn-red:hover { transform: translateY(-2px); }
.btn-red:active { transform: translateY(0); }

.btn-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--line);
}
.btn-ghost:hover { border-color: var(--ink); transform: translateY(-2px); }
.surface-dark .btn-ghost, .ftr .btn-ghost, .hdr .btn-ghost {
  color: var(--on-dark);
  border-color: #3a444b;
}
.surface-dark .btn-ghost:hover, .ftr .btn-ghost:hover, .hdr .btn-ghost:hover {
  border-color: var(--on-dark);
}

@media (pointer: coarse) {
  .btn { min-height: 48px; }
  .tel, .lnk { padding-block: 2px; }
}

/* --- Header --------------------------------------------------------------- */

.hdr {
  background: var(--dark);
  color: var(--on-dark);
  position: sticky;
  top: 0;
  z-index: 90;
  border-bottom: 1px solid var(--dark-rule);
}
.hdr-in {
  width: min(100% - (var(--gut) * 2), var(--wrap));
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 68px;
  min-width: 0;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  color: var(--on-dark);
  margin-right: auto;
  min-width: 0;
}
.brand-mark { display: flex; color: var(--on-dark); flex: none; }
.brand-mark svg { display: block; }
.brand-txt { display: flex; flex-direction: column; min-width: 0; }
.brand-name {
  font-weight: 800;
  font-variation-settings: "wdth" 86;
  letter-spacing: -0.024em;
  font-size: 1.04rem;
  line-height: 1.1;
  text-transform: uppercase;
  white-space: nowrap;
}
.brand-sub {
  font-family: var(--f-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav { display: flex; align-items: center; gap: 1.5rem; min-width: 0; }
.nav ul {
  display: flex;
  gap: 1.35rem;
  list-style: none;
  min-width: 0;
}
.nav a {
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--on-dark-mute);
  position: relative;
  padding-block: 0.4rem;
  white-space: nowrap;
  transition: color var(--t-fast) var(--e-out);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--red-dark);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-mid) var(--e-settle);
}
.nav a:hover { color: var(--on-dark); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--on-dark); }

.nav-tel { font-family: var(--f-mono); font-variant-numeric: tabular-nums; }

.burger {
  display: none;
  width: 46px; height: 46px;
  background: transparent;
  border: 1px solid #3a444b;
  border-radius: 2px;
  position: relative;
  cursor: pointer;
  flex: none;
}
.burger span, .burger span::before, .burger span::after {
  content: "";
  position: absolute;
  left: 50%; width: 20px; height: 2px;
  background: var(--on-dark);
  transform: translateX(-50%);
  transition: transform var(--t-mid) var(--e-settle), opacity var(--t-fast) linear;
}
.burger span { top: 50%; margin-top: -1px; }
.burger span::before { left: 0; transform: translateY(-6px); }
.burger span::after { left: 0; transform: translateY(6px); }
.burger[aria-expanded="true"] span { transform: translateX(-50%) rotate(45deg); }
.burger[aria-expanded="true"] span::before { opacity: 0; }
.burger[aria-expanded="true"] span::after { transform: rotate(-90deg); }

/* The full nav needs about 1060px: brand, six links, the phone button and
   the call to action, plus gutters. At the old 960px breakpoint the band
   between 960 and 1060 showed the whole nav in a space too small for it,
   and the links sat on top of the brand name. */
@media (max-width: 1080px) {
  .burger { display: block; order: 3; }
  .nav {
    order: 4;
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
    padding-bottom: 1.1rem;
    display: none;
  }
  .nav.open { display: flex; }
  .nav ul { flex-direction: column; gap: 0; }
  .nav ul a {
    display: block;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--dark-rule);
    font-size: 1rem;
  }
  .nav a::after { display: none; }
  .nav .btn { width: 100%; }
  .hdr-in { flex-wrap: wrap; padding-block: 0.7rem; }
}

/* --- Hero ----------------------------------------------------------------
   The hero fills the first screen on its own. That is not a styling whim: the
   cutaway below it is scrubbed by scroll, and it must START below the fold at
   every viewport height, or a tall monitor shows it already part-drawn on
   arrival and it reads as a rendering fault.
   ------------------------------------------------------------------------- */

.hero {
  min-height: calc(100svh - 68px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  padding-block: clamp(2.5rem, 7vh, 4.5rem) clamp(4rem, 11vh, 6rem);
}
.hero-in { max-width: min(100%, 62rem); }
.hero-kicker { margin-bottom: 1.2rem; }
.hero-sub {
  font-size: clamp(1.05rem, 1.9vw, 1.3rem);
  color: var(--on-dark-mute);
  max-width: 46ch;
  margin-top: 1.3rem;
}
.hero-acts { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.9rem; }
.hero-hours {
  font-family: var(--f-mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  color: var(--on-dark-dim);
  margin-top: 1.1rem;
}

.hero-cue {
  position: absolute;
  left: var(--gut);
  bottom: clamp(1rem, 3vh, 2rem);
  margin: 0;
  color: var(--on-dark-dim);
}
.hero-cue::after {
  content: "";
  display: block;
  width: 1px;
  height: 26px;
  margin-top: 0.6rem;
  background: linear-gradient(to bottom, var(--red-dark), transparent);
}

/* --- The cutaway: the signature moment -----------------------------------
   Scrubbed by scroll. Scroll position is the playhead: the first half of the
   travel plots the car in, the second half takes it apart, and scrolling back
   up runs both in reverse because each is a pure function of progress.

   NOTHING HERE IS STICKY. The stage scrolls with the page and the drawing
   advances as it passes through, so the page never stops moving under the
   visitor. A pinned stage on a 380vh track froze the page for three screens
   on an earlier build and read as a bug rather than as a feature.

   Every stroke ships DRAWN and every component ships in place. cutaway.js is
   what makes them start hidden, and only once it is running and able to drive
   them. No script, a failed script, or reduced motion all leave the complete
   assembled drawing with its nine working links.
   ------------------------------------------------------------------------- */

/* --- The pinned sequence --------------------------------------------------
   The stage holds still in the viewport while the scroll plays the drawing and
   the headline beats arrive over it. That hold is the effect.

   THE SECTION IS ONLY TALL WHILE SCRIPT IS DRIVING IT. `.pin-on` is added by
   cutaway.js once it has armed. Without it the section collapses to its
   natural height, the stage is not sticky, and the beats are read as ordinary
   stacked text. Nobody ever gets three screens of a static picture, which is
   the state that made the previous build read as broken.
   ------------------------------------------------------------------------- */

.pinsec { position: relative; padding-block: clamp(1.5rem, 5vh, 3rem) clamp(2.5rem, 7vh, 4.5rem); }
.pin-on .pinsec { height: 330vh; padding-block: 0; }
.pin { position: relative; }
.pin-on .pin {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.pin-in {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: clamp(0.5rem, 1.6svh, 1.1rem);
  padding-top: 68px;
  min-width: 0;
}

/* The beats sit stacked in one reserved box, so nothing reflows as they swap
   and the sequence cannot cost a point of CLS. */
.pin-copy { display: none; }
.pin-on .pin-copy {
  display: block;
  position: relative;
  height: clamp(6rem, 15svh, 9.5rem);
  width: min(100% - (var(--gut) * 2), 52rem);
  margin-inline: auto;
  text-align: center;
}
.beat {
  position: absolute;
  inset: 0;
  opacity: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.5rem;
}
.beat-h {
  margin: 0;
  font-size: clamp(1.6rem, 4.4vw, 3.1rem);
  font-weight: 800;
  font-variation-settings: "wdth" 88;
  letter-spacing: -0.032em;
  line-height: 1.02;
  color: var(--on-dark);
  text-wrap: balance;
}
.beat-s {
  margin: 0;
  font-size: clamp(0.95rem, 1.6vw, 1.12rem);
  color: var(--on-dark-mute);
  max-width: 46ch;
  margin-inline: auto;
}

/* In the pin the stage is sized by HEIGHT, so the car, the copy, the caption
   and the rail always fit one screen together at any viewport. */
.pin-on .cut-stage {
  height: min(50svh, 540px);
  width: auto;
  max-width: min(100% - (var(--gut) * 2), 1120px);
  aspect-ratio: var(--cut-ar);
  margin-inline: auto;
}

.pin-foot {
  width: min(100% - (var(--gut) * 2), 1120px);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem 1.5rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--dark-rule);
  min-width: 0;
}

/* The rail is not decoration. It says out loud that this is a sequence with an
   end, which is the single thing the previous pinned build did not do: a page
   that stops moving with no indication of why or for how long is what reads as
   a bug. */
.pin-rail { display: none; }
.pin-on .pin-rail {
  display: block;
  width: min(100% - (var(--gut) * 2), 1120px);
  margin-inline: auto;
  height: 2px;
  background: var(--dark-rule);
  overflow: hidden;
}
.pin-rail-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--red-dark);
  transform: scaleX(0);
  transform-origin: left center;
}

/* The readable fallback. Shown by default, hidden once the sequence is live. */
.pin-static { display: grid; gap: clamp(2rem, 5vw, 3.5rem); padding-block: clamp(2rem, 5vh, 3rem); }
.pin-on .pin-static { display: none; }
.beat-static { max-width: 52ch; }
.beat-static h2 {
  font-size: clamp(1.5rem, 3.4vw, 2.2rem);
  font-weight: 800;
  font-variation-settings: "wdth" 88;
  letter-spacing: -0.03em;
  margin-bottom: 0.5rem;
}
.beat-static p { color: var(--on-dark-mute); margin: 0; }

@media (max-width: 720px) {
  .pin-on .pinsec { height: 260vh; }
  .pin-on .cut-stage { height: min(38svh, 320px); }
  .pin-on .pin-copy { height: clamp(7rem, 20svh, 10rem); }
}

/* A short window has no room for the copy box AND the car. The car wins,
   because it is the thing being explained. */
@media (max-height: 560px) {
  .pin-on .pin-copy { display: none; }
  .pin-on .cut-stage { height: min(62svh, 420px); }
}

.cut-stage {
  width: min(100% - (var(--gut) * 2), 1120px);
  margin-inline: auto;
  position: relative;
  /* Generated by build.py from the SVG viewBox. Hand-maintaining this is how
     a drawing ends up letterboxed and floating in empty space. */
  aspect-ratio: var(--cut-ar);
  min-width: 0;
}
.cut-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.cut-ground path {
  fill: none;
  stroke: #2b3338;
  stroke-width: 1.5;
  stroke-dasharray: 1 7;
  stroke-linecap: round;
}

.cut-shell path,
.cut-wheels circle {
  fill: none;
  stroke: #8f9aa4;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.cut-wheels .rim { stroke: #5d686f; stroke-width: 1.5; }

.cut-systems .sys { cursor: pointer; }
.cut-systems .sys-art :is(path, rect, circle) {
  fill: none;
  stroke: #98a3ad;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  transition: stroke 240ms var(--e-out), stroke-width 240ms var(--e-out);
}
.cut-systems .sys:hover .sys-art :is(path, rect, circle),
.cut-systems .sys:focus-visible .sys-art :is(path, rect, circle),
.cut-systems .sys.live .sys-art :is(path, rect, circle) {
  stroke: var(--red-dark);
  stroke-width: 2.8;
}

/* Labels belong to the exploded half of the travel, and each fades up with
   its OWN component rather than as a group, so the stagger reads. Hidden is
   the correct resting state, which is what a visitor without script gets. */
.sys-label { opacity: 0; }
.sys-label {
  font-family: var(--f-mono);
  font-size: 14px;
  letter-spacing: 0.1em;
  fill: var(--on-dark-dim);
}

.cut-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem 1.5rem;
  margin-top: clamp(0.75rem, 2vw, 1.4rem);
  padding-top: 1rem;
  border-top: 1px solid var(--dark-rule);
}
.cut-caption {
  margin: 0;
  font-size: clamp(0.95rem, 1.7vw, 1.15rem);
  color: var(--on-dark);
  font-weight: 600;
  min-height: 1.6em;
}
.cut-caption .cap-svc { color: var(--red-dark); }
.cut-hint { margin: 0; flex: none; }

@media (max-width: 720px) {
  /* Nine labels cannot be read at this width, so the phone gets the plotter
     draw-in and keeps the car assembled. The drawing stays a full set of
     links either way. */
  .cut-labels { display: none; }
  .cut-hint { display: none; }
}

/* --- Answer block --------------------------------------------------------
   The paragraph answer engines lift. It is styled as the manual's opening
   note: indented, ruled, and quotable on its own.
   ------------------------------------------------------------------------- */

.ansec { padding-block: clamp(2.5rem, 5vw, 4rem); }

.answer-block {
  position: relative;
  padding: 0.2rem 0 0.2rem 1.4rem;
  margin-top: 1.8rem;
}
.answer-block::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--red);
}
.answer-block p {
  max-width: 68ch;
  font-size: clamp(1.05rem, 1.7vw, 1.22rem);
  line-height: 1.55;
  color: var(--ink);
  margin: 0;
}
.surface-dark .answer-block::before { background: var(--red-dark); }
.surface-dark .answer-block p { color: var(--on-dark); }

/* --- Breadcrumbs ---------------------------------------------------------- */

.crumbs { margin-bottom: 1.4rem; }
.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.7rem;
  list-style: none;
  font-family: var(--f-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.crumbs li + li::before { content: "/"; margin-right: 0.7rem; color: var(--line); }
.crumbs a { text-decoration: none; }
.crumbs a:hover { color: var(--red); }

.phero { padding-block: clamp(2.4rem, 5vw, 4rem) 0; }

/* --- Service cards --------------------------------------------------------
   A ruled index, not a card deck with soft shadows. Borders, not elevation.
   ------------------------------------------------------------------------- */

.scards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-top: 2.4rem;
  min-width: 0;
}
.scards-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }

.scard {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: 0.55rem;
  padding: 1.5rem 1.4rem 1.3rem;
  background: var(--paper);
  text-decoration: none;
  min-width: 0;
  position: relative;
  transition: background-color var(--t-mid) var(--e-out);
}
.scard::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-mid) var(--e-settle);
}
.scard:hover, .scard:focus-visible { background: var(--paper-2); }
.scard:hover::after, .scard:focus-visible::after { transform: scaleX(1); }

.scard-no {
  font-family: var(--f-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  color: var(--line);
  font-variant-numeric: tabular-nums;
}
.scard-name {
  font-size: 1.24rem;
  font-weight: 750;
}
.scard-lede { color: var(--ink-mute); font-size: 0.93rem; line-height: 1.5; }
.scard-go {
  font-family: var(--f-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--red);
  margin-top: 0.4rem;
}
.scard-go::after {
  content: " \2192";
  display: inline-block;
  transition: transform var(--t-mid) var(--e-latch);
}
.scard:hover .scard-go::after { transform: translateX(4px); }

/* --- Process track (dark) -------------------------------------------------
   A horizontal track with detents, sharing no skeleton with the grid above it.
   ------------------------------------------------------------------------- */

.psteps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 2rem 1.5rem;
  margin-top: 2.8rem;
  position: relative;
  min-width: 0;
}
.pstep { position: relative; padding-top: 2.1rem; min-width: 0; }
.pstep::before {
  content: "";
  position: absolute;
  top: 0.55rem; left: 0; right: -1.5rem;
  height: 1px;
  background: var(--dark-rule);
}
.pstep:last-child::before { right: 0; }
.pstep::after {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 11px; height: 11px;
  border-radius: 50%;
  border: 2px solid var(--on-dark-dim);
  background: var(--dark);
  transform: scale(0.4);
  opacity: 0;
  transition: transform 420ms var(--e-latch) calc(var(--i, 0) * 90ms),
              opacity 300ms var(--e-out) calc(var(--i, 0) * 90ms);
}
.psteps.in .pstep::after { transform: scale(1); opacity: 1; }
.psteps.in .pstep:first-child::after { border-color: var(--red-dark); }

.pstep-no { display: block; margin-bottom: 0.7rem; }
.pstep h3 {
  font-size: 1.16rem;
  font-weight: 700;
  font-variation-settings: "wdth" 92;
  letter-spacing: -0.015em;
  margin-bottom: 0.5rem;
}
.pstep p { font-size: 0.94rem; margin: 0; }

/* --- Heritage ------------------------------------------------------------- */

.herit { background: var(--paper-2); }
.herit-in {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
@media (max-width: 800px) { .herit-in { grid-template-columns: 1fr; } }

.herit-fig {
  display: grid;
  grid-template-columns: auto auto;
  align-items: start;
  justify-content: start;
  column-gap: 0.1rem;
  line-height: 0.8;
  border-top: 2px solid var(--red);
  padding-top: 1.2rem;
}
.herit-num {
  font-size: clamp(5rem, 15vw, 10rem);
  font-weight: 800;
  font-variation-settings: "wdth" 80;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}
.herit-plus {
  font-size: clamp(2rem, 5vw, 3.4rem);
  font-weight: 700;
  color: var(--red);
  padding-top: 0.3em;
}
.herit-unit { grid-column: 1 / -1; margin-top: 1.1rem; line-height: 1.4; }
.herit-txt p { color: var(--ink-mute); max-width: 54ch; }
.herit-txt .lnk { margin-top: 0.4rem; display: inline-block; }

/* --- Areas ---------------------------------------------------------------- */

.area-list { list-style: none; margin-top: 2.4rem; border-top: 1px solid var(--rule); }
.area-list li { border-bottom: 1px solid var(--rule); min-width: 0; }
.area-list a {
  display: grid;
  grid-template-columns: minmax(0, 12rem) auto minmax(0, 1fr);
  align-items: baseline;
  gap: 0.4rem 1.4rem;
  padding: 1.15rem 0.2rem;
  text-decoration: none;
  transition: background-color var(--t-fast) var(--e-out),
              padding-left var(--t-mid) var(--e-settle);
}
.area-list a:hover, .area-list a:focus-visible {
  background: var(--paper-2);
  padding-left: 0.9rem;
}
.area-name { font-size: 1.15rem; font-weight: 700; font-variation-settings: "wdth" 92; }
.area-pc { flex: none; }
.area-why { color: var(--ink-mute); font-size: 0.93rem; min-width: 0; }
.area-list a:hover .area-name { color: var(--red); }

@media (max-width: 720px) {
  .area-list a { grid-template-columns: 1fr auto; }
  .area-why { grid-column: 1 / -1; }
}

/* --- Emphasis list (suburb pages) ----------------------------------------- */

.emph-list { list-style: none; margin-top: 2rem; display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.emph { background: var(--paper); min-width: 0; }
.emph a {
  display: block;
  padding: 1.3rem 1.3rem;
  text-decoration: none;
  border-left: 3px solid transparent;
  transition: border-color var(--t-mid) var(--e-settle), background-color var(--t-fast) var(--e-out);
}
.emph a:hover, .emph a:focus-visible { border-left-color: var(--red); background: var(--paper-2); }
.emph-name { display: block; font-size: 1.1rem; font-weight: 750; margin-bottom: 0.35rem; }
.emph-why { display: block; color: var(--ink-mute); font-size: 0.95rem; }

/* --- Article cards --------------------------------------------------------
   Numbered entries in a manual's index. Stacked rows rather than a grid of
   tiles, so the car care hub does not read as the services grid a second time.
   ------------------------------------------------------------------------- */

.acards { list-style: none; margin-top: 2.4rem; border-top: 1px solid var(--rule); }
.acard { border-bottom: 1px solid var(--rule); min-width: 0; }
.acard a {
  display: grid;
  grid-template-columns: minmax(0, 7rem) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.5rem 1.6rem;
  padding: 1.6rem 0.2rem;
  text-decoration: none;
  transition: background-color var(--t-fast) var(--e-out),
              padding-left var(--t-mid) var(--e-settle);
}
.acard a:hover, .acard a:focus-visible { background: var(--paper-2); padding-left: 0.9rem; }
.acard-kick { grid-row: 1; }
.acard h2 {
  grid-column: 2;
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  font-weight: 750;
}
.acard a:hover h2 { color: var(--red); }
.acard p {
  grid-column: 2;
  margin: 0;
  color: var(--ink-mute);
  font-size: 0.95rem;
  max-width: 62ch;
}
.acard-go {
  grid-column: 3;
  grid-row: 1;
  font-family: var(--f-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--red);
  white-space: nowrap;
}
@media (max-width: 720px) {
  .acard a { grid-template-columns: 1fr auto; }
  .acard h2, .acard p { grid-column: 1 / -1; }
}

/* --- Prose ---------------------------------------------------------------- */

.prose-sec { margin-top: 2.9rem; }
.prose-sec:first-child { margin-top: 0; }
.prose-sec h2 { margin-bottom: 1.1rem; }
.prose-sec p { max-width: 68ch; color: var(--ink); }

.signs { margin-top: 2.9rem; }
.signs ul { list-style: none; margin-top: 1.3rem; }
.signs li {
  position: relative;
  padding: 0.62rem 0 0.62rem 2.1rem;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}
.signs li::before {
  content: "";
  position: absolute;
  left: 0.15rem; top: 1.24em;
  width: 10px; height: 2px;
  background: var(--red);
}

.numlist { margin-top: 1.4rem; padding-left: 0; list-style: none; counter-reset: n; }
.numlist li {
  counter-increment: n;
  position: relative;
  padding: 0.6rem 0 0.6rem 2.6rem;
  border-bottom: 1px solid var(--rule);
}
.numlist li::before {
  content: counter(n, decimal-leading-zero);
  position: absolute;
  left: 0; top: 0.75rem;
  font-family: var(--f-mono);
  font-size: 0.74rem;
  color: var(--red);
  font-variant-numeric: tabular-nums;
}

.artmeta { margin-bottom: 2rem; padding-bottom: 1rem; border-bottom: 1px solid var(--rule); }

.draft {
  border: 2px dashed var(--red);
  padding: 1rem 1.2rem;
  font-size: 0.95rem;
  color: var(--ink);
  margin-bottom: 2.4rem;
}

.outro { background: var(--paper-2); }

/* --- FAQ ------------------------------------------------------------------ */

.faq-list { margin-top: 1.9rem; border-top: 1px solid var(--rule); }
.faq-item { border-bottom: 1px solid var(--rule); }
.faq-item summary {
  cursor: pointer;
  list-style: none;
  padding: 1.15rem 2.6rem 1.15rem 0;
  position: relative;
  font-weight: 650;
  font-size: 1.04rem;
  transition: color var(--t-fast) var(--e-out);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--red); }
.faq-item summary::after, .faq-item summary::before {
  content: "";
  position: absolute;
  right: 0.4rem; top: 50%;
  background: var(--red);
  transition: transform var(--t-mid) var(--e-settle);
}
.faq-item summary::after { width: 14px; height: 2px; margin-top: -1px; }
.faq-item summary::before { width: 2px; height: 14px; margin-top: -7px; right: 0.8rem; }
.faq-item[open] summary::before { transform: scaleY(0); }
.faq-a { padding: 0 0 1.35rem; max-width: 68ch; color: var(--ink-mute); }
.faq-more { margin-top: 1.8rem; }

/* --- Contact -------------------------------------------------------------- */

.contact-in {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(1.6rem, 4vw, 3.5rem);
  align-items: start;
}
@media (max-width: 860px) { .contact-in { grid-template-columns: 1fr; } }

.contact-card { padding: clamp(1.6rem, 3vw, 2.4rem); border-radius: 2px; }
.contact-card address { margin: 0.9rem 0 1.2rem; font-size: 1.1rem; line-height: 1.5; color: var(--on-dark); }
.tel-big {
  font-size: clamp(1.4rem, 3.4vw, 2rem);
  font-weight: 600;
  border-bottom-width: 2px;
  color: var(--on-dark);
}
.contact-hours { font-size: 0.9rem; margin: 1rem 0 1.5rem; }
.contact-tel { margin: 0; }

.map { margin-top: 2rem; border: 1px solid var(--rule); padding: 1.3rem; background: var(--paper-2); }
.map-note { font-size: 0.86rem; color: var(--ink-mute); margin: 0.9rem 0 0; }
.map-fallback { margin: 0.7rem 0 0; font-size: 0.9rem; }
.map iframe { display: block; width: 100%; height: 340px; border: 0; margin-bottom: 0.9rem; }

/* --- Booking terminal -----------------------------------------------------
   A diagnostic terminal on a dark surface. The progress is a needle climbing
   through six detents, and every committed step prints a line into the log.
   ------------------------------------------------------------------------- */

.booksec { padding-block: clamp(2rem, 4vw, 3.5rem) var(--sec-y); }
.term { border-radius: 2px; }
.term-in {
  width: min(100% - (var(--gut) * 2), var(--wrap));
  margin-inline: auto;
  padding-block: clamp(1.8rem, 4vw, 3rem);
  min-width: 0;
}

.term-head {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.2rem);
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--dark-rule);
  min-width: 0;
}

.pgauge { position: relative; width: 126px; flex: none; }
.pgauge svg { display: block; width: 100%; height: auto; overflow: visible; }
.pg-track, .pg-fill { fill: none; stroke-width: 3; stroke-linecap: round; }
.pg-track { stroke: var(--dark-rule); }
/* The dash values are written by booking.js from a measured arc length. Only
   the easing lives here: a var() driven calc looks tidier and does not
   actually transition in Chrome when the custom property is what changed. */
.pg-fill {
  stroke: var(--red-dark);
  /* The dasharray has to be declared HERE as well as written by JS. With it
     only in JS, a visitor without scripting got a dash offset with nothing to
     offset against, so the arc drew full red and the gauge read as finished
     before they had typed anything. */
  stroke-dasharray: 201 201;
  stroke-dashoffset: 201;
  transition: stroke-dashoffset 620ms var(--e-settle);
}
/* Needle travel: 180 degrees across six detents, with a small overshoot and a
   hard stop, the way a real needle behaves. The angle is written by
   booking.js; this is the resting position and the easing. */
.pg-needle {
  stroke: var(--on-dark);
  stroke-width: 2.5;
  stroke-linecap: round;
  transform-origin: 80px 84px;
  transform: rotate(-90deg);
  transition: transform 700ms var(--e-latch);
}
.pg-hub { fill: var(--on-dark); }
.pg-detents { display: flex; gap: 4px; justify-content: center; margin-top: 0.5rem; }
.detent {
  width: 10px; height: 3px;
  background: var(--dark-rule);
  transition: background-color var(--t-mid) var(--e-out);
}
.detent.done { background: var(--red-dark); }
.pg-read {
  text-align: center;
  font-family: var(--f-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
  color: var(--on-dark-dim);
  margin: 0.4rem 0 0;
}
.pg-now { color: var(--on-dark); font-weight: 600; }

.term-title { min-width: 0; }
.term-steps {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.1rem;
  margin-top: 0.7rem;
  font-size: 0.82rem;
  color: var(--on-dark-dim);
  min-width: 0;
}
.term-steps li { position: relative; padding-left: 0.85rem; }
.term-steps li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.62em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--dark-rule);
  transition: background-color var(--t-fast) var(--e-out);
}
.term-steps li.done::before { background: var(--red-dark); }
.term-steps li.now { color: var(--on-dark); }
.term-steps li.now::before { background: var(--on-dark); }

.term-log {
  background: #06080a;
  border: 1px solid var(--dark-rule);
  border-radius: 2px;
  padding: 0.9rem 1.1rem;
  margin: 1.4rem 0 1.8rem;
  font-family: var(--f-mono);
  font-size: 0.78rem;
  line-height: 1.75;
  max-height: 9.5rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  min-width: 0;
}
.log-line { margin: 0; color: var(--on-dark-mute); word-break: break-word; }
.log-line .log-t { color: var(--red-dark); margin-right: 0.5rem; }
.log-boot { color: var(--on-dark-dim); }

.bform { max-width: 46rem; min-width: 0; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.step { min-width: 0; }
.step-no { display: block; margin-bottom: 0.7rem; }
.step-h {
  font-size: clamp(1.5rem, 3.4vw, 2.2rem);
  font-weight: 780;
  margin-bottom: 0.6rem;
}
.step-hint { color: var(--on-dark-mute); max-width: 52ch; font-size: 0.96rem; }

.fields { display: grid; gap: 1.5rem; margin-top: 1.8rem; min-width: 0; }
.field { min-width: 0; }

.lbl, .choices legend {
  display: block;
  font-weight: 650;
  font-size: 0.96rem;
  color: var(--on-dark);
  margin-bottom: 0.35rem;
  padding: 0;
}
.opt {
  font-family: var(--f-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-dim);
  font-weight: 400;
  margin-left: 0.4rem;
}
.hint { font-size: 0.85rem; color: var(--on-dark-dim); margin: 0 0 0.5rem; }

.inp {
  width: 100%;
  max-width: 100%;
  background: #06080a;
  border: 1px solid #333c42;
  border-radius: 2px;
  color: var(--on-dark);
  padding: 0.78rem 0.9rem;
  font: inherit;
  font-size: 1rem;
  transition: border-color var(--t-fast) var(--e-out), background-color var(--t-fast) var(--e-out);
}
.inp:hover { border-color: #47525a; }
.inp:focus { border-color: var(--red-dark); background: #0b0f12; }
.inp::placeholder { color: #5c666d; }
.inp-s { max-width: 8rem; }
.inp-m { max-width: 14rem; }
.mono-inp { font-family: var(--f-mono); letter-spacing: 0.1em; text-transform: uppercase; }
textarea.inp { resize: vertical; min-height: 7rem; }

.field.invalid .inp { border-color: var(--red-dark); }
.err {
  margin: 0.45rem 0 0;
  font-size: 0.86rem;
  color: var(--red-dark);
  font-weight: 600;
  min-height: 0;
}
.err:empty { display: none; }

.choices { border: 0; padding: 0; margin: 0; min-width: 0; }
.choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 1px;
  background: var(--dark-rule);
  border: 1px solid var(--dark-rule);
  margin-top: 0.6rem;
  min-width: 0;
}
.choice {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.8rem 0.9rem;
  background: var(--dark);
  cursor: pointer;
  min-width: 0;
  transition: background-color var(--t-fast) var(--e-out);
}
.choice:hover { background: var(--dark-3); }
.choice input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
}
.choice-box {
  flex: none;
  width: 18px; height: 18px;
  margin-top: 0.22rem;
  border: 2px solid #4a545b;
  border-radius: 1px;
  position: relative;
  transition: border-color var(--t-fast) var(--e-out);
}
.choice-box::after {
  content: "";
  position: absolute;
  inset: 3px;
  background: var(--red-dark);
  transform: scale(0);
  transition: transform 220ms var(--e-latch);
}
.choice input:checked ~ .choice-box { border-color: var(--red-dark); }
.choice input:checked ~ .choice-box::after { transform: scale(1); }
.choice input:focus-visible ~ .choice-box {
  outline: 3px solid var(--red-dark);
  outline-offset: 2px;
}
.choice-txt { font-size: 0.95rem; color: var(--on-dark); line-height: 1.45; min-width: 0; }
.choice input:checked ~ .choice-txt { font-weight: 650; }

.step-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--dark-rule);
}

.review { margin-top: 1.8rem; border-top: 1px solid var(--dark-rule); }
.review-row {
  display: grid;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr) auto;
  gap: 0.3rem 1.2rem;
  align-items: baseline;
  padding: 0.85rem 0.2rem;
  border-bottom: 1px solid var(--dark-rule);
  width: 100%;
  background: transparent;
  border-left: 0; border-right: 0; border-top: 0;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--t-fast) var(--e-out), padding-left var(--t-mid) var(--e-settle);
}
.review-row:hover, .review-row:focus-visible { background: var(--dark-3); padding-left: 0.8rem; }
.review-k {
  font-family: var(--f-mono);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-dark-dim);
  min-width: 0;
}
.review-v { color: var(--on-dark); min-width: 0; word-break: break-word; }
.review-e {
  font-family: var(--f-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--red-dark);
}
@media (max-width: 640px) {
  .review-row { grid-template-columns: 1fr auto; }
  .review-v { grid-column: 1 / -1; }
}

.term-note {
  font-size: 0.88rem;
  color: var(--on-dark-dim);
  border-left: 2px solid var(--red-dark);
  padding-left: 0.9rem;
  margin-top: 1.5rem;
  max-width: 52ch;
}
.form-error { color: var(--red-dark); font-weight: 650; margin-top: 1rem; }
.form-error:empty { display: none; }

.nojs-note {
  border: 1px solid var(--red-dark);
  border-left-width: 3px;
  padding: 1.1rem 1.2rem;
  margin-bottom: 1.6rem;
}
.nojs-note p { margin: 0; color: var(--on-dark); }

/* The job card. A perforated top edge, the details in monospace. */
.jobcard {
  background: var(--paper);
  color: var(--ink);
  max-width: 34rem;
  margin-top: 1.5rem;
  position: relative;
  border-radius: 0 0 2px 2px;
}
.jobcard-perf {
  height: 14px;
  background:
    radial-gradient(circle at 7px 0, transparent 0 6px, var(--paper) 6.5px) repeat-x;
  background-size: 14px 14px;
}
.jobcard-in { padding: 0.4rem 1.6rem 1.8rem; }
.jobcard-h {
  font-size: 2rem;
  font-weight: 800;
  font-variation-settings: "wdth" 86;
  letter-spacing: -0.03em;
  margin: 0.3rem 0 1.3rem;
}
.jobcard-dl { margin: 0; font-family: var(--f-mono); font-size: 0.82rem; }
.jobcard-dl div {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
  gap: 0.2rem 1rem;
  padding: 0.42rem 0;
  border-bottom: 1px dashed var(--rule);
}
.jobcard-dl dt { color: var(--ink-mute); letter-spacing: 0.08em; text-transform: uppercase; font-size: 0.7rem; }
.jobcard-dl dd { margin: 0; color: var(--ink); word-break: break-word; }
.jobcard-drop { margin-top: 1.5rem; padding-top: 1.2rem; border-top: 2px solid var(--ink); }
.jobcard-drop address { font-family: var(--f-mono); font-size: 0.85rem; margin-top: 0.5rem; line-height: 1.6; }
.jobcard-hours { font-size: 0.82rem; color: var(--ink-mute); margin-top: 0.6rem; }
.jobcard .term-note { color: var(--ink-mute); border-left-color: var(--red); }
.jobcard .btn { margin-top: 1.3rem; }

/* --- CTA strip ------------------------------------------------------------ */

.cta-in {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.8rem;
  min-width: 0;
}
.cta-txt { min-width: 0; }
.cta-txt h2 {
  font-size: clamp(1.7rem, 4vw, 2.6rem);
  font-weight: 800;
  font-variation-settings: "wdth" 88;
  letter-spacing: -0.03em;
}
.cta-txt p { margin: 0.7rem 0 0; }
.cta-hours { font-family: var(--f-mono); font-size: 0.76rem; letter-spacing: 0.06em; }
.cta-acts { display: flex; flex-wrap: wrap; gap: 0.8rem; }

/* --- Related -------------------------------------------------------------- */

.rel { background: var(--paper-2); }

/* --- 404 ------------------------------------------------------------------ */

.notfound { min-height: 58vh; display: flex; align-items: center; }
.nf-code { margin-bottom: 1.2rem; }
.nf-links { list-style: none; display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 2rem; }
.nf-tel { margin-top: 1.6rem; }

/* --- Footer --------------------------------------------------------------- */

.ftr {
  background: var(--dark);
  color: var(--on-dark);
  border-top: 3px solid var(--red-dark);
  position: relative;
  isolation: isolate;
}
.ftr::before {
  content: "";
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  opacity: 0.5;
  background-image: repeating-linear-gradient(
    to bottom, rgba(243, 240, 233, 0.028) 0 1px, transparent 1px 3px);
}
.ftr-in {
  width: min(100% - (var(--gut) * 2), var(--wrap));
  margin-inline: auto;
  padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
  min-width: 0;
}
.ftr-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 2.2rem 1.8rem;
  min-width: 0;
}
.ftr-col { min-width: 0; }
.ftr-col h2 {
  font-family: var(--f-mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--on-dark-dim);
  margin-bottom: 1rem;
  font-weight: 500;
}
.ftr-col ul { list-style: none; display: grid; gap: 0.5rem; }
.ftr-col a { text-decoration: none; font-size: 0.92rem; color: var(--on-dark-mute); }
.ftr-col a:hover { color: var(--red-dark); }
.ftr-addr { font-size: 0.92rem; line-height: 1.65; color: var(--on-dark-mute); }
.ftr-addr .tel { color: var(--on-dark); display: inline-block; margin-top: 0.5rem; }
.ftr-hours { font-size: 0.84rem; color: var(--on-dark-dim); margin: 0.9rem 0 1.2rem; }
.ftr-telnote, .contact-telnote {
  display: block;
  font-family: var(--f-mono);
  font-size: 0.64rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-dark-dim);
  margin-top: 0.25rem;
}
.ftr-addr .tel-alt { display: inline-block; margin-top: 0.5rem; opacity: 0.8; }
.contact-alt { font-size: 0.92rem; color: var(--on-dark-mute); margin: 0.9rem 0 0; }
.contact-hours + .contact-hours { margin-top: 0.4rem; }

/* The data plate. Machine output, so it is monospace. */
.plate {
  margin: 2.8rem 0 0;
  border: 1px solid var(--dark-rule);
  font-family: var(--f-mono);
  font-size: 0.72rem;
  min-width: 0;
}
.plate-row {
  display: grid;
  grid-template-columns: minmax(0, 5.5rem) minmax(0, 1fr);
  gap: 0.2rem 1rem;
  padding: 0.55rem 0.9rem;
  border-bottom: 1px solid var(--dark-rule);
  min-width: 0;
}
.plate-row:last-child { border-bottom: 0; }
.plate dt { color: var(--on-dark-dim); letter-spacing: 0.12em; }
.plate dd { margin: 0; color: var(--on-dark-mute); word-break: break-word; }

.ftr-base {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--dark-rule);
  display: grid;
  gap: 0.9rem;
}
.ftr-note { font-size: 0.82rem; color: var(--on-dark-dim); max-width: 62ch; margin: 0; }
.ftr-legal { font-size: 0.8rem; color: var(--on-dark-dim); margin: 0; }
.ftr-legal a { text-decoration: none; margin-left: 0.9rem; }
.ftr-legal a:hover { color: var(--red-dark); }

/* --- Entrances -----------------------------------------------------------
   Elements travel, settle and stop. Transform and opacity only, so nothing
   here can trigger layout.
   ------------------------------------------------------------------------- */

/* Every family gets its OWN entrance rather than one generic fade-up, because
   a single reused motion is what makes a page read as a template. All of them
   move transform and opacity only, so none can trigger layout and none can
   cost a point of CLS.

   These are scroll TRIGGERED, not scroll scrubbed. Nothing here pins the page,
   nothing sits on a tall track, and the page scrolls completely normally
   throughout. A sticky stage that swallows three screens of scrolling reads as
   a broken page, not as a feature. */

.js .reveal { --sd: calc(var(--i, 0) * 60ms); }

.js .reveal.in {
  transition:
    opacity 420ms var(--e-out) var(--sd, 0ms),
    transform 560ms var(--e-latch) var(--sd, 0ms);
}

/* Retire the stagger once the entrance has played, or every later hover on the
   staggered siblings keeps paying the delay forever. Three classes plus
   !important, so it beats the nth-child and inline --i rules it retires. */
.js .reveal.in.settled {
  --sd: 0ms !important;
  transition-delay: 0ms !important;
}

/* (a) Rise and latch. Cards and blocks: travel up, overshoot slightly, stop
       hard, the way a latch closes. */
.js .rv-rise { opacity: 0; transform: translateY(14px); }
.js .rv-rise.in { opacity: 1; transform: none; }

/* (b) Slide in from the left. List rows, which read as entries being stamped
       into a register one after another. */
.js .rv-slide { opacity: 0; transform: translateX(-18px); }
.js .rv-slide.in { opacity: 1; transform: none; }

/* (c) Process steps. The detent dot pops first (its own rule below), then the
       step's text arrives behind it, so the dot reads as the cause. */
.js .rv-step { opacity: 0; transform: translateY(12px); }
.js .rv-step.in { opacity: 1; transform: none; }
.js .psteps .rv-step.in {
  transition-delay: calc((var(--i, 0) * 90ms) + 120ms);
}
.js .psteps .rv-step.in.settled { transition-delay: 0ms !important; }

/* (d) Signs lists. The red rule draws out from the left, then the line follows
       it in. Two parts, one event. */
.js .rv-sign { opacity: 0; transform: translateX(-10px); }
.js .rv-sign.in { opacity: 1; transform: none; }
.js .rv-sign::before {
  transform: scaleX(0);
  transform-origin: left center;
}
.js .rv-sign.in::before {
  transform: scaleX(1);
  transition: transform 420ms var(--e-settle) calc(var(--sd, 0ms) + 90ms);
}

/* (e) The answer block. Its rule draws down the left edge like a margin mark
       being ruled in, and the paragraph settles after it. */
.js .rv-answer > p { opacity: 0; transform: translateY(8px); }
.js .rv-answer.in > p {
  opacity: 1;
  transform: none;
  transition: opacity 460ms var(--e-out) 160ms, transform 520ms var(--e-settle) 160ms;
}
.js .rv-answer::before {
  transform: scaleY(0);
  transform-origin: top center;
}
.js .rv-answer.in::before {
  transform: scaleY(1);
  transition: transform 620ms var(--e-settle);
}

/* The counting number. It ships with its final value in the markup, so it is
   correct without JavaScript; site.js locks the measured width before it
   resets to zero, so the count cannot shift anything sideways. */
.herit-num { font-variant-numeric: tabular-nums; }

/* --- Boot sequence --------------------------------------------------------
   Hidden by default. Only html.booting reveals it, and only the head script
   sets that, and only when motion is allowed, the connection is not saving
   data, and the session has not seen it. A visitor without JavaScript never
   gets a stuck overlay. It is fixed and reserves no space, so it cannot shift
   anything.
   Budget: gauges and lamps to 700ms, sweep to 1000ms, clear by 1150ms.
   ------------------------------------------------------------------------- */

.boot { display: none; }

html.booting .boot {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 300;
  background: var(--dark);
  animation: boot-out 180ms var(--e-out) 880ms both;
}

/* The page underneath fades up on its OWN timer rather than waiting for
   script. If boot.js never loads, or throws, the page still arrives at
   1160ms instead of staying blank forever. The overlay is fixed and the page
   is never scroll-locked, so a failure here costs a fade, not the site. */
html.booting body > *:not(.boot) {
  animation: page-in 260ms var(--e-out) 900ms both;
}
html.boot-done .boot { display: none !important; }
html.boot-done body > *:not(.boot) {
  animation: none !important;
  opacity: 1 !important;
}

.boot-in {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  gap: 2rem;
  padding: var(--gut);
}
.boot-gauges { display: flex; gap: clamp(1.5rem, 6vw, 3.5rem); justify-content: center; }
.gauge { width: clamp(96px, 22vw, 140px); text-align: center; }
.gauge svg { display: block; width: 100%; height: auto; overflow: visible; }
.g-track, .g-fill { fill: none; stroke-width: 3; stroke-linecap: round; }
.g-track { stroke: var(--dark-rule); }
.g-fill {
  stroke: var(--red-dark);
  stroke-dasharray: 151 151;
  stroke-dashoffset: 151;
  animation: g-sweep 620ms var(--e-settle) 60ms both;
}
.g-needle {
  stroke: var(--on-dark);
  stroke-width: 2.5;
  stroke-linecap: round;
  transform-origin: 60px 68px;
  animation: g-needle 700ms var(--e-latch) 60ms both;
}
.g-services .g-fill { animation-delay: 150ms; }
.g-services .g-needle { animation-delay: 150ms; }
.g-hub { fill: var(--on-dark); }
.g-val {
  display: block;
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  font-weight: 800;
  font-variation-settings: "wdth" 86;
  letter-spacing: -0.03em;
  color: var(--on-dark);
  font-variant-numeric: tabular-nums;
  margin-top: 0.3rem;
  opacity: 0;
  animation: fade-in 220ms var(--e-out) 560ms both;
}
.g-label {
  display: block;
  font-family: var(--f-mono);
  font-size: 0.56rem;
  letter-spacing: 0.13em;
  color: var(--on-dark-dim);
  margin-top: 0.35rem;
  opacity: 0;
  animation: fade-in 220ms var(--e-out) 620ms both;
}

.boot-lamps { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; }
.lamp {
  font-family: var(--f-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--dark-rule);
  color: var(--dark-rule);
  animation: lamp 560ms steps(1, end) calc(120ms + (var(--i) * 52ms)) both;
}

.boot-sweep {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    transparent 0 calc(50% - 2px),
    var(--red-dark) calc(50% - 2px) calc(50% + 2px),
    transparent calc(50% + 2px) 100%
  );
  opacity: 0;
  animation: sweep 320ms linear 700ms both;
}

@keyframes g-sweep { from { stroke-dashoffset: 151; } to { stroke-dashoffset: 38; } }
@keyframes g-needle { from { transform: rotate(-90deg); } to { transform: rotate(45deg); } }
@keyframes fade-in { to { opacity: 1; } }
@keyframes lamp {
  0% { color: var(--dark-rule); border-color: var(--dark-rule); }
  30% { color: var(--red-dark); border-color: var(--red-dark); }
  99% { color: var(--red-dark); border-color: var(--red-dark); }
  100% { color: var(--dark-rule); border-color: var(--dark-rule); }
}
@keyframes sweep {
  0% { opacity: 0; transform: translateY(-52%) scaleY(1); }
  12% { opacity: 1; }
  88% { opacity: 1; }
  100% { opacity: 0; transform: translateY(52%) scaleY(1); }
}
@keyframes boot-out { to { opacity: 0; } }
@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }

/* --- Map ------------------------------------------------------------------ */

.map iframe { background: var(--paper-3); }

/* --- Paused animations ----------------------------------------------------
   animation-play-state does not inherit, so it has to be set on every element
   and pseudo-element or it silently misses the nested ones.
   ------------------------------------------------------------------------- */

body.paused *,
body.paused *::before,
body.paused *::after { animation-play-state: paused !important; }

/* --- Reduced motion -------------------------------------------------------
   Everything collapses to instant state changes, and the result has to look
   intentional rather than broken. Final states are shown, not hidden.
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  /* html.ready is more specific than a bare html selector, and a media
     query adds no specificity, so the .ready form has to be named here
     or smooth scrolling survives a visitor turning reduced motion on
     after the page has loaded. */
  html, html.ready { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }

  /* Final states, shown. Pseudo-elements included: a blanket rule on the
     element itself never reaches ::before, and the drawn rules would stay at
     scale zero, which looks broken rather than still. */
  .rule-h::before { transform: scaleX(1); }
  .js .reveal,
  .js .rv-rise, .js .rv-slide, .js .rv-step, .js .rv-sign,
  .js .rv-answer > p { opacity: 1; transform: none; }
  .js .rv-sign::before { transform: scaleX(1); }
  .js .rv-answer::before { transform: scaleY(1); }
  /* The cutaway is left exactly as it ships: every stroke drawn, every part in
     place, no labels. cutaway.js does not arm under reduced motion and clears
     anything it already set, so there is nothing to override here. */
  .psteps .pstep::after { transform: scale(1); opacity: 1; }
  .boot { display: none !important; }
  html.booting body > *:not(.boot) { animation: none !important; opacity: 1 !important; }
}

/* --- Short screens --------------------------------------------------------
   Decorations with no room hide rather than collide.
   ------------------------------------------------------------------------- */

@media (max-height: 560px) {
  .cut-hint { display: none; }
  .boot-lamps { display: none; }
}

/* --- Print ---------------------------------------------------------------- */

@media print {
  .hdr, .ftr, .cut, .boot, .skip, .cta-strip { display: none; }
  body { background: #fff; color: #000; }
  body::before { display: none; }
}
