/* Permit Nav prototype — site styles. Every value comes from css/tokens.css unless noted. */

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  /* contract: 72 (header height). At 72 a landed heading sits 8px under the header hairline, which reads as
     glued; 72 + 48 gives it room. */
  scroll-padding-top: calc(var(--pn-header-height) + var(--pn-space-48));
  -webkit-text-size-adjust: 100%;
}
html.is-locked { overflow: hidden; }
body {
  margin: 0;
  background: var(--pn-color-background-canvas);
  color: var(--pn-color-text-primary);
  font: var(--pn-type-text-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, p, ul, ol, figure, dl, dd { margin: 0; }
ul { padding: 0; list-style: none; }
img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
:focus-visible {
  outline: 2px solid var(--pn-color-focus);
  outline-offset: 2px;
}
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: var(--pn-space-16); top: -100px; z-index: 100;
  padding: var(--pn-space-12) var(--pn-space-24);
  background: var(--pn-color-accent-fill); color: var(--pn-color-text-onAccent);
  border-radius: var(--pn-radius-pill); font: var(--pn-type-ui-label);
}
.skip-link:focus { top: var(--pn-space-16); }

/* ---------- Layout ---------- */
:root { --page-margin: var(--pn-layout-margin-1440); }
@media (max-width: 1439px) { :root { --page-margin: 40px; } }

.container {
  width: min(var(--pn-layout-maxWidth), 100% - 2 * var(--page-margin));
  margin-inline: auto;
}
/* Sections stack with space/128 between them (wireframe 71:2 auto-layout gap). */
/* owner 2026-11-01 ("make A & B 288"): every section gap equals the step rhythm (192 between + 96 inside = 288), so a page
   reads at one rhythm whether its blocks are workflow steps or ordinary sections. Was 128. */
.page-main { --section-gap: var(--pn-space-128); } /* owner 2026-11-04: 128 (was 288 = 128+128+32, owner 2026-11-01) */
.page-main > section + section { margin-top: var(--section-gap); }
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: var(--pn-layout-gutter);
  align-items: start;
}

/* ---------- Text links ---------- */
.link {
  font: var(--pn-type-ui-label);
  color: var(--pn-color-accent-primary);
  text-decoration: none; /* owner 2026-10-29: the underline is now the drawn bar on .link__text (LinkButton sample) */
  transition: text-decoration-color 160ms ease, color 160ms ease;
}
/* owner 2026-10-29: text links tailored from a LinkButton sample (Hyperiux). js/site.js (initLinks) wraps a link's text in
   .link__text and a leading/trailing arrow glyph in .link__arrow. Hover: a 1.5px bar draws in from the left under the text
   (and leaves to the right), and the arrow turns 45deg to point up-right (back arrows up-left). 500ms on the sample curve. */
.link__text { position: relative; display: inline-block; }
.link__text::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 1.5px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform 500ms cubic-bezier(0.62, 0.05, 0.01, 0.99);
}
.link:hover .link__text::after, .link:focus-visible .link__text::after { transform: scaleX(1); transform-origin: left; }
.link__arrow { display: inline-block; margin-left: 0.3em; transition: transform 500ms cubic-bezier(0.62, 0.05, 0.01, 0.99); }
.link__arrow--back { margin: 0 0.3em 0 0; }
.link:hover .link__arrow, .link:focus-visible .link__arrow { transform: rotate(-45deg); }
.link:hover .link__arrow--back, .link:focus-visible .link__arrow--back { transform: rotate(45deg); }
@media (prefers-reduced-motion: reduce) {
  .link__text::after { transform: scaleX(1); transition: none; } /* static underline: the affordance stays */
  .link__arrow { transition: none; }
  .link:hover .link__arrow, .link:hover .link__arrow--back { transform: none; }
}
.link--muted { color: var(--pn-color-text-secondary); }
.link--muted:hover { color: var(--pn-color-text-primary); }

/* ---------- Buttons (all pills) ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--pn-space-8);
  --btn-pad-x: var(--pn-space-24);
  padding: var(--pn-space-12) var(--btn-pad-x);
  border-radius: var(--pn-radius-pill);
  font: var(--pn-type-ui-label);
  white-space: nowrap;
  transition: background-color 160ms ease, transform 160ms ease, opacity 160ms ease;
}
.btn:active { transform: scale(0.98); }
.btn--lg { --btn-pad-x: var(--pn-space-32); padding: var(--pn-space-16) var(--btn-pad-x); font: var(--pn-type-ui-label-l); }
.btn--primary { background: var(--pn-color-accent-fill); color: var(--pn-color-text-onAccent); }
.btn--primary:hover { background: var(--pn-color-brand-green); color: var(--pn-color-background-canvas); } /* owner 2026-10-29: primaries go brand green on hover (was accent/hover) */
.btn--secondary {
  background: var(--pn-color-surface-frost);
  color: var(--pn-color-text-primary);
  -webkit-backdrop-filter: blur(var(--pn-blur-frost));
  backdrop-filter: blur(var(--pn-blur-frost));
}
.btn--secondary:hover { background: var(--pn-color-surface-frostHover); }
.btn--block { width: 100%; align-self: stretch; } /* owner 2026-10-29: full-width CTA (pricing cards) */
.btn--fixed { } /* owner 2026-10-29: sweep without growth, for centred rows where a wider pill would shove its neighbour (Home hero) */
.btn--block.btn--sweep:hover, .btn--block.btn--sweep:focus-visible,
.btn--fixed.btn--sweep:hover, .btn--fixed.btn--sweep:focus-visible { padding-right: var(--btn-pad-x); } /* no growth */
.btn--block.btn--sweep .btn__reveal, .btn--fixed.btn--sweep .btn__reveal { justify-content: center; padding-left: 0; } /* centred like the resting label */
.btn--outline { /* owner 2026-10-29: outline secondary (pricing plan cards): transparent, 1px ring, light text; same idea as the in-screen outline primaries */
  background: transparent; color: var(--pn-color-text-primary);
  box-shadow: inset 0 0 0 1px var(--pn-color-border-control);
  transition: background-color 160ms ease, box-shadow 160ms ease, transform 160ms ease, opacity 160ms ease;
}
.btn--outline:hover { box-shadow: inset 0 0 0 1px var(--pn-color-text-primary); }
.btn--outline.btn--sweep:hover { box-shadow: none; } /* the sweep fill replaces the ring */
.btn--text { padding: var(--pn-space-12) var(--pn-space-8); color: var(--pn-color-text-primary); }
.btn--text:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.btn[disabled], .btn[aria-disabled="true"] { cursor: default; }
/* owner 2026-10-29: sweep hover, tailored from an InteractiveHoverButton sample (used on the pricing cards). The label
   slides right and fades, a dot at 20%/40% grows to fill the pill in --btn-sweep, and a second label + arrow slides in
   from the right in --btn-sweep-ink. Defaults = the primary button's fill and ink; a host overrides the two props. */
.btn--sweep {
  --btn-sweep: var(--pn-color-accent-fill);
  --btn-sweep-ink: var(--pn-color-text-onAccent);
  --btn-sweep-extra: 26px; /* arrow 18 + gap 8: the pill grows by this on hover so the reveal is not crammed */
  position: relative; overflow: hidden; isolation: isolate;
  transition: background-color 160ms ease, transform 160ms ease, opacity 160ms ease, padding 300ms var(--pn-ease-out);
}
.btn--sweep .btn__label {
  display: inline-block;
  transition: transform 300ms var(--pn-ease-out), opacity 300ms var(--pn-ease-out);
}
.btn--sweep .btn__sweep {
  position: absolute; left: 20%; top: 40%; width: 8px; height: 8px; z-index: -1;
  border-radius: var(--pn-radius-pill); background: var(--btn-sweep);
  opacity: 0; /* owner 2026-10-29 "hide the white dots": invisible at rest, appears as it grows */
  transition: left 300ms var(--pn-ease-out), top 300ms var(--pn-ease-out), width 300ms var(--pn-ease-out),
              height 300ms var(--pn-ease-out), transform 300ms var(--pn-ease-out), opacity 120ms linear;
}
.btn--sweep .btn__reveal {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: flex-start; gap: var(--pn-space-8);
  padding-left: var(--btn-pad-x); /* the reveal label lands exactly where the resting label sat */
  color: var(--btn-sweep-ink);
  opacity: 0; transform: translateX(48px);
  transition: transform 300ms var(--pn-ease-out), opacity 300ms var(--pn-ease-out);
}
.btn--sweep .btn__arrow { flex: none; }
.btn--primary.btn--sweep { --btn-sweep: var(--pn-color-brand-green); --btn-sweep-ink: var(--pn-color-background-canvas); } /* a primary sweeps to brand green, dark ink */
.btn--secondary.btn--sweep { --btn-sweep: var(--pn-color-surface-frostHover); --btn-sweep-ink: var(--pn-color-text-primary); } /* a frost secondary sweeps to its hover frost, never to a primary look */
.btn--outline.btn--sweep { --btn-sweep: var(--pn-color-surface-frostHover); --btn-sweep-ink: var(--pn-color-text-primary); } /* an outline secondary fills with frost on hover, same rule: never a primary look */
.btn--sweep:hover .btn__label, .btn--sweep:focus-visible .btn__label { transform: translateX(48px); opacity: 0; }
.btn--sweep:hover .btn__sweep, .btn--sweep:focus-visible .btn__sweep { left: 0; top: 0; width: 100%; height: 100%; transform: scale(1.8); opacity: 1; }
.btn--sweep:hover, .btn--sweep:focus-visible { padding-right: calc(var(--btn-pad-x) + var(--btn-sweep-extra)); }
.btn--sweep:hover .btn__reveal, .btn--sweep:focus-visible .btn__reveal { opacity: 1; transform: translateX(0); }
@media (prefers-reduced-motion: reduce) {
  .btn--sweep, .btn--sweep .btn__label, .btn--sweep .btn__sweep, .btn--sweep .btn__reveal { transition: none; }
}

/* ---------- Header (Header/Desktop 178:4825) ---------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  height: var(--pn-header-height);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 240ms ease, border-color 240ms ease,
              -webkit-backdrop-filter 240ms ease, backdrop-filter 240ms ease;
}
.site-header.is-scrolled,
.site-header--solid {
  background: rgba(11, 14, 20, 0.8); /* canvas at 80% */
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  /* owner 2026-10-09: no divider under the scrolled header; the frost alone marks it */
}
.site-header__inner {
  height: 100%;
  display: flex; align-items: center; justify-content: space-between;
}
.site-header__left { display: flex; align-items: center; gap: var(--pn-space-64); height: 100%; }
.brand { display: inline-flex; align-items: center; gap: var(--pn-space-12); color: var(--pn-color-text-primary); }
.brand__mark { width: 32px; height: 32px; object-fit: contain; }
.brand__word { font: var(--pn-type-brand-wordmark); letter-spacing: -0.01em; white-space: nowrap; }
.site-header__left > nav { height: 100%; }
/* owner 2026-10-29: tabs interaction from a shadcn Tabs sample. js/site.js (initNavTabs) injects two sliders into
   .nav: a hover pill (.nav__hover) that glides between items, and ONE active bar (.nav__bar) that glides to the
   current page. Items gained 12px side padding so the pill has room; the gap drops 32 -> 8 and the nav shifts
   -12 so the text sits exactly where it did. Without JS the per-item ::after bar below still marks the page. */
.nav {
  position: relative;
  display: flex; align-items: stretch; gap: var(--pn-space-8); height: 100%;
  margin-left: calc(-1 * var(--pn-space-12));
}
.nav__item {
  position: relative; z-index: 1;
  display: flex; align-items: center;
  padding: 0 var(--pn-space-12);
  font: var(--pn-type-ui-label-s); /* owner 2026-10-09: 14/500, down from 16 */
  color: var(--pn-color-text-primary);
  white-space: nowrap;
  transition: color 300ms var(--pn-ease-out);
}
.site-header__actions .btn--text { font: var(--pn-type-ui-label-s); } /* Sign in matches the nav */
.nav__hover, .nav__bar {
  position: absolute; left: 0; width: 0; pointer-events: none;
  transition: left 300ms var(--pn-ease-out), width 300ms var(--pn-ease-out), opacity 300ms var(--pn-ease-out);
}
.nav__hover { /* hover pill: 32 tall, centred on the item, text-primary at 10% (the sample's white 10%) */
  top: 50%; height: 32px; margin-top: -16px;
  border-radius: var(--pn-radius-card);
  background: color-mix(in srgb, var(--pn-color-text-primary) 10%, transparent);
  opacity: 0;
}
.nav.is-hovering .nav__hover { opacity: 1; }
.nav__bar { /* active bar, 2px at the header baseline, one for the whole nav */
  bottom: 0; height: 2px;
  background: var(--pn-color-accent-primary);
  opacity: 0;
}
.nav.has-current .nav__bar { opacity: 1; }
.nav__item::after { /* no-JS fallback: per-item active bar */
  content: ""; position: absolute; left: var(--pn-space-12); right: var(--pn-space-12); bottom: 0; height: 2px;
  background: var(--pn-color-accent-primary);
  transform: scaleX(0); transform-origin: left;
}
.site-header--solid .nav__item { color: var(--pn-color-text-secondary); }
.site-header--solid .nav__item:hover,
.nav__item[aria-current="page"] { color: var(--pn-color-text-primary); }
.nav__item[aria-current="page"]::after { transform: scaleX(1); }
.nav.is-ready .nav__item::after { display: none; }
@media (prefers-reduced-motion: reduce) {
  .nav__hover, .nav__bar, .nav__item { transition: none; }
}
.site-header__actions { display: flex; align-items: center; gap: var(--pn-space-16); }
/* 2026-11-04 (responsive contract): below 1024 the nav and the actions move into a drawer. The toggle and the drawer are
   in every page's header and stay display:none at 1024 and up; js/site.js (initNav) opens and closes the drawer. */
