/* =============================================================================
   Lion Collision Center — design system
   Direction: A · Night Concierge (chosen 2026-08-11 from _ds-candidates.html)

   Every page wraps its content in <div class="pb-scope"> and links this file.
   Never inline these rules into a page; never redeclare a token locally.

   Sections:  TOKENS  →  BASE  →  COMPONENTS
   COMPONENTS holds section CSS for built pages (pages themselves stay clean HTML).
   `extract-to-library` later promotes stable parts of it into reusable blocks.
   ============================================================================= */


/* =============================================================================
   FONT FALLBACKS — metric-matched stand-ins for Manrope while the web font loads
   Google Fonts serves Manrope with display=swap. Until it arrives the text is set in a system font of
   another width, and the swap re-wraps the page: on a phone the estimate form jumped ~550 px under the
   visitor's finger (CLS 0.13). These faces take Arial (Windows, macOS, iOS; Liberation Sans on Linux) or
   Roboto (Android) and scale them to Manrope's width and vertical metrics per weight band, so the swap barely
   moves anything (measured on a phone: form shift 567 px → 0, CLS 0.13 → 0.001). size-adjust = median width
   ratio Manrope / fallback measured on these landings' own headlines, paragraphs and buttons (2026-10-04;
   generic averages from @capsizecss/metrics were ~1% too wide and made headlines re-wrap);
   ascent/descent-override = Manrope's 2132/600 per 2000 units divided by that size-adjust.
   They follow the --font-display / --font-body stacks below — keep the names there in that order.
   ============================================================================= */

@font-face {
  font-family: "Manrope Fallback";
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans");
  font-weight: 100 450;
  size-adjust: 101.92%;
  ascent-override: 104.59%;
  descent-override: 29.43%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Manrope Fallback";
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans");
  font-weight: 451 650;
  size-adjust: 103.68%;
  ascent-override: 102.82%;
  descent-override: 28.94%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Manrope Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  font-weight: 651 750;
  size-adjust: 100.86%;
  ascent-override: 105.69%;
  descent-override: 29.74%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Manrope Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  font-weight: 751 900;
  size-adjust: 101.92%;
  ascent-override: 104.59%;
  descent-override: 29.43%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Manrope Fallback Android";
  src: local("Roboto"), local("Roboto-Regular"), local("Roboto Regular");
  font-weight: 100 450;
  size-adjust: 102.71%;
  ascent-override: 103.79%;
  descent-override: 29.21%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Manrope Fallback Android";
  src: local("Roboto Medium"), local("Roboto-Medium");
  font-weight: 451 650;
  size-adjust: 103.64%;
  ascent-override: 102.86%;
  descent-override: 28.95%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Manrope Fallback Android";
  src: local("Roboto Bold"), local("Roboto-Bold");
  font-weight: 651 750;
  size-adjust: 107.88%;
  ascent-override: 98.81%;
  descent-override: 27.81%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Manrope Fallback Android";
  src: local("Roboto Bold"), local("Roboto-Bold");
  font-weight: 751 900;
  size-adjust: 108.02%;
  ascent-override: 98.69%;
  descent-override: 27.77%;
  line-gap-override: 0%;
}


/* =============================================================================
   TOKENS
   ============================================================================= */

.pb-scope {
  /* ---- Core six ---------------------------------------------------------- */
  --bg:        #08090B;   /* page canvas, near-black                          */
  --surface:   #101114;   /* cards, panels — one step above the canvas        */
  --fg:        #FFFFFF;   /* headings and primary text                        */
  --muted:     #9BA0A8;   /* body copy, captions — cool grey, never pure white */
  --border:    rgba(255, 255, 255, .08);
  --accent:    #2E7DFF;   /* trust / engineering: eyebrows, links, icon chips  */

  /* ---- Second accent role ------------------------------------------------ */
  /* Amber is ACTION only: the primary button and nothing else.               */
  --action:    #FFC23C;
  --action-fg: #12130F;   /* text on amber                                    */

  /* ---- Derived surfaces -------------------------------------------------- */
  --surface-2:      #0B0C0F;                 /* inputs, wells — below canvas  */
  --surface-hover:  #16171B;
  --border-strong:  rgba(255, 255, 255, .16);
  /* The visible EDGE of an interactive control (outline button, input, checkbox).
     --border is a decorative hairline at ~1.2:1 — fine between a card and the
     canvas, but a control the user must find needs 3:1 (WCAG 1.4.11). This grey
     clears it on both surfaces: 3.56:1 on --bg, 3.38:1 on --surface.           */
  --border-control: #636873;
  /* White on --accent is only 3.82:1. Any blue that FILLS a control uses this
     darkened step instead: white on it clears AA at 4.78:1.                  */
  --accent-deep:    #286EE0;
  --accent-soft:    rgba(46, 125, 255, .16); /* icon chip fill                */
  --accent-line:    rgba(46, 125, 255, .30); /* seal / highlighted border     */
  --accent-wash:    linear-gradient(90deg, rgba(46,125,255,.20), rgba(46,125,255,.02));

  /* ---- Status ------------------------------------------------------------ */
  --ok:      #4ADE80;
  --warn:    #FFC23C;
  --danger:  #FF5C5C;

  /* ---- Type -------------------------------------------------------------- */
  --font-display: "Manrope", "Manrope Fallback", "Manrope Fallback Android", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:    "Manrope", "Manrope Fallback", "Manrope Fallback Android", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Mono is an extension beyond the chosen candidate: use it only for
     figures, codes and short technical labels — never for body copy.        */
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --w-body:    400;
  --w-medium:  500;
  --w-bold:    700;
  --w-display: 800;

  /* Fluid display scale — the hero headline is the only step-1 use.          */
  --fs-d1:   clamp(38px, 4.4vw, 60px);
  --fs-d2:   clamp(30px, 3.2vw, 44px);
  --fs-h3:   22px;
  --fs-lead: 16.5px;
  --fs-body: 15px;
  --fs-sm:   13.5px;
  --fs-xs:   12.5px;
  --fs-eyebrow: 11.5px;

  --lh-display: 1.03;
  --lh-heading: 1.12;
  --lh-body:    1.6;

  --tr-display: -.035em;  /* tight — display weight needs it                  */
  --tr-heading: -.02em;
  --tr-eyebrow:  .2em;    /* uppercase accent labels                          */

  /* ---- Space (4px base) --------------------------------------------------- */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  22px;
  --sp-6:  30px;
  --sp-7:  40px;
  --sp-8:  56px;
  --sp-9:  80px;
  --sp-section: clamp(56px, 7vw, 96px);
  --maxw: 1240px;

  /* ---- Radius ------------------------------------------------------------ */
  --r-sm:   10px;
  --r-md:   14px;   /* chips, small cards                                     */
  --r:      20px;   /* the system radius: cards, panels, media                */
  --r-lg:   24px;
  --r-pill: 999px;  /* every button                                           */

  /* ---- Elevation --------------------------------------------------------- */
  --shadow-sm:     0 1px 2px rgba(0, 0, 0, .40);
  --shadow-card:   0 18px 40px rgba(0, 0, 0, .45);
  --shadow-action: 0 12px 26px rgba(255, 194, 60, .22);
  --shadow-accent: 0 12px 26px rgba(46, 125, 255, .26);

  /* ---- Motion ------------------------------------------------------------ */
  --ease: cubic-bezier(.2, .7, .25, 1);
  --dur:  .18s;
  --dur-slow: .32s;
}