.nav-toggle, .site-drawer { display: none; }
.nav-toggle {
  position: relative; width: 44px; height: 44px; margin-right: calc(-1 * var(--pn-space-12)); /* the bars, not the hit box, sit on the container edge */
  border-radius: var(--pn-radius-card);
  color: var(--pn-color-text-primary);
}
.nav-toggle__bar {
  position: absolute; left: var(--pn-space-12); right: var(--pn-space-12); height: 1.5px;
  background: currentColor; border-radius: 1px;
  transition: transform 240ms var(--pn-ease-out);
}
.nav-toggle__bar:first-child { top: calc(50% - var(--pn-space-4)); }
.nav-toggle__bar:last-child { top: calc(50% + var(--pn-space-4) - 1.5px); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:first-child { transform: translateY(2.75px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:last-child { transform: translateY(-2.75px) rotate(-45deg); }
.site-drawer {
  position: absolute; top: 100%; left: 0; right: 0;
  max-height: calc(100vh - var(--pn-header-height)); max-height: calc(100dvh - var(--pn-header-height)); overflow-y: auto;
  background: var(--pn-color-background-canvas);
  border-bottom: 1px solid var(--pn-color-border-decorative);
  visibility: hidden; opacity: 0; transform: translateY(calc(-1 * var(--pn-space-8)));
  transition: opacity 240ms var(--pn-ease-out), transform 240ms var(--pn-ease-out), visibility 0s linear 240ms;
}
.site-drawer.is-open { visibility: visible; opacity: 1; transform: none; transition-delay: 0s; }
.site-drawer__inner { padding-block: var(--pn-space-16) var(--pn-space-48); }
.site-drawer__nav { display: flex; flex-direction: column; }
.site-drawer__item {
  display: flex; align-items: center; min-height: 56px;
  border-bottom: 1px solid var(--pn-color-border-decorative);
  font: var(--pn-type-ui-label); color: var(--pn-color-text-secondary);
}
.site-drawer__item:hover { color: var(--pn-color-text-primary); }
.site-drawer__item[aria-current="page"] {
  color: var(--pn-color-text-primary);
  text-decoration: underline; text-decoration-color: var(--pn-color-accent-primary);
  text-decoration-thickness: 2px; text-underline-offset: 8px;
}
.site-drawer__actions { margin-top: var(--pn-space-32); display: flex; flex-direction: column; gap: var(--pn-space-16); }
.site-header.is-open { background: var(--pn-color-background-canvas); -webkit-backdrop-filter: none; backdrop-filter: none; }
@media (prefers-reduced-motion: reduce) {
  .site-drawer, .site-drawer.is-open { transform: none; transition: none; }
  .nav-toggle__bar { transition: none; }
}

/* ---------- H01 Hero (round 3: copy over two product windows, Linear-style) ---------- */
/* The section is at least one viewport tall (min 800). At 1440x900 the copy + 72 + the stage make it taller
   than the viewport, so the windows run off the bottom of the viewport at first view and dissolve into the
   fade at the hero's own bottom edge once scrolled. See BUILD-CONTRACT-hero-animation-r2.md and the r2 report. */
.hero {
  position: relative;
  min-height: max(100vh, 800px);
  display: flex; flex-direction: column;
  overflow: hidden;
  overflow: clip; /* r4: clip, not a scroll container, so focusing an accordion button can never scroll the hero itself */
  background: var(--pn-color-background-canvas);
}
.hero__content {
  position: relative; z-index: 2;
  width: 920px; margin: 144px auto 0; /* owner 2026-10-13: was 680; wide enough for a two-line lead */
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}
.hero__title { color: var(--pn-color-text-primary); }
.hero__lead { max-width: 920px; text-wrap: balance; margin-top: var(--pn-space-24); color: var(--pn-color-text-secondary); } /* owner 2026-10-13: two lines at desktop, was 640 / three lines */
.hero__buttons { display: flex; gap: var(--pn-space-16); margin-top: var(--pn-space-32); }
.hero__demo { margin-top: var(--pn-space-24); }

/* hero entrance (on load) */
.js .hero__title, .js .hero__lead, .js .hero__actions-anim {
  animation: rise 600ms var(--pn-ease-out) both;
}
.js .hero__lead { animation-delay: 80ms; }
.js .hero__actions-anim { animation-delay: 160ms; }
@keyframes rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
.hero__actions-anim { display: flex; flex-direction: column; align-items: center; }

/* Stage: 72 below the demo link, on the 1280 grid. Its visible height (--stage-h) sets how much of the windows
   shows before the hero ends; both windows are taller than that and are clipped by the hero. */
.hero {
  --hero-fade: 120px;
}
.hero__stage {
  --stage-h: 760px; /* owner 2026-11-04 ("increase the home page hero screen min height to approx this much"): was 560; the checklist window now shows seven rows before the fade */
  position: relative;
  flex: 1 0 var(--stage-h);
  margin-top: 72px; /* contract: 72 below the demo link (not a space token) */
}
/* soft accent glow behind the windows (contract: optional, <= 8% at its centre) */
.hero__stage::before {
  content: ""; position: absolute; z-index: 0;
  /* owner 2026-10-10: a wide, low ellipse (Linear-style), dimmer than the first pass — "too big too bright too round" */
  left: 50%; top: -300px; width: 2200px; height: 600px; margin-left: -1100px; /* centred on the window's top edge so the bright band sits on the horizon and spills upward */
  /* owner 2026-10-13: bluish grey. owner 2026-10-19: a little brand green mixed in as a second, smaller blob (900x420)
     that wanders on its own 31s rhythm inside the ellipse, so the two colours never settle into one shape. */
  background:
    radial-gradient(closest-side, rgba(70, 200, 138, 0.09), rgba(70, 200, 138, 0.035) 50%, rgba(70, 200, 138, 0)) 30% 45% / 900px 420px no-repeat,
    radial-gradient(closest-side, rgba(118, 136, 166, 0.14), rgba(118, 136, 166, 0.06) 50%, rgba(118, 136, 166, 0)) 0 0 / 100% 100% no-repeat;
  pointer-events: none;
  will-change: transform, opacity;
  /* owner 2026-10-13: subtle, organic, constant. Two rhythms that never line up (23s drift, 14s breath), small amplitude. */
  animation: pn-glow-drift 23s ease-in-out infinite alternate, pn-glow-breathe 14s ease-in-out infinite alternate, pn-glow-green 31s ease-in-out infinite alternate;
}
@keyframes pn-glow-drift {
  0%   { transform: translate3d(-110px, -24px, 0) scaleX(0.92) scaleY(1.06); }
  50%  { transform: translate3d(30px, 30px, 0) scaleX(1.08) scaleY(0.94); }
  100% { transform: translate3d(120px, -14px, 0) scaleX(0.96) scaleY(1.1); }
}
@keyframes pn-glow-green { /* the green blob's own wander: background-position of layer 1 only */
  0%   { background-position: 22% 38%, 0 0; }
  50%  { background-position: 64% 58%, 0 0; }
  100% { background-position: 40% 28%, 0 0; }
}
@keyframes pn-glow-breathe {
  0%   { opacity: 0.7; }
  100% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .hero__stage::before { animation: none; } }
/* owner 2026-10-31: "very faint glows behind these screens too" (Home H03 + H04). A wrapper around the figure carries
   the hero glow at half strength, static, centred on the screen's top edge like the hero's. Sized to the viewport
   (not the hero's 2200) so it never widens the page. */
.glow { position: relative; }
.glow > .figure { position: relative; z-index: 1; }
.glow::before {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  left: 50%; top: -300px; width: min(2200px, 100vw - 24px); height: 600px; translate: -50% 0;
  background:
    radial-gradient(closest-side, rgba(70, 200, 138, 0.045), rgba(70, 200, 138, 0.018) 50%, rgba(70, 200, 138, 0)) 30% 45% / 900px 420px no-repeat,
    radial-gradient(closest-side, rgba(118, 136, 166, 0.07), rgba(118, 136, 166, 0.03) 50%, rgba(118, 136, 166, 0)) 0 0 / 100% 100% no-repeat;
}
/* Owner 2026-10-09 (Linear reference): radial veil over the back window. Transparent around the parcel and search,
   darkening toward the right and bottom; the checklist window sits above it and stays crisp. */
.hero__stage::after {
  content: ""; position: absolute; z-index: 2; inset: 0;
  background: radial-gradient(1100px 820px at 38% 18%, rgba(11, 14, 20, 0) 0%, rgba(11, 14, 20, 0) 38%, rgba(11, 14, 20, 0.5) 72%, rgba(11, 14, 20, 0.9) 100%);
  pointer-events: none;
}
.hero__fade {
  position: absolute; z-index: 4; left: 0; right: 0; bottom: 0; height: var(--hero-fade); /* r4: 200 -> 120 */
  background: linear-gradient(to bottom, rgba(11, 14, 20, 0), var(--pn-color-background-canvas));
  pointer-events: none;
}
.hw-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- Window shell ---- */
/* The hairline is drawn by ::after on top of the content (not a border) so the window's inner box is its full
   width: the lookup window is exactly 1280 = 460 panel + 820 map. */
.hw {
  position: absolute;
  background: var(--pn-color-background-surface);
  border-radius: var(--pn-radius-card);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  color: var(--pn-color-text-primary);
  font-family: var(--pn-font-sans);
  text-align: left;
}
.hw::after { /* owner 2026-11-04 ("get rid of the outline on all screens across the site"): no hairline on any screen frame; the box stays for the focus ring */
  content: ""; position: absolute; inset: 0; z-index: 5;
  border: 0; border-radius: inherit;
  pointer-events: none;
}
.hw--lookup { z-index: 1; top: 0; left: 0; width: 1280px; box-shadow: 0 -8px 120px 8px rgba(118, 136, 166, 0.12), 0 24px 64px rgba(0, 0, 0, 0.5); /* owner 2026-10-10: faint bluish-grey rim, biased upward */ height: 100%; }
/* x 80-1360. r4: the window ends exactly at the hero's bottom edge (under the fully opaque end of the fade) instead of
   running 356px past it, so the scrolling panel's viewport is the part you can actually see. Looks identical. */
.hw--check {
  /* r3.1: x 848-1328 (right edge 32 inside the lookup window's), top = stage + 96 so the title and two full rows
     sit above y 900 at 1440x900 (stage + 160 leaves only one row) */
  z-index: 3; top: 96px; left: 864px; width: 480px; /* owner 2026-10-09: bleeds 64 past the lookup window (x 944-1424, 16 inside the viewport) */
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.6);
}
.hw__bar {
  height: 44px;
  display: flex; align-items: center; gap: var(--pn-space-8);
  padding: 0 var(--pn-space-16) 0 var(--pn-space-24);
  border-bottom: 1px solid var(--pn-color-border-decorative);
  background: rgba(11, 14, 20, 0.55); /* chrome a step darker than the body, so the window reads as an app, not a card */
  font: var(--pn-type-ui-label-s);
}
.hw--check .hw__bar { padding-right: var(--pn-space-24); background: rgba(11, 14, 20, 0.35); border-bottom-color: rgba(242, 240, 233, 0.1); }
/* Owner 2026-10-09: the checklist window is frosted glass over the map. Translucent canvas + backdrop blur; rows and tags
   use the frost tokens so the photo reads through the whole window, not just its margins. */
.hw--check {
  background: rgba(11, 14, 20, 0.62);
  -webkit-backdrop-filter: blur(24px) saturate(1.15);
  backdrop-filter: blur(24px) saturate(1.15);
}
.hw--check::after { border-color: rgba(242, 240, 233, 0.14); }
.hw--check .ck-row { background: var(--pn-color-surface-frostDisabled); }
.hw--check .hw-tag { background: rgba(11, 14, 20, 0.45); }
.hw__word { font-weight: 600; color: var(--pn-color-text-primary); }
.hw__sep { color: var(--pn-color-text-muted); }
.hw__where { color: var(--pn-color-text-secondary); }
.hw__tools { margin-left: auto; display: flex; gap: var(--pn-space-8); }

.hw-ico {
  width: 16px; height: 16px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
  color: var(--pn-color-text-secondary);
}
.hw-ico--sm { width: 12px; height: 12px; }
.hw-ico--accent { color: var(--pn-color-accent-primary); }
.hw-pill {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--pn-space-8);
  flex: none; height: 40px; padding: 0 var(--pn-space-16);
  border-radius: var(--pn-radius-pill);
  font: var(--pn-type-ui-label-s); white-space: nowrap;
}
.hw-pill--sm { height: 28px; padding: 0 var(--pn-space-12); gap: 6px; font: 500 13px/1 var(--pn-font-sans); }
.hw-pill--primary { background: transparent; color: var(--pn-color-text-primary); box-shadow: inset 0 0 0 1px var(--pn-color-border-control); } /* owner 2026-10-09: in-window primaries are white (Look up, Export PDF) */
.hw-pill--secondary { background: transparent; color: var(--pn-color-text-secondary); } /* owner 2026-10-09: no pill shape on the in-window secondary actions; text only */
.hw-pill--secondary:hover { color: var(--pn-color-text-primary); }
.hw-pill--secondary .hw-ico { color: inherit; }
.hw-tag {
  flex: none; padding: 4px 6px; border-radius: var(--pn-radius-control);
  background: var(--pn-color-background-surface); color: var(--pn-color-text-secondary);
  font: 500 11px/1 var(--pn-font-mono); letter-spacing: 0.02em;
}

/* ---- Back window: Address Lookup ---- */
.lk { display: flex; height: calc(100% - 44px); }
.lk-panel {
  flex: none; width: 460px;
  border-right: 1px solid var(--pn-color-border-decorative);
  background: var(--pn-color-background-surface);
  /* r4: the panel scrolls inside the window; the search row stays pinned */
  overflow-y: auto; overscroll-behavior-y: auto; /* see the r4 report: "contain" would never hand the wheel back to the page */
}
/* thin scrollbar: 6px thumb in frost 22%, transparent track. The track stops short of the hero fade so the thumb
   is always readable. WebKit/Blink use the pseudo-elements (6px); Firefox gets the standard properties. */
.lk-panel::-webkit-scrollbar { width: 6px; }
.lk-panel::-webkit-scrollbar-track { background: transparent; margin-bottom: var(--hero-fade); }
.lk-panel::-webkit-scrollbar-thumb { background: var(--pn-color-surface-frostHover); border-radius: var(--pn-radius-pill); }
@supports not selector(::-webkit-scrollbar) {
  .lk-panel { scrollbar-width: thin; scrollbar-color: var(--pn-color-surface-frostHover) transparent; }
}
.lk-search {
  position: sticky; top: 0; z-index: 3;
  display: flex; gap: var(--pn-space-8);
  padding: var(--pn-space-24);
  background: var(--pn-color-background-surface);
  border-bottom: 1px solid var(--pn-color-border-decorative);
}
.lk-field {
  flex: 1 1 auto; min-width: 0; height: 40px;
  display: flex; align-items: center; gap: var(--pn-space-8);
  padding: 0 var(--pn-space-12) 0 var(--pn-space-16);
  background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative);
  border-radius: var(--pn-radius-pill); /* owner 2026-10-09: pill search field */
}
/* Like a real input: the value scrolls to keep the caret in view while typing, and is clipped (never "…") */
.lk-field__box { flex: 1 1 auto; min-width: 0; overflow: hidden; display: flex; align-items: center; }
.lk-field__val { flex: none; white-space: nowrap; font: 400 15px/1.3 var(--pn-font-sans); }
.lk-field__box.is-clip-end { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); }
.lk-field__box.is-clip-start { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent); }
.lk-field__caret { flex: none; width: 2px; height: 18px; margin-left: 1px; background: var(--pn-color-accent-primary); opacity: 0; }
.lk-field__clear { color: var(--pn-color-text-muted); }
.lk-go { background: transparent; color: var(--pn-color-text-primary); box-shadow: inset 0 0 0 1px var(--pn-color-border-control); transition: background-color 160ms ease, color 160ms ease; } /* owner 2026-10-09: white, not accent */
.lk-go.is-off { background: var(--pn-color-surface-frostDisabled); color: var(--pn-color-text-secondary); }
.lk-suggest {
  position: absolute; z-index: 2; top: calc(var(--pn-space-24) + 40px + var(--pn-space-8));
  left: var(--pn-space-24); right: var(--pn-space-24);
  display: flex; align-items: center; gap: var(--pn-space-12);
  padding: var(--pn-space-12) var(--pn-space-16);
  background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative);
  border-radius: var(--pn-radius-card);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  transform-origin: 50% 0;
  opacity: 0; visibility: hidden;
}
.lk-suggest.is-hl { background: linear-gradient(var(--pn-color-accent-tint), var(--pn-color-accent-tint)), var(--pn-color-background-raised); }
.lk-suggest__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lk-suggest__addr { font: var(--pn-type-ui-label-s); white-space: nowrap; }
.lk-suggest__sub { font: 400 13px/1.4 var(--pn-font-sans); color: var(--pn-color-text-secondary); }

.lk-body {
  position: relative; padding: var(--pn-space-24);
  /* r4: room at the end so the last line scrolls clear of the hero fade */
  padding-bottom: calc(var(--hero-fade) + var(--pn-space-24));
}
/* Loading skeleton (r3.1): built by JS from the real content's geometry, so shapes sit exactly where the text will
   land (no layout shift). Shells copy the tile / accordion boxes; bars stand in for text. */
.lk-skel { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.lk-skel[hidden] { display: none; }
.lk-skel__grp { position: absolute; inset: 0; }
.lk-skel__shell { position: absolute; border-radius: var(--pn-radius-card); background: var(--pn-color-background-raised); }
.lk-skel__shell--tile { border-radius: var(--pn-radius-control); background: var(--pn-color-background-surface); border: 1px solid var(--pn-color-border-decorative); }
.lk-skel__bar {
  position: absolute; border-radius: var(--pn-radius-control); opacity: 0.6;
  background: linear-gradient(90deg, rgba(242, 240, 233, 0.12) 0%, rgba(242, 240, 233, 0.22) 50%, rgba(242, 240, 233, 0.12) 100%) 0 0 / 200% 100%;
  animation: skel-shimmer 1.6s linear infinite;
}
@keyframes skel-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
.lk-card {
  padding: 20px; /* contract: 20 (not a space token) */
  background: var(--pn-color-background-raised);
  border-radius: var(--pn-radius-card);
}
.lk-group + .lk-group { margin-top: var(--pn-space-32); }
.lk-group--env { padding-top: var(--pn-space-24); border-top: 1px solid var(--pn-color-border-decorative); }
.lk-label {
  margin-bottom: var(--pn-space-8);
  font: 500 11px/1.3 var(--pn-font-mono); letter-spacing: 0.04em; color: var(--pn-color-text-muted);
}
.lk-addr { margin-bottom: 6px; font: var(--pn-type-ui-label); line-height: 1.4; color: var(--pn-color-text-primary); }
.lk-val { font: 400 13px/1.6 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.lk-mono { font-family: var(--pn-font-mono); }
.lk-link { margin-left: var(--pn-space-8); color: var(--pn-color-accent-primary); }
.lk-link--block { margin: 6px 0 0; font: 400 14px/1.4 var(--pn-font-sans); }
.lk-zone { display: flex; align-items: center; gap: var(--pn-space-8); font: 400 13px/1 var(--pn-font-sans); }
.lk-chip {
  padding: 4px 10px; border-radius: var(--pn-radius-pill);
  background: var(--pn-color-background-surface); border: 1px solid var(--pn-color-border-decorative);
  color: var(--pn-color-text-primary);
}
.lk-zone__src { color: var(--pn-color-text-secondary); }
.lk-zone--ocp { margin-top: var(--pn-space-12); }
.lk-zone__k { color: var(--pn-color-text-secondary); }
.lk-env { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--pn-space-8); }
.lk-tile {
  display: flex; flex-direction: column; gap: 4px;
  padding: var(--pn-space-12);
  background: var(--pn-color-background-surface);
  border: 1px solid var(--pn-color-border-decorative);
  border-radius: var(--pn-radius-control);
}
.lk-tile__k { font: 500 11px/1.3 var(--pn-font-mono); letter-spacing: 0.04em; color: var(--pn-color-text-muted); }
.lk-tile__v { font: 400 16px/1.3 var(--pn-font-sans); color: var(--pn-color-text-primary); }
.lk-foot { margin-top: var(--pn-space-16); display: flex; flex-direction: column; gap: var(--pn-space-8); font: 400 12px/1.5 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.lk-acc { margin-top: var(--pn-space-12); display: flex; flex-direction: column; gap: var(--pn-space-12); }
.lk-acc__item { background: var(--pn-color-background-raised); border-radius: var(--pn-radius-card); }
.lk-acc__row {
  width: 100%; height: 56px; display: flex; align-items: center; justify-content: space-between;
  padding: 0 20px; /* matches the card's 20 */
  border-radius: var(--pn-radius-card);
  font: var(--pn-type-ui-label); color: var(--pn-color-accent-primary); text-align: left;
  transition: background-color 160ms ease;
}
.lk-acc__row:hover { background: var(--pn-color-surface-frostDisabled); }
.lk-acc__row[aria-expanded="true"] { border-radius: var(--pn-radius-card) var(--pn-radius-card) 0 0; }
.lk-acc__row:focus-visible { outline-offset: -2px; }
.lk-acc__row .hw-ico { color: var(--pn-color-accent-primary); transition: transform 200ms ease; }
.lk-acc__row[aria-expanded="true"] .hw-ico { transform: rotate(180deg); }
/* body: height animates 0fr -> 1fr (220 ease-out). Closed bodies are visibility:hidden (after the collapse), so they
   are out of the accessibility tree and out of the tab order. */
.lk-acc__body {
  display: grid; grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows 220ms ease-out, visibility 0s linear 220ms;
}
.lk-acc__row[aria-expanded="true"] + .lk-acc__body {
  grid-template-rows: 1fr; visibility: visible;
  transition: grid-template-rows 220ms ease-out, visibility 0s;
}
.lk-acc__clip { min-height: 0; overflow: hidden; }
.lk-acc__inner {
  padding: 20px 20px var(--pn-space-24); /* contract: 20 across (not a token) */
  border-top: 1px solid var(--pn-color-border-decorative);
  font: 400 14px/1.5 var(--pn-font-sans); color: var(--pn-color-text-secondary);
}
.lk-acc__inner > * + * { margin-top: var(--pn-space-16); } /* contract: 16 between groups */
.lk-acc__k { margin-bottom: var(--pn-space-8); font: 500 11px/1.3 var(--pn-font-mono); letter-spacing: 0.04em; color: var(--pn-color-text-muted); }
.lk-acc__p { font: 400 14px/1.5 var(--pn-font-sans); color: var(--pn-color-text-secondary); overflow-wrap: anywhere; }
.lk-acc__lead { color: var(--pn-color-text-primary); }
.lk-acc__links { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pn-space-8); }
.lk-acc__link { color: var(--pn-color-accent-primary); }
.lk-acc__foot { font: 400 12px/1.5 var(--pn-font-sans); color: var(--pn-color-text-muted); }
/* status chips: UNVERIFIED · CONFIDENCE MEDIUM · LLM-EXTRACTED */
.lk-flags { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pn-space-8) 6px; }
.lk-flag {
  padding: 4px 6px; border-radius: var(--pn-radius-control);
  background: var(--pn-color-background-surface); border: 1px solid var(--pn-color-border-decorative);
  font: 500 11px/1 var(--pn-font-mono); letter-spacing: 0.02em; color: var(--pn-color-text-secondary);
}
.lk-flags__sep { color: var(--pn-color-text-muted); font-size: 12px; }
/* label / value rows: label left (wraps), value right (never wraps), 36 tall, hairline between */
.lk-kv__row {
  display: grid; grid-template-columns: 1fr auto; column-gap: var(--pn-space-16); align-items: baseline;
  min-height: 36px; padding: 7px 0; /* 21 line + 14 + 1 hairline = 36 */
}
.lk-kv__row + .lk-kv__row { border-top: 1px solid var(--pn-color-border-decorative); }
.lk-kv dt { color: var(--pn-color-text-secondary); }
.lk-kv dd { white-space: nowrap; text-align: right; color: var(--pn-color-text-primary); }
.lk-kv dd.lk-acc__link { color: var(--pn-color-accent-primary); }
.lk-kv__aside { color: var(--pn-color-text-muted); }
.lk-nc { text-decoration: underline dotted var(--pn-color-text-muted); text-underline-offset: 3px; } /* the live app's "Not confirmed" */
/* permit records: small cards on the raised body (surface fill + hairline, like the envelope tiles) */
.lk-permits { display: flex; flex-direction: column; gap: var(--pn-space-12); }
.lk-permit {
  display: flex; flex-direction: column; gap: 4px;
  padding: var(--pn-space-16);
  background: var(--pn-color-background-surface); border: 1px solid var(--pn-color-border-decorative);
  border-radius: var(--pn-radius-control);
}
.lk-permit__top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--pn-space-16); }
.lk-permit__no { font: 500 14px/1.4 var(--pn-font-mono); color: var(--pn-color-text-primary); }
.lk-permit__date { font: 400 12px/1.4 var(--pn-font-mono); color: var(--pn-color-text-muted); }
.lk-permit__type { color: var(--pn-color-text-primary); }
.lk-permit__addr { font: 400 12px/1.4 var(--pn-font-mono); color: var(--pn-color-text-secondary); }
.lk-permit__meta { display: flex; gap: var(--pn-space-12); font: 400 13px/1.4 var(--pn-font-sans); color: var(--pn-color-text-muted); }
/* survey tables: mono 13, hairline rows, numbers right-aligned */
.lk-table { width: 100%; border-collapse: collapse; font: 400 13px/1.3 var(--pn-font-mono); color: var(--pn-color-text-primary); font-variant-numeric: tabular-nums; }
.lk-table th, .lk-table td { height: 32px; padding: 0; text-align: right; white-space: nowrap; }
.lk-table th:first-child { text-align: left; }
.lk-table thead th { height: 28px; font: 500 11px/1.3 var(--pn-font-mono); letter-spacing: 0.04em; color: var(--pn-color-text-muted); vertical-align: top; }
.lk-table tbody th { font-weight: 400; color: var(--pn-color-text-secondary); }
.lk-table tbody tr { border-top: 1px solid var(--pn-color-border-decorative); }
/* sources: two columns, name mono 13, date and record count muted, 32 rows */
.lk-src { display: grid; grid-template-columns: auto 1fr; column-gap: var(--pn-space-24); }
.lk-src dt, .lk-src dd { min-height: 32px; display: flex; align-items: center; }
.lk-src dt { font: 400 13px/1.3 var(--pn-font-mono); color: var(--pn-color-text-primary); }
.lk-src dd { font: 400 13px/1.3 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.lk-note { margin-top: var(--pn-space-24); font: 400 13px/1.5 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.lk-note strong { font-weight: 500; color: var(--pn-color-text-primary); }

/* Map: fictional aerial (assets/aerial-northshore-fictional.jpg), dimmed for the dark UI. All overlay positions are
   in map pixels (820 wide); the photo is placed so the clear lot (photo px 515-675 x 374-470, scale 1.13) sits
   exactly under the parcel rectangle (63-244 x 106-214), left of the checklist window (map x 308+). The photo is mirrored left-right so the lot's street and
   driveway face the parcel's left edge: the contract puts "front 3.1 m" on the left, and a front setback faces the street. */
.lk-map { position: relative; flex: 1 1 auto; overflow: hidden; background: var(--pn-color-background-canvas); }
.lk-map__world { position: absolute; inset: 0; transform-origin: 153.5px 160px; }
.lk-map__photo {
  position: absolute; left: -602.4px; top: -316.9px;
  width: 1428.3px; height: 958.2px; max-width: none;
  transform: scaleX(-1);
  filter: brightness(0.72) saturate(0.85);
}
.lk-map__vignette {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 620px 440px at 154px 170px, rgba(11, 14, 20, 0) 0%, rgba(11, 14, 20, 0.35) 100%);
}
/* Home hero at the 760 stage (owner 2026-11-04): the photo's bottom sat 75 above the window's, so the world moves down
   75 (parcel, labels and vignette together, as Platform's 79 and Municipalities' 36 do) and the photo reaches the edge */
.hero .lk-map__world { transform: translateY(75px); }
.hero .lk-map__vignette { background: radial-gradient(ellipse 620px 440px at 154px 245px, rgba(11, 14, 20, 0) 0%, rgba(11, 14, 20, 0.35) 100%); }
.lk-map__overlay { position: absolute; left: 0; top: 0; overflow: visible; }
.lk-parcel { fill: none; stroke: #f5c84b; stroke-width: 2; stroke-linejoin: miter; } /* the app's parcel yellow */
.lk-dot { fill: #f5c84b; transform-box: fill-box; transform-origin: center; }
.lk-setback { fill: none; stroke: #5b8def; stroke-width: 1.5; stroke-opacity: 0.8; stroke-dasharray: 4 4; }
.lk-dim, .lk-corner {
  position: absolute; white-space: nowrap;
  font: 500 12px/1 var(--pn-font-sans); color: #fff;
  /* dark halo, like the live app's outlined labels: the photo's light patches (road, sidewalk, driveway) measure
     3.4-4.4:1 against white on their own; the halo puts a dark ring under every glyph edge */
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.9), 0 0 2px rgba(0, 0, 0, 0.9), 0 0 4px rgba(0, 0, 0, 0.7);
}
.lk-corner { font-weight: 600; }
.lk-dim--c { transform: translate(-50%, -50%); }
.lk-dim--r { transform: translate(-100%, -50%); }
.lk-dim--l { transform: translate(0, -50%); }
.lk-dim--v { transform: translate(-50%, -50%) rotate(-90deg); }

/* ---- Front window: Required to submit (compact) ---- */
.ck { padding: var(--pn-space-24) 20px; } /* r3.1: 20 sides (not a token) + an 8 chevron gap so the longest name (338 at 15px) fits one line in 480 */
.ck-head__line { display: flex; align-items: baseline; gap: var(--pn-space-12); }
.ck-head__title { font: var(--pn-type-ui-label-l); }
.ck-head__count { font: var(--pn-type-caption-technical); color: var(--pn-color-text-muted); }
.ck-head__sub { margin-top: 6px; font: 400 14px/1.4 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.ck-list { display: flex; flex-direction: column; gap: var(--pn-space-8); margin: var(--pn-space-24) 0 0; padding: 0; list-style: none; }
.ck-row {
  display: flex; align-items: center; gap: var(--pn-space-12);
  min-height: 64px; padding: var(--pn-space-12) var(--pn-space-16);
  background: var(--pn-color-background-raised);
  border-radius: var(--pn-radius-card);
}
.ck-row__tile {
  flex: none; width: 32px; height: 32px; border-radius: var(--pn-radius-card);
  display: grid; place-items: center;
  background: var(--pn-color-accent-tint);
}
.ck-row__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: var(--pn-space-4); }
.ck-row__name { font: 500 15px/1.3 var(--pn-font-sans); }
.ck-row__chev { margin-left: calc(var(--pn-space-4) * -1); color: var(--pn-color-text-muted); }

/* Pre-hide the animated parts until the timeline's first frame (JS writes inline styles from then on).
   Under reduced motion nothing is hidden: the settled state is the markup. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-hero-stage] [data-anim]:not([data-anim="go"]) { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .lk-acc__body, .lk-acc__row[aria-expanded="true"] + .lk-acc__body, .lk-acc__row .hw-ico { transition: none; }
}

/* ---------- H02 Built for ---------- */
.intro { max-width: 800px; }
.route-cards {
  margin-top: var(--pn-space-64);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 410px));
  gap: var(--pn-space-24);
}
.route-card {
  position: relative;
  display: flex; flex-direction: column;
  height: 600px;
  padding-top: var(--card-text-top, 256px); /* Figma uses 289 (block H 311); the municipalities copy overflows that by ~6px and pushes its link out of line, so H = 344 here. */
  border-radius: var(--pn-radius-card-l); /* owner 2026-11-01 (audit VC-011): content cards 16 */
  overflow: hidden;
  isolation: isolate;
  background: var(--pn-color-background-raised);
  cursor: pointer;
}
.route-card__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1); transform-origin: center;
  transition: transform 600ms var(--pn-ease-out);
}
.route-card__scrim {
  position: absolute; left: 0; right: 0; bottom: 0; height: 70%; z-index: -1;
  /* Figma: canvas 0% -> 95% across the scrim. The real screenshots are light UI, so that ramp left the
     card copy on near-white (eyebrow ~1.3:1). The ramp now reaches 92% by the eyebrow line and holds. */
  background: linear-gradient(to bottom, rgba(11, 14, 20, 0) 0%, rgba(11, 14, 20, 0.92) 25%, rgba(11, 14, 20, 0.97) 45%, rgba(11, 14, 20, 0.97) 100%);
  transition: opacity 600ms var(--pn-ease-out);
}
.route-card:hover .route-card__img,
.route-card:focus-visible .route-card__img { transform: scale(1.03); }
.route-card:hover .route-card__scrim,
.route-card:focus-visible .route-card__scrim { opacity: 0.9; }
.route-card__text {
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  padding: var(--pn-space-32);
}
.route-card__eyebrow { color: var(--pn-color-text-primary); }
.route-card__title { margin-top: var(--pn-space-12); min-height: 3lh; color: var(--pn-color-text-primary); } /* owner 2026-11-04 ("make the captions aligned"): a three-line title slot, so the captions start on the same line across the row whether a title runs two lines or three */
.route-card__body { margin-top: var(--pn-space-12); color: var(--pn-color-text-secondary); }
.route-card__link { margin-top: auto; padding-top: var(--pn-space-12); }
/* Paul 2026-11-04: the whole card is the link, so the whole card hovers it: the bar draws and the arrow turns from anywhere on
   the card, not only over the text (the old rule set text-decoration-color, dead since the drawn bar of 2026-10-29) */