/* =============================================================================
   BASE — scoped reset, typography and UI primitives
   ============================================================================= */

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

.pb-scope {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: var(--w-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

.pb-scope h1, .pb-scope h2, .pb-scope h3, .pb-scope h4 {
  text-wrap: balance;
  font-family: var(--font-display);
  font-weight: var(--w-display);
  line-height: var(--lh-heading);
  letter-spacing: var(--tr-heading);
  color: var(--fg);
  margin: 0 0 var(--sp-4);
}
.pb-scope h1 { font-size: var(--fs-d1); line-height: var(--lh-display); letter-spacing: var(--tr-display); }
.pb-scope h2 { font-size: var(--fs-d2); letter-spacing: var(--tr-display); }
.pb-scope h3 { font-size: var(--fs-h3); }
.pb-scope p  { margin: 0 0 var(--sp-4); color: var(--muted); }
/* Reading measure, applied to every paragraph rather than to an enumerated list of
   parents — max-width only ever constrains, so prose already sitting in a narrow
   grid column is unaffected. Manrope's `ch` (the "0" glyph) is far wider than its
   average character, so 55ch lands at ~70 real characters, which is the target band.
   Declared BEFORE .lead so the tighter lead measure wins at equal specificity. */
.pb-scope p,
.pb-scope .clist li,
.pb-scope .contrast__list li { max-width: 55ch; }
.pb-scope p.lead { font-size: var(--fs-lead); max-width: 46ch; }
/* Full-bleed exceptions: these are layout, not prose. */
.pb-scope .record__figure,
.pb-scope .icon-strip__item,
.pb-scope .terms__item { max-width: none; }
.pb-scope strong { color: var(--fg); font-weight: var(--w-bold); }
.pb-scope a { color: var(--accent); text-decoration: none; }
.pb-scope a:hover { text-decoration: underline; }

/* `hidden` must win over any display rule a component sets. */
.pb-scope [hidden] { display: none !important; }

.pb-scope :focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ---- Layout ------------------------------------------------------------- */
.pb-scope .container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--sp-5); }
.pb-scope .section   { padding-block: var(--sp-section); }

/* ---- Eyebrow ------------------------------------------------------------- */
/* Use sparingly — at most one per screen. Blue caps, never amber.           */
.pb-scope .eyebrow {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  color: var(--accent);
  font-size: var(--fs-eyebrow); font-weight: var(--w-bold);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase;
  margin-bottom: var(--sp-3);
}

/* ---- Buttons ------------------------------------------------------------- */
.pb-scope .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 44px; padding: 11px 22px;
  border: 1px solid transparent; border-radius: var(--r-pill);
  font-family: inherit; font-size: 14.5px; font-weight: var(--w-bold);
  cursor: pointer; text-decoration: none;
  max-width: 100%; text-align: center; text-wrap: balance;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}
.pb-scope .btn:hover { transform: translateY(-1px); text-decoration: none; }
.pb-scope .btn:active { transform: translateY(0); }