.route-card:hover .route-card__link .link__text::after,
.route-card:focus-visible .route-card__link .link__text::after { transform: scaleX(1); transform-origin: left; }
.route-card:hover .route-card__link .link__arrow,
.route-card:focus-visible .route-card__link .link__arrow { transform: rotate(-45deg); }

/* ---------- H03 / H04 Linear-style feature sections ---------- */
.feature__lead { color: var(--pn-color-text-secondary); } /* owner 2026-10-14: fills its column (was capped at 560 in a 608 column) */
.feature__more { display: inline-block; margin-top: var(--pn-space-24); }
.figure {
  position: relative;
  margin-top: var(--pn-space-96);
  width: 100%; aspect-ratio: 16 / 9;
  border-radius: var(--pn-radius-card);
  overflow: hidden;
  background: var(--pn-color-background-raised);
}
.figure__img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 0; }
.figure__expand {
  position: absolute; top: var(--pn-space-12); right: var(--pn-space-12);
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: var(--pn-radius-control);
  /* Figma fills this glyph with canvas; a white frost vanished on the light screenshots, so canvas-frost */
  background: rgba(11, 14, 20, 0.72);
  -webkit-backdrop-filter: blur(var(--pn-blur-frost));
  backdrop-filter: blur(var(--pn-blur-frost));
  color: var(--pn-color-text-primary);
  opacity: 0.7;
  transition: opacity 160ms ease, background-color 160ms ease;
}
.figure:hover .figure__expand, .figure__expand:focus-visible { opacity: 1; }
.figure__expand:hover { background: rgba(11, 14, 20, 0.9); }
.figure__img { cursor: zoom-in; }

/* ---------- r5: H03 / H04 static dark-mode UI recreations (.figure--ui) ----------
   Native HTML/CSS/SVG laid out at 1280x720; not interactive (pointer-events off), no lightbox.
   Extra status colours are not tokens; they are scoped here. The *-text variants exist because the contract hexes
   (#E5484D red, #5B8DEF blue) fall under 4.5:1 as text on the dark raised fill; the base hexes stay for fills,
   outlines and icons. */
.figure--ui, .mu-hero__win {
  --ui-amber: #e8b23a;
  --ui-amber-tint: rgba(232, 178, 58, 0.14);
  --ui-red: #e5484d;
  --ui-red-text: #f07075;
  --ui-red-fill: #c9363b; /* badge fill: white on #E5484D is 3.9:1 */
  --ui-blue: #5b8def;
  --ui-blue-text: #8fb3f6;
  --ui-blue-tint: rgba(91, 141, 239, 0.12);
  background: var(--pn-color-background-surface);
  user-select: none; -webkit-user-select: none;
}
/* Amendment r5: the recreation scrolls inside the frame. The scroll region is the only interactive thing: wheel, drag
   and arrow keys scroll it; the recreation inside has pointer-events off, so nothing in it is clickable or hoverable.
   Scroll chaining stays on (overscroll-behavior auto), as in the hero panel: at the end the page takes over. */
.figure__scroll {
  position: relative; z-index: 1; height: 100%;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior-y: auto;
  border-radius: inherit;
}
.figure__scroll:focus-visible { outline: 2px solid var(--pn-color-focus); outline-offset: -2px; }
.figure__scroll::-webkit-scrollbar { width: 6px; }
.figure__scroll::-webkit-scrollbar-track { background: transparent; }
.figure__scroll::-webkit-scrollbar-thumb { background: var(--pn-color-surface-frostHover); border-radius: var(--pn-radius-pill); }
@supports not selector(::-webkit-scrollbar) {
  .figure__scroll { scrollbar-width: thin; scrollbar-color: var(--pn-color-surface-frostHover) transparent; }
}
/* Only the figure whose content is taller than 720 gets the bottom fade and the 96 + 24 run-out. On the checker
   (exactly 720) the padding would create a 120px scroll and the fade would cover its footer button. The fade stops
   8px short of the right edge so the 6px scrollbar column stays clear.
   Owner 2026-11-04 ("remove the hairline outline and just simply give it a bottom fade", then "same for these
   screens"): every UI figure's fade ends in the page canvas, like the hero fades, so the window dissolves into the
   page instead of ending at a box edge; the .figure--ui::after hairline is gone, as is every other screen frame's
   (.hw::after, .aw::after, .co-view::after): "get rid of the outline on all screens across the site". */
.figure--ui-scroll .figure__scroll { padding-bottom: calc(96px + 24px); }
.figure--ui-scroll::before {
  content: ""; position: absolute; z-index: 4; left: 0; right: 8px; bottom: 0; height: 96px;
  background: linear-gradient(to bottom, rgba(11, 14, 20, 0), var(--pn-color-background-canvas));
  border-bottom-left-radius: inherit;
  pointer-events: none;
}
.ui {
  position: relative; width: 1280px; overflow: hidden; /* height = content: the checker is exactly 720, approvals taller */
  pointer-events: none;
  color: var(--pn-color-text-primary); font-family: var(--pn-font-sans); text-align: left;
}
/* zero-specificity resets so the component classes below can set margins */
:where(.ui) p { margin: 0; }
:where(.ui) ul { margin: 0; padding: 0; list-style: none; }
.ui .hw-ico { color: var(--pn-color-text-muted); }
.ui .hw-ico--accent { color: var(--pn-color-accent-primary); }
.ui-amber { color: var(--ui-amber); }
.ui-green { color: var(--pn-color-accent-primary); }
.ui-label { font: 500 11px/1.3 var(--pn-font-mono); letter-spacing: 0.08em; color: var(--pn-color-text-muted); }
.ui-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ui-dot--green { color: var(--pn-color-accent-primary); }
.ui-dot--amber { color: var(--ui-amber); }
.ui-chip {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  height: 24px; padding: 0 10px; border-radius: var(--pn-radius-pill);
  font: 500 12px/1 var(--pn-font-sans); white-space: nowrap;
}
.ui-chip--lg { height: 28px; padding: 0 12px; font-size: 13px; }
.ui-chip--code { height: 22px; padding: 0 8px; font: 500 10.5px/1 var(--pn-font-mono); letter-spacing: 0.06em; }
.ui-chip--sq { border-radius: var(--pn-radius-control); height: 26px; font-size: 11.5px; }
.ui-chip--amber { background: var(--ui-amber-tint); color: var(--ui-amber); }
.ui-chip--green { background: var(--pn-color-accent-tint); color: var(--pn-color-accent-primary); }
.ui-chip--blue { background: var(--ui-blue-tint); color: var(--ui-blue-text); }
.ui-chip--neutral { background: var(--pn-color-surface-frostDisabled); color: var(--pn-color-text-secondary); }
.ui-count, .ui-mk {
  flex: none; display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%;
  background: var(--ui-amber); color: var(--pn-color-background-canvas);
  font: 600 11px/1 var(--pn-font-sans);
}
.ui-round {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%;
  background: var(--pn-color-surface-frost);
}
.ui-round .hw-ico { color: var(--pn-color-text-primary); }
.ui-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex: none;
  height: 40px; padding: 0 18px; border-radius: var(--pn-radius-pill);
  font: var(--pn-type-ui-label-s); white-space: nowrap;
}
.ui-btn--sm { height: 28px; padding: 0 11px; gap: 5px; font-size: 12px; }
.ui-btn--block { display: flex; width: 100%; }
.ui-btn--frost { background: var(--pn-color-surface-frost); color: var(--pn-color-text-primary); }
.ui-btn--frost .hw-ico { color: var(--pn-color-text-primary); }
.ui-btn--fill { background: var(--pn-color-brand-greenTint); color: var(--pn-color-brand-green); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--pn-color-brand-green) 35%, transparent); } /* owner 2026-10-29: secondary, translucent green */
.ui-btn--danger { border: 1px solid var(--ui-red); color: var(--ui-red-text); }