/* Primary = amber. One per screen. */
.pb-scope .btn--primary { background: var(--action); color: var(--action-fg); box-shadow: var(--shadow-action); }
.pb-scope .btn--primary:hover { background: #FFCD5E; box-shadow: 0 16px 32px rgba(255,194,60,.30); }

/* Secondary = blue fill. Trust, not action — so it may share a screen with the
   amber primary without competing with it. Fills with --accent-deep, never with
   raw --accent: white on the raw token is 3.82:1 and fails AA. */
.pb-scope .btn--secondary {
  background: var(--accent-deep);
  color: #fff; box-shadow: var(--shadow-accent);
}
/* Hover DARKENS. Lightening blue towards --accent would drop white text to
   3.82:1 — a hover state is a state, and AA applies to it too. */
.pb-scope .btn--secondary:hover { background: #2263C9; box-shadow: 0 16px 32px rgba(46,125,255,.34); }

/* A ghost button on a near-black canvas is found by its EDGE, not by its fill:
   no fill one step above the canvas can reach 3:1 without turning mid-grey and
   competing with the primary. So the outline carries the control and the fill
   only separates it from the page. */
.pb-scope .btn--ghost {
  background: var(--surface);
  color: var(--fg);
  border-color: var(--border-control);
}
.pb-scope .btn--ghost:hover { background: var(--surface-hover); border-color: #8A9099; }

.pb-scope .btn[disabled] { opacity: .45; pointer-events: none; transform: none; box-shadow: none; }

/* Anything that follows a hard edge — the last rule of a .spec-table, the bottom
   of a .card / .contact-card, the closing border of a .contrast or .reviews-grid
   panel, a divider — has nothing pushing it away: `p` only carries a BOTTOM
   margin, so the element ends up glued to the block above it.
   `.btn--spaced` restores that breathing room on a button (use it on the button,
   not a wrapper). `.spaced` is its element-agnostic twin, for the sentence that
   remarks on the panel it follows. One step, one source of truth. */
.pb-scope .btn--spaced,
.pb-scope .spaced { margin-top: var(--sp-6); }

/* ---- Card ---------------------------------------------------------------- */
.pb-scope .card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: var(--sp-5);
}
.pb-scope .card--flat { box-shadow: none; }
.pb-scope .card--raised { box-shadow: var(--shadow-card); }

/* Compact fact chip — the 2×2 grid under the hero headline. */
.pb-scope .chip {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 13px 15px;
  font-size: var(--fs-sm); font-weight: 600; line-height: 1.35;
  color: var(--fg);
}
/* Icon plate inside a chip or card. Blue wash, never amber. */
.pb-scope .icon-plate svg { width: 15px; height: 15px; display: block; }
.pb-scope .chip__icon,
.pb-scope .icon-plate {
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border-radius: var(--r-sm);
  background: var(--accent-soft);
  color: var(--accent);
  margin-bottom: var(--sp-2);
}

/* ---- Seal — the highlighted guarantee strip ------------------------------ */
.pb-scope .seal {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 14px 18px;
  border: 1px solid var(--accent-line);
  border-radius: var(--r-md);
  background: var(--accent-wash);
}
/* The seal is a highlighted strip, so it never butts against the copy under it. */
.pb-scope .seal:not(:last-child) { margin-bottom: var(--sp-5); }
.pb-scope .seal__mark { flex: none; width: 34px; height: 34px; border-radius: 50%; border: 2px solid var(--accent); }
.pb-scope .seal__title { display: block; font-size: 14.5px; font-weight: var(--w-bold); color: var(--fg); }
.pb-scope .seal__note  { display: block; font-size: var(--fs-xs); color: var(--muted); }

/* ---- Form controls ------------------------------------------------------- */
.pb-scope .field { display: block; margin-bottom: var(--sp-4); }
.pb-scope .field__label { display: block; font-size: var(--fs-sm); font-weight: 600; margin-bottom: var(--sp-2); color: var(--fg); }
.pb-scope .input,
.pb-scope .textarea,
.pb-scope .select {
  width: 100%; min-height: 44px;
  background: var(--surface-2);
  /* An input's fill is a step BELOW its card, so the fill alone can never mark
     it out — the border is the only thing telling the user where to type. */
  border: 1px solid var(--border-control);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  color: var(--fg);
  font-family: inherit; font-size: 14px;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.pb-scope .input::placeholder,
.pb-scope .textarea::placeholder { color: var(--muted); }
.pb-scope .input:focus,
.pb-scope .textarea:focus,
.pb-scope .select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.pb-scope .textarea { min-height: 108px; resize: vertical; }

/* The native file button ships light, square and state-less — the only such control
   on the page. Restyle it into the system instead of leaving the OS default. */
.pb-scope input[type="file"] { padding: 8px 10px; cursor: pointer; }
.pb-scope input[type="file"]::file-selector-button {
  margin-right: var(--sp-3);
  border: 1px solid var(--border-control); border-radius: var(--r-pill);
  background: var(--surface); color: var(--fg);
  font-family: inherit; font-size: var(--fs-sm); font-weight: var(--w-bold);
  padding: 8px 16px; min-height: 36px; cursor: pointer;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.pb-scope input[type="file"]::file-selector-button:hover {
  background: var(--surface-hover); border-color: var(--border-strong);
}
.pb-scope .field__hint { font-size: var(--fs-xs); color: var(--muted); margin-top: var(--sp-2); }

/* ---- Media plate — used until real photography lands --------------------- */
.pb-scope .plate {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--r);
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 78% 12%, rgba(255,255,255,.10), transparent 60%),
    linear-gradient(150deg, #1b1d21 0%, #0e0f12 55%, #141519 100%);
}
/* The slot says what it is waiting for — an unlabelled dark rectangle reads as a bug. */
.pb-scope .plate::after {
  content: attr(data-slot);
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .18em;
  text-transform: uppercase; color: rgba(255, 255, 255, .34);
  text-align: center; padding: 0 var(--sp-4); max-width: 100%;
}

/* ---- Trust row ----------------------------------------------------------- */
.pb-scope .trust {
  display: flex; flex-wrap: wrap; gap: var(--sp-6);
  border-top: 1px solid var(--border);
  padding-top: var(--sp-4);
  color: var(--muted); font-size: var(--fs-sm);
}
.pb-scope .trust strong { color: var(--fg); }

/* ---- Utilities ----------------------------------------------------------- */
.pb-scope .mono { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: .04em; }
.pb-scope .muted { color: var(--muted); }
.pb-scope .nowrap { white-space: nowrap; }
.pb-scope .visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .pb-scope *, .pb-scope *::before, .pb-scope *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
  .pb-scope .btn:hover { transform: none; }
}

@media (max-width: 920px) {
  .pb-scope .container { padding-inline: var(--sp-4); }
  .pb-scope .trust { gap: var(--sp-4); }
}


/* =============================================================================
   COMPONENTS
   -----------------------------------------------------------------------------
   Section CSS for built pages. Authored during `page-builder-orchestrator`
   stage 7 because pages must stay clean HTML — there is no other legal place
   for it. `extract-to-library` later promotes the stable parts of this section
   into reusable blocks (`blocks/*.html` + `components.json`).

   First page: Directions/bmw/Result/index.html (2026-08-11).
   ============================================================================= */

/* ---- Build-time marker: content the client still owes us ----------------- */
/* Deliberately neutral, never amber — it must not compete with the CTA.      */
.pb-scope .req {
  display: block;
  margin: var(--sp-3) 0;
  padding: 10px 13px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 400;
  line-height: 1.5;
}
.pb-scope .req::before {
  content: "TO CONFIRM";
  display: block;
  font-family: var(--font-mono);
  font-size: 9.5px; letter-spacing: .16em;
  color: #8A9099;
  margin-bottom: 4px;
}

/* ---- Sticky header ------------------------------------------------------- */
.pb-scope .site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(8, 9, 11, .88);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.pb-scope .site-header__inner {
  display: flex; align-items: center; gap: var(--sp-5);
  min-height: 68px;
}
.pb-scope .brand {
  display: flex; flex-direction: column; justify-content: center;
  min-height: 44px; color: var(--fg); text-decoration: none;
}
.pb-scope .brand:hover { text-decoration: none; }
.pb-scope .brand__name {
  display: block; font-family: var(--font-display); font-weight: var(--w-display);
  font-size: 18px; letter-spacing: -.03em; line-height: 1.1;
}
.pb-scope .brand__sub {
  display: block; font-size: 8.5px; font-weight: 600;
  letter-spacing: .3em; text-transform: uppercase; color: var(--muted);
}
/* Horizontal lockup: shield mark + wordmark set in DS type */
.pb-scope .brand--lockup { flex-direction: row; align-items: center; gap: 11px; }
.pb-scope .brand__mark { display: block; height: 44px; width: auto; flex: none; }
.pb-scope .brand__text { display: flex; flex-direction: column; justify-content: center; }
.pb-scope .brand--lockup .brand__name { font-size: 21px; }
.pb-scope .brand--lockup .brand__sub { margin-top: 2px; }

.pb-scope .header-actions { display: flex; align-items: center; gap: var(--sp-3); margin-left: auto; }

/* ---- Header navigation ---------------------------------------------------- */
.pb-scope .site-nav { margin-inline: auto; }
.pb-scope .site-nav__list {
  display: flex; align-items: center; gap: var(--sp-2);
  list-style: none; margin: 0; padding: 0;
}
.pb-scope .site-nav__link {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 var(--sp-3);
  color: #D6D9DE; font-size: 14.5px; font-weight: 500;
  border-radius: var(--r-sm); text-decoration: none;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.pb-scope .site-nav__link:hover { color: var(--fg); background: var(--surface); text-decoration: none; }
.pb-scope .site-nav__link[aria-current="true"] { color: var(--fg); }

.pb-scope .header-phone {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--muted); font-size: var(--fs-sm); font-weight: 600; text-decoration: none;
}
.pb-scope .header-phone:hover { color: var(--fg); text-decoration: none; }

/* ---- Header menu: hamburger + drawer (tablet and phone only) -------------- */
/* The five-item nav is a desktop convenience; below 920px it moves behind a
   white hamburger that swaps to a close glyph while the panel is open. */
.pb-scope .nav-toggle {
  display: none;
  width: 44px; height: 44px; flex: none; padding: 0;
  align-items: center; justify-content: center;
  background: transparent; color: #fff; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.pb-scope .nav-toggle:hover { background: var(--surface); border-color: #3A3F47; }
/* Both glyphs are stacked in the same 22px cell at the centre of the button, so
   the swap happens in place — no reflow, no shift. Exactly one is ever visible.
   The `display` of each glyph is set only by the pair of rules below: a shared
   `.nav-toggle svg { display: … }` would outrank them on specificity and pin
   both glyphs visible, which is the failure this replaces. */
.pb-scope .nav-toggle__icons {
  position: relative; display: block; width: 22px; height: 22px; flex: none;
}
.pb-scope .nav-toggle svg { position: absolute; inset: 0; width: 22px; height: 22px; }
.pb-scope .nav-toggle .nav-toggle__open  { display: block; }
.pb-scope .nav-toggle .nav-toggle__close { display: none; }
.pb-scope .nav-toggle[aria-expanded="true"] .nav-toggle__open  { display: none; }
.pb-scope .nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

.pb-scope .nav-drawer {
  position: absolute; left: 0; right: 0; top: 100%;
  /* No backdrop-filter here: the panel sits inside the header, whose own
     backdrop-filter already closes the backdrop root, so the blur would be a
     no-op — and a second filtered layer on the sticky subtree is exactly what
     upsets sticky repainting in some engines. The fill is opaque anyway. */
  background: rgba(8, 9, 11, .98);
  border-bottom: 1px solid var(--border);
  /* +80px of panel height over the original 8/16 pair, split evenly so the
     items stay optically centred in the sheet rather than riding its top edge. */
  padding-block: calc(var(--sp-2) + 40px) calc(var(--sp-4) + 40px);
  box-shadow: 0 24px 48px rgba(0, 0, 0, .45);
}
.pb-scope .nav-drawer[hidden] { display: none; }
.pb-scope .nav-drawer__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column;
}
.pb-scope .nav-drawer__link {
  display: flex; align-items: center; min-height: 52px;
  color: #D6D9DE; font-size: 16px; font-weight: 500; text-decoration: none;
  border-bottom: 1px solid var(--border);
  transition: color var(--dur) var(--ease);
}
.pb-scope .nav-drawer__list li:last-child .nav-drawer__link { border-bottom: 0; }
.pb-scope .nav-drawer__link:hover { color: var(--fg); text-decoration: none; }
/* Phone + CTA live in the drawer only on a phone, where they leave the bar. */
.pb-scope .nav-drawer__foot { display: none; }
.pb-scope .nav-drawer__phone {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 16px;
  color: var(--fg); font-size: 16px; font-weight: 700; text-decoration: none;
  border: 1px solid var(--border); border-radius: var(--r-pill);
}
.pb-scope .nav-drawer__phone:hover { text-decoration: none; border-color: #3A3F47; }

/* The header is sticky, so a jump to an anchor would land the heading underneath
   it. Every id on the page keeps the header's height plus a breath of air clear. */
.pb-scope [id] { scroll-margin-top: calc(68px + var(--sp-5)); }

/* ---- Hero ---------------------------------------------------------------- */
.pb-scope .hero { padding-block: var(--sp-8) var(--sp-7); }
.pb-scope .hero__grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: var(--sp-6); align-items: stretch; }
.pb-scope .hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.pb-scope .hero__media { min-height: 420px; }

/* ---- Terms strip — icon-strip archetype ---------------------------------- */
.pb-scope .icon-strip {
  display: grid; grid-template-columns: repeat(4, 1fr);
  border-block: 1px solid var(--border);
}
.pb-scope .icon-strip__item {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-5) var(--sp-5) var(--sp-5) 0;
  font-size: var(--fs-sm); font-weight: 600; color: var(--muted); line-height: 1.4;
  margin: 0;
}
.pb-scope .icon-strip__item + .icon-strip__item { border-left: 1px solid var(--border); padding-left: var(--sp-5); }
.pb-scope .icon-strip .icon-plate { flex: none; width: 26px; height: 26px; margin-bottom: 0; }

/* ---- Scope grid — what the shop actually does, one card per discipline ----
   Cards sit one step above the canvas; the two disciplines that have their own
   section deeper in the page carry a quiet link down to it, so the row reads as
   a map of the page rather than a second telling of it. */
.pb-scope .scope-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-4); }
.pb-scope .scope-card { display: flex; flex-direction: column; }
/* Discipline cards carry the largest icon plate in the system — one glyph per
   card, so it can read as a marker rather than a chip decoration. */
.pb-scope .scope-card .icon-plate { width: 52px; height: 52px; }
.pb-scope .scope-card .icon-plate svg { width: 26px; height: 26px; stroke-width: 1.6; }
.pb-scope .scope-card h3 { font-size: 18px; line-height: 1.25; margin: 0 0 var(--sp-2); }
.pb-scope .scope-card p { font-size: var(--fs-sm); line-height: 1.5; margin: 0; }
.pb-scope .scope-card__more {
  margin-top: auto; padding-top: var(--sp-4);
  font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: .04em;
  color: var(--accent); text-decoration: none;
}
.pb-scope .scope-card__more:hover { text-decoration: underline; }

/* ---- Section head / body — heading holds the left rail, content runs right --- */
.pb-scope .sec { display: grid; grid-template-columns: minmax(260px, 1fr) 1.85fr; gap: var(--sp-7); align-items: start; }
.pb-scope .sec__head { position: sticky; top: calc(68px + var(--sp-6)); }
.pb-scope .sec__head h2 { margin-bottom: var(--sp-3); }
.pb-scope .sec__head .lead { margin-bottom: 0; }
.pb-scope .sec__body > *:first-child { margin-top: 0; }

/* ---- Checklist ------------------------------------------------------------ */
.pb-scope .clist { list-style: none; margin: 0 0 var(--sp-4); padding: 0; }
.pb-scope .clist li {
  position: relative; padding-left: 26px; margin-bottom: var(--sp-3);
  font-size: var(--fs-sm); color: var(--muted);
}
.pb-scope .clist li::before {
  content: ""; position: absolute; left: 0; top: 4px;
  width: 14px; height: 8px; border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

/* ---- Stepper (process) ---------------------------------------------------- */
.pb-scope .steps { counter-reset: st; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }
.pb-scope .steps__item {
  counter-increment: st;
  padding-top: var(--sp-4); border-top: 2px solid var(--accent);
}
.pb-scope .steps__item::before {
  content: counter(st, decimal-leading-zero);
  display: block; font-family: var(--font-mono); font-size: var(--fs-xs);
  color: var(--accent); margin-bottom: var(--sp-2);
}
.pb-scope .steps__item h3 { font-size: 17px; margin-bottom: 6px; }
.pb-scope .steps__item p { font-size: var(--fs-sm); margin: 0; }
.pb-scope .steps + p { margin-top: var(--sp-6); }

/* ---- Statement band -------------------------------------------------------- */
.pb-scope .band {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface);
  padding: var(--sp-7);
}
.pb-scope .band__grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: var(--sp-7); align-items: center; }
.pb-scope .band h2 { margin-bottom: var(--sp-3); }