/* ---- H03: Drawing Checker ---- */
.uc-bar {
  height: 56px; display: flex; align-items: center; gap: 48px;
  padding: 0 24px;
  background: var(--pn-color-background-canvas);
  border-bottom: 1px solid var(--pn-color-border-decorative);
}
.uc-brand { display: flex; align-items: center; gap: 10px; font: 600 16px/1 var(--pn-font-sans); }
.uc-logo { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 7px; background: var(--pn-color-accent-fill); }
.uc-logo .hw-ico { color: var(--pn-color-text-onAccent); }
.uc-nav { display: flex; gap: 32px; font: 500 14px/1 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.uc-nav > span { display: flex; align-items: center; gap: 8px; }
.uc-bell { position: relative; margin-left: auto; display: grid; place-items: center; width: 32px; height: 32px; margin-right: -24px; }
.uc-bell .hw-ico { width: 20px; height: 20px; color: var(--pn-color-text-secondary); }
.uc-bell__badge {
  position: absolute; top: 1px; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px;
  display: grid; place-items: center; background: var(--ui-red-fill); color: #fff; font: 600 10px/1 var(--pn-font-sans);
  box-shadow: 0 0 0 2px var(--pn-color-background-canvas);
}
.uc-user {
  display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 10px 0 5px;
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-pill);
  font: 500 14px/1 var(--pn-font-sans);
}
.uc-avatar { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--pn-color-accent-fill); color: var(--pn-color-text-onAccent); font: 600 11px/1 var(--pn-font-sans); letter-spacing: 0.02em; }
.uc-body { display: flex; height: 664px; }
.uc-side {
  flex: none; width: 224px; padding: 24px 6px;
  background: var(--pn-color-background-surface);
  border-right: 1px solid var(--pn-color-border-decorative);
}
.uc-back, .uc-set { display: flex; align-items: center; gap: 8px; padding: 0 11px; }
.uc-back { font: 500 14px/1 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.uc-back .hw-ico { margin-left: -2px; }
.uc-set { margin-top: 24px; font: 600 14px/1 var(--pn-font-sans); }
.uc-setstatus { display: flex; align-items: center; justify-content: space-between; margin: 14px -6px 0; padding: 0 17px 20px; /* divider runs full-bleed across the sidebar */ border-bottom: 1px solid var(--pn-color-border-decorative); }
.uc-round { font: 500 12px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uc-sec { margin: 22px 11px 8px; }
.uc-sheets { display: flex; flex-direction: column; gap: 2px; }
.uc-sheet {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 8px 8px 10px; border-radius: var(--pn-radius-card); border: 1px solid transparent;
}
.uc-sheet.is-sel { background: var(--pn-color-background-raised); border-color: var(--pn-color-border-decorative); }
.uc-sheet__t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.uc-sheet__n { font: 500 13px/1.2 var(--pn-font-mono); }
.uc-sheet__m { font: 400 11.5px/1.25 var(--pn-font-sans); color: var(--pn-color-text-secondary); white-space: nowrap; }

.uc-view { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; background: var(--pn-color-background-canvas); }
.uc-view__head { display: flex; align-items: flex-start; justify-content: space-between; padding: 24px 32px 0; }
.uc-view__title { display: flex; align-items: baseline; gap: 10px; font: var(--pn-type-ui-label-l); }
.uc-view__num { font: 500 18px/1.3 var(--pn-font-mono); }
.uc-view__sub { margin-top: 6px; font: 400 13px/1.3 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uc-view__tools { display: flex; align-items: center; gap: 8px; }
.uc-view__tools .ui-chip { margin-right: 8px; }
.uc-sheetwrap { flex: 1 1 auto; display: grid; place-items: center; padding: 0 0 8px; }
.uc-plan {
  display: block; background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-control);
}
.uc-plan__frame { fill: none; stroke: var(--pn-color-border-control); stroke-width: 1; }
.uc-plan__setback { fill: none; stroke: var(--pn-color-text-muted); stroke-width: 1; stroke-dasharray: 6 4; }
.uc-plan__tick { fill: none; stroke: var(--pn-color-text-muted); stroke-width: 1; }
.uc-plan__lot { fill: none; stroke: var(--pn-color-text-secondary); stroke-width: 1.5; }
.uc-plan__house { fill: var(--pn-color-background-surface); stroke: var(--pn-color-text-secondary); stroke-width: 1.25; }
.uc-plan__add { stroke: var(--pn-color-text-secondary); stroke-width: 1.25; }
.uc-plan__hatch { stroke: var(--pn-color-text-muted); stroke-width: 1; }
.uc-plan__lblbg { fill: var(--pn-color-background-raised); }
.uc-plan__lbl { font: 500 9px var(--pn-font-mono); letter-spacing: 0.06em; fill: var(--pn-color-text-secondary); }
.uc-plan__lbl--b { font-weight: 500; fill: var(--pn-color-text-primary); }
.uc-plan__street { font: 400 10px var(--pn-font-mono); letter-spacing: 0.08em; fill: var(--pn-color-text-secondary); }
.uc-plan__north { fill: none; stroke: var(--pn-color-text-secondary); stroke-width: 1; }
.uc-plan__north-a { fill: none; stroke: var(--pn-color-text-secondary); stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }
.uc-plan__mk circle { fill: var(--ui-amber); }
.uc-plan__mk text { font: 600 11px var(--pn-font-sans); fill: var(--pn-color-background-canvas); }
.uc-tb__box { fill: var(--pn-color-background-raised); stroke: var(--pn-color-border-control); stroke-width: 1; }
.uc-tb__rule { fill: none; stroke: var(--pn-color-border-control); stroke-width: 1; }
.uc-tb__brand { font: 500 8.5px var(--pn-font-mono); letter-spacing: 0.08em; fill: var(--pn-color-text-primary); }
.uc-tb__k { font: 400 6.5px var(--pn-font-mono); letter-spacing: 0.04em; fill: var(--pn-color-text-secondary); }
.uc-tb__v { font: 500 8px var(--pn-font-mono); fill: var(--pn-color-text-primary); }
.uc-tb__sheet { font: 500 13px var(--pn-font-mono); fill: var(--pn-color-text-primary); }

.uc-panel {
  flex: none; width: 328px; display: flex; flex-direction: column;
  background: var(--pn-color-background-surface);
  border-left: 1px solid var(--pn-color-border-decorative);
}
.uc-panel__scroll { flex: 1 1 auto; min-height: 0; overflow: hidden; padding: 16px 20px 0; }
.uc-prog { display: flex; align-items: center; gap: 14px; }
.uc-ring { width: 42px; height: 42px; }
.uc-ring { flex: none; }
.uc-ring__track { fill: none; stroke: var(--pn-color-border-decorative); stroke-width: 3; }
.uc-ring__arc { fill: none; stroke: var(--pn-color-accent-primary); stroke-width: 3; stroke-linecap: round; }
.uc-ring text { font: 500 12px var(--pn-font-sans); fill: var(--pn-color-text-primary); }
.uc-prog__t { display: block; font: 600 15px/1.3 var(--pn-font-sans); }
.uc-prog__s { display: block; margin-top: 3px; font: 400 12px/1.3 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uc-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--pn-color-border-decorative); }
.uc-stat { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 9px 0 8px; background: var(--pn-color-background-raised); border-radius: var(--pn-radius-card); }
.uc-stat__n { font: 500 17px/1 var(--pn-font-mono); }
.uc-stat__k { font: 400 11.5px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uc-tabs { display: flex; gap: 4px; margin-top: 12px; padding: 3px; border-radius: var(--pn-radius-card); background: var(--pn-color-background-canvas); }
.uc-tab { padding: 7px 10px; border-radius: 6px; font: 500 12.5px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uc-tab.is-sel { background: var(--pn-color-background-raised); color: var(--pn-color-text-primary); }
.uc-cmt {
  margin-top: 10px; padding: 14px 14px;
  background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card);
}
.uc-cmt.is-sel { border-color: var(--pn-color-accent-primary); }
.uc-cmt__top { display: flex; align-items: center; gap: 8px; }
.uc-cmt__state { margin-left: auto; font: 500 12px/1 var(--pn-font-sans); color: var(--ui-amber); }
.uc-cmt__t { margin-top: 8px; font: 600 14px/1.3 var(--pn-font-sans); }
.uc-cmt__b { margin-top: 4px; font: 400 12.5px/1.5 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.uc-cmt__foot { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
.uc-cmt__ref { font: 400 11px/1 var(--pn-font-mono); white-space: nowrap; color: var(--pn-color-text-muted); }
.uc-panel__foot { flex: none; padding: 12px 20px 18px; border-top: 1px solid var(--pn-color-border-decorative); text-align: center; }
.uc-panel__foot p { margin-bottom: 8px; font: 400 12px/1.3 var(--pn-font-sans); color: var(--pn-color-text-muted); }

/* ---- r6 / r6.1: H03 two-window stack. Form validation (front) over the drawing checker (back); hover/focus swaps depth ----
   r6.1: both windows are 960x600: the recreations are laid out natively at 1280x800 (no app bar) and scaled by 0.75
   (top left), so text stays vector. Back x 320 y 0, front x 0 y 120: 640px horizontal overlap. No frame behind them:
   the figure keeps its 1280x720 footprint but has no fill, hairline or clipping, so the windows float on the canvas
   and their shadows run past the footprint. The window in front gets the deep shadow and a frost hairline; the one
   behind gets a canvas veil at 45%. The swap: each window travels 12/12 toward its new spot over 320ms; z-index flips
   at 160ms (a delayed zero-length transition), so the windows pass each other at the midpoint. */
.figure--stack { background: transparent; border-radius: 0; overflow: visible; }
.figure--stack::after { content: none; }
.figure__stack { position: relative; z-index: 1; height: 100%; outline: none; }
.aw {
  --aw-shadow-front: 0 32px 96px rgba(0, 0, 0, 0.7);
  --aw-shadow-back: 0 24px 64px rgba(0, 0, 0, 0.55);
  position: absolute; width: 960px; height: 600px;
  border-radius: var(--pn-radius-card); overflow: hidden;
  background: var(--pn-color-background-surface);
  box-shadow: var(--aw-shadow-back);
  transition: transform 320ms ease-in-out, box-shadow 320ms ease-in-out, z-index 0s linear 160ms;
}
.aw--back { top: 0; left: 320px; z-index: 1; }
.aw--front { top: 120px; left: 0; z-index: 2; }
.aw__scale { width: 1280px; height: 800px; transform: scale(0.75); transform-origin: 0 0; }
.aw::before { /* veil */
  content: ""; position: absolute; inset: 0; z-index: 4;
  background: var(--pn-color-background-canvas); opacity: 0;
  transition: opacity 320ms ease-in-out;
  pointer-events: none;
}
.aw::after { /* owner 2026-11-04: no hairline (was 1px border-decorative); the box stays for the hover tint and the focus ring */
  content: ""; position: absolute; inset: 0; z-index: 5;
  border: 0; border-radius: inherit;
  transition: border-color 320ms ease-in-out;
  pointer-events: none;
}
/* depth states: at rest the form is in front. Owner 2026-10-31: whichever window the pointer is over comes to the
   front, so the checker comes forward only while the pointer is on ITS exposed area (:has(.aw--back:hover)); over the
   form, the form stays in front. Keyboard focus still brings the checker forward (Paul 2026-11-04: :focus-visible, not
   :focus-within; a mouse click also focused the region and pinned the checker forward, so hover stopped working). */
.aw--front,
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--back { box-shadow: var(--aw-shadow-front); }
.aw--front::after,
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--back::after { border-color: rgba(242, 240, 233, 0.18); }
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--front { box-shadow: var(--aw-shadow-back); }
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--front::after { border-color: var(--pn-color-border-decorative); }
.aw--back::before { opacity: 0.45; }
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--back { z-index: 2; transform: translate(-12px, 12px); }
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--front { z-index: 1; transform: translate(12px, -12px); }
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--back::before { opacity: 0; }
.figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--front::before { opacity: 0.45; }
/* keyboard focus brings the checker forward; the focus ring is that front window's outline */
.figure--stack:has(.figure__stack:focus-visible) .aw--back::after { border: 2px solid var(--pn-color-focus); }
/* both recreations in their windows: no app bar, 800 tall (r7: the checker's own layout is the .dc-* block below) */
.aw .ui { height: 800px; }
/* responsive fit (2026-11-04, contract §1): the H03 stack and the H04 dashboard are laid out at their native 1280 x 720 and
   scale whole to their figure (k = figure width / 1280, from-top-left), never reflowed. Keyed to the figure's own width, not
   a viewport tier, so it is a no-op at a 1280 container (1440 unchanged) and covers the 1280-1359 viewports where the 40
   margin narrows the container. tan(atan2(a, b)) = a / b as a plain number (lengths cannot be divided in CSS yet). */
.figure--stack, #municipal-review .figure { container-type: inline-size; }
@container (max-width: 1279.98px) {
  .figure--stack > .figure__stack { position: absolute; top: 0; left: 0; } /* out of flow, so the figure's 16:9 (not the 720 native box) sets its height */
  .figure--stack > .figure__stack, #municipal-review .figure__scroll {
    width: 1280px; height: 720px;
    transform: scale(tan(atan2(100cqw, 1280px))); transform-origin: 0 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .aw, .aw::before, .aw::after { transition: none; }
  .figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--back,
  .figure--stack:is(:has(.aw--back:hover), :has(.figure__stack:focus-visible)) .aw--front { transform: none; }
}

/* ---- r7: H03 back window = Drawing Package Checker results (.dc-*), native 1280x800, no app bar ----
   Dark recreation of a real checker run (identity fictional: docs/reference/drawing-checker-results-fictional.txt).
   Left 544 (results: project row, verdict, table, other checks, readiness) scrolls under the H04-style bottom fade;
   right 736 (file bar + page well) is a static frame scrolled past most of p.1. Same system as the hero's lookup
   window: surface fill, raised cards and well, decorative hairlines. Green = pass only (and group headers, as in the
   real checker). Amber = --ui-amber (this figure family's warning amber, also on the form window). Sheets are paper. */
.dc-body { --dc-paper: var(--pn-color-background-surface); /* owner 2026-10-14: no white paper; sheets inverted into the dark system */ --dc-fail-tint: color-mix(in srgb, var(--pn-color-status-error) 16%, transparent);
  display: flex; height: 800px; background: var(--pn-color-background-surface); }
.dc-left { position: relative; flex: none; width: 544px; border-right: 1px solid var(--pn-color-border-decorative); }
.dc-scroll {
  height: 100%; overflow-x: hidden; overflow-y: auto; overscroll-behavior-y: auto;
  pointer-events: auto; /* wheel-scrollable like H04; nothing inside is interactive */
  padding-bottom: calc(96px + 24px);
}
.dc-scroll::-webkit-scrollbar { width: 6px; }
.dc-scroll::-webkit-scrollbar-track { background: transparent; }
.dc-scroll::-webkit-scrollbar-thumb { background: var(--pn-color-surface-frostHover); border-radius: var(--pn-radius-pill); }
@supports not selector(::-webkit-scrollbar) {
  .dc-scroll { scrollbar-width: thin; scrollbar-color: var(--pn-color-surface-frostHover) transparent; }
}
.dc-left::after, .dc-well::after { /* the H04 fade: 96 tall, 8 short of the right edge so the scrollbar column stays clear */
  content: ""; position: absolute; z-index: 2; left: 0; right: 8px; bottom: 0; height: 96px;
  background: linear-gradient(to bottom, rgba(11, 14, 20, 0), var(--pn-color-background-canvas)); /* owner 2026-11-04: to the canvas */
  pointer-events: none;
}
.dc-proj { padding: 40px 28px 32px; border-bottom: 1px solid var(--pn-color-border-decorative); }
.dc-proj__top { display: flex; align-items: center; justify-content: space-between; }
.dc-pill {
  display: inline-flex; align-items: center; height: 32px; padding: 0 16px;
  border: 1px solid var(--pn-color-text-primary); border-radius: var(--pn-radius-pill);
  font: 500 13px/1 var(--pn-font-sans); color: var(--pn-color-text-primary);
}
.dc-proj__name { margin-top: 12px; font: var(--pn-type-ui-label); color: var(--pn-color-text-primary); }
.dc-main { padding: 28px 28px 0; } /* keeps the summary line clear of the front window's top edge (native y 160) at rest */
.dc-sum { font: 400 13px/1.5 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.dc-verdict { display: flex; gap: 8px; margin-top: 12px; }
.dc-chip {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 10px 0 8px;
  border-radius: var(--pn-radius-pill); font: 500 12px/1 var(--pn-font-sans); white-space: nowrap;
}
.dc-chip--pass { background: var(--pn-color-accent-tint); color: var(--pn-color-accent-primary); }
.dc-chip--fail { background: var(--dc-fail-tint); color: var(--pn-color-status-error); }
.ui .dc-chip .hw-ico { color: currentColor; stroke-width: 2; }
.dc-search {
  display: flex; align-items: center; gap: 8px; height: 40px; margin-top: 20px; padding: 0 16px;
  background: var(--pn-color-background-raised); border: 1px solid var(--pn-color-border-decorative);
  border-radius: var(--pn-radius-pill);
  font: 400 14px/1 var(--pn-font-sans); color: var(--pn-color-text-muted);
}
/* the table: one grid template per row so the three columns line up */
.dc-table { margin-top: 20px; border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card); overflow: hidden; }
.dc-th, .dc-tr { display: grid; grid-template-columns: 116px 156px minmax(0, 1fr); column-gap: 10px; padding: 0 12px; }
.dc-th {
  align-items: center; height: 36px; background: var(--pn-color-background-raised);
  font: 500 11px/1 var(--pn-font-sans); letter-spacing: 0.08em; color: var(--pn-color-text-muted);
}
.dc-tr { align-items: start; padding-top: 10px; padding-bottom: 10px; border-top: 1px solid var(--pn-color-border-decorative); font: 400 13px/1.45 var(--pn-font-sans); }
.dc-f { color: var(--pn-color-text-secondary); }
.dc-v { color: var(--pn-color-text-primary); overflow-wrap: anywhere; }
.dc-c { display: flex; align-items: flex-start; gap: 6px; color: var(--pn-color-text-secondary); }
.dc-c .hw-ico { margin-top: 2px; stroke-width: 2; }
.ui .dc-c--ok .hw-ico { color: var(--pn-color-accent-primary); }
.dc-c--warn, .ui .dc-c--warn .hw-ico { color: var(--ui-amber); }
.dc-c--muted { color: var(--pn-color-text-muted); }
.dc-select {
  display: inline-flex; align-items: center; gap: 10px; height: 26px; margin: -3px 0; padding: 0 8px 0 10px;
  border: 1px solid var(--pn-color-border-control); border-radius: var(--pn-radius-control);
}
.dc-add { color: var(--pn-color-text-secondary); text-decoration: underline; text-decoration-color: var(--pn-color-border-control); text-underline-offset: 3px; }
.dc-grp {
  display: flex; align-items: center; gap: 10px; height: 40px; padding: 0 12px;
  border-top: 1px solid var(--pn-color-border-decorative); background: var(--pn-color-surface-frostDisabled);
}
.dc-grp__n { font: 600 14px/1 var(--pn-font-sans); color: var(--pn-color-accent-primary); }
.dc-grp__k { font: 400 12px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.dc-grp .hw-ico { margin-left: auto; }
.ui .dc-grp:not(.is-closed) .hw-ico { color: var(--pn-color-accent-primary); }
.dc-grp.is-closed { background: transparent; }
.dc-sec { margin: 40px 0 12px; }
.dc-checks { border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card); }
.dc-ck { display: flex; align-items: flex-start; gap: 12px; padding: 14px 16px; }
.dc-ck + .dc-ck { border-top: 1px solid var(--pn-color-border-decorative); }
.dc-badge {
  flex: none; display: inline-grid; place-items: center; width: 42px; height: 22px; margin-top: -1px;
  border-radius: var(--pn-radius-pill); font: 500 11.5px/1 var(--pn-font-sans);
}
.dc-badge--pass { background: var(--pn-color-accent-tint); color: var(--pn-color-accent-primary); }
.dc-badge--fail { background: var(--dc-fail-tint); color: var(--pn-color-status-error); }
.dc-ck__txt { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.dc-ck__t { font: 500 13px/1.45 var(--pn-font-sans); color: var(--pn-color-text-primary); }
.dc-ck__b { font: 400 12.5px/1.5 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.dc-ready { padding: 16px; background: var(--pn-color-background-raised); border-radius: var(--pn-radius-card); }
.dc-ready__file { display: flex; align-items: center; gap: 8px; font: 500 13px/1.3 var(--pn-font-sans); }
.dc-ready__flag { display: flex; align-items: center; gap: 6px; margin-top: 12px; font: 500 13px/1.3 var(--pn-font-sans); color: var(--ui-amber); }
.ui .dc-ready__flag .hw-ico { color: currentColor; stroke-width: 2; }
.dc-ready__b { margin-top: 6px; font: 400 12.5px/1.5 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
/* right pane: file bar + page well */
.dc-right { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.dc-file {
  flex: none; display: flex; align-items: center; gap: 16px; height: 72px; padding: 0 24px;
  border-bottom: 1px solid var(--pn-color-border-decorative);
}
.dc-file__name { display: block; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font: 500 14px/1.3 var(--pn-font-sans); white-space: nowrap; } /* 2026-10-14 shared fix: truncates instead of running into the meta text when the checker is laid out narrow (Homeowners step 04) */
.dc-file__name .hw-ico { vertical-align: -3px; margin-right: 8px; }
.dc-file__meta { flex: none; margin-left: auto; padding-left: 16px; font: 400 13px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); white-space: nowrap; }
.dc-file__tools { flex: none; display: flex; gap: 8px; margin-left: 16px; }
.dc-file { container-type: inline-size; }
@container (max-width: 520px) { .dc-file__meta { display: none; } } /* narrow layouts (scaled partial): drop the page/size meta so the filename keeps some width */
.dc-trash { background: var(--dc-fail-tint); }
.ui .dc-trash .hw-ico { color: var(--pn-color-status-error); }
.dc-well { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; background: var(--pn-color-background-raised); }
.dc-well::after { right: 0; background: linear-gradient(to bottom, transparent, var(--pn-color-background-raised)); }
/* scrolled: the last ~100px of p.1, all of p.2, the top of p.3 under the fade */
.dc-pages { display: flex; flex-direction: column; gap: 16px; padding: 24px 24px 0; transform: translateY(-354px); } /* architect 2026-10-14: open on p.2 (plans); the blank p.1 sits above the well */
.dc-sheet { position: relative; padding: 16px; background: var(--dc-paper); border-radius: 2px; box-shadow: inset 0 0 0 1px var(--pn-color-border-decorative); }
.dc-sheet img { display: block; width: 100%; height: auto; filter: invert(1) grayscale(1); mix-blend-mode: screen; opacity: 0.78; } /* black-on-white drawing → light lines on the dark sheet */
.dc-sheet--blank { height: 330px; } /* same box as p.2; its real title block cannot be shown */
.dc-sheet__lbl { position: absolute; left: 20px; bottom: 16px; font: 500 11px/1 var(--pn-font-sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--pn-color-text-secondary); }

/* ---- r6: Form validation screen (.ui--form), native 1280x800 (r6.1: no app bar) ---- */
.ui--form { background: var(--pn-color-background-surface); }
.uf-body { display: flex; gap: 64px; height: 800px; padding: 32px 48px 0; overflow: hidden; }
.uf-main { flex: none; width: 720px; }
.uf-top { display: flex; align-items: center; justify-content: space-between; height: 22px; }
.uf-top > .uc-back { padding: 0; }
.uf-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 40px; margin-top: 20px; }
.uf-title { white-space: nowrap; font: 500 24px/1.25 var(--pn-font-sans); letter-spacing: -0.01em; }
.uf-meta { display: flex; align-items: center; gap: 12px; font: 400 13px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uf-prog { flex: none; width: 144px; }
.uf-prog__t { font: 500 13px/1.3 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.uf-prog__bar { display: block; height: 4px; margin-top: 8px; border-radius: var(--pn-radius-pill); background: var(--pn-color-border-decorative); overflow: hidden; }
.uf-prog__fill { display: block; width: 62%; height: 100%; border-radius: inherit; background: var(--pn-color-accent-primary); }
.uf-sec { margin: 32px 0 12px; }
.uf-rows { display: flex; flex-direction: column; gap: 8px; }
.uf-row {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  height: 56px; padding: 0 12px 0 16px;
  background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card);
}
.uf-row--err { border-color: rgba(229, 72, 77, 0.5); }
.uf-row__f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.uf-row__k { font: 400 13px/1.2 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uf-row__v { font: 400 15px/1.25 var(--pn-font-sans); color: var(--pn-color-text-primary); white-space: nowrap; }
.uf-row__v--mono { font: 400 14px/1.25 var(--pn-font-mono); }
.uf-row__v--empty { color: var(--pn-color-text-muted); }
.uf-chk {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  height: 26px; padding: 0 10px; border-radius: var(--pn-radius-pill);
  font: 500 12px/1 var(--pn-font-sans); white-space: nowrap;
}
.uf-chk--icon { width: 26px; padding: 0; justify-content: center; }
.uf-chk--ok { background: var(--pn-color-accent-tint); color: var(--pn-color-accent-primary); }
.uf-chk--err { background: rgba(229, 72, 77, 0.12); color: var(--ui-red-text); }
.uf-chk--adv { background: var(--ui-amber-tint); color: var(--ui-amber); }
.ui .uf-chk .hw-ico { width: 14px; height: 14px; color: currentColor; }

.uf-rail { flex: none; width: 400px; display: flex; flex-direction: column; gap: 16px; }
.uf-card {
  padding: 24px; background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card);
}
.uf-card__t { margin-top: 12px; font: var(--pn-type-ui-label-l); }
.uf-issues { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
.uf-issues li { display: flex; align-items: center; gap: 10px; font: 500 14px/1.3 var(--pn-font-sans); }
.ui .uf-issues .hw-ico { color: var(--ui-red-text); }
.uf-issue { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--pn-color-text-muted); }
.uf-adv {
  display: flex; align-items: center; gap: 10px; margin-top: 20px; padding-top: 20px;
  border-top: 1px solid var(--pn-color-border-decorative);
  font: 400 14px/1.3 var(--pn-font-sans); color: var(--pn-color-text-secondary);
}
.ui .uf-adv .hw-ico { color: var(--ui-amber); }
.uf-actions { display: flex; gap: 12px; margin-top: 24px; }
.uf-actions .ui-btn { flex: 1 1 0; }
.uf-btn--white { background: transparent; color: var(--pn-color-text-primary); box-shadow: inset 0 0 0 1px var(--pn-color-border-control); }
.uf-note {
  display: flex; align-items: flex-start; gap: 12px; padding: 20px 24px;
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card);
  font: 400 13px/1.55 var(--pn-font-sans); color: var(--pn-color-text-muted);
  text-wrap: pretty; /* no one-word last line */
}
.uf-note .hw-ico { margin-top: 2px; }

/* ---- H04: municipal approvals dashboard ---- */
.ui--approvals { width: auto; padding: 0 48px; } /* fills the scroll region: 1280 minus the 6px scrollbar column, so nothing is clipped sideways */
.ua-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  padding: 32px 0 24px; border-bottom: 1px solid var(--pn-color-border-decorative);
  /* owner 2026-11-04 ("make this part sticky on scroll"): the application head stays at the top of the scrolling screen,
     on the screen's own fill so the content passes under it. Needs the recreation's overflow open (below), or the
     sticky box would stick to the recreation, which does not scroll, instead of the scroll region. */
  position: sticky; top: 0; z-index: 3; background: var(--pn-color-background-surface);
}
.figure--ui-scroll .ui--approvals { overflow: visible; }
/* owner 2026-11-04 ("make the scroll bar move below the header, not exceed the header"): the track starts under the sticky
   head (157 at the native 1280 layout: 32 + ref line + title + chip + 24) and runs to the bottom edge, so the thumb covers
   exactly the part that scrolls and reaches the end when the content does. WebKit/Chromium only; Firefox shows its thin bar full height. */
.figure--ui-scroll .figure__scroll:has(> .ui--approvals)::-webkit-scrollbar-track { margin-top: var(--ua-head-h, 157px); } /* no bottom margin (owner 2026-11-04: with one, the thumb stopped short of the bottom when the content was at its end and read out of sync) */
.ua-ref { font: 400 11.5px/1.3 var(--pn-font-mono); letter-spacing: 0.06em; color: var(--pn-color-text-muted); }
.ua-title { margin: 10px 0 14px; font: var(--pn-type-heading-sub); letter-spacing: -0.01em; }
.ua-via { display: flex; align-items: center; gap: 10px; margin-top: 4px; font: 400 14px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.ua-via__pn { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; color: var(--pn-color-text-primary); }
.ua-cols { display: flex; gap: 32px; padding-top: 28px; }
.ua-main { flex: 1 1 auto; min-width: 0; }
.ua-rail { flex: none; width: 400px; display: flex; flex-direction: column; gap: 16px; }
.ua-main > .ui-label { margin-bottom: 12px; }
.ua-main > .ua-card + .ui-label { margin-top: 32px; }
.ua-card {
  padding: 24px; background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card);
}
.ua-who { margin-top: 18px; font: 400 14.5px/1.4 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.ua-who b { font-weight: 600; color: var(--pn-color-text-primary); }
.ua-more { display: inline-flex; align-items: center; gap: 4px; font: 400 13px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.ua-card--ov .ua-more { margin-top: 8px; }
.ua-desc { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--pn-color-border-decorative); font: 400 14.5px/1.55 var(--pn-font-sans); color: var(--pn-color-text-primary); }
.ua-flags { display: flex; flex-wrap: wrap; gap: 10px 8px; margin-top: 14px; }
.ua-flags li {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px;
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-pill);
  font: 400 13px/1 var(--pn-font-sans); color: var(--pn-color-text-secondary);
}
.ui .ua-ico--warn { color: var(--ui-amber); }
.ua-intake { margin-top: 16px; font: 500 13.5px/1 var(--pn-font-sans); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--pn-color-text-muted); }
.ua-card--dc { display: flex; align-items: center; gap: 20px; padding: 20px 24px; }
.ua-thumb { flex: none; display: block; background: var(--pn-color-background-surface); border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-control); }
.ua-thumb__frame, .ua-thumb__lot, .ua-thumb__tb { fill: none; stroke: var(--pn-color-text-muted); stroke-width: 0.75; }
.ua-thumb__lot { stroke: var(--pn-color-text-secondary); }
.ua-thumb__set { fill: none; stroke: var(--pn-color-border-control); stroke-width: 0.75; stroke-dasharray: 2 2; }
.ua-thumb__house { fill: var(--pn-color-background-raised); stroke: var(--pn-color-text-secondary); stroke-width: 0.75; }
.ua-thumb__add { fill: none; stroke: var(--pn-color-text-muted); stroke-width: 0.75; }
.ua-thumb__mk { fill: var(--ui-amber); }
.ua-dc__text { flex: 1 1 auto; min-width: 0; }
.ua-dc__t { font: 600 16px/1.3 var(--pn-font-sans); }
.ua-dc__s { margin-top: 5px; font: 400 13px/1.5 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.ua-dc__side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.ua-lead { font: 400 13px/1.5 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.ua-lead--req { margin: -4px 0 12px; }
.ua-card--req { display: flex; align-items: center; gap: 16px; }
.ua-req__t { margin-right: auto; font: 600 16px/1.3 var(--pn-font-sans); }
.ua-rail .ua-card { padding: 20px 24px; }
.ua-rail .ui-label { margin-bottom: 14px; }
.ua-rail .ui-btn + .ui-btn { margin-top: 10px; }
.ua-rail .ua-lead { margin-top: -4px; }
.ua-routes { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.ua-routes li {
  display: flex; align-items: center; justify-content: space-between; height: 42px; padding: 0 16px;
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card);
  font: 600 13.5px/1 var(--pn-font-sans); color: var(--ui-blue);
}
.ua-routes .hw-ico { color: var(--pn-color-text-muted); }
.ua-miss { display: flex; align-items: center; justify-content: space-between; margin-top: 14px; }
.ua-miss__t { display: block; font: 500 14px/1.3 var(--pn-font-sans); }
.ua-miss__s { display: block; margin-top: 4px; font: 400 11.5px/1.3 var(--pn-font-mono); color: var(--pn-color-text-muted); }
.ua-req-link { font: 500 13.5px/1 var(--pn-font-sans); color: var(--ui-red-text); text-decoration: underline; text-underline-offset: 3px; }

.features { margin-top: var(--pn-space-96); grid-template-columns: auto 1fr; } /* owner 2026-10-10: pills on one line; label column 160, pills take the rest */
.features__label { display: flex; align-items: center; gap: var(--pn-space-24); min-height: 40px; margin: 0; } /* owner 2026-10-10: persona links replace the Features label */ /* centred on the first pill row */
.features__pills { display: flex; flex-wrap: wrap; gap: var(--pn-space-12); justify-content: flex-end; } /* owner 2026-10-10: pills flush right */
/* No --pn-space-20 token exists: 18px literal right padding (contract fallback). No --pn-color-surface-raised token exists: --pn-color-background-raised used. */
.feature-pill {
  display: inline-flex; align-items: center; gap: var(--pn-space-8);
  height: 40px; padding: 0 18px 0 var(--pn-space-12);
  border-radius: var(--pn-radius-pill);
  background: var(--pn-color-background-raised);
  color: var(--pn-color-text-primary);
  font: var(--pn-type-ui-label);
  white-space: nowrap;
  transition: background-color 160ms ease;
}
.feature-pill:hover { background: var(--pn-color-background-raisedHover); }
/* 2026-10-10: branded app-icon tiles (Raycast-style): gradient square + white 12px glyph, one colour per feature */
.feature-pill__tile {
  display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; flex: 0 0 auto;
  background: var(--pn-tile-dark);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.feature-pill__tile .hw-ico { width: 12px; height: 12px; color: inherit; stroke-width: 1.75; filter: drop-shadow(0 0 3px currentColor); }
.feature-pill__tile--lookup { color: var(--pn-tile-lookup); }
.feature-pill__tile--nav { color: var(--pn-tile-nav); }
.feature-pill__tile--checker { color: var(--pn-tile-checker); }
.feature-pill__tile--tracker { color: var(--pn-tile-tracker); }
.feature-pill__tile--verifier { color: var(--pn-tile-verifier); }

/* ---------- H05 Coverage ---------- */
.coverage__caption { margin-top: var(--pn-space-48); color: var(--pn-color-text-muted); }
.logo-wall {
  margin-top: var(--pn-space-12);
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--pn-space-16);
}
.logo-tile {
  height: 140px;
  display: grid; place-items: center;
  border-radius: var(--pn-radius-card);
  background: var(--pn-color-background-raised); /* owner 2026-10-09: dark grey tiles, white logos */
}
/* owner 2026-10-14 (Municipalities): the logo wall as a continuous carousel. Both lists scroll left together; when the first has
   fully left, the track is exactly one list further on, so the keyframe can restart invisibly. Edges fade with a mask. */
.logo-marquee {
  --tile-w: 243px; --tile-gap: var(--pn-space-16);
  margin-top: var(--pn-space-12); display: flex; gap: var(--tile-gap); overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 64px, #000 calc(100% - 64px), transparent);
  mask-image: linear-gradient(to right, transparent, #000 64px, #000 calc(100% - 64px), transparent);
}
.logo-marquee .logo-wall--marquee { margin-top: 0; display: flex; gap: var(--tile-gap); flex: none; animation: logo-marquee 28s linear infinite; }
.logo-marquee .logo-tile { width: var(--tile-w); flex: none; }
.logo-marquee:hover .logo-wall--marquee, .logo-marquee:focus-within .logo-wall--marquee { animation-play-state: paused; }
@keyframes logo-marquee { to { transform: translateX(calc(-100% - var(--tile-gap))); } }
@media (prefers-reduced-motion: reduce) {
  .logo-marquee .logo-wall--marquee { animation: none; }
  .logo-marquee [aria-hidden="true"] { display: none; }
  .logo-marquee { mask-image: none; -webkit-mask-image: none; flex-wrap: wrap; }
}
.logo-tile img {
  max-width: 160px; max-height: 64px; width: auto; height: auto; object-fit: contain;
  filter: brightness(0) invert(1); /* coloured artwork on transparent backgrounds becomes solid white */
  opacity: 0.92;
}
/* owner 2026-10-31: a tile may carry a one-colour alternate (img.logo-tile__alt, first in the tile) for artwork the white
   filter cannot read: Langley City's blue L and red C fuse into one block once the yellow band between them goes white,
   so its alternate has that band knocked out. The alternate shows at rest; a lit or hovered marquee tile shows the colour
   artwork instead (the Township of Langley crest did not need this: its white interior is knocked out in the one file). */
.logo-tile:has(> .logo-tile__alt) > img:not(.logo-tile__alt) { display: none; }
.logo-marquee .logo-tile:is(.is-lit, :hover):has(> .logo-tile__alt) > img:not(.logo-tile__alt) { display: block; }
.logo-marquee .logo-tile:is(.is-lit, :hover) > .logo-tile__alt { display: none; }

/* ---------- H06 Offer ---------- */
.offer__text { max-width: 640px; align-self: center; } /* architect 2026-10-10: copy centred on the promo card height */
.offer__lead { margin-top: var(--pn-space-24); color: var(--pn-color-text-secondary); }
.offer__links { margin-top: var(--pn-space-48); display: flex; flex-direction: column; align-items: flex-start; gap: var(--pn-space-16); }
/* Promo card (owner 2026-10-10, Linear-style bright card): big text top-left, small text bottom-left, empty space between. Not a link: no hover. */
.offer { align-items: center; min-height: 480px; /* owner 2026-10-10: section row stays 480; the card is shorter and centred on it */ grid-template-columns: minmax(0, 640px) 1fr; /* text column keeps its 640: the lead's longest hard-broken line is 619px and orphans "for" at the default 608 */ }
.offer-card {
  display: grid; grid-template-rows: auto 1fr auto;
  min-height: 360px; padding: var(--pn-space-32);
  border-radius: var(--pn-radius-card-l);
  background: var(--pn-color-accent-primary); color: var(--pn-color-background-canvas);
}
.offer-card__big { grid-row: 1; display: flex; align-items: baseline; gap: var(--pn-space-12); margin: 0; } /* owner 2026-10-10: really big number, smaller word, shared baseline */
.offer-card__num { font: 800 160px/0.9 var(--pn-font-display); letter-spacing: -0.05em; }
.offer-card__word { font: var(--pn-type-display-hero); letter-spacing: -0.025em; }
.offer-card__small { grid-row: 3; align-self: end; font: var(--pn-type-text-body); opacity: 0.72; }

/* ---------- H07 Early-access band (CTA/Band mixed 126:2254) ---------- */
.band {
  background: var(--pn-color-background-surface);
  /* owner 2026-11-01 ("remove the hairline here too"): no top rule; the surface fill against the canvas marks the band */
  padding-block: var(--pn-space-96);
}
.page-main > section.band { margin-top: var(--section-gap); } /* owner 2026-11-01: 288 like every section gap (was 128) */
.band__eyebrow { color: var(--pn-color-accent-primary); }
.band__title { margin-top: var(--pn-space-24); max-width: 760px; }
.band__body { margin-top: var(--pn-space-24); max-width: 640px; color: var(--pn-color-text-secondary); }
.band__actions { margin-top: calc(var(--pn-space-24) + var(--pn-space-16)); /* Figma: gap 24 + actions top padding 16 */ display: flex; align-items: center; gap: var(--pn-space-48); }
/* owner 2026-11-01 (audit VC-053): on the persona pages the primary action is the Home band's card and Sign in stays a small
   outline pill beside it, centred on the card. The card is as wide as one Home card ((1280 - 16) / 2 = 632). */
.band__actions > .cta-card { flex: 0 0 calc(50% - var(--pn-space-8)); }
.band__cta { display: flex; align-items: center; gap: var(--pn-space-16); }
.band__caption { color: var(--pn-color-text-muted); white-space: nowrap; }
/* Block-card CTAs (Home band): two wide cards, label top-left, arrow top-right, caption bottom-left. */
.band__cards {
  margin-top: calc(var(--pn-space-24) + var(--pn-space-16)); /* same as .band__actions */
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--pn-space-16); width: 100%;
}
.cta-card {
  position: relative; display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto 1fr auto;
  column-gap: var(--pn-space-24); row-gap: var(--pn-space-12);
  min-height: 180px; padding: var(--pn-space-32); /* owner 2026-10-10: shorter, was 240 */
  border: 0; border-radius: var(--pn-radius-card-l);
  font: inherit; text-align: left; text-decoration: none; cursor: pointer;
  transition: background-color 160ms ease, transform 160ms ease;
}
/* owner 2026-10-10: caption moved above the label as an eyebrow; the arrow sits on the label's row */
.cta-card__caption { grid-row: 1; grid-column: 1 / -1; font: var(--pn-type-ui-eyebrow); letter-spacing: 0.08em; text-transform: uppercase; }
.cta-card__label { grid-row: 3; grid-column: 1; align-self: end; /* owner 2026-10-10: CTA row at the bottom */ font: var(--pn-type-heading-section); letter-spacing: -0.025em; }
.cta-card__arrow {
  grid-row: 3; grid-column: 2; align-self: end;
  font: var(--pn-type-heading-section); font-weight: 400;
  transition: transform 160ms ease-out;
}
.cta-card:hover .cta-card__arrow { transform: translateX(4px); }
.cta-card:focus-visible { outline: 2px solid var(--pn-color-focus); outline-offset: 2px; }
.cta-card--primary:focus-visible, .offer-card:focus-visible, :root[data-accent="lime"] .btn--primary:focus-visible { outline-color: var(--pn-color-focus-onLight); outline-offset: -4px; } /* dark ring inset on light surfaces */
.cta-card--primary { background: var(--pn-color-text-primary); color: var(--pn-color-background-canvas); }
.cta-card--primary .cta-card__caption { opacity: 0.64; }
.cta-card--primary:hover { background: #ffffff; } /* fix 2026-10-13: was the on-accent token, which the neutral theme sets to canvas (card went black on hover) */
/* owner 2026-10-29/31: origin fill for EVERY primary CTA card (persona heroes, Home/Platform/Our Story band), tailored from an OriginButton sample (motion/react). js/site.js (initOriginFill) injects
   .cta-card__fill and sets --ox/--oy (pointer entry point, card-relative) and --cover (the diameter that covers the
   card from that point); the circle scales 0 -> 1 in 500ms on the sample's curve and the card's ink flips to light.
   Keyboard focus fills from the centre. Press = scale .985. Reduced motion: the fill is instant. */
.cta-card { overflow: hidden; isolation: isolate; transition: background-color 160ms ease, color 300ms cubic-bezier(0.16, 1, 0.3, 1), transform 160ms ease; }
/* owner 2026-10-31: the secondary card runs the SAME fill in its own colour: the frost hover tone over raised, ink unchanged */
.cta-card--primary { --card-fill: var(--pn-color-brand-green); --card-ink: var(--pn-color-background-canvas); }
.cta-card--secondary { --card-fill: var(--pn-color-background-raisedHover); --card-ink: var(--pn-color-text-primary); } /* owner 2026-10-31 (picked C of six): the quiet raised-hover tone, same as raised pills; the primary owns the band */
.cta-card__fill {
  position: absolute; left: var(--ox, 50%); top: var(--oy, 50%); width: 0; height: 0;
  translate: -50% -50%; border-radius: 50%; z-index: -1; pointer-events: none;
  /* owner 2026-10-29 "feather the green": the disc is solid out to the cover radius and fades over --feather beyond it;
     js adds 2x --feather to --cover so the solid core still covers the card at scale 1. Green per owner (raised before). */
  --feather: 320px; /* owner 2026-10-29 "feather the edge more": 160 -> 320 */
  background: radial-gradient(circle closest-side, var(--card-fill) calc(100% - var(--feather)), transparent 100%);
  /* the disc grows by SIZE, not scale, so the --feather rim stays 320 screen px at every stage (owner: "the edge
     does not look feathered when the green is small"; under scale the rim shrank with the disc) */
  /* owner 2026-10-29: the disc only grows on the way IN; on the way out it fades (300ms) and snaps to 0 once invisible */
  opacity: 0;
  transition: opacity 300ms ease, width 0s linear 300ms, height 0s linear 300ms;
}
.cta-card.is-filled { color: var(--card-ink); }
.cta-card.is-filled .cta-card__fill { width: var(--cover, 0px); height: var(--cover, 0px); opacity: 1; transition: width 500ms cubic-bezier(0.16, 1, 0.3, 1), height 500ms cubic-bezier(0.16, 1, 0.3, 1), opacity 0s; }
.cta-card:active { transform: scale(0.985); }
@media (prefers-reduced-motion: reduce) { .cta-card__fill, .cta-card { transition: none; } }
.cta-card--secondary { background: var(--pn-color-background-raised); color: var(--pn-color-text-primary); }
.cta-card--secondary .cta-card__caption { color: var(--pn-color-text-muted); }
.cta-card--secondary:hover { background: var(--pn-color-background-raisedHover); }

/* ---------- Footer (75:399) ---------- */
.site-footer {
  background: var(--pn-color-background-canvas);
  /* owner 2026-11-01: no top rule (it was the band's bottom hairline; the band's surface fill ends here anyway) */
  padding-top: var(--pn-space-96);
  padding-bottom: var(--pn-space-48);
}
.footer__cols { display: flex; gap: var(--pn-space-24); align-items: flex-start; }
.footer__col { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pn-space-16); min-width: 0; }
.footer__col--brand { flex: 0 0 200px; }
.footer__col--pages, .footer__col--legal { flex: 1 1 0; }
.footer__col--actions { flex: 0 0 232px; }
.footer__col--contact { flex: 0 0 280px; gap: var(--pn-space-32); }
.footer__group { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pn-space-16); }
.footer__heading { color: var(--pn-color-text-muted); }
.footer__tagline { color: var(--pn-color-text-muted); }
.footer__link {
  font: var(--pn-type-ui-label);
  color: var(--pn-color-text-secondary);
  text-align: left;
  text-decoration: underline; text-decoration-color: transparent;
  text-decoration-thickness: 1px; text-underline-offset: 4px;
  transition: color 160ms ease, text-decoration-color 160ms ease;
}
.footer__link:hover { color: var(--pn-color-text-primary); text-decoration-color: currentColor; }
.footer__pair { display: flex; flex-direction: column; gap: var(--pn-space-4); }
.footer__note { color: var(--pn-color-text-muted); }
.footer__plain { font: var(--pn-type-ui-label); color: var(--pn-color-text-secondary); }
.footer__bottom {
  margin-top: var(--pn-space-96);
  padding-top: var(--pn-space-24);
  border-top: 1px solid var(--pn-color-border-decorative);
  display: flex; justify-content: space-between; gap: var(--pn-space-24);
  color: var(--pn-color-text-muted);
}
/* The band sits directly on the footer. Figma drew a hairline between them; off since 2026-11-01 (owner), the change
   from the band's surface fill to the footer's canvas is the boundary. */

/* ---------- Dialogs ---------- */
dialog { padding: 0; border: 0; color: inherit; background: transparent; max-width: none; max-height: none; }
dialog::backdrop { background: rgba(11, 14, 20, 0.9); }
dialog[open] { animation: dialog-in 240ms var(--pn-ease-out); }
dialog[open]::backdrop { animation: fade-in 240ms ease; }
@keyframes dialog-in { from { opacity: 0; transform: translateY(12px) scale(0.99); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* Demo form (Overlay/Demo Form 54:583) */
/* The dialog is the full-viewport scroll container (a tall form scrolls instead of clipping); the panel inside is top-anchored at the
   default-state centre so the title never moves when errors add height. 838 = the default-state panel height. */
.demo-dialog { width: 100%; height: 100%; margin: 0; overflow-y: auto; overscroll-behavior: contain; }
.demo {
  width: min(640px, calc(100% - var(--pn-space-32)));
  min-height: 838px;
  margin: max(var(--pn-space-48), calc((100vh - 838px) / 2)) auto var(--pn-space-48);
  padding: var(--pn-space-32);
  background: var(--pn-color-background-surface);
  border: 1px solid var(--pn-color-border-decorative);
  border-radius: var(--pn-radius-card-l); /* owner 2026-11-01 (audit VC-011): content cards 16 */
}
.demo__inner { display: flex; flex-direction: column; gap: var(--pn-space-24); }
.demo__header { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--pn-space-24); }
.demo__titles { display: flex; flex-direction: column; gap: var(--pn-space-8); }
.demo__eyebrow { color: var(--pn-color-accent-primary); }
.demo__for { color: var(--pn-color-text-muted); }
.demo__intro { color: var(--pn-color-text-secondary); }
.icon-btn {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: var(--pn-radius-pill);
  border: 1px solid var(--pn-color-border-decorative);
  color: var(--pn-color-text-primary);
  transition: background-color 160ms ease;
}
.icon-btn:hover { background: var(--pn-color-surface-frost); }
.demo__form { display: flex; flex-direction: column; gap: var(--pn-space-24); }
.demo__fields { display: flex; flex-direction: column; gap: var(--pn-space-16); transition: opacity 160ms ease; }
.demo__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--pn-space-24); }
.field { display: flex; flex-direction: column; gap: var(--pn-space-8); min-width: 0; }
.field__label { font: var(--pn-type-ui-label); color: var(--pn-color-text-primary); }
.field__control {
  width: 100%; height: 48px;
  padding: var(--pn-space-12) var(--pn-space-16);
  font: var(--pn-type-text-body-m);
  color: var(--pn-color-text-primary);
  background: var(--pn-color-background-surface);
  border: 1px solid var(--pn-color-border-control);
  border-radius: var(--pn-radius-control);
  transition: border-color 160ms ease;
}
.field__control::placeholder { color: var(--pn-color-text-muted); opacity: 1; }
.field__control:focus { outline: none; }
.field__control:focus-visible {
  border-color: var(--pn-color-focus);
  outline: 2px solid var(--pn-color-focus); outline-offset: 2px;
}
textarea.field__control { height: 120px; resize: vertical; }
select.field__control {
  appearance: none; -webkit-appearance: none;
  padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23B8BDBB' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 16px center;
}
.field__error { display: none; font: var(--pn-type-caption-technical); color: var(--pn-color-status-error); }
.field.is-invalid .field__control,
.field.is-invalid .field__control:focus-visible { border-color: var(--pn-color-status-error); }
.field.is-invalid .field__error { display: block; }
.field__control[hidden] { display: none; }
.demo__error { font: var(--pn-type-caption-technical); color: var(--pn-color-status-error); }
.demo__error[hidden] { display: none; }
/* Role picker: native radios dressed as tiles that share the .field__control look */
.role-picker { border: 0; padding: 0; margin: 0; min-width: 0; display: flex; flex-direction: column; gap: var(--pn-space-8); }
.role-picker legend { padding: 0; margin-bottom: var(--pn-space-8); float: none; }
.role-picker__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--pn-space-12); }
.role-tile {
  position: relative; display: flex; align-items: center; justify-content: center;
  height: 48px; padding: 0 var(--pn-space-16);
  font: var(--pn-type-text-body-m); color: var(--pn-color-text-secondary);
  background: var(--pn-color-background-surface);
  border: 1px solid var(--pn-color-border-control);
  border-radius: var(--pn-radius-control);
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}
.role-tile--wide { grid-column: 1 / -1; }
.role-tile input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.role-tile:hover { border-color: var(--pn-color-text-muted); }
.role-tile:has(input:checked) { border-color: var(--pn-color-accent-primary); box-shadow: inset 0 0 0 1px var(--pn-color-accent-primary); background: var(--pn-color-accent-tint); color: var(--pn-color-text-primary); }
.role-tile:has(input:focus-visible) { border-color: var(--pn-color-focus); outline: 2px solid var(--pn-color-focus); outline-offset: 2px; }
.demo__actions { display: flex; align-items: center; gap: var(--pn-space-24); }
.demo__consent { flex: 1 1 auto; color: var(--pn-color-text-muted); }
.demo__consent a { color: var(--pn-color-text-secondary); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.demo__consent a:hover { color: var(--pn-color-text-primary); }
.demo__submit { position: relative; flex: 0 0 176px; width: 176px; }
.spinner {
  display: none;
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35); border-top-color: #fff;
  animation: spin 800ms linear infinite;
  position: absolute; right: 20px; top: 50%; margin-top: -8px;
}
@keyframes spin { to { transform: rotate(360deg); } }
.is-loading .demo__fields { opacity: 0.6; }
.is-loading .demo__submit { opacity: 0.6; cursor: progress; }
.is-loading .spinner { display: inline-block; }
.demo__success { display: none; flex-direction: column; gap: var(--pn-space-8); }
.demo__success-lead { color: var(--pn-color-text-primary); }
.demo__success-sub { color: var(--pn-color-text-secondary); }
.is-success .demo__form { display: none; }
.is-success .demo__success { display: flex; }
.is-success .demo { min-height: 0; } /* owner 2026-11-04: the sent state hugs its two lines; the top margin is unchanged, so the title stays put */
@media (max-width: 559px) {
  .demo { padding: var(--pn-space-24); min-height: 0; margin-top: var(--pn-space-24); margin-bottom: var(--pn-space-24); }
  .demo__row { grid-template-columns: 1fr; gap: var(--pn-space-16); }
  .demo__actions { flex-direction: column-reverse; align-items: stretch; gap: var(--pn-space-16); }
  .demo__submit { flex: 0 0 auto; width: 100%; }
}

/* Lightbox */
.lightbox { width: 100vw; height: 100vh; margin: 0; inset: 0; }
.lightbox__stage { width: 100%; height: 100%; display: grid; place-items: center; }
.lightbox__img { max-width: 90vw; max-height: 90vh; height: auto; border-radius: var(--pn-radius-card); }
.lightbox__close {
  position: fixed; top: var(--pn-space-24); right: var(--pn-space-24);
  width: 40px; height: 40px; display: grid; place-items: center;
  border-radius: var(--pn-radius-pill);
  background: var(--pn-color-surface-frost);
  -webkit-backdrop-filter: blur(var(--pn-blur-frost));
  backdrop-filter: blur(var(--pn-blur-frost));
  color: var(--pn-color-text-primary);
  font: 400 24px/1 var(--pn-font-sans);
  transition: background-color 160ms ease;
}
.lightbox__close:hover { background: var(--pn-color-surface-frostHover); }

/* ---------- Placeholder pages ---------- */
.placeholder { min-height: 100vh; padding-top: calc(var(--pn-header-height) + var(--pn-space-128)); }
.placeholder__note { margin-top: var(--pn-space-24); color: var(--pn-color-text-muted); }
.placeholder__back { display: inline-block; margin-top: var(--pn-space-32); }
.stubs { margin-top: var(--pn-space-96); display: flex; flex-direction: column; gap: var(--pn-space-96); }
.stub { padding-top: var(--pn-space-32); border-top: 1px solid var(--pn-color-border-decorative); min-height: 240px; }

/* ---------- Reveal on scroll ---------- */
.js .reveal { opacity: 0; transform: translateY(24px); transition: opacity 600ms var(--pn-ease-out), transform 600ms var(--pn-ease-out); }
.js .reveal.is-visible { opacity: 1; transform: none; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none; transition: none; }
  .js .reveal { opacity: 1; transform: none; }
  .route-card:hover .route-card__img { transform: none; }
  .cta-card:hover .cta-card__arrow { transform: none; }
}