/* ---- Contact card ---------------------------------------------------------- */
.pb-scope .contact-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); padding: var(--sp-5);
}

/* ---- The record (rating) — stat-band archetype ---------------------------- */
.pb-scope .stat-band__grid,
.pb-scope .record__grid { display: grid; grid-template-columns: .8fr 1.2fr; gap: var(--sp-7); align-items: start; }
.pb-scope .record__figure {
  font-family: var(--font-display); font-weight: var(--w-display);
  font-size: clamp(64px, 8vw, 108px); line-height: .9; letter-spacing: -.05em;
}
/* Stars are SVG: U+2605 is absent from Manrope and rendered as tofu. */
.pb-scope .record__stars { display: flex; gap: 5px; margin-top: var(--sp-3); }
.pb-scope .record__stars svg { width: 19px; height: 19px; fill: #FFC23C; }
.pb-scope .record__window { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); margin-top: var(--sp-3); }
.pb-scope .dist__caption { font-size: var(--fs-xs); margin-bottom: var(--sp-2); letter-spacing: .1em; text-transform: uppercase; }
.pb-scope .dist { display: grid; gap: 7px; margin-bottom: var(--sp-5); }
.pb-scope .dist__row { display: grid; grid-template-columns: 40px 1fr 34px; align-items: center; gap: var(--sp-3); }
.pb-scope .dist__label,
.pb-scope .dist__count { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--muted); }
.pb-scope .dist__count { text-align: right; }
.pb-scope .dist__track { height: 8px; border-radius: var(--r-pill); background: var(--surface); overflow: hidden; }
.pb-scope .dist__fill { display: block; height: 100%; border-radius: var(--r-pill); background: var(--accent); }
.pb-scope .tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-5); }
.pb-scope .tag {
  border: 1px solid var(--border); border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .07);
  padding: 5px 12px; font-size: var(--fs-xs); color: var(--muted);
}
.pb-scope .tag b { color: var(--fg); font-weight: var(--w-bold); }

/* ---- Quotes -------------------------------------------------------------- */
.pb-scope .quotes { display: grid; gap: var(--sp-4); }
.pb-scope .quotes--two,
.pb-scope .reviews-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.pb-scope .quote {
  margin: 0; padding: var(--sp-5);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
}
.pb-scope .quote p { color: var(--muted); font-size: var(--fs-sm); line-height: 1.62; margin: 0 0 var(--sp-3); }
.pb-scope .quote footer { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

/* ---- Estimate checklist table -------------------------------------------- */
.pb-scope .spec-table { width: 100%; border-collapse: collapse; }
.pb-scope .spec-table th,
.pb-scope .spec-table td { text-align: left; padding: var(--sp-4) var(--sp-4) var(--sp-4) 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.pb-scope .spec-table thead th {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
  padding-block: var(--sp-2);
}
.pb-scope .spec-table tbody th { width: 34%; color: var(--fg); font-weight: var(--w-bold); font-size: var(--fs-sm); }
.pb-scope .spec-table td { color: var(--muted); font-size: var(--fs-sm); }

/* ---- Split (media + copy) ------------------------------------------------ */
.pb-scope .split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-7); align-items: center; }
.pb-scope .split--media-first .split__media { order: -1; }
.pb-scope .split__media { min-height: 320px; }

/* ---- Chip row (ADAS scope) ------------------------------------------------ */
.pb-scope .chiprow { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.pb-scope .chiprow .chip { flex: 1 1 190px; }

/* ---- Contrast columns (is / is not) --------------------------------------- */
.pb-scope .contrast { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); }
.pb-scope .contrast__col { padding: var(--sp-5); border: 1px solid var(--border); border-radius: var(--r); background: var(--surface); }
.pb-scope .contrast__col--neg { background: transparent; }
.pb-scope .contrast__title {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 var(--sp-3);
}
/* The negative column is the twin of .clist, so it copies its metrics exactly —
   same 26px indent, same 14px mark — and changes only what carries the meaning:
   a cross instead of a tick, grey instead of blue. A hollow ring was doing the
   job before, at 1.6:1 against the canvas, and it read as an EMPTY CHECKBOX —
   the one thing this column must not suggest. The cross is --danger red so the
   boundary of the offer reads at a glance; the text stays --muted so the column
   never shouts louder than the positive one. */
.pb-scope .contrast__list { list-style: none; margin: 0; padding: 0; }
.pb-scope .contrast__list li {
  position: relative; padding-left: 26px; margin-bottom: var(--sp-3);
  font-size: var(--fs-sm); color: var(--muted);
}
.pb-scope .contrast__list li::before,
.pb-scope .contrast__list li::after {
  content: ""; position: absolute; left: 1px; top: 10px;
  width: 13px; height: 2px; border-radius: 1px; background: var(--danger);
}
.pb-scope .contrast__list li::before { transform: rotate(45deg); }
.pb-scope .contrast__list li::after  { transform: rotate(-45deg); }

/* ---- Lead form ------------------------------------------------------------ */
.pb-scope .leadform { display: grid; grid-template-columns: 1.1fr .9fr; gap: var(--sp-7); }
.pb-scope .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.pb-scope .form-grid .field--wide { grid-column: 1 / -1; }
.pb-scope .form-note { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.pb-scope .form-note li { position: relative; padding-left: 20px; margin-bottom: var(--sp-2); font-size: var(--fs-xs); color: var(--muted); }
.pb-scope .form-note li::before { content: ""; position: absolute; left: 0; top: 7px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
/* Privacy fine print beside the form — legal, not sales copy. */
.pb-scope .form-privacy { font-size: var(--fs-xs); line-height: 1.55; color: var(--muted); max-width: 55ch; margin-top: var(--sp-5); }

/* ---- Consent block (SMS opt-in) ------------------------------------------- */
.pb-scope .consent { border-top: 1px solid var(--border); margin-top: var(--sp-5); padding-top: var(--sp-4); }
.pb-scope .consent__head { display: flex; align-items: baseline; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.pb-scope .consent__title {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); margin: 0;
}
/* ---- Disclosure — reusable show/hide for optional content ------------------ */
.pb-scope .disclosure { margin-top: var(--sp-4); }
.pb-scope .disclosure__toggle {
  background: none; border: 0;
  padding: 11px 0; min-height: 44px;
  color: var(--accent); font-family: inherit; font-size: var(--fs-xs); font-weight: 600;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
  transition: color var(--dur) var(--ease);
}
.pb-scope .disclosure__toggle:hover { color: #5C99FF; }
.pb-scope .disclosure__panel[hidden] { display: none; }
.pb-scope .disclosure__panel .field:last-child { margin-bottom: 0; }
/* Inside the consent header the toggle sits on the right of the label row. */
.pb-scope .consent__head .disclosure__toggle { margin-left: auto; }

.pb-scope .consent__opt { display: grid; grid-template-columns: 24px 1fr; gap: var(--sp-3); margin-bottom: var(--sp-2); }
.pb-scope .consent__opt input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 24px; height: 24px; margin: 10px 0 0;
  border: 1px solid var(--border-control); border-radius: 6px;
  background: var(--surface-2); cursor: pointer; flex: none;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.pb-scope .consent__opt input[type="checkbox"]:hover { border-color: var(--accent); }
.pb-scope .consent__opt input[type="checkbox"]:checked {
  background: var(--accent); border-color: var(--accent);
  /* check mark drawn, not a font glyph */
  background-image: linear-gradient(45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%),
                    linear-gradient(-45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%);
  background-size: 13px 2px, 7px 2px;
  background-position: 8px 13px, 5px 12px;
  background-repeat: no-repeat;
}
/* The checkbox itself is 24px (WCAG 2.5.8 AA); the label is the generous target
   for the same control, so the pair is comfortable without a clumsy 44px box. */
.pb-scope .consent__label {
  display: block; padding-block: 12px;
  font-size: var(--fs-sm); font-weight: 600; color: var(--fg); cursor: pointer; max-width: 55ch;
}
.pb-scope .consent__detail { display: block; margin-top: var(--sp-2); font-size: var(--fs-xs); font-weight: 400; color: var(--muted); line-height: 1.55; }
.pb-scope .consent__detail[hidden] { display: none; }
.pb-scope .consent { margin-top: var(--sp-5); }
.pb-scope .consent__legal { font-size: var(--fs-xs); color: var(--muted); line-height: 1.55; margin: var(--sp-4) 0 0; max-width: 55ch; }
/* Submit sits clear of the legal copy above it, not glued to the last line. */
.pb-scope .leadform form > .btn[type="submit"] { margin-top: var(--sp-6); }

/* ---- Handover list -------------------------------------------------------- */
.pb-scope .handover { counter-reset: ho; display: grid; gap: var(--sp-4); }
.pb-scope .handover__item {
  counter-increment: ho;
  display: grid; grid-template-columns: 44px 1fr; gap: var(--sp-4);
  padding-bottom: var(--sp-4); border-bottom: 1px solid var(--border);
}
.pb-scope .handover__item::before {
  content: counter(ho, decimal-leading-zero);
  font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--accent);
  padding-top: 3px;
}
.pb-scope .handover__item h3 { font-size: 16px; margin-bottom: 6px; }
.pb-scope .handover__item p { margin: 0; font-size: var(--fs-sm); }

/* ---- Gallery -------------------------------------------------------------- */
.pb-scope .gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }
.pb-scope .gallery__item { display: grid; gap: var(--sp-2); }
.pb-scope .gallery__item .plate { aspect-ratio: 4 / 3; }
.pb-scope .gallery__cap { font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }

/* Gallery head — title and lead hold the left, the rail controls sit far right.
   `align-items: end` puts the arrows on the baseline of the lead's last line, so
   the pair reads as one row rather than as a button floating in the margin. */
.pb-scope .gallery__head {
  display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between;
  gap: var(--sp-4) var(--sp-6);
  margin-bottom: var(--sp-6);
}
/* A basis, not just a cap: below ~420px the nav has to drop to its own line
   instead of squeezing the headline into two words per line. */
.pb-scope .gallery__intro { flex: 1 1 320px; max-width: 46ch; }
.pb-scope .gallery__intro h2 { margin-bottom: var(--sp-3); }
.pb-scope .gallery__intro .lead { margin-bottom: 0; }

.pb-scope .gallery__nav { display: flex; gap: var(--sp-2); flex-shrink: 0; }
/* Round scroll controls. Blue, never amber: amber is the ACTION role and the
   page spends it on the estimate button — moving a filmstrip is navigation.
   Fills with --accent-deep so the white glyph clears AA (4.78:1). */
.pb-scope .gallery__btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid transparent; border-radius: var(--r-pill);
  background: var(--accent-deep); color: #fff;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              opacity var(--dur) var(--ease);
}
.pb-scope .gallery__btn svg { width: 18px; height: 18px; display: block; }
.pb-scope .gallery__btn:hover { background: #2263C9; box-shadow: var(--shadow-accent); }
/* An end-of-rail button stays visible but reads as unavailable — and keeps its
   edge, so it is still findable against the canvas at 3:1. */
.pb-scope .gallery__btn[disabled] {
  background: transparent; color: var(--muted);
  border-color: var(--border-control);
  box-shadow: none; pointer-events: none;
}

/* Rail — the same figures, scrolled horizontally instead of wrapped in a grid.
   Overrides the grid above; the responsive grid rules below are inert on flex. */
.pb-scope .gallery--rail {
  display: flex;
  gap: var(--sp-4);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  /* Bleed to the container's padding edge only — never to 100vw, which would
     add a horizontal scrollbar to the page whenever a vertical one exists. */
  margin-inline: calc(-1 * var(--sp-5));
  padding-inline: var(--sp-5);
  scroll-padding-inline: var(--sp-5);
  padding-bottom: var(--sp-2);
  /* Native bar hidden: the arrows and a focusable rail carry the interaction. */
  scrollbar-width: none;
}
.pb-scope .gallery--rail::-webkit-scrollbar { display: none; }
.pb-scope .gallery--rail:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: var(--r-sm); }
.pb-scope .gallery--rail .gallery__item {
  /* 360px on desktop; the 78% cap keeps a card narrower than the rail on a phone
     so the next one always peeks and the strip reads as scrollable. */
  flex: 0 0 min(360px, 78%);
  scroll-snap-align: start;
}
/* Portrait tiles, as in the reference: a taller frame reads as a photo slot,
   not as a wide banner, and lets four cards live in the fold. */