/* ======================================================================
   Round 7: Municipalities page (municipalities.html), desktop 1440.
   Reuses header, footer, band, dialogs, .ui--approvals / .ui--checker / .lk from Home; everything new is .mu-* / .uv-*.
   ====================================================================== */
.intro__lead { margin-top: var(--pn-space-24); max-width: 720px; color: var(--pn-color-text-secondary); }

/* ---- MU01 Hero: split, copy vertically centred on the first viewport; approvals window 1120x720 at page x 640 ---- */
.mu-hero {
  position: relative;
  /* owner 2026-10-10: no viewport-height hero; content is top-anchored like Home (headline top at 144) and the hero ends with the window */
  padding-top: 224px; /* owner: 144 read too tight on this page; 224 = header 72 + 152 of air */
  overflow: hidden; overflow: clip;
  background: var(--pn-color-background-canvas);
}
.mu-hero__inner { position: relative; min-height: 640px; } /* the window is absolutely positioned; 640 keeps 80px of it under the bottom fade */
/* the column is 560 (contract); the copy stops 64 short of it so it never touches the window at x 640 */
.mu-hero__copy { position: relative; z-index: 3; width: 560px; padding-right: var(--pn-layout-gutter); }
.mu-hero__lead { margin-top: var(--pn-space-24); color: var(--pn-color-text-secondary); }
/* hero actions: the persona hero CTA card (css/persona-hero.css) then the text link; the card's dials live on .ph-hero there, so set them here */
.mu-hero__buttons {
  --ph-cta-pad: var(--pn-space-32); --ph-cta-row-gap: var(--pn-space-16); --ph-cta-label-size: 40px;
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--pn-space-24); margin-top: var(--pn-space-32);
}
/* owner 2026-10-15: label + arrow only (no caption, no proof points), so the card is one row */
.mu-hero__buttons .mu-hero__card { align-self: stretch; grid-template-rows: auto; } /* two classes: persona-hero.css loads after this file and its .ph-cta-card sets three rows */ /* two classes: persona-hero.css loads after this file and its .ph-cta-card sets three rows */
.mu-hero__card .ph-cta-card__label, .mu-hero__card .ph-cta-card__action { grid-row: 1; }
.mu-hero__textlink { font: var(--pn-type-ui-label-l); }
/* window: left edge at container x 560 (= page x 640 at 1440), top aligned with the headline's top */
.mu-hero__win { z-index: 1; top: 0; left: 560px; width: 1120px; height: 720px; }
.mu-hero__win .ui--approvals { height: calc(720px - 44px); }
/* veil like Home's hero: clear over the window's top-left, darkening toward the right and the bottom */
.mu-hero__veil {
  position: absolute; z-index: 2; inset: 0; pointer-events: none;
  background:
    linear-gradient(to right, rgba(11, 14, 20, 0) 72%, rgba(11, 14, 20, 0.85) 100%),
    radial-gradient(1200px 900px at 46% 28%, rgba(11, 14, 20, 0) 0%, rgba(11, 14, 20, 0) 36%, rgba(11, 14, 20, 0.5) 70%, rgba(11, 14, 20, 0.92) 100%);
}
.mu-hero__fade {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; height: 160px; pointer-events: none;
  background: linear-gradient(to bottom, rgba(11, 14, 20, 0), var(--pn-color-background-canvas));
}