.pb-scope .gallery--rail .gallery__item .plate { aspect-ratio: 3 / 4; }
/* A real photograph takes the same frame as the slot it replaces — same ratio,
   radius and hairline — so a half-filled rail keeps one rhythm. `cover` because
   the shop's photos arrive in whatever ratio the phone shot them in; the crop is
   biased right of centre, where collision damage and the repaired front end sit. */
.pb-scope .gallery--rail .gallery__item img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover; object-position: 56% 50%;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: var(--surface-2);
}
.pb-scope .gallery--rail .gallery__cap { padding-top: 2px; }

/* ---- Carousel — paged photo cards -----------------------------------------
   The client's own site runs this shape: a bordered panel holding a row of photo
   cards, round arrows pinned half-over the panel's left and right edges, one dot
   per page underneath. Rebuilt on this system's tokens — `--surface` panel,
   hairline border, 20px radius, blue controls. No amber anywhere in it: the page
   spends its one amber on the estimate button, and paging a strip of photographs
   is navigation, not the action we want the reader to take.

   Paging is scroll-driven, not transform-driven. The track is a scroll-snap flex
   row, so before `components.js` loads — or with JS off entirely — the block is
   still a usable horizontal strip. The hook only sets `scrollLeft`, paints the
   dots and disables an arrow at each end.

   The 16/10 media frame is a deliberate uniform crop. The shop's photographs
   arrive in whatever ratio the phone shot them in (4:3, 3:2, 1.23:1); a row of
   cards only reads as a row when every frame matches, and the subject — the bay,
   wall to wall — survives the trim. Full-frame treatment belongs to the
   before/after rail above, where the crop would cut the damage out of the shot.
   --------------------------------------------------------------------------- */
.pb-scope .carousel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: var(--sp-5);
}
/* The arrows are positioned against the frame, not the panel: the frame ends
   where the cards end, so `top: 50%` is the middle of a card rather than the
   middle of the panel-plus-dots block. */
.pb-scope .carousel__frame { position: relative; }
.pb-scope .carousel__viewport {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;   /* the arrows, the dots and drag carry the interaction */
  border-radius: var(--r-md);
}
.pb-scope .carousel__viewport::-webkit-scrollbar { display: none; }
.pb-scope .carousel__viewport:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) {
  .pb-scope .carousel__viewport { scroll-behavior: auto; }
}

.pb-scope .carousel__track { display: flex; gap: var(--sp-4); }
/* Three across on desktop, from a gap-aware basis so the third card lands flush
   with the panel's inner edge. */
.pb-scope .carousel__card {
  flex: 0 0 calc((100% - 2 * var(--sp-4)) / 3);
  scroll-snap-align: start;
  display: flex; flex-direction: column;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
}
.pb-scope .carousel__media { position: relative; aspect-ratio: 16 / 10; background: var(--surface-2); overflow: hidden; }
.pb-scope .carousel__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Hover: the photograph grows inside its frame, the frame itself does not move.
   4% is the whole effect — enough to register as a response, small enough that
   the crop does not visibly lose anything at the edges. The frame clips it, so
   nothing spills over the caption or the neighbouring card. Requested by the
   operator; it is the one motion in the system that is not a button state. */
.pb-scope .carousel__media img { transition: transform var(--dur-slow) var(--ease); }
.pb-scope .carousel__card:hover .carousel__media img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .pb-scope .carousel__media img { transition: none; }
  .pb-scope .carousel__card:hover .carousel__media img { transform: none; }
}
/* A workshop photograph is busiest at its foot, exactly where the caption block
   starts. The wash settles that edge; it is a legibility device, not a gradient
   background — the system forbids those. */
.pb-scope .carousel__media::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(8, 9, 11, .70), rgba(8, 9, 11, .06) 44%, transparent 70%);
  pointer-events: none;
}
.pb-scope .carousel__body { display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-4); }
/* The plate sits on the title's first line, not centred against the whole
   caption: the glyph and the title have to read as one row. */
.pb-scope .carousel__body .icon-plate { flex: none; width: 40px; height: 40px; margin-bottom: 0; border-radius: var(--r-md); }
.pb-scope .carousel__body .icon-plate svg { width: 18px; height: 18px; }
.pb-scope .carousel__title { font-size: 16px; line-height: 1.3; margin: 3px 0 var(--sp-1); }
.pb-scope .carousel__note { font-size: var(--fs-sm); line-height: 1.5; margin: 0; color: var(--muted); }

/* Arrows sit fully inside the strip, inset from the first and last card's edge,
   so each one reads as a control ON the photograph rather than as a button
   straddling the panel's edge. `top: 50%` is measured against the frame, which
   ends where the cards end — that lands the pair on the media band, clear of the
   caption underneath. They reuse `.gallery__btn` for fill, size and disabled
   state, so the two paged blocks on a page cannot drift apart. */
.pb-scope .carousel__arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; }
.pb-scope .carousel__arrow--prev { left: var(--sp-3); }
.pb-scope .carousel__arrow--next { right: var(--sp-3); }
/* An end-of-strip arrow here sits half over a photograph, so it keeps a solid
   fill instead of the rail's transparent disabled state — a grey glyph directly
   on a busy image is neither legible nor findable. */
.pb-scope .carousel__arrow[disabled] { background: var(--surface); color: var(--muted); }

/* One dot per page. A dot is a control, so it carries the 44px tap target while
   the visible mark stays small — the padding around it is transparent. */
.pb-scope .carousel__dots { display: flex; justify-content: center; align-items: center; gap: var(--sp-1); margin-top: var(--sp-2); }
.pb-scope .carousel__dot {
  appearance: none; -webkit-appearance: none;
  width: 44px; height: 44px; padding: 0;
  border: 0; background: none; cursor: pointer;
  display: grid; place-items: center;
}
.pb-scope .carousel__dot::before {
  content: "";
  width: 8px; height: 8px; border-radius: var(--r-pill);
  background: var(--border-control);
  transition: background-color var(--dur) var(--ease), width var(--dur) var(--ease);
}
.pb-scope .carousel__dot:hover::before { background: var(--muted); }
.pb-scope .carousel__dot[aria-current="true"]::before { background: var(--accent); width: 22px; }
.pb-scope .carousel__dot:focus-visible { outline: 2px solid var(--accent); outline-offset: -9px; border-radius: var(--r-pill); }