/* ---- MU02 overview ---- */
.mu-compare-sum { margin-top: var(--pn-space-64); }
.mu-cmp__label { color: var(--pn-color-text-muted); }
.mu-cmp--with .mu-cmp__label { color: var(--pn-color-accent-primary); }
.mu-cmp__sum { margin-top: var(--pn-space-12); }
.mu-cols { display: grid; gap: var(--pn-space-24); margin: var(--pn-space-64) 0 0; padding: 0; list-style: none; }
.mu-cols--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.mu-cols--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mu-col { padding-top: var(--pn-space-24); border-top: 1px solid var(--pn-color-border-decorative); }
.mu-col__num { display: block; color: var(--pn-color-text-muted); }
.mu-col__num + .mu-col__h { margin-top: var(--pn-space-12); }
.mu-col__t { color: var(--pn-color-text-primary); }
.mu-col__p { margin-top: var(--pn-space-12); color: var(--pn-color-text-secondary); }
.mu-col__p, .mu-feat__b, .mu-cmp__text, .mu-stat__s { text-wrap: pretty; } /* no one-word last lines in body copy */
.mu-col__t + .mu-col__p { margin-top: var(--pn-space-8); }
.mu-overview__more { display: inline-block; margin-top: var(--pn-space-48); }

/* ---- Round 8: MU02 stage strip as an animated workflow timeline (r8.4: triangle nodes with a tint halo) ----
   One track row over the four columns (same 4-col grid, gap 24): a 1px line to node 4's centre, and on each column's left edge
   a right-pointing triangle (16x16 box centred where the r8 12px dot's centre was, so the 12px node band, the copy 24 below it
   and the progress maths are unchanged). js initWorkflowTimeline() moves one active step (li.is-active + .mu-wf__cell.is-active,
   earlier cells .is-done) every 2400ms and sets --wf-progress (0..1, node 1 .. node 4).
   Upcoming: outlined on surface. Done: filled. Active: filled + a larger tint triangle behind it. All triangles beat while running.
   Colour lands as the progress line arrives (r8.2: 300ms ease-in after 420ms). Nothing changes layout size.
   Reduced motion: .is-static, all filled, no halo, no motion. */
.mu-wf { --wf-gap: var(--pn-space-24); --wf-node: 32px; --wf-head: 32px; /* owner 2026-11-04: marks 16 -> 32; the node band grows with them so the copy keeps its 24 below */ --wf-progress: 0; margin-top: var(--pn-space-64); }
.mu-wf__track {
  position: relative;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--wf-gap);
  height: var(--wf-node);
}
.mu-wf__track::before, .mu-wf__track::after {
  content: ""; position: absolute; left: 0; top: calc(var(--wf-node) / 2 - 0.5px); height: 1px;
}
/* base line and progress both end at node 4's centre (r8.1): node pitch = (track + gap) / 4, node 1 -> node 4 = 3 pitches */
.mu-wf__track::before { width: calc(var(--wf-node) / 2 + 0.75 * (100% + var(--wf-gap))); background: var(--pn-color-border-decorative); }
/* progress: from the track start to the active node's centre */
.mu-wf__track::after {
  width: calc(var(--wf-node) / 2 + var(--wf-progress) * 0.75 * (100% + var(--wf-gap)));
  background: var(--pn-color-brand-green); /* owner 2026-10-31: the progress line is brand green like the marks it lights (accent/primary is off-white under the neutral theme) */
  transition: width 600ms ease-in-out;
}
.mu-wf__cell { position: relative; z-index: 1; }
/* r8.4: the node is a 16x16 box centred where the r8 dot's centre was; inside it a right-pointing triangle (14 wide x 16 tall
   with its 1px round-joined stroke) and, behind it, a halo: the same triangle in accent/tint, shown on the active step only */
.mu-wf__node {
  position: absolute;
  left: calc(var(--wf-node) / 2 - var(--wf-head) / 2); top: calc(var(--wf-node) / 2 - var(--wf-head) / 2);
  width: var(--wf-head); height: var(--wf-head);
}
.mu-wf__node svg { display: block; width: var(--wf-head); height: var(--wf-head); overflow: visible; }
.mu-wf__tri { position: relative; }
/* owner 2026-10-18: the marker is the Permit Nav mark (open ring + check), drawn as strokes so it can land from grey to green.
   A surface disc sits behind it so the track line does not show through the open ring. */
.mu-wf__bg { fill: var(--pn-color-background-surface); }
.mu-wf__ring, .mu-wf__check {
  fill: none; stroke: var(--pn-color-border-control); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
  /* r8.2: the progress line (600ms ease-in-out) arrives at ~570ms; colour starts at 420 with an ease-in so it lands as the line does */
  transition: stroke 300ms ease-in 420ms;
}
.mu-wf__cell.is-done .mu-wf__tri :is(.mu-wf__ring, .mu-wf__check), .mu-wf__cell.is-active .mu-wf__tri :is(.mu-wf__ring, .mu-wf__check),
.mu-wf.is-static .mu-wf__tri :is(.mu-wf__ring, .mu-wf__check) { stroke: var(--pn-color-brand-green); }
.mu-wf__halo { position: absolute; inset: 0; opacity: 0; transition: opacity 300ms ease-in 420ms; }
.mu-wf__halo circle { fill: rgba(70, 200, 138, 0.32); } /* r8.5: accent at 32%; the 16% tint was invisible on canvas. Now a disc behind the mark */
.mu-wf__cell.is-active .mu-wf__halo { opacity: 1; }
/* every triangle beats continuously while running, staggered 0.2s left to right; each halo breathes in step with its triangle */
.mu-wf__tri { animation: mu-wf-beat 1.6s ease-in-out infinite both paused; }
.mu-wf__halo svg { animation: mu-wf-halo 1.6s ease-in-out infinite both paused; }
.mu-wf__cell:nth-child(2) :is(.mu-wf__tri, .mu-wf__halo svg) { animation-delay: 0.2s; }
.mu-wf__cell:nth-child(3) :is(.mu-wf__tri, .mu-wf__halo svg) { animation-delay: 0.4s; }
.mu-wf__cell:nth-child(4) :is(.mu-wf__tri, .mu-wf__halo svg) { animation-delay: 0.6s; }
.mu-wf.is-running :is(.mu-wf__tri, .mu-wf__halo svg) { animation-play-state: running; }
@keyframes mu-wf-beat {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.12); }
}
@keyframes mu-wf-halo {
  0%, 100% { transform: scale(1.7); opacity: 0.9; }
  50% { transform: scale(2.1); opacity: 0.5; }
}
.mu-wf.is-static .mu-wf__halo { display: none; }
.mu-wf.is-static .mu-wf__tri { animation: none; }
.mu-process { margin-top: var(--pn-space-24); }
.mu-process .mu-col { padding-top: 0; border-top: 0; }
.mu-process .mu-col__h { color: var(--pn-color-text-secondary); }
.mu-process .mu-col__p { color: var(--pn-color-text-muted); }
.mu-process .mu-col__num, .mu-process .mu-col__h, .mu-process .mu-col__p { transition: color 300ms ease-in 420ms; } /* r8.2: text lands with the line */
/* active step (and every step when static); done steps keep the inactive text colours (r8.1) */
.mu-process .mu-col.is-active .mu-col__num, .mu-process .mu-col.is-active .mu-col__h,
.mu-wf.is-static .mu-col__num, .mu-wf.is-static .mu-col__h { color: var(--pn-color-text-primary); }
.mu-process .mu-col.is-active .mu-col__p, .mu-wf.is-static .mu-col__p { color: var(--pn-color-text-secondary); }
.mu-wf.is-static { --wf-progress: 1; }
@media (prefers-reduced-motion: reduce) {
  .mu-wf__tri, .mu-wf__halo svg { animation: none; }
  .mu-wf__halo { display: none; }
  .mu-wf__track::after, .mu-wf__halo, .mu-wf__node path, .mu-wf__node circle,
  .mu-process .mu-col__num, .mu-process .mu-col__h, .mu-process .mu-col__p { transition: none; }
}

/* ---- MU03-06 module features ---- */
.mu-feats { display: grid; column-gap: var(--pn-layout-gutter); row-gap: var(--pn-space-48); margin: var(--pn-space-96) 0 0; padding: 0; list-style: none; }
.mu-feats--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mu-feats--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.mu-feat__t { color: var(--pn-color-text-primary); }
.mu-feat__b { margin-top: var(--pn-space-8); color: var(--pn-color-text-secondary); } /* owner 2026-11-01: captions fill their column site-wide (was capped 520 in 608 columns) */
.mu-privacy { margin-top: var(--pn-space-32); color: var(--pn-color-text-secondary); } /* owner 2026-11-01: an icon-list line with the shield, like Platform's; secondary ink (was a loose muted sentence) */

/* MU04: the checker alone, native 1280x800 (no app bar, as in the H03 window) scaled 0.9 to 1152x720, centred */
.mu-fig-checker { background: var(--pn-color-background-canvas); }
.mu-fit {
  /* native width 1280/0.9 = 1422.2 so the scaled window fills the frame edge to edge (no pillarbox bands);
     the centre sheet viewer absorbs the extra 142px, the sidebar and review panel keep their native widths */
  position: absolute; top: 0; left: 0; width: calc(1280px / 0.9); height: 800px;
  transform: scale(0.9); transform-origin: 0 0;
}
.mu-fit .ui { width: 100%; }
.mu-fit .ui, .mu-fit .uc-body { height: 800px; }
/* responsive fit (2026-11-04, contract §1): the MU04 checker, the MU05 verifier, the MU06 lookup and the tracker figure keep their
   native boxes and scale whole to the figure below a 1280 container (same mechanism as Home's H03 / H04, k = width / native) */
.page-municipalities .figure--ui { container-type: inline-size; }
@container (max-width: 1279.98px) {
  .mu-fit { transform: scale(tan(atan2(100cqw, 1280px / 0.9))); }
  .page-municipalities .figure--ui-scroll > .figure__scroll, .mu-fig-lookup > .hw {
    width: 1280px; height: 720px;
    transform: scale(tan(atan2(100cqw, 1280px))); transform-origin: 0 0;
  }
}

/* MU06: the Address Lookup window filling the 1280x720 frame; only the panel scrolls, nothing inside is clickable */
.mu-fig-lookup { --hero-fade: 0px; }
.mu-fig-lookup .hw { box-shadow: none; }
/* .mu-fig-lookup .lk-panel > * pointer-events: none removed 2026-11-04: the accordions work, as on the hero */
.mu-fig-lookup .lk-panel:focus-visible { outline: 2px solid var(--pn-color-focus); outline-offset: -2px; }
.mu-fig-lookup .lk-body { padding-bottom: var(--pn-space-32); }

/* ---- MU05: Rule Verifier (.ui--verifier), static dark recreation of docs/reference/rule-verifier-light.jpg ---- */
.ui--verifier { width: auto; display: grid; grid-template-columns: minmax(0, 1fr) 560px; min-height: 720px; background: var(--pn-color-background-canvas); }
.uv-list { position: relative; overflow: hidden; }
.uv-list__page { padding: 40px 48px; filter: blur(2px); }
.uv-list__title { margin: 16px 0 20px; font: 600 26px/1.2 var(--pn-font-sans); letter-spacing: -0.01em; color: var(--pn-color-text-secondary); }
.uv-sk { display: block; height: 10px; border-radius: var(--pn-radius-control); background: rgba(242, 240, 233, 0.16); }
.uv-sk--t { height: 12px; margin-top: 12px; }
.uv-list__chips { display: flex; gap: 8px; margin-top: 32px; }
.uv-sk--chip { height: 28px; border-radius: var(--pn-radius-pill); background: rgba(242, 240, 233, 0.08); }
.uv-list__table { margin-top: 32px; border-top: 1px solid var(--pn-color-border-decorative); }
.uv-row { display: grid; grid-template-columns: 160px 1fr; align-items: center; height: 46px; padding: 0 12px; border-bottom: 1px solid var(--pn-color-border-decorative); }
.uv-row--head .uv-sk { background: rgba(242, 240, 233, 0.24); }
.uv-row.is-sel { background: var(--pn-color-accent-tint); }
.uv-list__veil { position: absolute; inset: 0; background: rgba(11, 14, 20, 0.5); }
.uv-drawer {
  position: relative; display: flex; flex-direction: column;
  background: var(--pn-color-background-surface);
  border-left: 1px solid var(--pn-color-border-decorative);
  box-shadow: -24px 0 64px rgba(0, 0, 0, 0.45);
}
.uv-head { padding: 28px 32px 24px; border-bottom: 1px solid var(--pn-color-border-decorative); }
.uv-head__t { display: flex; align-items: center; gap: 12px; font: 600 20px/1.2 var(--pn-font-sans); }
.uv-status {
  display: inline-flex; align-items: center; height: 24px; padding: 0 10px;
  border: 1px solid var(--pn-color-border-control); border-radius: var(--pn-radius-pill);
  font: 500 12px/1 var(--pn-font-sans); color: var(--pn-color-text-secondary);
}
.uv-head__s { margin-top: 10px; font: 400 14px/1.4 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uv-fields { display: flex; flex-direction: column; gap: 14px; padding: 28px 32px; }
.uv-field { display: grid; grid-template-columns: 136px minmax(0, 1fr) 16px 76px; align-items: center; column-gap: 16px; } /* chip column ends on the citation fields' right edge */
.uv-field__k { font: 400 14px/1.3 var(--pn-font-sans); color: var(--pn-color-text-secondary); }
.uv-input {
  display: flex; align-items: center; height: 40px; padding: 0 14px;
  background: var(--pn-color-background-raised);
  border: 1px solid var(--pn-color-border-decorative); border-radius: var(--pn-radius-card);
  font: 400 15px/1 var(--pn-font-sans); color: var(--pn-color-text-primary);
}
.uv-input.is-focus { border-color: var(--pn-color-accent-primary); box-shadow: 0 0 0 3px var(--pn-color-accent-tint); }
.uv-unit { font: 400 13px/1 var(--pn-font-sans); color: var(--pn-color-text-muted); }
.uv-conf { justify-self: end; }
.uv-cite { display: flex; flex-direction: column; gap: 20px; padding: 4px 32px 32px; }
.uv-block__k { margin-bottom: 8px; font: 500 14px/1.3 var(--pn-font-sans); color: var(--pn-color-text-primary); }
.uv-input--link { justify-content: space-between; color: var(--pn-color-accent-primary); }
.uv-input--link .hw-ico { color: var(--pn-color-accent-primary); transform: rotate(-45deg); }
.uv-input--area { height: auto; min-height: 72px; align-items: flex-start; padding: 12px 14px; line-height: 1.5; }
.uv-foot {
  margin-top: auto; display: flex; align-items: center; gap: 12px;
  padding: 20px 32px 24px; border-top: 1px solid var(--pn-color-border-decorative);
}
.uv-btn--white { background: transparent; color: var(--pn-color-text-primary); box-shadow: inset 0 0 0 1px var(--pn-color-border-control); }
.uv-btn--reject { margin-left: auto; background: rgba(229, 72, 77, 0.12); color: var(--ui-red-text); }

/* ---- MU07 comparison ---- */
.mu-rows { margin-top: var(--pn-space-64); }
.mu-row { padding: var(--pn-space-32) 0; } /* owner 2026-11-01 (audit VC-019): row rules off; the 64 of padding between rows separates them */
.mu-cmp__text { margin-top: var(--pn-space-12); /* max-width 560 removed 2026-11-01 (owner: captions fill their column) */ color: var(--pn-color-text-secondary); }
.mu-cmp__text b { font-weight: 500; color: var(--pn-color-text-primary); }
.mu-cmp--with .mu-cmp__text { color: var(--pn-color-text-primary); }
.mu-stats {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--pn-layout-gutter);
  margin: var(--pn-space-96) 0 0; padding: var(--pn-space-48);
  list-style: none;
  background: var(--pn-color-background-surface); border-radius: var(--pn-radius-card-l); /* owner 2026-11-01 (audit VC-011): content cards 16 */
}
.mu-stat__s { margin-top: var(--pn-space-12); color: var(--pn-color-text-secondary); }