@media (max-width: 920px) {
  .pb-scope .carousel { padding: var(--sp-4); }
  .pb-scope .carousel__card { flex: 0 0 calc((100% - var(--sp-4)) / 2); }
  /* Below the tablet break the padding band is too narrow to hold a 44px control
     beside the cards, so the arrows drop out of the overlay and sit in a row
     under the strip rather than covering a photograph. The frame becomes the
     flex row that centres them — `text-align` would have been inherited by the
     card captions and centred those too. */
  .pb-scope .carousel__frame { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3) var(--sp-2); }
  .pb-scope .carousel__viewport { flex: 0 0 100%; min-width: 0; }
  .pb-scope .carousel__arrow { position: static; transform: none; }
  .pb-scope .carousel__dots { margin-top: var(--sp-1); }
}
@media (max-width: 560px) {
  /* One card at a time, with the next one peeking so the strip still reads as
     scrollable. */
  .pb-scope .carousel__card { flex: 0 0 82%; }
}

/* ---- Contact -------------------------------------------------------------- */
.pb-scope .contact { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-7); align-items: start; }
.pb-scope .nap { list-style: none; margin: 0 0 var(--sp-5); padding: 0; }
.pb-scope .nap li { display: grid; grid-template-columns: 108px 1fr; gap: var(--sp-4); padding: var(--sp-3) 0; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); }
/* A rule separates rows; after the last one it separates nothing. */
.pb-scope .nap li:last-child { border-bottom: 0; padding-bottom: 0; }
.pb-scope .nap dt,
.pb-scope .nap .nap__k { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); padding-top: 3px; }
.pb-scope .nap a {
  color: var(--fg);
  display: inline-flex; align-items: center; min-height: 44px;
}

/* ---- Footer --------------------------------------------------------------- */
/* Two rows, not three columns: identity + contact on top, fine print in a bar
   below a hairline. Three equal columns forced the address, a legal sentence and
   a button into the same visual weight, and squeezed the button until it
   overflowed its column. */
.pb-scope .site-footer { border-top: 1px solid var(--border); padding-block: var(--sp-6) var(--sp-5); }
.pb-scope .site-footer__top {
  display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-6);
  align-items: center; justify-content: space-between;
}
.pb-scope .site-footer__brand .brand__name { display: block; font-size: 20px; }
.pb-scope .site-footer__brand p { margin: 6px 0 0; font-size: var(--fs-sm); }

.pb-scope .site-footer__contact { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-5); }
.pb-scope .site-footer__mail { color: var(--muted); font-size: var(--fs-sm); }
.pb-scope .site-footer__mail:hover { color: var(--fg); text-decoration: none; }

.pb-scope .site-footer__bar {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5);
  align-items: center; justify-content: space-between;
  margin-top: var(--sp-5); padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
}
.pb-scope .site-footer__legal { margin: 0; font-size: var(--fs-xs); color: var(--muted); max-width: 68ch; }
.pb-scope .site-footer__links { display: flex; gap: var(--sp-5); }
.pb-scope .site-footer__links a { color: var(--muted); font-size: var(--fs-xs); }
.pb-scope .site-footer__links a:hover { color: var(--fg); text-decoration: none; }

/* Standalone footer links are tap targets, so they carry the 44px minimum. The
   rule is scoped to them rather than to every <a> in the footer — a blanket rule
   here turns any inline link inside a sentence into a 44px block. */
.pb-scope .site-footer__mail,
.pb-scope .site-footer__links a { display: inline-flex; align-items: center; min-height: 44px; }
/* Inline links inside a sentence keep the prose flow — WCAG 2.5.8 exempts them
   from the target-size minimum, and padding them to 44px would break the paragraph. */
.pb-scope .consent__legal a { display: inline; min-height: 0; }

/* ---- Responsive ----------------------------------------------------------- */
@media (max-width: 920px) {
  .pb-scope .hero__grid,
  .pb-scope .record__grid,
  .pb-scope .split,
  .pb-scope .contrast,
  .pb-scope .leadform,
  .pb-scope .stat-band__grid,
  .pb-scope .band__grid,
  .pb-scope .contact,
  .pb-scope .sec { grid-template-columns: 1fr; gap: var(--sp-5); }
  .pb-scope .sec__head { position: static; }
  .pb-scope .split--media-first .split__media { order: 0; }
  .pb-scope .icon-strip { grid-template-columns: 1fr 1fr; }
  .pb-scope .icon-strip__item { padding-right: var(--sp-4); }
  .pb-scope .icon-strip__item:nth-child(odd) { border-left: 0; padding-left: 0; }
  .pb-scope .icon-strip__item:nth-child(even) { border-left: 1px solid var(--border); padding-left: var(--sp-4); }
  .pb-scope .band { padding: var(--sp-5); }
  .pb-scope .quotes--two,
  .pb-scope .reviews-grid,
  .pb-scope .steps,
  .pb-scope .form-grid { grid-template-columns: 1fr; }
  .pb-scope .gallery,
  .pb-scope .scope-grid { grid-template-columns: 1fr 1fr; }
  .pb-scope .hero__media { min-height: 260px; }
  /* The five-item nav does not survive a tablet width beside a logo and a CTA;
     it moves into the hamburger drawer, which carries the same items. */
  .pb-scope .site-nav { display: none; }
  .pb-scope .nav-toggle { display: inline-flex; }
}
@media (max-width: 560px) {
  /* Brand + phone + CTA + hamburger do not fit 390px together. The bar keeps
     the logo and the hamburger; the number and the CTA move into the drawer. */
  .pb-scope .site-header__inner .header-phone,
  .pb-scope .site-header__inner .btn { display: none; }
  .pb-scope .nav-drawer__foot {
    display: flex; flex-direction: column; gap: var(--sp-3);
    margin-top: var(--sp-4);
  }
  .pb-scope .nav-drawer__foot .btn { width: 100%; justify-content: center; }
  .pb-scope .site-header__inner { gap: var(--sp-3); }
  .pb-scope .icon-strip { grid-template-columns: 1fr; }
  .pb-scope .icon-strip__item { border-left: 0 !important; padding-left: 0 !important; }
  .pb-scope .gallery,
  .pb-scope .scope-grid { grid-template-columns: 1fr; }
  .pb-scope .nap li { grid-template-columns: 1fr; gap: 2px; }
}