/* ---- MU08 Municipalities Data driven illustrations (bento master in css/bento.css) ----
   The grid, cell anatomy, dotted ground, drawing vocabulary (.b-*), --bd stagger and run state live in css/bento.css
   (docs/BENTO.md). What stays here is page-owned: the six r9 drawings' group rules (.mu-b1-* ... .mu-b6-*) and their
   keyframes (mu-b*). The SVGs are generated isometric line art (docs/qa/round9/gen-bento-svgs.py, 30deg, viewBox 280 x 200).
   Base styles = the most complete frame (reduced motion shows exactly that); loops authored paused, run by js/bento.js. */
/* the most complete frame (static + reduced motion) */
.bento .mu-b1-lift { transform: translateY(-10px); }
.bento .mu-b1-scan { opacity: 0; transform: translateY(var(--scan)); } /* static: the rim alone carries the accent */
.bento .mu-b2-lot { opacity: 0; }
.bento .mu-b2-lot--on { opacity: 1; }
.bento .mu-b4-new { opacity: 0; }
.bento .mu-b4-card--4 .mu-b4-new { opacity: 1; }
.bento .mu-b6-map { transform-box: fill-box; transform-origin: 50% 50%; }

/* loops: each tile has its own length; the start offset --bd per cell comes from css/bento.css, so the six never beat together */
.bento :is(.mu-b1-lift, .mu-b1-scan, .mu-b1-rim) { animation: 5.2s ease-in-out var(--bd) infinite both paused; }
.bento .mu-b1-lift { animation-name: mu-b1-lift; }
.bento .mu-b1-scan { animation-name: mu-b1-scan; }
.bento .mu-b1-rim { animation-name: mu-b1-rim; }
.bento .mu-b2-lot { animation: mu-b2-lot 5.6s ease-in-out calc(var(--bd) + var(--i) * 0.35s) infinite both paused; }
.bento .mu-b3-ticks { animation: mu-b3-clear 5s ease-in-out var(--bd) infinite both paused; }
.bento .mu-b3-tick--1 { animation: mu-b3-tick1 5s ease-in-out var(--bd) infinite both paused; }
.bento .mu-b3-tick--2 { animation: mu-b3-tick2 5s ease-in-out var(--bd) infinite both paused; }
.bento .mu-b3-tick--3 { animation: mu-b3-tick3 5s ease-in-out var(--bd) infinite both paused; }
.bento :is(.mu-b4-card, .mu-b4-new) { animation: 6s ease-in-out var(--bd) infinite both paused; }
.bento .mu-b4-card--1 { animation-name: mu-b4-card1; }
.bento .mu-b4-card--2 { animation-name: mu-b4-card2; }
.bento .mu-b4-card--3 { animation-name: mu-b4-card3; }
.bento .mu-b4-card--4 { animation-name: mu-b4-card4; }
.bento .mu-b4-card--1 .mu-b4-new { animation-name: mu-b4-new1; }
.bento .mu-b4-card--2 .mu-b4-new { animation-name: mu-b4-new2; }
.bento .mu-b4-card--3 .mu-b4-new { animation-name: mu-b4-new3; }
.bento .mu-b4-card--4 .mu-b4-new { animation-name: mu-b4-new4; }
.bento :is(.mu-b5-plug, .mu-b5-seam, .mu-b5-pulse) { animation: 5.6s ease-in-out var(--bd) infinite both paused; }
.bento .mu-b5-plug { animation-name: mu-b5-plug; }
.bento .mu-b5-seam { animation-name: mu-b5-seam; }
.bento .mu-b5-pulse { animation-name: mu-b5-pulse; }
.bento :is(.mu-b6-map, .mu-b6-new) { animation: 6s ease-in-out var(--bd) infinite both paused; }
.bento .mu-b6-map { animation-name: mu-b6-map; }
.bento .mu-b6-new--1 { animation-name: mu-b6-new1; }
.bento .mu-b6-new--2 { animation-name: mu-b6-new2; }
.bento .mu-b6-new--3 { animation-name: mu-b6-new3; }
.bento .mu-b6-new--4 { animation-name: mu-b6-new4; }
.bento .mu-b6-new--5 { animation-name: mu-b6-new5; }
.bento.is-running :is(.mu-b1-lift, .mu-b1-scan, .mu-b4-card, .mu-b5-plug, .mu-b6-map, .mu-b6-new) { will-change: transform, opacity; }

/* 1 Rules database: top sheet lifts, a scan sweeps the stack's front faces, the second sheet's rim lights, settle */
@keyframes mu-b1-lift { 0%, 10% { transform: none; } 24%, 76% { transform: translateY(-10px); } 90%, 100% { transform: none; } }
@keyframes mu-b1-scan {
  0%, 24% { opacity: 0; transform: none; }
  29% { opacity: 1; transform: none; }
  58% { opacity: 1; transform: translateY(var(--scan)); }
  64%, 100% { opacity: 0; transform: translateY(var(--scan)); }
}
@keyframes mu-b1-rim { 0%, 56% { opacity: 0; } 63%, 76% { opacity: 1; } 86%, 100% { opacity: 0; } }
/* 2 Local insights: the eight lots light one after another around the civic block (about three lit at a time), then fade */
@keyframes mu-b2-lot { 0% { opacity: 0; } 7%, 16% { opacity: 1; } 27%, 100% { opacity: 0; } }
/* 3 Field input: three ticks draw in sequence, hold, clear */
@keyframes mu-b3-tick1 { 0%, 10% { stroke-dashoffset: 1; } 18%, 100% { stroke-dashoffset: 0; } }
@keyframes mu-b3-tick2 { 0%, 22% { stroke-dashoffset: 1; } 30%, 100% { stroke-dashoffset: 0; } }
@keyframes mu-b3-tick3 { 0%, 34% { stroke-dashoffset: 1; } 42%, 100% { stroke-dashoffset: 0; } }
@keyframes mu-b3-clear { 0%, 78% { opacity: 1; } 88%, 100% { opacity: 0; } }
/* 4 Every project: cards ride the ramp one at a time onto the stack (new card in accent, absorbed after landing), stack fades at four */
@keyframes mu-b4-card1 {
  0%, 4.2% { opacity: 0; transform: translate(var(--ax), var(--ay)); }
  9.2% { opacity: 1; transform: translate(var(--ax), var(--ay)); }
  21.7% { opacity: 1; transform: translate(var(--bx), var(--by)); }
  27.5%, 87.5% { opacity: 1; transform: none; }
  95%, 100% { opacity: 0; transform: none; }
}
@keyframes mu-b4-new1 { 0%, 27.5% { opacity: 1; } 35.8%, 100% { opacity: 0; } }
@keyframes mu-b4-card2 {
  0%, 21.7% { opacity: 0; transform: translate(var(--ax), var(--ay)); }
  26.7% { opacity: 1; transform: translate(var(--ax), var(--ay)); }
  39.2% { opacity: 1; transform: translate(var(--bx), var(--by)); }
  45%, 87.5% { opacity: 1; transform: none; }
  95%, 100% { opacity: 0; transform: none; }
}
@keyframes mu-b4-new2 { 0%, 45% { opacity: 1; } 53.3%, 100% { opacity: 0; } }
@keyframes mu-b4-card3 {
  0%, 39.2% { opacity: 0; transform: translate(var(--ax), var(--ay)); }
  44.2% { opacity: 1; transform: translate(var(--ax), var(--ay)); }
  56.7% { opacity: 1; transform: translate(var(--bx), var(--by)); }
  62.5%, 87.5% { opacity: 1; transform: none; }
  95%, 100% { opacity: 0; transform: none; }
}
@keyframes mu-b4-new3 { 0%, 62.5% { opacity: 1; } 70.8%, 100% { opacity: 0; } }
@keyframes mu-b4-card4 {
  0%, 56.7% { opacity: 0; transform: translate(var(--ax), var(--ay)); }
  61.7% { opacity: 1; transform: translate(var(--ax), var(--ay)); }
  74.2% { opacity: 1; transform: translate(var(--bx), var(--by)); }
  80%, 87.5% { opacity: 1; transform: none; }
  95%, 100% { opacity: 0; transform: none; }
}
@keyframes mu-b4-new4 { 0%, 80% { opacity: 1; } 88.3%, 100% { opacity: 0; } }
@keyframes mu-b6-new1 {
  0%, 6.7% { opacity: 1; transform: translateY(var(--sink)); }
  16.7%, 76% { opacity: 1; transform: none; }
  86% { opacity: 0; transform: none; }
  86.1% { opacity: 0; transform: translateY(var(--sink)); }
  94%, 100% { opacity: 1; transform: translateY(var(--sink)); }
}
@keyframes mu-b6-new2 {
  0%, 16.7% { opacity: 1; transform: translateY(var(--sink)); }
  26.7%, 76% { opacity: 1; transform: none; }
  86% { opacity: 0; transform: none; }
  86.1% { opacity: 0; transform: translateY(var(--sink)); }
  94%, 100% { opacity: 1; transform: translateY(var(--sink)); }
}
@keyframes mu-b6-new3 {
  0%, 26.7% { opacity: 1; transform: translateY(var(--sink)); }
  36.7%, 76% { opacity: 1; transform: none; }
  86% { opacity: 0; transform: none; }
  86.1% { opacity: 0; transform: translateY(var(--sink)); }
  94%, 100% { opacity: 1; transform: translateY(var(--sink)); }
}
@keyframes mu-b6-new4 {
  0%, 36.7% { opacity: 1; transform: translateY(var(--sink)); }
  46.7%, 76% { opacity: 1; transform: none; }
  86% { opacity: 0; transform: none; }
  86.1% { opacity: 0; transform: translateY(var(--sink)); }
  94%, 100% { opacity: 1; transform: translateY(var(--sink)); }
}
@keyframes mu-b6-new5 {
  0%, 46.7% { opacity: 1; transform: translateY(var(--sink)); }
  56.7%, 76% { opacity: 1; transform: none; }
  86% { opacity: 0; transform: none; }
  86.1% { opacity: 0; transform: translateY(var(--sink)); }
  94%, 100% { opacity: 1; transform: translateY(var(--sink)); }
}
/* 5 Direct integration: plug seats, both seams light, a pulse runs Permit Nav -> municipal system, unplug */
@keyframes mu-b5-plug {
  0%, 12% { transform: translate(var(--ux), var(--uy)); }
  26%, 74% { transform: none; }
  88%, 100% { transform: translate(var(--ux), var(--uy)); }
}
@keyframes mu-b5-seam { 0%, 26% { opacity: 0; } 32%, 62% { opacity: 1; } 70%, 100% { opacity: 0; } }
@keyframes mu-b5-pulse {
  0%, 32% { opacity: 1; stroke-dashoffset: 0.14; }
  62% { opacity: 1; stroke-dashoffset: -1; }
  62.1%, 100% { opacity: 0; stroke-dashoffset: -1; }
}
/* 6 Vision: five new buildings rise from the map in turn (accent window each), the map tilts 1deg, then resets */
@keyframes mu-b6-map { 0%, 60% { transform: none; } 68%, 78% { transform: skewY(-1deg); } 88%, 100% { transform: none; } }

/* ---- MU09 coverage ---- */
.cov__q { margin-top: var(--pn-space-16); color: var(--pn-color-text-secondary); }
.cov__demo { font: inherit; color: var(--pn-color-text-primary); text-decoration-color: currentColor; } /* inline text trigger inside the qualifier */
.cov { margin-top: var(--pn-space-48); }
/* owner 2026-10-14: the map runs the full 1280 container (1280x720 like the module figures); the city list moves under it in three columns */
.cov { display: block; } /* archetype body: block, not the 6+6 split it once was */
.cov__map { position: relative; width: 100%; --map-h: 560px; --map-shift: 60px; } /* owner 2026-10-14: less height; shift keeps DNV and the Langleys inside the crop */
.cov__frame { position: relative; height: var(--map-h); overflow: hidden; border-radius: var(--pn-radius-card); }
.cov__map img { display: block; width: 100%; height: var(--map-h); object-fit: cover; object-position: 50% calc(-1 * var(--map-shift)); }
/* owner 2026-10-14: no hairline around the full-width map (the 608 frame had one so it would not melt into the page) */
.cov__attr { margin-top: var(--pn-space-12); color: var(--pn-color-text-muted); }
.mu-cities { margin-top: var(--pn-space-48); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(3, 44px); grid-auto-flow: column; column-gap: var(--pn-space-24); align-content: start; }
.mu-cities li { display: flex; align-items: center; gap: var(--pn-space-12); font: var(--pn-type-ui-label); color: var(--pn-color-text-primary); }
.mu-cities li::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--pn-color-accent-primary); }
.cov__caption { margin-top: var(--pn-space-64); }

/* ---- Band, municipalities variant ---- */
.mu-checks { display: flex; gap: var(--pn-space-32); margin-top: var(--pn-space-32); }
.mu-checks li { display: flex; align-items: center; gap: var(--pn-space-8); }
.mu-checks .hw-ico { width: 20px; height: 20px; stroke-width: 2; }
.mu-band__actions { margin-top: 40px; }
/* the photo is 641px tall from the world's top edge; the frame's map is 676 tall, so shift the whole world (photo + overlay
   together, alignment unchanged) down 36px so the photo reaches the bottom edge */
.mu-fig-lookup .lk-map__world { transform: translateY(36px); }
/* MU05: the H04 run-out (96 + 24 under the fade) is drawn by the verifier's own columns, not as a bare strip under them:
   the grid pulls into the scroll padding and both columns extend 120, so at the end of the scroll the drawer footer sits
   clear of the fade with drawer surface beneath it */
.figure--ui-scroll .ui--verifier { margin-bottom: calc(-1 * (96px + 24px)); }
/* owner 2026-11-04 ("make this non scrollable, keep the fade"): the verifier's frame shows its first 720 and stops; the
   figure's bottom fade (::before on .figure--ui-scroll) stays over the cut. No scroll region, so no focus stop either. */
.figure--ui-scroll .figure__scroll:has(> .ui--verifier) { overflow: clip; } /* clip, not hidden: no scrolling by wheel, keys or script */
.ui--verifier .uv-drawer, .ui--verifier .uv-list { padding-bottom: calc(96px + 24px); }

/* owner 2026-10-10: the "Without" side of the comparison rows reads translucent so the "With Permit Nav" side carries the weight */
.mu-row .mu-cmp:not(.mu-cmp--with) { opacity: 0.55; }

/* owner 2026-10-10: each "With Permit Nav" eyebrow carries a check */
.mu-row .mu-cmp__label { display: flex; align-items: center; gap: var(--pn-space-8); height: 18px; } /* same box on both sides so the rows stay level */
.mu-cmp__check { flex: none; width: 16px; height: 16px; border-radius: 50%; display: grid; place-items: center; background: rgba(70, 200, 138, 0.22); } /* owner: check on a round background */
.mu-cmp__check svg { fill: none; stroke: currentColor; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }

/* owner 2026-10-10 gave the three module sections 224 (more air than the page's 128); owner 2026-11-01 set every section gap
   to 288, so the override is gone and they take the page gap. */

/* owner 2026-10-10 hid the FIG_0N plates here; owner 2026-11-01 removed them from every page ("remove all of the figs on the site") */

/* owner 2026-10-10: the nine municipalities as dots on the coverage map; the SVG uses the same slice fit as the image so the dots stay put */
.cov__pins { position: absolute; left: 0; top: calc(-1 * var(--map-shift)); width: 100%; aspect-ratio: 1536 / 1024; height: auto; pointer-events: none; } /* meet-fit at the image's own scaled size, so pin coordinates follow the image */
.cov__pin-dot { fill: var(--pn-color-accent-primary); }
.cov__pin-ring { fill: rgba(70, 200, 138, 0.22); }
/* owner 2026-10-10: Municipalities band keeps only the demo card, at the same width as before */
/* owner 2026-10-10: Municipalities band is text left, demo card right */
.page-municipalities #early-access .container { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--pn-layout-gutter); align-items: center; }
.page-municipalities #early-access .band__eyebrow, .page-municipalities #early-access .band__title, .page-municipalities #early-access .band__body { grid-column: 1; }
.page-municipalities #early-access .band__cards { grid-column: 2; grid-row: 1 / span 3; grid-template-columns: minmax(0, 1fr); margin-top: 0; }
/* launch 2026-11-04 (owner: "start your project buttons are for homeowners and professionals, hide these buttons and make the
   book demo button primary"): every band now holds the demo card alone, so the Municipalities layout (text left, the card
   right) applies to any band whose card row has one card */
.band:has(.band__cards > :only-child) .container { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--pn-layout-gutter); align-items: center; }
.band:has(.band__cards > :only-child) :is(.band__eyebrow, .band__title, .band__body) { grid-column: 1; }
.band:has(.band__cards > :only-child) .band__cards { grid-column: 2; grid-row: 1 / span 3; grid-template-columns: minmax(0, 1fr); margin-top: 0; }

/* owner 2026-10-10: each map dot has a hover/focus: the ring swells, a name tip appears above it, and the matching city in the list lights */
.cov__pins { pointer-events: none; }
.cov__pin { pointer-events: auto; cursor: default; outline: none; }
.cov__pin-ring { transition: transform 200ms ease, fill 200ms ease; transform-box: fill-box; transform-origin: center; }
.cov__pin:hover .cov__pin-ring, .cov__pin:focus-visible .cov__pin-ring, .cov__pin.is-hot .cov__pin-ring { transform: scale(1.5); fill: rgba(70, 200, 138, 0.34); }
.cov__pin:focus-visible .cov__pin-dot { stroke: var(--pn-color-focus); stroke-width: 3; }
.cov__tip {
  position: absolute; z-index: 2; transform: translate(-50%, calc(-100% - 14px)); white-space: nowrap;
  padding: 6px 10px; border-radius: var(--pn-radius-control);
  background: rgba(11, 14, 20, 0.85); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid rgba(242, 240, 233, 0.14); color: var(--pn-color-text-primary);
  font: var(--pn-type-ui-label-s); pointer-events: none; opacity: 0; transition: opacity 160ms ease;
}
.cov__tip.is-on { opacity: 1; }
.mu-cities li { transition: color 160ms ease; }
.mu-cities li.is-hot { color: var(--pn-color-accent-primary); }
@media (prefers-reduced-motion: reduce) { .cov__pin-ring, .cov__tip, .mu-cities li { transition: none; } }

/* owner 2026-10-10 (Municipalities): no divider hairlines around the band; the demo card is green */
.page-municipalities .band { border-top: 0; }
.page-municipalities .site-footer { border-top: 0; }
.page-municipalities #early-access .cta-card--secondary { background: var(--pn-color-text-primary); color: var(--pn-color-background-canvas); } /* owner 2026-10-14: off-white, not green */ /* owner: the offer card's green with black text */
.page-municipalities #early-access .cta-card--secondary .cta-card__caption { color: rgba(11, 14, 20, 0.64); }
.page-municipalities #early-access .cta-card--secondary { --card-fill: var(--pn-color-brand-green); --card-ink: var(--pn-color-background-canvas); } /* owner 2026-10-31: this off-white card fills brand green on hover like every primary card (the generic secondary raisedHover fill sat under its dark ink); replaces the old plain white hover */

/* ---------- Accent exploration: neutral chrome (2026-10-13) ---------- */
:root[data-accent="neutral"] .link:not(.link--muted) { text-decoration-color: currentColor; } /* colour no longer marks links, so the underline always shows */
:root[data-accent="neutral"] .link:not(.link--muted):hover { color: #ffffff; }
:root[data-accent="neutral"] .band__eyebrow, :root[data-accent="neutral"] .t-eyebrow { color: var(--pn-color-text-muted); } /* eyebrows go quiet instead of white */
:root[data-accent="neutral"] .btn--primary:focus-visible, :root[data-accent="neutral"] .offer-card:focus-visible { outline-color: var(--pn-color-focus-onLight); outline-offset: -4px; }

/* owner 2026-10-14 (Municipalities): map pins and logo tiles are linked. Hover a pin: the carousel holds, the matching logo
   turns to its real colours and slides to the centre. Hover a logo: its pin lights and names itself. */
.logo-marquee.is-held .logo-wall--marquee { animation-play-state: paused; transition: transform 600ms cubic-bezier(.2,.7,.2,1); }
.logo-marquee.is-held .logo-tile:not(.is-lit) { opacity: 0.55; }
.logo-marquee .logo-tile { transition: opacity 240ms ease, background-color 240ms ease; }
.logo-marquee .logo-tile img { transition: filter 240ms ease, opacity 240ms ease; }
.logo-marquee .logo-tile.is-lit img, .logo-marquee .logo-tile:hover img { filter: none; opacity: 1; } /* scoped: Home H05 keeps its white logos with no hover (H, 2026-10-14) */
.logo-marquee .logo-tile.is-lit, .logo-marquee .logo-tile:hover { background: var(--pn-color-text-primary); }
.logo-marquee .logo-tile--light.is-lit, .logo-marquee .logo-tile--light:hover { background: var(--pn-color-background-raisedHover); } /* a logo whose only artwork is white stays on a dark tile */ /* the native artwork is dark on every logo we have, so a lit tile goes off-white like a real logo card */
@media (prefers-reduced-motion: reduce) { .logo-marquee.is-held .logo-wall--marquee { transition: none; } }

/* coverage archetype: the host section's data-audience picks the qualifier line */
[data-include="coverage"] .cov__q { display: none; }
[data-include="coverage"][data-audience="municipal"] .cov__q--municipal { display: block; }
[data-include="coverage"][data-audience="applicant"] .cov__q--applicant { display: block; }

/* owner 2026-10-14: the 'With Permit Nav' eyebrows stay bright under any accent theme (the neutral theme mutes .t-eyebrow) */
.page-municipalities .mu-cmp--with .mu-cmp__label { color: var(--pn-color-text-primary); } /* owner: off-white text */
.page-municipalities .mu-cmp--with .mu-cmp__check { background: var(--pn-color-brand-green); color: var(--pn-color-background-canvas); } /* owner: solid green circle, dark check */


/* owner 2026-10-29: in-screen primaries are outline buttons (Look up, Export PDF, Continue, Save & Verify, Start a project), never white fills */
.hw-pill--primary .hw-ico, .lk-go .hw-ico, .uf-btn--white .hw-ico, .uv-btn--white .hw-ico { color: inherit; }

/* ---------- Canada archetype (partials/canada.html; Municipalities MU07 + Our Story OS05, 2026-10-29): Canadian owned / data stays in Canada ---------- */
.ca__lead { margin-top: var(--pn-space-24); max-width: 72ch; color: var(--pn-color-text-secondary); text-wrap: pretty; } /* owner 2026-10-31: the title is a section heading (40) now, not a sub (26); the lead sits 24 under it like every other section intro */
.ca { margin: var(--pn-space-48) 0 0; --map-h: 420px; } /* owner 2026-10-29: not much taller than the cards (about 270 + 32 inset) */
.ca__frame { position: relative; height: var(--map-h); overflow: hidden; border-radius: var(--pn-radius-card); background: var(--pn-color-background-canvas); }
/* the image is bottom-anchored at full width; the three cards sit over its lower band (owner: cards over the map, no pin, no hairlines) */
/* owner 2026-10-29: zoomed in; full width, bottom-anchored so the south border and the Great Lakes sit in the frame (about lat 40 to 60 at 1440).
   The image fades into the canvas on its own left, right and bottom; the top is cropped by the frame, so a mask fades that edge too. */
.ca__img {
  position: absolute; left: 0; bottom: 0; width: 100%; height: auto; display: block;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 140px); mask-image: linear-gradient(to bottom, transparent 0, #000 140px);
}
.ca__cards {
  position: absolute; inset: 0 var(--pn-space-32); /* owner 2026-10-29: centred on the map */
  display: grid; align-content: center; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--pn-space-24); margin: 0; padding: 0; list-style: none;
}
.ca__card { padding: 0; } /* owner 2026-10-29: no card background, no inner padding; with the fills gone the 24 inset only shortened the titles into two lines */
.ca__ico { display: block; height: 24px; color: var(--pn-color-text-secondary); }
.ca__glyph { display: block; width: 24px; height: 24px; fill: currentColor; } /* owner 2026-10-29: solid glyphs, inline in the page; the list sprite stays outline */
.ca__card-h { margin-top: var(--pn-space-16); color: var(--pn-color-text-primary); }
.ca__card-p { margin-top: var(--pn-space-8); color: var(--pn-color-text-secondary); text-wrap: pretty; }

/* ======================================================================
   Responsive layer (docs/BUILD-CONTRACT-responsive-2026-11-04.md). Desktop-first: the rules above are the 1440 contract;
   these three tiers only override. Foundations here (tiers, type, container, split, header drawer, band, CTA cards,
   footer, images); the Home and Municipalities page blocks add their own tier rules (phase 2).
   ====================================================================== */

/* ---- responsive: laptop (2026-11-04) ---- */
@media (max-width: 1279px) {
  :root { --pn-layout-gutter: var(--pn-space-48); }

  /* page: home */
  /* hero: the two windows keep their native 1280 stage (640 tall here) and scale whole to the container, from the top left
     (k = container / 1280); the stage's layout box is pulled up to the scaled height, and the hero ends with the stage */
  .hero { container-type: inline-size; min-height: 0; }
  .hero__content { width: min(920px, 100% - 2 * var(--page-margin)); }
  .hero__stage {
    --hero-k: tan(atan2(100cqw - 2 * var(--page-margin), 1280px));
    flex: none; width: 1280px; height: 760px; margin-inline: var(--page-margin) 0; /* 760: the desktop --stage-h (owner 2026-11-04) */
    margin-bottom: calc(760px * (var(--hero-k) - 1));
    transform: scale(var(--hero-k)); transform-origin: 0 0;
  }
}

/* ---- responsive: tablet (2026-11-04) ---- */
@media (max-width: 1023px) {
  :root {
    --pn-layout-gutter: var(--pn-space-32);
    --pn-type-display-hero: 700 44px/1.1 var(--pn-font-display);
    --pn-type-heading-section: 700 34px/1.15 var(--pn-font-display);
    --pn-type-heading-sub: 700 24px/1.2 var(--pn-font-display);
  }
  .page-main { --section-gap: var(--pn-space-96); }

  /* content images and drawings never run past their box (zero specificity: any class rule still wins; icon sprites keep their size) */
  :where(.page-main) :where(img, svg):where(:not(.hw-ico)) { max-width: 100%; height: auto; } /* 2b: :not() inside :where() so the rule really is zero-specificity (bare :not(.hw-ico) scored 0,1,0 and beat .lk-map__photo's max-width: none) */

  /* header: brand left, the 44 toggle right; nav and actions live in the drawer */
  .site-header__left > nav, .site-header__actions { display: none; }
  .nav-toggle { display: block; }
  .site-drawer { display: block; }

  /* band: each CTA puts its caption under the button, so two fit side by side */
  .band__actions { align-items: flex-start; gap: var(--pn-space-32); }
  .band__cta { flex-direction: column; align-items: flex-start; gap: var(--pn-space-12); }
  .band__caption { white-space: normal; }
  .band__actions > .cta-card { flex: 1 1 0; min-width: 0; }

  /* footer: brand on its own row, then two columns */
  .footer__cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pn-layout-gutter); row-gap: var(--pn-space-64); }
  .footer__col--brand { grid-column: 1 / -1; }
  .footer__col--contact { gap: var(--pn-space-48); } /* Contact and Support: 48 apart, closer to the 64 row gap than the desktop 32 */
  /* footer links: a 45 tap target (12 above and below the 21 line); the negative margin hands 8 of each side back, so
     neighbouring targets touch without overlapping and the list opens up only from a 37 to a 45 pitch */
  .footer__link { padding-block: var(--pn-space-12); margin-block: calc(-1 * var(--pn-space-8)); }

  /* page: home */
  .hero { --hero-fade: var(--pn-space-96); }
  #applicant-preparation .figure, #municipal-review .figure { margin-top: var(--pn-space-64); }
  .features { margin-top: var(--pn-space-64); }
  /* route cards: one per row, the desktop card otherwise (owner 2026-11-04, "make these cards similar to the desktop
     view, with a black transparent gradient overlay and reduce opacity on hover"; the r1 photo-beside-copy card is gone):
     the photo is the whole card, cropped from its top (the faces are in the upper half), the scrim over its lower
     band, the copy at the bottom, the scrim easing and the photo growing on hover as on desktop. The height follows
     the width (16:10 here at one column; 4:5 on phone) instead of the fixed 600. */
  .route-cards { grid-template-columns: minmax(0, 1fr); gap: var(--pn-space-32); }
  .route-card { height: auto; aspect-ratio: 16 / 10; padding-top: 0; justify-content: flex-end; }
  .route-card__title { min-height: 0; } /* one card per row: nothing to align with */
  .route-card__img { object-position: 50% 0; }
  .route-card__text { flex: 0 0 auto; }

  /* page: municipalities */
  /* hero: copy first at full width, then the approvals window (native 1120 x 720) scaled whole to the container below it */
  .mu-hero { container-type: inline-size; padding-top: calc(var(--pn-space-48) + var(--pn-space-96)); }
  .mu-hero__inner { min-height: 0; }
  .mu-hero__copy { width: auto; max-width: 560px; padding-right: 0; }
  .mu-hero__win {
    --mu-k: tan(atan2(100cqw - 2 * var(--page-margin), 1120px));
    position: relative; top: auto; left: auto; margin-top: var(--pn-space-64);
    margin-bottom: calc(720px * (var(--mu-k) - 1));
    transform: scale(var(--mu-k)); transform-origin: 0 0;
  }
  /* owner 2026-11-04 ("if they are not left and right, always put the screen above the button"): whenever the hero stacks
     (below 1024), the order is title, lead, the screen, then the demo card and the link. The copy wrapper dissolves
     (display: contents) so the screen can sit between the lead and the buttons; the hero's bottom fade (over the
     screen before) is off, and the screen fades itself out instead. */
  .mu-hero__inner { display: flex; flex-direction: column; align-items: flex-start; }
  .mu-hero__copy { display: contents; }
  .mu-hero__copy > .t-display-hero { order: 1; max-width: 560px; } /* the wrapper's 560 column, kept on the copy itself */
  .mu-hero__lead { order: 2; max-width: 560px; }
  .mu-hero__win { order: 3; }
  .mu-hero__buttons { order: 4; margin-top: var(--pn-space-64); align-self: stretch; max-width: 560px; }
  .mu-hero__fade { display: none; }
  .mu-hero__veil { display: none; } /* owner 2026-11-04 ("the overlay should only apply to the screen, not over the buttons"): the section-wide vignette is for the side-by-side composition; stacked, the screen's own fade below is the only overlay */
  .mu-hero__win::before {
    content: ""; position: absolute; z-index: 6; left: 0; right: 0; bottom: 0; height: 160px; /* native px: scaled with the screen */
    background: linear-gradient(to bottom, rgba(11, 14, 20, 0), var(--pn-color-background-canvas));
    pointer-events: none;
  }
  .mu-wf, .mu-cols, .page-municipalities .figure { margin-top: var(--pn-space-64); }
  /* workflow: 2 x 2 (four 150 columns at 768 hyphenated the copy into five lines). The track's node pitch is one column
     of four, so off the single row it has nothing to point at: the decorative (aria-hidden) track goes, the numbered steps
     carry the sequence, and every step shows in full colour (the .is-static colours), not the timeline's dimmed state */
  .mu-wf__track { display: none; }
  .mu-process { margin-top: 0; }
  .mu-cols--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pn-layout-gutter); row-gap: var(--pn-space-48); }
  .mu-process .mu-col :is(.mu-col__num, .mu-col__h) { color: var(--pn-color-text-primary); }
  .mu-process .mu-col .mu-col__p { color: var(--pn-color-text-secondary); }
  .mu-feats { margin-top: var(--pn-space-64); }

  /* coverage archetype (partials/coverage.html): below 944 a 560-tall frame is taller than the width-fitted map, so cover
     would scale the photo by height and the pins (fitted to the width) would drift; frame and shift follow the width instead */
  .cov__map { container-type: inline-size; --map-h: calc(100cqw * 560 / 1280); --map-shift: calc(100cqw * 60 / 1280); }
  /* canada archetype: three 192 columns over a 370-tall map crowded the copy onto the coastline; the map now sits whole on
     top (its top fade scaled to the shorter image) and the three points follow below it on the canvas, at the gutter */
  /* owner 2026-11-04 ("the map the bg of the copy, not separated from it" / "they are not overlapped, the copy is still
     below"): the map is the block's background at every width. The frame grows with the copy; the image covers it
     (object-fit) and fades out at all four edges so no rectangle shows; the three points sit on top with 64 above and
     below. (The 2026-11-04 r1 version showed the map whole above the copy; it read as a separate picture.) */
  .ca__frame { height: auto; overflow: hidden; }
  .ca__img {
    --ca-fade: var(--pn-space-96);
    position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; object-position: 50% 45%;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--ca-fade), #000 calc(100% - var(--ca-fade)), transparent 100%), linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0, #000 var(--ca-fade), #000 calc(100% - var(--ca-fade)), transparent 100%), linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%);
    -webkit-mask-composite: source-in; mask-composite: intersect;
  }
  .ca__cards { position: relative; inset: auto; column-gap: var(--pn-layout-gutter); margin-top: 0; padding: var(--pn-space-64) 0; }
}

/* ---- responsive: phone (2026-11-04) ---- */
@media (max-width: 767px) {
  /* section titles carry a hard break for the 6-col split ("Permit <br>Tracker"); at one column the words fit on one line */
  .t-heading-section br { display: none; }
  :root {
    --page-margin: var(--pn-layout-gutter-mobile);
    --pn-layout-gutter: var(--pn-layout-gutter-mobile);
    --pn-type-display-hero: 700 36px/1.12 var(--pn-font-display);
    --pn-type-heading-section: 700 30px/1.15 var(--pn-font-display);
    --pn-type-heading-sub: 700 22px/1.25 var(--pn-font-display);
  }
  .page-main { --section-gap: calc(var(--pn-space-64) + var(--pn-space-16)); } /* 80 */

  .split { grid-template-columns: minmax(0, 1fr); row-gap: var(--pn-space-16); }

  /* band: stacked, full width */
  .band { padding-block: var(--pn-space-64); }
  .band__actions { flex-direction: column; align-items: stretch; gap: var(--pn-space-32); }
  .band__actions > .cta-card { flex: none; }
  .band__cta { align-items: stretch; }
  .band__cards { grid-template-columns: minmax(0, 1fr); gap: var(--pn-space-24); }
  .cta-card { padding: var(--pn-space-24); min-height: 0; } /* owner 2026-11-04 ("this height needs to be smaller on mobile, reduce the empty space"): no 180 floor; the card is its caption, 12, and the label row */

  /* footer: one column, brand first, the legal line last */
  .site-footer { padding-top: var(--pn-space-64); }
  .footer__cols { grid-template-columns: minmax(0, 1fr); row-gap: var(--pn-space-48); }
  .footer__bottom { flex-direction: column; gap: var(--pn-space-8); margin-top: var(--pn-space-64); }

  /* page: home */
  .hero { --hero-fade: var(--pn-space-48); }
  .hero__stage { margin-top: var(--pn-space-64); }
  /* owner 2026-11-04 ("this is too small on phone, any way to make it bigger?"): the stage no longer shrinks whole (0.27 at
     390); it is cropped: scaled so the lookup panel and the parcel fill the width (k = width / 760, 0.46 at 390), anchored
     top-left, the rest of the map running off the right edge under the hero's clip. The checklist window sits at native
     x 864+, outside the crop, so it is off here. */
  .hero { overflow-x: clip; }
  .hero__stage { --hero-k: tan(atan2(100cqw - 2 * var(--page-margin), 760px)); }
  .hw--check { display: none; }
  .hero__actions-anim { align-self: stretch; }
  .hero__buttons { flex-direction: column; }
  #applicant-preparation .figure, #municipal-review .figure { margin-top: var(--pn-space-48); }
  .features { margin-top: var(--pn-space-48); }
  .features__pills { justify-content: flex-start; }
  .route-cards { margin-top: var(--pn-space-48); gap: var(--pn-space-24); }
  .route-card { aspect-ratio: 4 / 5; } /* portrait at 350 wide: room for the faces above the copy */
  .route-card__text { padding: var(--pn-space-24); }

  /* page: municipalities */
  .mu-hero__buttons { --ph-cta-pad: var(--pn-space-24); --ph-cta-label-size: 32px; margin-top: var(--pn-space-48); }
  .mu-hero__win { margin-top: var(--pn-space-48); } /* the stacked order (screen before the buttons) is the tablet rule */
  .mu-cols--4 { grid-template-columns: minmax(0, 1fr); }
  /* owner 2026-11-04 ("keep the timeline animation here but vertical"): the track (hidden at tablet) comes back as a
     column on the left. Track and list are display: contents, so the four cells and the four steps are items of one
     .mu-wf grid: column 1 the nodes, column 2 the copy, one row per step, each node level with its step's number. The
     base line and the progress line are the track's pseudo-elements, in column 1 across rows 1-3 plus the row gap and
     half a node each end, so they run from node 1's centre to node 4's centre; progress is a height now, not a width. */
  .mu-wf { display: grid; grid-template-columns: var(--wf-node) minmax(0, 1fr); column-gap: var(--pn-space-24); row-gap: var(--pn-space-48); }
  .mu-wf__track, .mu-process { display: contents; }
  .mu-wf__cell { grid-column: 1; align-self: start; height: var(--wf-node); }
  .mu-wf__cell:nth-child(1), .mu-process .mu-col:nth-child(1) { grid-row: 1; }
  .mu-wf__cell:nth-child(2), .mu-process .mu-col:nth-child(2) { grid-row: 2; }
  .mu-wf__cell:nth-child(3), .mu-process .mu-col:nth-child(3) { grid-row: 3; }
  .mu-wf__cell:nth-child(4), .mu-process .mu-col:nth-child(4) { grid-row: 4; }
  .mu-process .mu-col { grid-column: 2; padding-top: 7px; } /* the 13/1.4 number line's centre (9) on the node's centre (16) */
  .mu-wf__track::before, .mu-wf__track::after {
    position: static; grid-column: 1; grid-row: 1 / 4; justify-self: center; align-self: stretch;
    width: 1px; height: auto;
    margin-top: calc(var(--wf-node) / 2); margin-bottom: calc(-1 * (var(--pn-space-48) + var(--wf-node) / 2));
  }
  .mu-wf__track::after { align-self: start; height: calc(var(--wf-progress) * (100% + var(--pn-space-48))); transition: height 600ms ease-in-out; }
  /* the timeline's dimmed state is back (tablet lit every step because the track was gone) */
  .mu-wf:not(.is-static) .mu-process .mu-col:not(.is-active) :is(.mu-col__num, .mu-col__h) { color: var(--pn-color-text-secondary); }
  .mu-wf:not(.is-static) .mu-process .mu-col:not(.is-active) .mu-col__p { color: var(--pn-color-text-muted); }
  .mu-feats--3, .mu-feats--2 { grid-template-columns: minmax(0, 1fr); }
  .mu-feats { margin-top: var(--pn-space-48); }
  .mu-wf, .mu-cols, .page-municipalities .figure { margin-top: var(--pn-space-48); }
  .mu-row.split { row-gap: var(--pn-space-24); }
  .page-municipalities #early-access .container { grid-template-columns: minmax(0, 1fr); }
  .page-municipalities #early-access .band__cards { grid-column: 1; grid-row: auto; margin-top: var(--pn-space-48); }
  .band:has(.band__cards > :only-child) .container { grid-template-columns: minmax(0, 1fr); }
  .band:has(.band__cards > :only-child) .band__cards { grid-column: 1; grid-row: auto; margin-top: var(--pn-space-48); }

  /* canada archetype: one point per row, the map behind all three (tablet rule), fades 48 top and bottom */
  .ca__img { --ca-fade: var(--pn-space-48); }
  .ca__cards { grid-template-columns: minmax(0, 1fr); row-gap: var(--pn-space-48); padding: var(--pn-space-48) 0; }
}

/* Legal page (privacy.html): the live policy text on a comfortable reading measure */
.page-main > .legal-head { padding-top: calc(var(--pn-header-height) + var(--pn-space-64)); }
.page-main > .legal-head + .legal { margin-top: var(--pn-space-48); }
.legal__measure { max-width: 720px; }
.legal__eyebrow { color: var(--pn-color-accent-primary); }
.legal-head h1 { margin-top: var(--pn-space-16); }
.legal__meta { margin-top: var(--pn-space-16); color: var(--pn-color-text-muted); }
.legal__intro { margin-top: var(--pn-space-24); color: var(--pn-color-text-secondary); }
.legal__sec + .legal__sec { margin-top: var(--pn-space-48); }
.legal__sec h2 { color: var(--pn-color-text-primary); }
.legal__sec p, .legal__sec li { font: var(--pn-type-text-body); color: var(--pn-color-text-secondary); }
.legal__sec h2 + p, .legal__sec h2 + ul { margin-top: var(--pn-space-16); }
.legal__sec p + p, .legal__sec p + ul, .legal__sec ul + p { margin-top: var(--pn-space-16); }
.legal__sec ul { padding-left: var(--pn-space-24); list-style: disc; }
.legal__sec li + li { margin-top: var(--pn-space-8); }
.legal__sec strong { color: var(--pn-color-text-primary); font-weight: 700; }
.legal__sec a { color: var(--pn-color-text-primary); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
@media (max-width: 767px) { .page-main > .legal-head { padding-top: calc(var(--pn-header-height) + var(--pn-space-32)); } }
