/* RPMTX - styles.css
   Brand (locked): navy #061727 · orange #F45313 · white · alt (blue tint) #EAF0F7
   Colours are defined once, below; everything else uses the custom properties.
   Headings: Space Grotesk 700 · Body: Inter · Mono (IBM Plex Mono) only on
   record-like data: .record*, .mock*, and the calculator's door count. */

:root {
  --navy: #061727;
  --navy-deep: #10263D;   /* hover on navy buttons: a step lighter, so the change shows */
  --orange: #F45313;
  --navy-rgb: 6, 23, 39;
  --orange-rgb: 244, 83, 19;
  --bg: #FFFFFF;
  --alt: #EAF0F7;   /* soft blue tint for alternating sections (owner, 2026-09-30) */
  --ink: #22303F;
  --ink-soft: #55636F;
  --line: #E3E8EE;
  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 22px;
  --navy-raised: #10263D;  /* cards ON navy (same value as --navy-deep) */
  --nav-h: 72px;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --shadow: 0 1px 2px rgba(var(--navy-rgb), .05), 0 12px 32px -12px rgba(var(--navy-rgb), .14);
  --shadow-lift: 0 2px 4px rgba(var(--navy-rgb), .06), 0 24px 48px -16px rgba(var(--navy-rgb), .22);
  --font-head: "Space Grotesk", system-ui, sans-serif;
  --font-body: "Inter", system-ui, -apple-system, sans-serif;
  --ease: cubic-bezier(.22,.61,.21,1);
  /* motion tokens: expo-out for arrivals, a quick ease-in for exits */
  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease-in: cubic-bezier(.4,0,1,1);
  --ease-io: cubic-bezier(.65,0,.35,1);
  --d1: 160ms; --d2: 280ms; --d3: 520ms; --d4: 900ms;

  /* ---- design system (design review, 2026-10-14) ----
     One scale for type, one rhythm for sections, one radius per kind of
     thing. Components read these; nothing below should invent a size. */
  --fs-display: clamp(2.9rem, 8vw, 6.4rem);     /* the hero tagline only */
  --fs-statement: clamp(2.4rem, 5.2vw, 4.25rem); /* the two statement lines: the make-good and the closing band */
  --fs-h1: clamp(2.3rem, 5.4vw, 3.9rem);
  --fs-h2: clamp(1.85rem, 3.6vw, 2.75rem);
  --fs-h3: 1.2rem;
  --fs-lede: clamp(1.06rem, 1.3vw, 1.18rem);
  --fs-body: 1.0625rem;
  --fs-small: .9rem;
  --fs-label: .76rem;                            /* eyebrows, card labels, badges */
  --space-section: clamp(4rem, 8vw, 7rem);       /* every section's top and bottom */
  --space-head: clamp(1.8rem, 3.2vw, 2.75rem);   /* section header to its content */
  --radius-btn: var(--radius-sm);                /* ONE button radius, everywhere */
  --radius-card: var(--radius);                  /* every card */
  --card-pad: clamp(1.2rem, 2vw, 1.5rem);
  --shadow-card: 0 18px 40px -22px rgba(var(--navy-rgb), .55);
}

/* ---------- reset-ish ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* `hidden` always wins over a component's display value */
[hidden] { display: none !important; }
/* Anchor jumps land below the fixed nav. Smooth scrolling is switched on by
   main.js (html.smooth) only after load and only with motion, so arriving at
   /page#section jumps straight there instead of gliding past it mid-layout. */
html { scroll-padding-top: calc(var(--nav-h) + 14px); }
html.smooth { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg { max-width: 100%; height: auto; }
/* clip, not hidden: hidden makes body a scroll container and silently breaks the sticky nav. */
html, body { overflow-x: clip; }
h1, h2, h3 {
  font-family: var(--font-head);
  font-weight: 700;
  color: var(--navy);
  line-height: 1.12;
  margin: 0 0 .5em;
  letter-spacing: -.015em;
  text-wrap: balance;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); letter-spacing: -.02em; }
h3 { font-size: var(--fs-h3); }
p { margin: 0 0 1em; }
/* ONE orange (#F45313) site-wide. It is 3.45:1 on white, too light for small text,
   so links on white are navy with an orange underline; orange TEXT is for large or
   bold callouts and for anything on navy (5.25:1). */
a { color: var(--navy); text-decoration-color: var(--orange); text-decoration-thickness: 2px; text-underline-offset: 3px; }

:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
  border-radius: 4px;
}

/* 1280px column (was 1140): less empty margin on desktop screens (owner, 2026-09-30) */
.container { width: min(1280px, 100% - 2.5rem); margin-inline: auto; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 1rem; top: -4rem; z-index: 200;
  background: var(--navy); color: #fff; padding: .6rem 1rem; border-radius: 8px;
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 1rem; }
.u-orange { color: var(--orange); }
/* callout words: short phrases a reader should remember. Bold, and only where
   they pass contrast: large text on white, or any size on navy. */
.hl, .num.hl, .hero__proof .num.hl { color: var(--orange); font-weight: 700; }
.eyebrow {
  font-family: var(--font-head);
  font-weight: 700; font-size: var(--fs-label); letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-soft);
  margin-bottom: 1rem;
}
/* Intro paragraphs run the full container width (owner request): no ch cap.
   text-wrap: pretty avoids a lone word on the last line. */
.section__lede { color: var(--ink-soft); font-size: var(--fs-lede); line-height: 1.55; margin: .4rem 0 var(--space-head); text-wrap: pretty; }
.section__ctas { display: flex; flex-wrap: wrap; gap: .9rem; margin-top: 1.6rem; }

/* The ONE accent for key numbers: 642 doors, $2M, $0, 1-7 nights, next
   morning, the calculator output. Orange, heading weight, never mono
   (the calculator overrides the face below, where the data is record-like). */
.num {
  font-family: var(--font-head); font-weight: 700;
  color: inherit; font-style: normal; /* orange rule: numbers are facts, not accents */
  font-variant-numeric: tabular-nums;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--font-head); font-weight: 700; font-size: 1rem;
  padding: .85rem 1.6rem; border-radius: var(--radius-btn); border: 2px solid transparent;
  text-decoration: none; cursor: pointer; line-height: 1.2;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease),
              background-color .18s var(--ease), color .18s var(--ease);
}
/* navy label on orange: 5.25:1 (white on this orange is 3.45:1 and fails AA) */
.btn--primary {
  background: var(--orange); color: var(--navy);
  box-shadow: 0 6px 16px -8px rgba(var(--navy-rgb), .35);
}
.btn--primary:hover { background: var(--navy); color: #fff; transform: translateY(-2px); box-shadow: 0 10px 24px -8px rgba(var(--navy-rgb), .5); }
.btn--primary:active { transform: translateY(0); }
/* On the navy nav bar the default navy hover disappears into the bar (owner,
   2026-09-30): flip to a white button with a navy label there. The floating
   pill crosses white and navy sections, so it also goes white, with a navy
   edge so it stays visible on white. */
.nav .btn--primary:hover, .nav .btn--primary:focus-visible,
.sticky-cta__btn:hover, .sticky-cta__btn:focus-visible { background: #fff; color: var(--navy); }
.sticky-cta__btn:hover, .sticky-cta__btn:focus-visible { border-color: var(--navy); }
.btn--ghost { color: var(--navy); border-color: var(--navy); background: transparent; }
.btn--ghost:hover { background: var(--navy); color: #fff; transform: translateY(-2px); }
.btn--navy { background: var(--navy); color: #fff; box-shadow: 0 6px 18px -6px rgba(var(--navy-rgb), .5); }
.btn--navy:hover { background: var(--navy-deep); transform: translateY(-2px); }
.btn--sm { padding: .55rem 1.1rem; font-size: .92rem; }
.btn--block { width: 100%; text-align: center; }
@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover { transition: none; transform: none; }
}

.link-arrow {
  color: var(--navy); font-weight: 600; text-decoration: none;
  white-space: nowrap; padding: .35rem .1rem; display: inline-block;
}
/* non-breaking space before the arrow: where the link may wrap (.contract-mini,
   the success links) the arrow never lands alone on a line (audit m11) */
.link-arrow::after { content: "\00a0\2192"; color: var(--orange); }
.link-arrow:hover, .link-arrow:focus-visible { text-decoration: underline; text-decoration-color: var(--orange); }

/* ---------- scroll reveal: see "motion system" at the end of this file ---------- */
.reveal { opacity: 1; }

/* ---------- nav ----------
   Owner decision 2026-09-28: white bar, navy-lettering lockup WITH tagline at
   the top of the page, condensing to the compact logo once scrolled.

   Geometry: the header box is always --nav-h (72px) tall and fixed, so the
   condense never moves the page. The tall top state is drawn, not laid out:
   .nav::before (the white bar) is --nav-top-h tall and slides up by the
   difference; .nav__inner sits --nav-shift lower. Both logos are stacked
   top-left in a --logo-w box. The compact wordmark is exactly the lockup's
   top row, so scaling the lockup by --logo-k makes the two wordmarks
   coincide and the morph reads as the tagline dissolving, not a swap.
   Uniform scale + crossfade only: no stretch, recolour or effect (brand rule).
   body.page offset: body padding-top = --nav-top-h (see below). */
:root {
  --nav-top-h: 112px;
  --logo-w: 360px;          /* lockup width at the top of the page */
  --logo-compact-h: 32px;   /* compact logo height once condensed */
  --logo-k: .5853;          /* (32 * 608 / 92.32) / 360: compact width / lockup width */
  --logo-lift: -22.27px;    /* -(lockup height - compact height) / 2 */
  --nav-shift: 20px;        /* (--nav-top-h - --nav-h) / 2 */
}
@media (max-width: 820px) {
  /* 390px and up (most phones): 290px lockup; 20 + 290 + 12 + 44 + 20 = 386 */
  :root {
    --nav-top-h: 90px; --logo-w: 290px; --logo-compact-h: 24px;
    --logo-k: .5450;        /* (24 * 608 / 92.32) / 290 */
    --logo-lift: -18.83px;  /* -(61.66 - 24) / 2 */
    --nav-shift: 9px;
  }
  .nav__inner { gap: .75rem; }
}
@media (max-width: 389px) {
  :root { --nav-top-h: 84px; --logo-w: 250px; --logo-k: .6322; --logo-lift: -14.58px; --nav-shift: 6px; }
}
@media (max-width: 359px) {
  /* 320px (400% zoom): the menu button must keep its 44px */
  :root { --nav-top-h: 72px; --logo-w: 200px; --logo-k: .7903; --logo-lift: -9.26px; --nav-shift: 0px; }
}
/* 821-1199px: the 360px lockup plus the links do not fit on one line, so
   the bar starts (and stays) compact. Phones get the lockup back: there the
   bar holds only the logo and the menu button. */
@media (min-width: 821px) and (max-width: 1199px) {
  :root { --nav-top-h: var(--nav-h); --nav-shift: 0px; --logo-w: 210.75px; --logo-lift: 0px; }
  .nav .nav__logo .nav__logo-full { display: none; }
  .nav .nav__logo .nav__logo-compact { opacity: 1; transform: none; }
}
/* 821-1100px: tighter gaps so every link fits, Residents included (audit m30:
   hiding it left residents no header route to pickup rules, and the menu
   button only appears at 820px). `.nav .nav__links` out-ranks the base
   `.nav__links` gap below, which used to win on source order. */
@media (min-width: 821px) and (max-width: 1100px) {
  .nav .nav__inner { gap: 1.1rem; }
  .nav .nav__links { gap: 1rem; }
  .nav .nav__links > a, .nav .nav__dd-btn { font-size: .9rem; }
  .nav .nav__links a.nav__util { padding-left: 1rem; font-size: .84rem; }
  .nav .nav__links a.nav__util::after { left: 1rem; }
  .nav .nav__cta { padding: .55rem .9rem; font-size: .88rem; }
}
body { padding-top: var(--nav-top-h); }
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  height: var(--nav-h);
}
.nav::before {
  content: ""; position: absolute; inset: 0 0 auto; height: var(--nav-top-h);
  /* navy bar, white + orange logo (owner, 2026-09-30); a hairline marks where
     the bar ends over the navy hero */
  background: var(--navy); border-bottom: 1px solid rgba(255,255,255,.1);
  transition: transform var(--d3) var(--ease-out);
}
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; top: var(--nav-h); height: 18px;
  background: linear-gradient(rgba(0,0,0,.28), rgba(0,0,0,0));
  opacity: 0; pointer-events: none; transition: opacity var(--d2) var(--ease-out);
}
.nav__inner {
  position: relative; display: flex; align-items: center; gap: 1.8rem; height: var(--nav-h);
  transform: translateY(var(--nav-shift));
  transition: transform var(--d3) var(--ease-out);
}
.nav.is-scrolled::before { transform: translateY(calc(var(--nav-h) - var(--nav-top-h))); }
.nav.is-scrolled::after { opacity: 1; }
.nav.is-scrolled .nav__inner { transform: none; }

.nav__logo {
  position: relative; display: block; flex: none;
  width: var(--logo-w); height: var(--logo-compact-h);
}
.nav__logo img {
  position: absolute; top: 0; left: 0; display: block; max-width: none;
  transform-origin: left top;
  transition: transform var(--d3) var(--ease-out), opacity var(--d1) linear;
}
.nav__logo-full { width: var(--logo-w); height: auto; transform: translateY(var(--logo-lift)); }
.nav__logo-compact {
  height: var(--logo-compact-h); width: auto; opacity: 0;
  transform: translateY(var(--logo-lift)) scale(calc(1 / var(--logo-k)));
}
.nav.is-scrolled .nav__logo-full { opacity: 0; transform: scale(var(--logo-k)); }
.nav.is-scrolled .nav__logo-compact { opacity: 1; transform: none; }
/* A page that loads already scrolled (hash link, back button) starts condensed with no animation. */
.nav--instant::before, .nav--instant::after, .nav--instant .nav__inner, .nav--instant .nav__logo img { transition: none !important; }

.nav__links { display: flex; align-items: center; gap: 1.6rem; margin-left: auto; white-space: nowrap; }
/* the header's one primary action (design review, 2026-10-14): orange, navy
   label, the site's button radius; white with a navy label on hover (below) */
.nav__cta { flex: none; white-space: nowrap; padding: .62rem 1.15rem; font-size: .93rem; box-shadow: none; }
.nav__links > a, .nav__dd-btn {
  font-family: var(--font-head); font-weight: 500; font-size: .95rem;
  color: #C7D2DE; text-decoration: none; position: relative; padding: .3rem 0;
  transition: color var(--d1) var(--ease);
}
.nav__links > a:hover, .nav__links > a:focus-visible, .nav__links > a[aria-current],
.nav__dd-btn:hover, .nav__dd-btn[aria-expanded="true"], .nav__dd-btn.is-current { color: #fff; }
/* underline grows from the left, leaves to the right: scaleX only */
.nav__links > a::after, .nav__dd-btn::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--orange); transform: scaleX(0); transform-origin: right center;
  transition: transform var(--d2) var(--ease-out);
}
.nav__links > a:hover::after, .nav__links > a:focus-visible::after,
.nav__links > a[aria-current]::after, .nav__dd-btn.is-current::after,
.nav__dd-btn:hover::after, .nav__dd-btn[aria-expanded="true"]::after { transform: scaleX(1); transform-origin: left center; }
/* Residents: a utility link after a hairline, quieter than the property-manager
   links, so the row reads "five links, one aside, one action" */
.nav__links a.nav__util {
  font-family: var(--font-body); font-weight: 400; font-size: .86rem; color: #9FB0C2;
  padding-left: 1.6rem; border-left: 1px solid rgba(255,255,255,.16);
}
.nav__links a.nav__util:hover, .nav__links a.nav__util:focus-visible, .nav__links a.nav__util[aria-current] { color: #fff; }
.nav__links a.nav__util::after { left: 1.6rem; background: #9FB0C2; }

/* ----- Services dropdown (disclosure: button + panel, not an ARIA menu) ----- */
.nav__dd { position: relative; }
.nav__dd-btn {
  display: inline-flex; align-items: center; gap: .35rem;
  background: none; border: 0; cursor: pointer;
}
.nav__dd-chev { transition: transform var(--d2) var(--ease-out); }
.nav__dd-btn[aria-expanded="true"] .nav__dd-chev { transform: rotate(180deg); }
.nav__dd-panel {
  position: absolute; top: calc(100% + 18px); left: -1.1rem; width: min(34rem, 90vw);
  /* navy-tint edge + deeper shadow: over the pale #EAF0F7 heroes a borderless
     white panel read as white on pale (audit m3) */
  padding: .55rem; background: #fff; border: 1px solid rgba(var(--navy-rgb), .2); border-radius: var(--radius);
  white-space: normal; /* the links row is nowrap; the panel must wrap */
  box-shadow: 0 28px 64px -18px rgba(var(--navy-rgb), .5), 0 4px 12px rgba(var(--navy-rgb), .12);
  opacity: 0; visibility: hidden; transform: translateY(-6px) scale(.985); transform-origin: top left;
  transition: opacity var(--d1) var(--ease-in), transform var(--d1) var(--ease-in), visibility 0s linear var(--d1);
}
/* invisible bridge over the gap so a diagonal pointer path does not close it */
.nav__dd-panel::before { content: ""; position: absolute; left: 0; right: 0; top: -20px; height: 20px; }
@media (max-width: 1199px) {
  /* pinned to the container's right edge so it never runs off-screen */
  .nav__dd { position: static; }
  .nav__dd-panel { top: 100%; left: auto; right: 0; width: min(34rem, calc(100vw - 2.5rem)); transform-origin: top right; }
  .nav__dd-panel::before { top: -30px; height: 30px; } /* bridge reaches the button: no dead strip */
}
.nav__dd-panel.is-open {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--d2) var(--ease-out), transform var(--d2) var(--ease-out), visibility 0s;
}
.nav__dd-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .15rem;
}
.nav__dd-list a {
  position: relative; display: grid; gap: .15rem; padding: .7rem .85rem .7rem 1.05rem;
  border-radius: 10px; text-decoration: none;
  transition: background-color var(--d1) var(--ease-out);
}
.nav__dd-list a::before {
  content: ""; position: absolute; left: .35rem; top: .75rem; bottom: .75rem; width: 2px;
  border-radius: 2px; background: var(--orange); transform: scaleY(0);
  transition: transform var(--d1) var(--ease-out);
}
.nav__dd-list a:hover, .nav__dd-list a:focus-visible, .nav__dd-list a[aria-current] { background: var(--alt); }
.nav__dd-list a:hover::before, .nav__dd-list a:focus-visible::before, .nav__dd-list a[aria-current]::before { transform: scaleY(1); }
.nav__dd-label { font: 600 .95rem/1.25 var(--font-head); color: var(--navy); }
.nav__dd-blurb { font-size: .82rem; line-height: 1.35; color: var(--ink-soft); }
.nav__dd-all {
  display: block; margin: .4rem .2rem .1rem; padding: .7rem .85rem; border-top: 1px solid var(--line);
  font: 600 .88rem/1.2 var(--font-head); color: var(--navy); text-decoration: none;
}
.nav__dd-all::after { content: "\00a0\2192"; color: var(--orange); }
.nav__dd-all:hover, .nav__dd-all:focus-visible { text-decoration: underline; }

.nav__toggle { display: none; }
.mobile-menu { display: none; }

/* The menu button takes over below 1024px: the five links, Residents and the
   CTA no longer fit beside the logo. Tablets (821-1023px) keep the CTA in the
   bar next to the menu button; phones have the quick-action bar instead. */
@media (min-width: 821px) and (max-width: 1023px) {
  .nav .nav__cta { margin-left: auto; padding: .55rem 1rem; font-size: .9rem; }
  .nav .nav__cta ~ .nav__toggle { margin-left: 0; }
}
@media (max-width: 820px) { .nav__cta { display: none; } }
@media (max-width: 1023px) {
  .nav__links { display: none; }
  .nav__toggle {
    display: flex; flex-direction: column; justify-content: center;
    align-items: stretch; gap: 5px;
    flex: none; margin-left: auto; width: 44px; height: 44px; padding: 10px;
    background: none; border: 0; cursor: pointer; border-radius: 8px;
  }
  .nav__toggle span { display: block; height: 2.5px; background: #fff; border-radius: 2px; transition: transform var(--d2) var(--ease-out), opacity var(--d1); }
  .nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
  .nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }
  .mobile-menu {
    position: absolute; left: 0; right: 0; top: calc(var(--nav-top-h));
    display: flex; flex-direction: column; gap: .2rem;
    max-height: calc(100dvh - var(--nav-top-h)); overflow-y: auto; overscroll-behavior: contain;
    padding: .6rem 1.25rem 1.4rem; background: #fff;
    border-bottom: 1px solid var(--line); box-shadow: 0 24px 40px -24px rgba(var(--navy-rgb), .35);
    opacity: 0; transform: translateY(-8px); transition: opacity var(--d2) var(--ease-out), transform var(--d2) var(--ease-out);
  }
  .nav.is-scrolled .mobile-menu { top: var(--nav-h); max-height: calc(100dvh - var(--nav-h)); }
  .mobile-menu.is-open { opacity: 1; transform: none; }
  .mobile-menu[hidden] { display: none; }
  .mobile-menu a:not(.btn), .mobile-menu__dd-btn {
    font-family: var(--font-head); font-weight: 500; font-size: 1.05rem;
    color: var(--navy); text-decoration: none; padding: .6rem .25rem; border-radius: 6px;
  }
  .mobile-menu__dd-btn {
    display: flex; align-items: center; justify-content: space-between; width: 100%;
    background: none; border: 0; cursor: pointer; text-align: left;
  }
  .mobile-menu__dd-btn[aria-expanded="true"] .nav__dd-chev { transform: rotate(180deg); }
  .mobile-menu__sub {
    list-style: none; margin: 0 0 .3rem; padding: 0 0 0 .9rem; border-left: 2px solid var(--line);
    display: grid; gap: .05rem;
  }
  .mobile-menu__sub[hidden] { display: none; }
  .mobile-menu__sub a:not(.btn) { font-size: .98rem; font-weight: 500; color: var(--ink); padding: .45rem .25rem; }
  .mobile-menu__sub a[aria-current] { color: var(--navy); font-weight: 700; }
  .mobile-menu .btn { margin-top: .6rem; text-align: center; }
  .mobile-menu a.nav__util {
    font-family: var(--font-body); font-weight: 400; font-size: .95rem; color: var(--ink-soft);
    margin-top: .3rem; padding-top: .8rem; border-top: 1px solid var(--line); border-radius: 0;
  }
}

/* ---------- hero ---------- */
/* Light heroes under the navy bar (owner, 2026-09-30): the homepage hero is
   white and meets the navy logo band below; inner-page heroes sit on the soft
   blue tint so they never merge with a white first section. */
.hero {
  background: #fff; color: var(--ink);
  padding: clamp(2rem, 4vw, 3rem) 0 clamp(2.6rem, 5vw, 4.5rem);
  overflow: hidden;
}
.hero h1 { color: var(--navy); }
.hero .eyebrow { color: var(--ink-soft); }
.page-hero, .svc-hero { background: var(--alt); }
.hero__grid {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2rem, 5vw, 4.5rem); align-items: start; /* photo top lines up with the copy (owner: alignment) */
}
.hero__sub { font-size: 1.2rem; color: var(--ink); max-width: 34em; margin-bottom: 1.2rem; text-wrap: pretty; }
/* "No subcontractors. No excuses." is a badge line, not the headline. */
.hero__badge {
  display: inline-flex; align-items: center; gap: .65rem;
  font-family: var(--font-head); font-weight: 700; font-size: .98rem;
  letter-spacing: .02em; color: #fff; margin: 0 0 1.7rem;
}
.hero__badge::before {
  content: ""; width: 1.6rem; height: 3px; border-radius: 2px;
  background: var(--orange); flex: none;
}
.hero__ctas { display: flex; flex-wrap: wrap; gap: .9rem; margin-bottom: 2rem; }

.hero__proof {
  display: inline-flex; align-items: center; gap: .55rem; flex-wrap: wrap;
  font-size: .95rem; color: var(--ink); letter-spacing: .01em;
  margin-bottom: 1.2rem; padding: .5rem .9rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: transparent;
}
.hero__proof .num { font-size: 1.4rem; line-height: 1; } /* 22px bold: large enough for orange on white */
.hero__call { font-size: .92rem; color: var(--ink-soft); margin: 0; }
.hero__call a {
  color: var(--navy); font-weight: 600; text-decoration: underline;
  text-underline-offset: 3px; text-decoration-color: var(--orange);
}
.hero__call a:hover { text-decoration-color: var(--orange); }
@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; }
}

/* ---------- HERO: scroll-controlled flyover (pattern 1, see .claude/skills/rpmtx-frontend) ----------
   The section is taller than the screen; its stage sticks under the nav while
   js/flyover.js maps scroll progress (--p, 0..1) to frames of the flyover.
   The poster is the CSS background, so the hero paints before any frame
   loads. Text lives bottom-left, where the shade is darkest. */
.fly { position: relative; height: 230vh; background: var(--navy); }
.fly__stage {
  position: sticky; top: var(--nav-h); height: calc(100svh - var(--nav-h)); min-height: 520px;
  overflow: hidden; isolation: isolate; color: #fff;
  background: var(--navy) url("/img/fly/v3/poster.jpg?v=638de708") center / cover no-repeat;
}
.fly__canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: -2; display: block;
  opacity: 0; transition: opacity .6s var(--ease-out);
  transform: scale(calc(1 + var(--p, 0) * .05)); transform-origin: 50% 65%;
}
.fly.is-live .fly__canvas { opacity: 1; }
.fly__shade {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(ellipse 75% 85% at 0% 100%, rgba(var(--navy-rgb), .88), rgba(var(--navy-rgb), 0) 70%),
    linear-gradient(180deg, rgba(var(--navy-rgb), .45) 0%, rgba(var(--navy-rgb), 0) 18%, rgba(var(--navy-rgb), 0) 45%, rgba(var(--navy-rgb), .55) 72%, rgba(var(--navy-rgb), .92) 100%);
}
.fly__content { position: absolute; left: 0; right: 0; bottom: clamp(2rem, 7vh, 4.5rem); }
.fly__kicker {
  margin: 0 0 .9rem; font-family: var(--font-head); font-weight: 700; font-size: .8rem;
  letter-spacing: .14em; text-transform: uppercase; color: #C7D2DE;
}
.fly__title {
  margin: 0; max-width: 11ch; color: #fff;
  font-size: clamp(2.9rem, 8.2vw, 6.6rem); line-height: .94; letter-spacing: -.035em; text-wrap: balance;
}
.fly__dot { color: var(--orange); }
.fly__sub { max-width: 40ch; margin: 1.2rem 0 1.6rem; font-size: clamp(1.02rem, 1.4vw, 1.2rem); line-height: 1.55; color: #fff; } /* white, not #D5DEE8: the lit stone on short landscape screens dropped it to 3.7:1 (pre-launch verify, 2026-10-06) */
.fly__value { display: flex; flex-wrap: wrap; gap: .2rem .9rem; margin: -.6rem 0 1.5rem; font-family: var(--font-head); font-weight: 700; font-size: clamp(.95rem, 1.3vw, 1.08rem); color: #fff; }
.fly__value span { white-space: nowrap; }
.fly__value span + span::before { content: ""; display: inline-block; width: 5px; height: 5px; margin-right: .9rem; border-radius: 50%; background: rgba(255,255,255,.5); vertical-align: .2em; }
/* The last item is a whole sentence ("Every miss made right within 24 hours
   at no charge."), wider than a phone column: it may wrap, and its second line
   hangs under the text, not under the dot. Where it fits, nothing changes. */
.fly__value span:last-child { white-space: normal; text-wrap: balance; }
.fly__value span + span:last-child { padding-left: calc(5px + .9rem); text-indent: calc(-5px - .9rem); }
/* Tablets and phones: the line stops short of the corner where the Ask Dessa
   launcher floats (at 768 the full sentence ran under it). */
@media (max-width: 1100px) { .fly__value { max-width: 34em; } }
/* 360px: the kicker pill fits on one line ("... SINCE / 2012." otherwise) */
@media (max-width: 374px) { .fly__kicker { letter-spacing: .08em; } }
.fly__ctas { display: flex; flex-wrap: wrap; gap: .8rem; }
.fly__call { margin: 1rem 0 0; font-size: .9rem; color: #C7D2DE; }
.fly__call a { color: #fff; text-decoration-color: rgba(255,255,255,.45); }
/* The slip and the scene captions are decoration: pointer-events none, and the
   slip is visibility-hidden (not just transparent) until it is shown, so it
   never swallows a tap meant for the CTAs it sits over (audit B3). */
.fly__slip {
  position: absolute; right: clamp(1rem, 3vw, 2.5rem); bottom: clamp(5.5rem, 12vh, 7.5rem); width: 250px;
  display: grid; gap: .35rem; padding: .95rem 1.05rem; border-radius: var(--radius);
  background: rgba(255,255,255,.96); color: var(--navy); box-shadow: 0 24px 50px -20px rgba(0,0,0,.6);
  font-family: var(--font-mono); font-size: .8rem; pointer-events: none;
  opacity: 0; visibility: hidden; transform: translateY(14px) rotate(-1.5deg);
  transition: opacity .45s var(--ease-out), transform .45s var(--ease-out), visibility 0s linear .45s;
}
.fly.slip-on .fly__slip, .fly--static .fly__slip { opacity: 1; visibility: visible; transform: rotate(-1.5deg); transition-delay: 0s; }
.fly__slip-tag { font-family: var(--font-head); font-weight: 700; font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.fly__slip-row b { font-family: var(--font-head); font-size: 1rem; margin-right: .25rem; }
@media (max-width: 900px) { .fly__slip { left: 1rem; right: auto; bottom: 1.2rem; width: min(260px, calc(100vw - 2rem)); } }
/* static hero (reduced motion, Save-Data, ?noanim): below ~1000px the text
   block reaches the slip's corner (CTAs on phones, the value line at 901-940),
   so the static slip bows out there (audit B3) */
@media (max-width: 1000px) { .fly--static .fly__slip { display: none; } }
.btn--ghost-dark { color: #fff; border-color: rgba(255,255,255,.7); background: rgba(var(--navy-rgb), .25); }
.btn--ghost-dark:hover, .btn--ghost-dark:focus-visible { background: #fff; color: var(--navy); border-color: #fff; transform: translateY(-2px); }
.fly__beats {
  position: absolute; right: clamp(1rem, 3vw, 2.5rem); top: .9rem; pointer-events: none;
  margin: 0; padding: 0; list-style: none; text-align: right;
  font-family: var(--font-mono); font-size: .8rem; letter-spacing: .04em; color: #fff;
}
.fly__beats li {
  position: absolute; right: 0; top: 0; white-space: nowrap; padding: .35rem .7rem; border-radius: 999px;
  background: rgba(var(--navy-rgb), .7); border: 1px solid rgba(255,255,255,.18);
  opacity: 0; transform: translateY(8px); transition: opacity .35s var(--ease-out), transform .35s var(--ease-out);
}
.fly__beats li::before { content: ""; display: inline-block; width: .5rem; height: .5rem; margin-right: .5rem; border-radius: 50%; background: var(--orange); vertical-align: .05em; }
.fly__beats li.is-on { opacity: 1; transform: none; }
.fly__credit {
  position: absolute; top: .9rem; left: 1rem; margin: 0; padding: .28rem .6rem; border-radius: 999px;
  background: rgba(var(--navy-rgb), .72); font-size: .72rem; color: rgba(255,255,255,.9);
}
.fly__cue {
  position: absolute; left: 50%; bottom: 1rem; width: 1px; height: 38px; background: rgba(255,255,255,.35); overflow: hidden;
  opacity: calc(1 - var(--p, 0) * 6);
}
.motion .fly__cue::after { content: ""; position: absolute; left: 0; top: -40%; width: 1px; height: 40%; background: #fff; animation: fly-cue 1.8s var(--ease-io) infinite; }
@keyframes fly-cue { to { top: 100%; } }
/* static: reduced motion, Save-Data, slow connections (flyover.js adds it) */
.fly--static { height: auto; }
.fly--static .fly__stage { position: relative; top: 0; height: calc(100svh - var(--nav-h)); }
.fly--static .fly__beats, .fly--static .fly__cue { display: none; }
@media (max-width: 820px) {
  .fly { height: 200vh; }
  .fly__beats { left: 1rem; right: auto; top: 3.2rem; text-align: left; }
  .fly__beats li { left: 0; right: auto; }
  /* the hero carries its own CTAs: the bottom bar waits until it has scrolled away */
  .in-hero .mobile-bar { transform: translateY(110%); opacity: 0; pointer-events: none; }
  .fly__content { bottom: 2rem; }
  .fly__sub { margin: 1rem 0 1.3rem; }
}

@media (prefers-reduced-motion: reduce) { .fly__canvas, .fly__beats li { transition: none; } }

/* ===== Hero flyover v3 deltas (imagery/motion audit, 2026-10-01). Append after the .fly block. ===== */
/* 1. sky-trimmed posters; ONE portrait rule (same test as flyover.js and the preload) */
.fly__stage { background-image: url("/img/fly/v3/poster.jpg?v=638de708"); background-size: cover; background-position: 50% 80%; }
@media (max-aspect-ratio: 1/1) {
  .fly__stage { background-image: url("/img/fly/v3/poster-portrait.jpg?v=c9c7b789"); background-position: 50% 30%; }
}
/* delete the old "(max-aspect-ratio: 8/5) and (min-aspect-ratio: 1/1)" background-size: auto 135% rule
   and the "(max-width: 820px) and (orientation: portrait)" poster rule */

/* 2. the text sits IN THE SKY (owner, 2026-10-01) and keeps rising as you scroll
      down, fading out near the top, so the camera move and the closing report
      slip own the end of the pass; scroll back up and it comes back down. */
.fly__content {
  top: clamp(1.25rem, 6vh, 3.5rem); bottom: auto; will-change: transform, opacity;
  transform: translate3d(0, calc(var(--p, 0) * -38vh), 0);
  opacity: calc(1 - max(0, var(--p, 0) - .2) * 2.2);
}
.fly--static .fly__content { transform: none; opacity: 1; }
/* the sky behind the text is always shaded, so white text holds contrast;
   the top-left pool (design review, 2026-10-14) sits under the one text block
   and leaves the skyline in the middle of the frame lit */
.fly__shade::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 62% 80% at 0% 0%, rgba(var(--navy-rgb), .72), rgba(var(--navy-rgb), 0) 72%),
    linear-gradient(180deg, rgba(var(--navy-rgb), .82) 0%, rgba(var(--navy-rgb), .6) 35%, rgba(var(--navy-rgb), .15) 62%, rgba(var(--navy-rgb), 0) 75%);
}

/* 3. kicker on its own ground (1.4:1 median on the bright horizon otherwise).
      .9 navy, not .74: the orange "Still weirdly into it." fell to 4.15:1
      where the photo bled through (audit m38) */
.fly__kicker { display: inline-block; padding: .32rem .7rem; border-radius: 999px; background: rgba(var(--navy-rgb), .9); color: #E3EAF1; }

/* 4. phones: less stacked text; the slip is the payoff under the risen text; chips bow out */
@media (max-width: 820px) {
  .fly { --fly-b: 2rem; }
  .fly__call { display: none; }                 /* Call/Text live in the mobile bar after the hero */
  .fly__title { font-size: clamp(2.6rem, 12vw, 3.6rem); }
  .fly__value { font-size: .92rem; margin-bottom: 1.1rem; }
  .fly__ctas .btn { padding-block: .8rem; }
  .fly__beats { top: auto; bottom: 1.2rem; left: 1rem; right: auto; opacity: calc(1 - var(--p, 0) * 2.2); }
  .fly__slip { display: grid; left: 1rem; right: auto; bottom: 1.2rem; width: min(260px, calc(100vw - 2rem)); }
}
.fly__stage { contain: layout paint; }

/* ---------- service area (owner, 2026-09-30) ----------
   A schematic route board: Austin as the hub, routes drawn out to each city
   as the section arrives (same pathLength trick as the logo draw-in). */
.area__grid-wrap { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
@media (max-width: 900px) {
  .area__grid-wrap { grid-template-columns: 1fr; gap: 1.4rem; }
  .area__map { order: -1; }   /* phones: the map first, compact, then the list */
  .area__svg { max-height: 300px; }
  .area__board { padding: .8rem; }
  .area__list { margin: 1rem 0 1rem; }
  .area__row { padding: .6rem 0; }
}
.area__list { list-style: none; margin: 1.6rem 0 1.4rem; padding: 0; border-top: 1px solid rgba(var(--navy-rgb), .14); }
.area__row { display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); gap: .3rem 1rem; padding: .8rem 0; border-bottom: 1px solid rgba(var(--navy-rgb), .14); align-items: baseline; }
@media (max-width: 480px) { .area__row { grid-template-columns: 1fr; } }
.area__name { font-family: var(--font-head); font-weight: 700; font-size: 1.1rem; color: var(--navy); }
.area__note { color: var(--ink-soft); font-size: .95rem; }
.area__ask { margin: 0; color: var(--ink); }
.area__map { margin: 0; }
.area__board { background: var(--navy); border-radius: 18px; padding: clamp(1rem, 3vw, 1.8rem); box-shadow: 0 30px 60px -30px rgba(var(--navy-rgb), .55); }
.area__svg { display: block; width: 100%; height: auto; max-height: 520px; }
@media (max-width: 900px) { .area__board .area__svg { max-height: 300px; } }
.area__grid path { stroke: rgba(255,255,255,.06); stroke-width: 1; fill: none; }
.area__route { fill: none; stroke: var(--orange); stroke-width: 2.5; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; opacity: .9; }
.area__city circle { fill: #fff; stroke: var(--navy); stroke-width: 3; }
.area__city--hub circle { fill: var(--orange); stroke: #fff; stroke-width: 3; }
.area__city text { fill: #E8EDF3; font: 600 15px var(--font-head); paint-order: stroke; stroke: var(--navy); stroke-width: 5px; stroke-linejoin: round; }
.area__city--hub text { fill: #fff; font-size: 17px; font-weight: 700; }
.motion .area__map .area__route { stroke-dashoffset: 1; }
.motion .area__map.is-in .area__route { animation: area-route 1100ms var(--ease-out) calc(250ms + var(--i, 0) * 140ms) forwards; }
.motion .area__map .area__city { opacity: 0; }
.motion .area__map.is-in .area__city { animation: area-city 500ms var(--ease-out) 900ms forwards; }
.motion .area__map.is-in .area__city--hub { animation-delay: 150ms; }
@keyframes area-route { to { stroke-dashoffset: 0; } }
@keyframes area-city { to { opacity: 1; } }

/* ---------- sections ---------- */
.section { padding: var(--space-section) 0; }
.section--alt { background: var(--alt); }

/* ---------- calculator: the centerpiece ----------
   White card, inputs on the left, a navy result panel with the spread as a
   single huge figure on the right. Mono appears on the two outputs only. */
.calc {
  background: var(--bg); border: 1px solid var(--line); border-radius: 18px;
  box-shadow: var(--shadow-lift); padding: clamp(1.4rem, 3vw, 2.2rem);
  display: grid; gap: 1.2rem 2.2rem; align-items: start;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  grid-template-areas:
    "title illus"
    "inputs result"
    "inputs ctas"
    "note note"
    "legal legal";
}
.calc__title { grid-area: title; font-size: 1.25rem; margin: 0; align-self: center; }
.calc__illus {
  grid-area: illus; justify-self: end; align-self: center; margin: 0;
  font-family: var(--font-head); font-weight: 700; font-size: .72rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
  border: 1px solid var(--line); border-radius: 999px; padding: .25rem .7rem;
}
.calc__inputs { grid-area: inputs; display: grid; gap: 1.2rem; }
.calc__field { min-width: 0; }
.calc__label {
  display: block; font-family: var(--font-head); font-weight: 700; font-size: .78rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
  margin-bottom: .35rem;
}
.calc__units {
  display: block; font-size: 2.6rem; line-height: 1.1; margin-bottom: .2rem;
  color: var(--navy);
}
.calc input[type="range"] {
  width: 100%; margin: .2rem 0 .1rem; accent-color: var(--orange);
  height: 2rem; cursor: pointer;
}
/* Chromium paints the unfilled part of an accent-coloured range charcoal (audit
   m4), and a styled WebKit track loses the native fill. So the custom track
   only switches on once a script writes --fill (0%-100%) on the input; until
   then the native, always-correct slider stays. */
.calc input[type="range"][style*="--fill"] { -webkit-appearance: none; appearance: none; background: none; }
.calc input[type="range"][style*="--fill"]::-webkit-slider-runnable-track {
  height: 6px; border-radius: 3px;
  background: linear-gradient(90deg, var(--orange) var(--fill), rgba(var(--navy-rgb), .16) var(--fill));
}
.calc input[type="range"][style*="--fill"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 22px; height: 22px; margin-top: -8px;
  border-radius: 50%; background: var(--orange); border: 3px solid #fff;
  box-shadow: 0 0 0 1px rgba(var(--navy-rgb), .35), 0 2px 6px rgba(var(--navy-rgb), .3);
}
.calc__scale {
  display: flex; justify-content: space-between;
  font-size: .78rem; color: var(--ink-soft);
}
/* field edges #7C8B9A: 3.5:1 on white (WCAG 1.4.11 asks 3:1; --line was 1.23:1, audit m4) */
.calc__field select, .calc__money input {
  width: 100%; font: inherit; font-size: 1rem; color: var(--ink);
  background: #fff; border: 1.5px solid #7C8B9A; border-radius: 9px;
  padding: .62rem .8rem;
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.calc__field select:focus, .calc__money input:focus {
  outline: none; border-color: var(--orange); box-shadow: 0 0 0 1px var(--orange);
}
/* keyboard focus gets the site's 3px orange ring like everything else (audit n8) */
.calc__field select:focus-visible, .calc__money input:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }
.calc__money {
  display: flex; align-items: center; gap: .5rem;
  font-family: var(--font-head); font-weight: 700; color: var(--navy);
}
.calc__money input { flex: 0 1 7rem; min-width: 5rem; }
.calc__hint { font-family: var(--font-body); font-weight: 400; font-size: .82rem; color: var(--ink-soft); }

.calc__result {
  grid-area: result; background: var(--navy-deep); color: #C7D2DE;
  border-radius: 14px; padding: 1.5rem 1.5rem 1.2rem; align-self: stretch;
}
.calc__out-label {
  margin: 0 0 .3rem; font-family: var(--font-head); font-weight: 500;
  font-size: .85rem; letter-spacing: .06em; text-transform: uppercase; color: #9FB0C0;
}
.calc__big {
  display: block; font-size: clamp(2.5rem, 5.4vw, 3.9rem); line-height: 1.05;
  letter-spacing: -.02em; margin-bottom: .35rem; word-break: break-word;
}
.calc__big small { font-size: .38em; font-weight: 500; color: #9FB0C0; margin-left: .2em; letter-spacing: 0; }
.calc__annual { margin: 0 0 1rem; font-size: .95rem; color: #B9C6D2; }
.calc__annual .num { font-size: 1.15rem; }
.calc__annual .num small { font-size: .72em; font-weight: 500; color: #9FB0C0; }
.calc__detail {
  list-style: none; margin: 0; padding: .9rem 0 0;
  border-top: 1px solid rgba(255,255,255,.14);
}
.calc__detail li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  padding: .3rem 0; font-size: .9rem; color: #B9C6D2;
}
.calc__detail strong { font-family: var(--font-head); font-weight: 700; color: #fff; white-space: nowrap; font-variant-numeric: tabular-nums; }
.calc__detail strong small { font-size: .78em; font-weight: 500; color: #9FB0C0; }
/* Record-like output: the door count is mono. The money figure is the heading
   face with tabular figures: in mono the thousands comma took a full cell and
   "+$4 , 500" read like a typo (audit m4). */
.calc__units { font-family: var(--font-mono); font-weight: 500; }
.calc__big { font-family: var(--font-head); font-weight: 700; font-variant-numeric: tabular-nums; }
.calc__ctas { grid-area: ctas; }
.calc__ctas .btn { width: 100%; text-align: center; }
.calc__note { grid-area: note; margin: .4rem 0 0; font-size: .9rem; color: var(--ink-soft); max-width: 70ch; }
.calc__legal { grid-area: legal; margin: 0; font-size: .78rem; line-height: 1.5; color: var(--ink-soft); max-width: 70ch; }
@media (max-width: 860px) {
  .calc {
    grid-template-columns: 1fr;
    grid-template-areas: "title" "illus" "inputs" "result" "ctas" "note" "legal";
  }
  .calc__illus { justify-self: start; }
}
@media (max-width: 420px) {
  .calc__detail li { flex-direction: column; gap: .1rem; padding: .45rem 0; }
}

.calc__example { margin-top: 1.4rem; }
.calc__example > summary {
  cursor: pointer; list-style: none; display: inline-block;
  font-family: var(--font-head); font-weight: 600; color: var(--navy);
  padding: .5rem .1rem;
}
.calc__example > summary::-webkit-details-marker { display: none; }
.calc__example > summary::after { content: " \25BE"; color: var(--navy); }
.calc__example[open] > summary::after { content: " \25B4"; }
.calc__example > summary:hover { text-decoration: underline; text-underline-offset: 3px; }

/* the 400-door worked example */
.math { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); margin-top: .8rem; }
.math__col { background:#fff; border:1px solid var(--line); border-radius: var(--radius); padding: 1.4rem; box-shadow: var(--shadow); }
.math__col--good { border-color: rgba(var(--navy-rgb), .4); }
.math__label { display:block; font-family: var(--font-head); font-weight:700; font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; color: var(--ink-soft); margin-bottom:.9rem; }
.math__row { display:flex; justify-content:space-between; align-items:baseline; gap:1rem; padding:.6rem 0; border-bottom:1px solid var(--line); font-size:.95rem; color: var(--ink-soft); }
.math__row:last-child { border-bottom:0; }
.math__row b { font-family: var(--font-mono); font-size:1.05rem; color: var(--navy); white-space:nowrap; }
.math__row b i { font-style:normal; font-size:.72rem; color: var(--ink-soft); }
.math__row--total { border-top:2px solid var(--navy); margin-top:.4rem; padding-top:.8rem; }
.math__row--total b { color: var(--navy); font-size:1.25rem; }
.math__note { margin-top:1.4rem; background:#fff; border-left:4px solid var(--navy); border-radius:0 var(--radius) var(--radius) 0; padding:1.2rem 1.4rem; }
.math__note p { margin:0 0 .7rem; color: var(--ink-soft); line-height:1.65; }
.math__note p:last-child { margin-bottom:0; }
.math__note strong { color: var(--navy); }
.math__legal { font-size: .78rem; line-height: 1.5; margin: 1.4rem 0 .4rem; color: var(--ink-soft); }

/* compact contract check, one line under the calculator */
.contract-mini {
  margin: 2rem 0 0; padding: 1rem 1.3rem;
  background: var(--bg); border: 1px dashed rgba(var(--navy-rgb), .3); border-radius: 12px;
  font-size: 1rem; color: var(--navy); font-weight: 500;
  display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .8rem;
}
.contract-mini .link-arrow { white-space: normal; }

/* ---------- why RPMTX: three pillars ---------- */
.pillars { display: grid; gap: 2rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pillar { border-top: 3px solid var(--navy); padding-top: 1.2rem; }
.pillar__num {
  display: block; font-family: var(--font-head); font-weight: 700; font-size: .8rem;
  letter-spacing: .14em; color: var(--ink-soft); margin-bottom: .7rem;
}
.pillar h3 { font-size: 1.25rem; }
.pillar p { margin: 0; color: var(--ink-soft); font-size: .97rem; }
.pillars--four { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.6rem; }
.pillar__check { margin: .8rem 0 0; padding-top: .7rem; border-top: 1px dashed rgba(var(--navy-rgb), .2); font-size: .9rem; color: var(--ink-soft); }
.pillar__check b { color: var(--navy); }
@media (max-width: 1100px) { .pillars--four { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; } }
@media (max-width: 860px) { .pillars { grid-template-columns: 1fr; gap: 1.4rem; } }

/* ---------- the nightly report (pattern 3: accountability / data) ----------
   ONE component, two sizes: the homepage preview (#report .mock) and the full
   example on /sample-report/ (.mock--full). It is an EXAMPLE: fictional A-
   to Q- units, a made-up 642-door community, illustrative photos; the
   "Example" tag and the caption under it must stay visible. Mono is for the
   record data only (units, times, counts). Status colours: collected green,
   no set-out grey ring, exception orange (the report's exception flags are
   one of orange's sanctioned jobs). No orange text on white here. */
.report__intro {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 1rem clamp(2rem, 5vw, 4.5rem); align-items: end;
}
.report__intro h2 { margin-bottom: 0; }
.report__intro .section__lede { margin: 0; }
.report__ctas { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.4rem; margin: 1.4rem 0 0; }
.section--navy .report__ctas .btn--primary:hover,
.section--navy .report__ctas .btn--primary:focus-visible { background: #fff; color: var(--navy); }
.report__stage { margin: clamp(2.2rem, 5vw, 3.4rem) 0 0; }
@media (max-width: 900px) { .report__intro { grid-template-columns: minmax(0, 1fr); } }

.mock {
  --pad: clamp(1rem, 2.4vw, 1.6rem);
  --ok: #1E8E3E; --ok-dot: #34A853; --ok-bg: #E7F6EC; --none: #9FB0C2;
  background: #fff; color: var(--ink); border-radius: 18px; overflow: hidden;
  box-shadow: var(--shadow-lift); font-family: var(--font-body); font-size: .92rem; line-height: 1.45;
}
.section--navy .mock { box-shadow: 0 0 0 1px rgba(255,255,255,.08), 0 40px 80px -36px rgba(0,0,0,.75); }
.mock p, .mock h2, .mock h3 { margin: 0; }
.mock__mono, .mock__unit, .mock__time, .mock__stat strong, .mock__when dd, .mock__h span, .mock__foot, .mock__stamp, .mock__tbl td { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* app bar */
.mock__bar { display: flex; align-items: center; gap: .45rem; background: var(--navy-deep); padding: .7rem var(--pad); }
.mock__dot { width: 9px; height: 9px; border-radius: 50%; background: rgba(255,255,255,.24); flex: none; }
.mock__title { margin-left: .5rem !important; color: #E8EDF3; font-family: var(--font-mono); font-weight: 500; font-size: .82rem; letter-spacing: 0; }
.mock__tag {
  margin-left: auto; padding: .12rem .6rem; border-radius: 999px; border: 1px solid rgba(255,255,255,.3);
  color: #fff; font-family: var(--font-head); font-weight: 700; font-size: .68rem; letter-spacing: .12em; text-transform: uppercase;
}

/* property and night */
.mock__prop { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: .9rem 2rem; padding: 1.15rem var(--pad) 1.05rem; border-bottom: 1px solid var(--line); }
.mock__name { font-family: var(--font-head); font-weight: 700; font-size: 1.2rem; color: var(--navy); letter-spacing: -.01em; }
.mock__meta { margin-top: .15rem !important; color: var(--ink-soft); font-size: .84rem; }
.mock__when { display: flex; flex-wrap: wrap; gap: .5rem 1.6rem; margin: 0; }
.mock__when dt { font-size: .66rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.mock__when dd { margin: .1rem 0 0; color: var(--navy); font-size: .88rem; font-weight: 500; white-space: nowrap; }
.mock__done dd { display: inline-flex; align-items: center; gap: .4rem; padding: 0 .55rem; border-radius: 999px; background: var(--ok-bg); color: #17692F; font-family: var(--font-body); font-weight: 600; font-size: .8rem; line-height: 1.6; }
.mock__done dd::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--ok-dot); }

/* totals */
.mock__kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-bottom: 1px solid var(--line); }
.mock__stat { padding: 1rem var(--pad) 1.05rem; border-right: 1px solid var(--line); min-width: 0; }
.mock__stat:last-child { border-right: 0; }
.mock__k { display: flex; align-items: center; gap: .45rem; font-size: .7rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); white-space: nowrap; }
.mock__stat strong { display: block; margin-top: .3rem; font-weight: 500; font-size: clamp(1.35rem, 2.6vw, 1.85rem); line-height: 1.1; color: var(--navy); letter-spacing: -.02em; white-space: nowrap; }
.mock__stat small { font-size: .55em; color: var(--ink-soft); letter-spacing: 0; }

/* status marks: one shape per status, never colour alone */
.mock__check, .mock__flag, .mock__none, .mock__k--ok::before, .mock__k--none::before, .mock__k--flag::before { width: 16px; height: 16px; border-radius: 50%; flex: none; position: relative; box-sizing: border-box; }
.mock__k--ok::before, .mock__k--none::before, .mock__k--flag::before { content: ""; width: 10px; height: 10px; }
.mock__check, .mock__k--ok::before { background: var(--ok-bg); }
.mock__k--ok::before { background: var(--ok-dot); }
.mock__check::after {
  content: ""; position: absolute; inset: 4px 3px 5px 4px;
  border-left: 2px solid var(--ok); border-bottom: 2px solid var(--ok); transform: rotate(-45deg);
}
.mock__none, .mock__k--none::before { border: 2px solid var(--none); background: #fff; }
.mock__flag, .mock__k--flag::before { background: var(--orange); }
.mock__flag::after { content: "!"; position: absolute; inset: 0; display: grid; place-items: center; color: var(--navy); font-weight: 800; font-size: .72rem; font-family: var(--font-body); }
.mock__gapdot { width: 16px; flex: none; text-align: center; color: var(--none); font-weight: 700; line-height: 1; position: relative; z-index: 1; }

/* progress: every door accounted for */
.mock__progress { display: flex; align-items: center; gap: 1rem; padding: .85rem var(--pad); border-bottom: 1px solid var(--line); }
.mock__progress p { font-size: .8rem; color: var(--ink-soft); white-space: nowrap; }
.mock__progress b { font-family: var(--font-mono); font-weight: 500; color: var(--navy); }
.mock__meter { flex: 1; display: flex; gap: 2px; height: 8px; border-radius: 99px; overflow: hidden; background: var(--line); transform-origin: left center; }
.mock__meter span { flex: var(--n) 1 0; min-width: 5px; }
.mock__meter .m-ok { background: var(--ok-dot); }
.mock__meter .m-none { background: #C9D4DF; }
.mock__meter .m-flag { background: var(--orange); }

/* body: door log beside the exceptions */
.mock__body { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
.mock__pane { min-width: 0; padding: .3rem 0 .6rem; }
.mock__pane + .mock__pane { border-left: 1px solid var(--line); background: color-mix(in srgb, var(--alt) 45%, #fff); }
.mock__h { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .1rem 1rem; padding: .85rem var(--pad) .45rem; font-family: var(--font-head); font-weight: 700; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--navy); }
.mock__h span { font-weight: 400; font-size: .74rem; letter-spacing: 0; text-transform: none; color: var(--ink-soft); }

.mock__rows { padding: .1rem 0 .2rem; }
.mock__row { position: relative; display: flex; align-items: center; gap: .75rem; padding: .56rem var(--pad); font-size: .86rem; }
.mock__row + .mock__row { border-top: 1px dashed var(--line); }
.mock__unit { flex: none; width: 4.6em; color: var(--navy); font-weight: 500; }
.mock__row--wide .mock__unit { width: auto; }
.mock__st { flex: 1 1 auto; min-width: 0; color: var(--ink-soft); }
.mock__row--flag .mock__st { color: var(--navy); font-weight: 600; }
.mock__row--gap .mock__st { font-style: italic; }
.mock__time { margin-left: auto; flex: none; color: var(--ink-soft); font-size: .8rem; white-space: nowrap; }
/* a photo is attached */
.mock__cam {
  flex: none; width: 15px; height: 13px; background: var(--ink-soft);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 13'%3E%3Cpath d='M5 0h5l1.2 2H13.5A1.5 1.5 0 0 1 15 3.5v8a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 11.5v-8A1.5 1.5 0 0 1 1.5 2h2.3zm2.5 4a3 3 0 1 0 0 6 3 3 0 0 0 0-6z'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 13'%3E%3Cpath d='M5 0h5l1.2 2H13.5A1.5 1.5 0 0 1 15 3.5v8a1.5 1.5 0 0 1-1.5 1.5h-12A1.5 1.5 0 0 1 0 11.5v-8A1.5 1.5 0 0 1 1.5 2h2.3zm2.5 4a3 3 0 1 0 0 6 3 3 0 0 0 0-6z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* exceptions, with their photos */
.mock__exs { list-style: none; margin: 0; padding: .2rem var(--pad) .4rem; display: grid; gap: .7rem; }
.mock__exc { display: grid; grid-template-columns: 6.2rem minmax(0, 1fr); gap: .85rem; align-items: start; padding: .7rem; border-radius: 12px; background: #fff; box-shadow: 0 1px 2px rgba(var(--navy-rgb), .06), 0 6px 16px -10px rgba(var(--navy-rgb), .25); }
.mock__shot { position: relative; display: block; border-radius: 8px; overflow: hidden; background: var(--navy-deep); aspect-ratio: 4 / 3; }
.mock__shot img { display: block; width: 100%; height: 100%; object-fit: cover; }
.mock__stamp { position: absolute; left: 4px; bottom: 4px; padding: 0 .3rem; border-radius: 4px; background: rgba(var(--navy-rgb), .78); color: #fff; font-size: .62rem; line-height: 1.5; }
.mock__exc-t { display: flex; flex-wrap: wrap; align-items: center; gap: .2rem .5rem; color: var(--navy); font-weight: 600; font-size: .88rem; }
.mock__exc-t .mock__unit { width: auto; }
.mock__exc-n { margin-top: .2rem !important; color: var(--ink-soft); font-size: .8rem; }
.mock__chips { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .45rem; }
.mock__chip { display: inline-flex; align-items: center; gap: .3rem; padding: .05rem .5rem; border-radius: 999px; border: 1px solid rgba(var(--navy-rgb), .18); color: var(--navy); font-size: .7rem; font-weight: 600; white-space: nowrap; }
.mock__chip--ok::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--ok-dot); }

.mock__foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .3rem 1.4rem; padding: .75rem var(--pad); border-top: 1px solid var(--line); color: var(--ink-soft); font-size: .76rem; }
.mock__foot b { font-weight: 500; color: var(--navy); }

.mock__cap { margin: .9rem 0 0; font-size: .84rem; color: var(--ink-soft); }
.section--navy .mock__cap { color: #9FB0C2; }
.section--navy .mock__cap a { color: #fff; }

@media (max-width: 820px) {
  .mock__body { grid-template-columns: minmax(0, 1fr); }
  .mock__pane + .mock__pane { border-left: 0; border-top: 1px solid var(--line); }
}
@media (max-width: 640px) {
  .mock__kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mock__stat:nth-child(2) { border-right: 0; }
  .mock__stat:nth-child(-n + 2) { border-bottom: 1px solid var(--line); }
  .mock__prop { flex-direction: column; align-items: flex-start; }
  .mock__progress { flex-wrap: wrap; gap: .5rem; }
  .mock__meter { flex-basis: 100%; }
  .mock__exc { grid-template-columns: 5.2rem minmax(0, 1fr); gap: .7rem; padding: .6rem; }
  .mock__row { gap: .6rem; font-size: .82rem; }
  .mock__unit { width: 4.2em; }
  .mock__time { font-size: .76rem; }
}
@media (max-width: 359px) {
  .mock__cam { display: none; }
  .mock__when { gap: .5rem 1.1rem; }
}

/* the statuses, explained (under the homepage preview; light on /sample-report/) */
.statuses { list-style: none; margin: clamp(1.8rem, 4vw, 2.6rem) 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.4rem 2rem; }
.statuses__row { padding-top: .9rem; border-top: 1px solid rgba(255,255,255,.14); color: #C7D2DE; font-size: .95rem; }
.statuses__row p { margin: .35rem 0 0; }
.statuses__key { display: inline-flex; align-items: center; gap: .5rem; font-family: var(--font-mono); font-weight: 500; font-size: .86rem; color: #fff; }
.statuses__key::before { content: ""; width: 10px; height: 10px; border-radius: 50%; border: 2px solid #9FB0C2; flex: none; }
.statuses__key--ok::before { background: #34A853; border-color: #34A853; }
.statuses__key--flag::before { background: var(--orange); border-color: var(--orange); }
.statuses__key--photo::before { border-radius: 3px; background: #fff; border-color: #fff; }
.statuses--light .statuses__row { border-top-color: var(--line); color: var(--ink); }
.statuses--light .statuses__key { color: var(--navy); }
.statuses--light .statuses__key--none::before { border-color: var(--ink-soft); }
.statuses--light .statuses__key--photo::before { background: var(--navy); border-color: var(--navy); }
@media (max-width: 1000px) { .statuses { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .statuses { grid-template-columns: minmax(0, 1fr); gap: 1rem; } }

/* /sample-report/: the full example. Its headings are real h2/h3 (the report
   is the page's content there), so they out-rank `.section--navy h2/h3`. */
.mock .mock__title { color: #E8EDF3; font-size: .82rem; line-height: 1.4; }
.mock .mock__h { color: var(--navy); line-height: 1.4; text-wrap: initial; }
.mock--full .mock__body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.mock__tbl { width: 100%; border-collapse: collapse; font-size: .82rem; }
.mock__tbl th { padding: .35rem .5rem; text-align: right; font-family: var(--font-body); font-size: .64rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); vertical-align: bottom; }
.mock__tbl td { padding: .42rem .5rem; text-align: right; color: var(--ink); border-top: 1px dashed var(--line); white-space: nowrap; }
.mock__tbl th:first-child, .mock__tbl td:first-child { padding-left: var(--pad); text-align: left; color: var(--navy); font-weight: 500; }
.mock__tbl th:last-child, .mock__tbl td:last-child { padding-right: var(--pad); }
.mock__tbl .is-flag { color: var(--navy); font-weight: 600; }
.mock__tbl .is-flag::before { content: ""; display: inline-block; width: 7px; height: 7px; margin-right: .35rem; border-radius: 50%; background: var(--orange); vertical-align: .08em; }
.mock__tbl .is-zero { color: #A7B3BF; }
.mock__tbl tfoot td { border-top: 1px solid var(--line); color: var(--navy); font-weight: 500; }
.mock__mini { display: flex; gap: 1px; width: 4.5rem; height: 6px; margin-left: auto; border-radius: 99px; overflow: hidden; }
.mock__mini span { flex: var(--n) 1 0; }
.mock__mini .m-ok { background: var(--ok-dot); }
.mock__mini .m-none { background: #C9D4DF; }
.mock__mini .m-flag { background: var(--orange); min-width: 3px; }
.mock__section { border-top: 1px solid var(--line); padding: .3rem 0 calc(var(--pad) * .9); }
.mock__exs--big { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; padding-top: .3rem; }
.mock__exs--big .mock__exc { grid-template-columns: minmax(0, 1fr); gap: .75rem; padding: .75rem .75rem 1rem; }
.mock__exs--big .mock__stamp { font-size: .7rem; left: 6px; bottom: 6px; }
.mock__notice { margin: .65rem 0 0; padding: .7rem .8rem; border-radius: 8px; background: color-mix(in srgb, var(--alt) 70%, #fff); border-left: 3px solid var(--navy); font-size: .82rem; color: var(--ink); }
.mock__notice b { display: block; margin-bottom: .2rem; font-size: .66rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.mock__summary { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.mock__summary > div + div { border-left: 1px solid var(--line); }
.mock__facts { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .45rem 1.2rem; margin: 0; padding: .2rem var(--pad) .4rem; font-size: .86rem; }
.mock__facts dt { color: var(--ink-soft); }
.mock__facts dd { margin: 0; text-align: right; color: var(--navy); font-family: var(--font-mono); font-weight: 500; }
.mock__todo { list-style: none; margin: 0; padding: .2rem var(--pad) .4rem; display: grid; gap: .55rem; font-size: .88rem; }
.mock__todo li { display: grid; grid-template-columns: 16px minmax(0, 1fr); gap: .7rem; align-items: start; }
.mock__todo li > span:first-child { margin-top: .2rem; }
.mock__todo b { color: var(--navy); }
@media (max-width: 1000px) { .mock__exs--big { grid-template-columns: minmax(0, 1fr); } .mock__exs--big .mock__exc { grid-template-columns: 9rem minmax(0, 1fr); } }
@media (max-width: 820px) {
  .mock--full .mock__body, .mock__summary { grid-template-columns: minmax(0, 1fr); }
  .mock__summary > div + div { border-left: 0; border-top: 1px solid var(--line); }
}
/* exception cards in a row: notices line up at the bottom */
.mock__exs--big .mock__exc { grid-template-rows: auto 1fr; }
.mock__exs--big .mock__exc > div { display: flex; flex-direction: column; }
.mock__exs--big .mock__notice { margin-top: auto; }
.mock__exs--big .mock__exc-n { margin-bottom: .65rem !important; }
.statuses + .services__close { margin-top: clamp(1.8rem, 4vw, 2.6rem); }
@media (max-width: 1000px) { .mock__exs--big .mock__exc { grid-template-rows: none; } }
@media (max-width: 560px) {
  .mock__exs--big .mock__exc { grid-template-columns: minmax(0, 1fr); }
  .mock__exs--big .mock__shot { aspect-ratio: 16 / 9; }
  .mock__tbl .is-wide { display: none; }
}
.sample__lede { max-width: 46em; }
.sample__actions { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.4rem; margin: 1.4rem 0 0; }

.feature-list { list-style: none; margin: 1.8rem 0 0; padding: 0; display: grid; gap: 1.3rem; }
.feature-list li { padding-left: 1.3rem; border-left: 3px solid var(--navy); }
.feature-list h3 { font-size: 1.12rem; margin-bottom: .25rem; }
.feature-list p { margin: 0; color: var(--ink-soft); font-size: .97rem; }

/* ---------- switch plan timeline ---------- */
.plan {
  list-style: none; margin: 0; padding: 0; counter-reset: plan;
  display: grid; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
}
.plan__step {
  background: var(--alt); border-radius: 10px;   /* tinted on white: never white-on-white */
  padding: .9rem 1rem 1rem;
}
/* No white plan card on the tint: the steps are navy cards everywhere (the
   2026-10-05 block), and a white fill here would leave white text on white
   if that rule ever lost the cascade (/how-it-works/ reuses the plan). */
.section--alt .plan__step { box-shadow: var(--shadow); }
.plan__step::before {
  counter-increment: plan; content: counter(plan);
  display: inline-grid; place-items: center;
  width: 1.7rem; height: 1.7rem; border-radius: 50%;
  background: var(--navy); color: #fff;
  font-family: var(--font-head); font-weight: 700; font-size: .85rem;
  margin-bottom: .6rem;
}
.plan__when {
  display: block; font-family: var(--font-head); font-weight: 700; font-size: .76rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft);
  margin-bottom: .25rem;
}
.plan__what { display: block; font-size: .93rem; color: var(--ink); line-height: 1.5; }
.switchplan { position: relative; margin-top: 2.2rem; padding-top: 1.1rem; }
.switchplan::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  height: 3px; border-radius: 2px;
  background: var(--navy);
}
.switchplan__foot { margin: 1.4rem 0 0; font-size: 1.05rem; color: var(--ink); }
.switchplan__foot .num { font-size: 1.35rem; }

/* ---------- integration: Inbox -> Work orders -> Resident records ---------- */
.integ {
  list-style: none; margin: 0; padding: 0; counter-reset: integ;
  display: grid; gap: 1.4rem; grid-template-columns: repeat(3, minmax(0, 1fr));
}
.integ__card {
  position: relative; display: flex; flex-direction: column;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.5rem 1.4rem; box-shadow: var(--shadow);
}
.integ__card + .integ__card::before {
  content: "\2192"; position: absolute; left: -1.25rem; top: 1.55rem;
  width: 1.1rem; text-align: center; color: var(--ink-soft); font-weight: 700; font-size: 1.1rem;
}
.integ__level {
  display: inline-block; align-self: flex-start; margin-bottom: .8rem;
  font-family: var(--font-head); font-weight: 700; font-size: .72rem;
  letter-spacing: .12em; text-transform: uppercase;
  padding: .28rem .65rem; border-radius: 999px; background: var(--navy); color: #fff;
}
.integ__level::before { counter-increment: integ; content: counter(integ) "\00A0\00B7\00A0"; color: var(--ink-soft); }
.integ__card h3 { font-size: 1.15rem; margin-bottom: .5rem; }
.integ__card p { margin: 0 0 .7rem; color: var(--ink-soft); font-size: .95rem; line-height: 1.6; }
.integ__meta { margin-top: auto !important; padding-top: .7rem; border-top: 1px solid var(--line); font-size: .85rem; }
.integ__meta b { color: var(--navy); }
@media (max-width: 900px) {
  .integ { grid-template-columns: 1fr; }
  .integ__card + .integ__card::before { content: "\2193"; left: 1.4rem; top: -1.25rem; }
}
.integ + p { margin-top: 1.8rem; }  /* the closing line sat flush against the cards' shadow (audit n2) */

/* ---------- pricing ---------- */
.keynums {
  list-style: none; margin: 0 0 1.6rem; padding: 0;
  display: grid; gap: 1rem; grid-template-columns: repeat(3, minmax(0, 1fr));
}
.keynums li { border-left: 3px solid var(--navy); padding-left: .8rem; }
.keynums b { display: block; font-size: clamp(1.15rem, 1.7vw, 1.45rem); line-height: 1.1; letter-spacing: -.01em; white-space: nowrap; }
.keynums span { display: block; font-size: .85rem; color: var(--ink-soft); margin-top: .2rem; }
@media (max-width: 420px) { .keynums { grid-template-columns: 1fr; gap: .8rem; } }

.incl-list { list-style: none; margin: 0 0 1.4rem; padding: 0; display: grid; gap: .5rem; }
.incl-list li { position: relative; padding-left: 1.9rem; font-size: .97rem; color: var(--ink); }
.incl-list li::before {
  content: ""; position: absolute; left: 0; top: .28em;
  width: 1.2rem; height: 1.2rem; border-radius: 50%; background: var(--navy);
}
.incl-list li::after {
  content: ""; position: absolute; left: .32rem; top: calc(.28em + .3rem);
  width: .55rem; height: .3rem;
  border-left: 2px solid #fff; border-bottom: 2px solid #fff; transform: rotate(-45deg);
}
.band {
  margin: 0 0 1.6rem; padding: .95rem 1.2rem; border-radius: 12px;
  background: var(--navy); color: #fff;
  font-family: var(--font-head); font-weight: 700; font-size: 1.08rem; line-height: 1.35;
}

/* the make-good promise */
.makegood {
  background: var(--bg); border: 2px solid var(--navy); border-radius: var(--radius);
  padding: 1.4rem 1.4rem 1.2rem; box-shadow: var(--shadow);
}
/* inside "Why properties switch" it follows the pull quote: give the two bordered blocks room */
#switch .makegood { margin: 2rem 0 1.8rem; }
.makegood .eyebrow { margin-bottom: .4rem; }
.makegood__title { font-size: 1.35rem; margin-bottom: .9rem; }
.makegood__steps { list-style: none; margin: 0; padding: 0; counter-reset: mg; display: grid; gap: .7rem; }
.makegood__steps li {
  position: relative; padding-left: 2.3rem; font-size: .95rem; color: var(--ink-soft);
}
.makegood__steps li::before {
  counter-increment: mg; content: counter(mg);
  position: absolute; left: 0; top: .05rem;
  display: grid; place-items: center; width: 1.6rem; height: 1.6rem; border-radius: 50%;
  background: var(--navy); color: #fff;
  font-family: var(--font-head); font-weight: 700; font-size: .82rem;
}
.makegood__steps b { display: block; color: var(--navy); font-family: var(--font-head); font-size: 1rem; }

/* ---------- homepage pricing summary ---------- */
.price { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(1.8rem, 5vw, 4.5rem); align-items: start; }
@media (max-width: 900px) { .price { grid-template-columns: 1fr; } }
.price .section__lede { margin-bottom: 1.4rem; }
.price__ctas { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem 1.4rem; margin: 0; }
.price-facts { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
@media (max-width: 560px) { .price-facts { grid-template-columns: 1fr; } }
.price-facts div { background: #fff; border-radius: var(--radius); box-shadow: var(--shadow); padding: 1.15rem 1.25rem 1.2rem; }
.price-facts dt { font-family: var(--font-head); font-weight: 700; color: var(--navy); font-size: 1rem; }
.price-facts dd { margin: .3rem 0 0; color: var(--ink); font-size: .96rem; line-height: 1.55; }

/* ---------- navy sections (pattern 3: accountability / data; founders) ---------- */
.section--navy { background: var(--navy); color: #C7D2DE; }
.section--navy h2, .section--navy h3 { color: #fff; }
.section--navy .eyebrow { color: #9FB0C2; }
.section--navy .section__lede { color: #C7D2DE; }

/* ---------- homepage: trust band (experience logos + insurance) ----------
   Navy, continuing the hero. Static row: never crop or dim another
   company's mark (claims audit, 2026-09-30). */
.trust { background: var(--navy); color: #C7D2DE; padding: clamp(1.8rem, 4vw, 2.6rem) 0 clamp(1.8rem, 4vw, 2.4rem); border-top: 1px solid rgba(255,255,255,.08); }
.trust__label { margin: 0 0 1.2rem; text-align: center; font-size: .98rem; color: #E8EDF3; }
/* scrolling banner: four copies of the set, slides by half (two sets) so the
   loop is seamless; soft edge fade; pauses on hover and off screen */
.trust__marquee { overflow: hidden; padding: .4rem 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.trust__logos { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; width: max-content;
  animation: trust-slide 38s linear infinite; }
.trust__logos li { flex: none; margin-right: clamp(3rem, 7vw, 5.5rem); }
.trust__logos img { display: block; width: var(--w); height: auto; }
.trust__marquee:hover .trust__logos, .trust__marquee.is-offscreen .trust__logos { animation-play-state: paused; }
@keyframes trust-slide { to { transform: translateX(-50%); } }
.op-greystar { --w: 139px; }
.op-willow-bridge { --w: 124px; }
.op-avenue5-residential { --w: 169px; }
.op-apartment-management-consultants { --w: 130px; }
@media (max-width: 560px) {
  .op-greystar { --w: 112px; } .op-willow-bridge { --w: 100px; } .op-avenue5-residential { --w: 134px; } .op-apartment-management-consultants { --w: 104px; }
}
/* reduced motion: one static, centred row */
.rm .trust__marquee { -webkit-mask-image: none; mask-image: none; }
.rm .trust__logos { animation: none; width: auto; flex-wrap: wrap; justify-content: center; gap: 1.4rem 3rem; }
.rm .trust__logos li { margin: 0; }
.rm .trust__logos li[aria-hidden="true"] { display: none; }
@media (prefers-reduced-motion: reduce) { .trust__logos { animation: none; } }
.trust__creds { list-style: none; margin: 1.5rem 0 0; padding: 1.3rem 0 0; border-top: 1px solid rgba(255,255,255,.1); display: flex; flex-wrap: wrap; justify-content: center; gap: .6rem 2.2rem; }
.trust__creds li { display: flex; align-items: center; gap: .55rem; font-family: var(--font-head); font-weight: 600; font-size: .95rem; color: #fff; }
.trust__creds li::before { content: ""; width: 8px; height: 8px; border-radius: 2px; background: var(--orange); flex: none; }

/* ---------- homepage: services bento (breadth early) ----------
   Tint section, white tiles with shadow (cards on tint). The lead tile
   carries the core service; photo tiles are labelled illustrative. */
.bento { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 1rem; margin-top: 1rem; }
.bento__tile {
  position: relative; grid-column: span 3; display: flex; flex-direction: column; gap: .35rem;
  padding: 1.2rem 1.25rem 1.3rem; border-radius: var(--radius); background: #fff; box-shadow: var(--shadow);
  color: inherit; text-decoration: none; overflow: hidden;
}
.bento__tile--lead { grid-column: span 6; grid-row: span 2; }
.bento__tile--photo { grid-column: span 3; }
.bento__tile--more { grid-column: span 6; }
.bento__links { list-style: none; margin: .3rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .35rem 1rem; }
.bento__links a { color: var(--navy); font-weight: 600; font-size: .93rem; text-decoration: underline; text-decoration-color: rgba(var(--navy-rgb), .25); text-underline-offset: 3px; }
.bento__links a:hover { text-decoration-color: var(--orange); }
@media (max-width: 600px) { .bento__links { grid-template-columns: 1fr; } }
.bento__tile--cta { grid-column: span 12; background: var(--navy); color: #C7D2DE; flex-direction: row; flex-wrap: wrap; justify-content: flex-start; align-items: center; gap: .8rem 1.4rem; }
.bento__tile--cta .bento__cta-line { flex: 1 1 22rem; }
.bento__media { position: relative; margin: -1.2rem -1.25rem .6rem; }
.bento__media img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.bento__tile--lead .bento__media img { aspect-ratio: 4 / 3; }
.bento__badge { align-self: flex-start; font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); }
.bento__badge--core { color: #fff; background: var(--navy); padding: .15rem .55rem; border-radius: 999px; }
.bento__name { margin: 0; font-size: 1.12rem; color: var(--navy); }
.bento__tile--lead .bento__name { font-size: clamp(1.4rem, 2.4vw, 1.9rem); }
.bento__line { margin: 0; color: var(--ink-soft); font-size: .93rem; line-height: 1.5; }
.bento__tile--lead .bento__line { font-size: 1.02rem; }
.bento__tile[href]:focus-visible { outline: 3px solid var(--orange); outline-offset: 3px; }
.bento__tile[href]:hover .bento__name { text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: 3px; }
.bento__cta-line { margin: 0; font-family: var(--font-head); font-weight: 700; font-size: 1.2rem; color: #fff; }
.bento__all { color: #fff; }
@media (max-width: 1100px) {
  .bento__tile, .bento__tile--photo { grid-column: span 6; }
  .bento__tile--lead { grid-column: span 12; grid-row: auto; }
  .bento__tile--lead .bento__media img { aspect-ratio: 16 / 9; }
  .bento__tile--cta, .bento__tile--more { grid-column: span 12; }
}
@media (max-width: 600px) { .bento__tile, .bento__tile--photo { grid-column: span 12; } }

.section--navy .link-arrow { color: #fff; }

/* ---------- homepage: what your team stops chasing ---------- */
.stops { list-style: none; margin: 1.8rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
.stops__item { background: var(--alt); border-radius: var(--radius); padding: 1.4rem 1.4rem 1.5rem; border-top: 4px solid var(--navy); }
.stops__item h3 { font-size: 1.2rem; margin-bottom: .45rem; }
.stops__item p { margin: 0; color: var(--ink); font-size: .97rem; }
@media (max-width: 860px) { .stops { grid-template-columns: 1fr; } }

/* ---------- homepage: the make-good promise ---------- */
.promise { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 1.2rem clamp(2rem, 5vw, 4.5rem); align-items: center; }
.promise__title { font-size: clamp(2.2rem, 5vw, 3.6rem); margin: 0; }
.promise__rules { margin: 0; display: grid; gap: .8rem; }
.promise__rule { display: grid; grid-template-columns: 8.5rem minmax(0, 1fr); gap: 1rem; align-items: baseline; background: #fff; border-radius: var(--radius); box-shadow: var(--shadow); padding: 1.1rem 1.3rem; }
.promise__rule dt { font-family: var(--font-head); font-weight: 700; color: var(--navy); font-size: 1rem; }
.promise__rule dt .num { font-size: 2.2rem; line-height: 1; letter-spacing: -.02em; }
.promise__rule dd { margin: 0; color: var(--ink); }
.promise__more { grid-column: 2; margin: 0; }
@media (max-width: 860px) { .promise { grid-template-columns: 1fr; } .promise__more { grid-column: auto; } }
@media (max-width: 480px) { .promise__rule { grid-template-columns: 1fr; gap: .3rem; } }

/* ---------- homepage: founders (navy) ---------- */
.founders__grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.founders__lede { color: #C7D2DE; font-size: 1.05rem; max-width: 34em; }
.founders__more { color: #fff; }
.founders__people { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.founder { margin: 0; }
.founder__photo { display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; border-radius: var(--radius); background: var(--navy-raised); }
.founder__name { margin: .8rem 0 0; font-family: var(--font-head); font-weight: 700; font-size: 1.1rem; color: #fff; }
.founder__role { margin: .15rem 0 0; font-size: .88rem; color: #9FB0C2; }
@media (max-width: 900px) { .founders__grid { grid-template-columns: 1fr; } }

/* ---------- homepage: service area rows are grouped, so they stack ---------- */
#service-area .area__row { grid-template-columns: 1fr; gap: .15rem; }
/* The city list's separators are literal " · " text, so a wrap could start a
   line with a dot ("· San Marcos", Gemini review). Here the text separators
   are set to zero size and each city but the last draws its own dot, glued to
   it (nowrap); the zero-size spaces between cities are the only breaks. The
   dot is inline-block, so the link underline never runs under it. */
#service-area .area__name:has(a) { font-size: 0; }
#service-area .area__name:has(a) a { font-size: 1.1rem; white-space: nowrap; }
#service-area .area__name a:not(:last-child)::after {
  content: "\00b7"; display: inline-block; margin: 0 .55em 0 .5em; color: var(--ink-soft); font-weight: 700;
}
.area__name a { color: inherit; text-decoration: underline; text-decoration-color: rgba(var(--navy-rgb), .25); text-underline-offset: 3px; }
.area__name a:hover { text-decoration-color: var(--orange); }
.area__ask .link-arrow { display: inline-block; margin-top: .4rem; }

/* ---------- FAQ on a white section: tinted, never white-on-white ---------- */
.section:not(.section--alt):not(.section--navy) .faq__item { background: var(--alt); border-color: transparent; box-shadow: none; }
.section:not(.section--alt):not(.section--navy) .faq__q::after { background: #fff; }

/* ---------- /services/ hub (cards generated from content/services.json) ---------- */
.hub__group + .hub__group { margin-top: clamp(2.4rem, 5vw, 3.6rem); }
.hub__title { margin: 0 0 .2rem; font-size: clamp(1.4rem, 2.6vw, 1.9rem); }
.hub__sub { margin: 0 0 1.1rem; color: var(--ink-soft); }
.hub__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr)); gap: 1rem; }
.hub__card { position: relative; display: grid; gap: .35rem; align-content: start; padding: 1.3rem 1.35rem 1.4rem; border-radius: var(--radius); background: var(--alt); color: inherit; text-decoration: none; }
.hub__group--core .hub__card { background: var(--navy); }
.hub__name { font-family: var(--font-head); font-weight: 700; font-size: 1.2rem; line-height: 1.2; color: var(--navy); }  /* two-line titles: heading leading, not body 1.6 (audit n4) */
.hub__line { color: var(--ink); font-size: .97rem; }
.hub__more { margin-top: .4rem; font-weight: 600; font-size: .92rem; color: var(--navy); }
.hub__more::after { content: "\00a0\2192"; color: var(--orange); }
.hub__group--core .hub__name, .hub__group--core .hub__more { color: #fff; }
.hub__group--core .hub__line { color: #C7D2DE; }
.hub__card:hover .hub__name { text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: 3px; }
.hub__card:focus-visible { outline: 3px solid var(--orange); outline-offset: 3px; }

/* ---------- /service-area/ ---------- */
.sa__grid { align-items: start; }
.sa__list { list-style: none; margin: 1.2rem 0 0; padding: 0; border-top: 1px solid rgba(var(--navy-rgb), .14); }
.sa__city { padding: 1rem 0 1.05rem; border-bottom: 1px solid rgba(var(--navy-rgb), .14); scroll-margin-top: calc(var(--nav-h) + 1rem); }
.sa__city:target { background: var(--alt); margin-inline: -1rem; padding-inline: 1rem; border-radius: var(--radius-sm); }
.sa__name { margin: 0 0 .2rem; font-size: 1.15rem; }
.sa__note { margin: 0; color: var(--ink); font-size: .97rem; }
.sa__link { margin: .35rem 0 0; font-size: .93rem; }
.sa .area__map { position: sticky; top: calc(var(--nav-h) + 1.5rem); }
@media (max-width: 900px) { .sa .area__map { position: static; order: -1; } }
.sa__limits .section__lede { max-width: 46em; margin-bottom: 0; }

/* ---------- /faq/ ---------- */
.faqnav { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.4rem; }
/* topic chips: navy on the tint hero, never white on pale (audit M3) */
.faqnav a { padding: .45rem .9rem; border-radius: 999px; background: var(--navy); color: #fff; font-weight: 600; font-size: .9rem; text-decoration: none; }
.faqnav a:hover, .faqnav a:focus-visible { text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: 3px; }
/* the answers keep a readable measure but start on the container edge, the
   same left line as the hero copy (audit n5: it used to be centred) */
.faqpage__body > * { max-width: 52rem; }
.faqpage__h { font-size: clamp(1.3rem, 2.4vw, 1.7rem); margin: 2.6rem 0 .9rem; scroll-margin-top: calc(var(--nav-h) + 1rem); }
.faqpage__h:first-child { margin-top: 0; }
.faq__a a { color: var(--navy); font-weight: 600; }

/* ---------- 404 ---------- */
.nf__links { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; gap: .3rem; }
.nf__cta { display: flex; flex-wrap: wrap; gap: .8rem; margin: 1.8rem 0 0; }

/* ---------- /pricing/ calculator: 1-3 nights go to an owner ---------- */
.calc__review { margin: .2rem 0 0; font-family: var(--font-head); font-weight: 700; font-size: 1.15rem; color: #fff; line-height: 1.35; }

/* ---------- PRICE MY PROPERTY (/quote/) ----------
   Light working surface (tint page, white form card) + a navy "estimate so
   far" panel: pattern 2 with a pattern-3 data panel. Options (service cards
   and chips) are navy on the white card and turn orange when picked (owner,
   2026-10-05; the cards' override is in the 2026-10-05 block at the end). */
.page-quote .qhead { background: var(--alt); padding: clamp(1.8rem, 4vw, 3rem) 0 1.4rem; }
.qhead__title { margin: 0 0 .35rem; }
.qhead__sub { margin: 0; max-width: 40em; color: var(--ink-soft); font-size: 1.05rem; }
.qpage { background: var(--alt); padding: .6rem 0 clamp(3rem, 7vw, 5rem); }
.qpage__grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: clamp(1.2rem, 3vw, 2.2rem); align-items: start; }
@media (max-width: 960px) { .qpage__grid { grid-template-columns: 1fr; } .qsum { display: none; } }

.qform-wrap { min-width: 0; }
.qform, .qsuccess { background: #fff; border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: clamp(1.2rem, 3.2vw, 2.2rem); }
.qform fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }

.qprog { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .4rem; margin: 0 0 .5rem; padding: 0; list-style: none; }
.qprog li { min-width: 0; }
.qprog button {
  display: block; width: 100%; min-height: 44px; padding: .7rem 0 .2rem; border: 0; background: none; cursor: pointer; text-align: left;
  font: 600 .78rem/1.2 var(--font-body); letter-spacing: .02em; color: var(--ink-soft);
  border-top: 4px solid var(--line); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qprog button:disabled { cursor: default; }
.qprog .is-done button { border-top-color: var(--navy); color: var(--navy); }
.qprog .is-done button:hover { text-decoration: underline; text-underline-offset: 3px; }
.qprog .is-on button { border-top-color: var(--orange); color: var(--navy); font-weight: 700; }
.qprog button:focus-visible { outline: 3px solid var(--orange); outline-offset: 3px; }
@media (max-width: 560px) { .qprog button { font-size: 0; padding-top: .4rem; } .qprog .is-on button { font-size: .74rem; overflow: visible; } }
.qprog__label { margin: -.3rem 0 1rem; font-size: .82rem; color: var(--ink-soft); min-height: 1.2em; }
.q--topic .qprog, .q--topic .qprog__label { display: none; }

.qstep__q { display: block; padding: 0; margin: 0 0 .35rem; font-family: var(--font-head); font-weight: 700; font-size: clamp(1.35rem, 2.6vw, 1.7rem); color: var(--navy); letter-spacing: -.015em; line-height: 1.2; }
.qstep__q:focus { outline: none; }
.qstep__sub { margin: 0 0 1.1rem; color: var(--ink-soft); font-size: .95rem; }
.qgroup { margin-top: 1.15rem !important; }
.qgroup > legend, .qform .field > label { display: block; padding: 0; margin: 0 0 .5rem; font-weight: 600; font-size: .92rem; color: var(--navy); }
.qform .field { margin-top: 1.15rem; }
.qform .field-grid .field { margin-top: 0; }
/* make-ready unit mix: one count per floor plan (2026-10-14) */
.qmix { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .75rem; }
.qform .qmix .field { margin-top: 0; }
@media (max-width: 560px) { .qmix { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.qhelp { margin: .45rem 0 0; font-size: .84rem; color: var(--ink-soft); }
.qhelp:empty { display: none; }
.qnote { margin: .2rem 0 0; padding: .7rem .9rem; border-left: 3px solid var(--navy); background: var(--alt); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; font-size: .92rem; color: var(--ink); }
.qerr { margin: 1rem 0 0; color: #B3261E; font-weight: 600; font-size: .92rem; }
/* a message under one contact field sits tight to that field */
.qerr--field { margin-top: .4rem; font-size: .86rem; }
/* estimator.js moves a step's message just above the tiles or chips at fault:
   leave a gap so it doesn't touch the first option; under a group's question
   it sits with that question, not 1.5rem below it */
.qerr:not([hidden]) + .qcards, .qerr:not([hidden]) + .qchips { margin-top: .6rem; }
.qgroup > legend + .qerr { margin-top: 0; }
/* contract check: the "Email it to quotes@" note sat flush on the Name label */
.qform .contract-fields:not([hidden]) + .field-grid { margin-top: 1.4rem; }

/* service tiles (design review 2026-10-14: a calmer picker). Valet trash is
   the one lead card; the other nine are a compact two-column list of rows
   (icon, name, one line), and "Market range" is said once in the list's
   heading instead of on seven cards. */
.qcards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .7rem; }
@media (max-width: 560px) { .qcards { grid-template-columns: 1fr; } }
.qcards--lead { grid-template-columns: 1fr; }
.qcards__h { margin: 1.4rem 0 .6rem; font-weight: 600; font-size: .92rem; color: var(--navy); }
.qcards__h span { display: block; margin-top: .1rem; font-weight: 400; font-size: .84rem; color: var(--ink-soft); }
.qcards--mini { gap: .5rem; }
.qcard { position: relative; display: block; cursor: pointer; }
.qcard input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.qcard__body {
  display: grid; gap: .25rem; height: 100%; padding: .95rem 2.8rem .95rem 1rem; border-radius: var(--radius);
  background: var(--alt); border: 2px solid transparent; position: relative;
  transition: background-color var(--d1) var(--ease), border-color var(--d1) var(--ease), color var(--d1) var(--ease);
}
.qcard__body::after {
  content: ""; position: absolute; top: .95rem; right: .95rem; width: 1.15rem; height: 1.15rem; border-radius: 5px;
  border: 2px solid #9FB0C2; background: #fff;
}
.qcard__name { font-family: var(--font-head); font-weight: 700; color: var(--navy); font-size: 1rem; line-height: 1.25; }
.qcard__desc { font-size: .86rem; color: var(--ink-soft); line-height: 1.4; }
.qcard__badge { justify-self: start; margin-top: .3rem; font-size: .72rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.qcard__badge--instant { color: var(--navy); background: #fff; padding: .15rem .5rem; border-radius: 999px; }
.qcard:hover .qcard__body { border-color: #9FB0C2; }
.qcard input:checked + .qcard__body { background: var(--navy); border-color: var(--navy); }
.qcard input:checked + .qcard__body .qcard__name { color: #fff; }
.qcard input:checked + .qcard__body .qcard__desc, .qcard input:checked + .qcard__body .qcard__badge { color: #C7D2DE; }
.qcard input:checked + .qcard__body .qcard__badge--instant { background: var(--orange); color: var(--navy); }
.qcard input:checked + .qcard__body::after {
  border-color: #fff; background: #fff
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23061727' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 80% no-repeat;
}
.qcard input:focus-visible + .qcard__body { outline: 3px solid var(--orange); outline-offset: 3px; }
/* the lead card: icon beside the copy, the badge under it */
.qcard--lead .qcard__body { grid-template-columns: auto minmax(0, 1fr); column-gap: 1rem; align-items: start; padding: 1.1rem 3rem 1.15rem 1.1rem; }
.qcard--lead .qcard__ic { grid-row: 1 / span 3; width: 2.6rem; height: 2.6rem; margin: 0; }
.qcard--lead .qcard__name { font-size: 1.12rem; }
.qcard--lead .qcard__body::after { top: 1.15rem; right: 1.1rem; }
/* compact rows: 1.6rem icon, name, one muted line; 56px+ tap target */
.qcard--mini .qcard__body { grid-template-columns: 1.6rem minmax(0, 1fr); column-gap: .75rem; row-gap: .1rem; align-items: start; min-height: 56px; padding: .7rem 2.6rem .7rem .85rem; }
.qcard--mini .qcard__ic { grid-row: 1 / span 3; width: 1.6rem; height: 1.6rem; margin: .05rem 0 0; }
.qcard--mini .qcard__body > :not(svg) { grid-column: 2; }
.qcard--mini .qcard__name { font-size: .95rem; }
.qcard--mini .qcard__desc { font-size: .8rem; line-height: 1.35; }
.qcard--mini .qcard__badge { margin-top: .15rem; font-size: .68rem; }
.qcard--mini .qcard__body::after { top: .75rem; right: .8rem; width: 1.05rem; height: 1.05rem; }
.qform .is-invalid + .qcard__body, .qform .is-invalid + span { box-shadow: 0 0 0 2px #D93025; }
.qother { margin-top: 1rem; }
/* optional disclosures: valet building details, and the wish list on the
   last screen (off the critical path, design review 2026-10-14) */
.qopt, .qmore { margin-top: 1.15rem; border-top: 1px solid var(--line); }
.qopt > summary, .qmore > summary {
  position: relative; display: block; min-height: 48px; padding: .8rem 0 .8rem 2.1rem; cursor: pointer;
  font-weight: 600; font-size: .92rem; line-height: 1.35; color: var(--navy); list-style: none;
}
.qopt > summary::-webkit-details-marker, .qmore > summary::-webkit-details-marker { display: none; }
.qopt > summary::before, .qmore > summary::before {
  content: "+"; position: absolute; left: 0; top: .72rem; display: grid; place-items: center; width: 1.5rem; height: 1.5rem; border-radius: 50%;
  background: var(--alt); color: var(--navy); font: 700 1rem/1 var(--font-head);
}
.qopt[open] > summary::before, .qmore[open] > summary::before { content: "\2212"; }
.qopt > summary span, .qmore > summary span { font-weight: 400; color: var(--ink-soft); }
.qopt > summary:hover, .qmore > summary:hover { text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: 3px; }
.qopt > summary:focus-visible, .qmore > summary:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }
.qopt > .qgroup:first-of-type, .qopt > .field:first-of-type { margin-top: .3rem !important; }
.qopt[open] { padding-bottom: .4rem; }
.qmore { padding-bottom: .1rem; border-bottom: 1px solid var(--line); }
.qmore .qgroup { margin: .2rem 0 .9rem !important; }
.qmore .qgroup > legend { font-weight: 400; font-size: .86rem; color: var(--ink-soft); }
.qchip--sm > span { font-size: .86rem; padding-inline: .8rem; }
.qalt { margin: 1.2rem 0 0; font-size: .86rem; color: var(--ink-soft); }
.qalt a { color: var(--navy); }

/* chips (radios and checkboxes) */
.qchips { display: flex; flex-wrap: wrap; gap: .45rem; }
.qchip { position: relative; cursor: pointer; }
.qchip input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
/* Same scheme as the service cards (owner, 2026-10-05): navy on the white form,
   orange with a navy label when picked. Pale-tint chips were light on light
   (audit M3), and a navy unpicked chip needs a different picked colour. */
.qchip > span {
  display: inline-flex; align-items: center; min-height: 44px; padding: .45rem .95rem; border-radius: 999px;
  background: var(--navy); border: 2px solid var(--navy); color: #fff; font-size: .92rem; font-weight: 500;
  transition: background-color var(--d1) var(--ease), border-color var(--d1) var(--ease), color var(--d1) var(--ease);
}
.qchip:hover > span { border-color: var(--orange); }
.qchip input:checked + span { background: var(--orange); border-color: var(--orange); color: var(--navy); font-weight: 600; }
.qchip input:focus-visible + span { outline: 3px solid var(--orange); outline-offset: 2px; }
.qchips--nums .qchip > span { justify-content: center; min-width: 48px; padding-inline: .6rem; font-family: var(--font-head); font-weight: 700; }
.qchips--cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: .55rem; }
.qchip--card > span { display: grid; gap: .15rem; height: 100%; border-radius: var(--radius); padding: .75rem .9rem; align-content: start; }
.qchip--card b { font-family: var(--font-head); font-size: .95rem; }
.qchip--card small { font-size: .8rem; color: #C7D2DE; line-height: 1.35; }
.qchip--card input:checked + span small { color: var(--navy); }

/* action bar: ends each screen. It used to stick to the bottom of phones,
   where it floated over the form (design review 2026-10-14: nothing floats
   over the form at 390px); the shorter screens keep it within reach. */
.qbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .7rem 1rem; margin-top: 1.5rem; padding-top: 1.1rem; border-top: 1px solid var(--line); }
.qbar__mini { font-size: .84rem; color: var(--navy); font-weight: 600; }
.qbar__nav { display: flex; align-items: center; gap: .6rem; margin-left: auto; }
.qbar__back { background: none; border: 0; padding: .7rem .6rem; font: inherit; font-weight: 600; color: var(--navy); cursor: pointer; min-height: 44px; }
.qbar__back:hover { text-decoration: underline; text-underline-offset: 3px; }
.qbar__back::before { content: "\2190\00a0"; }
.qbar .btn { margin: 0; }
#form-submit.qbar__next { margin-top: 0; }
@media (max-width: 960px) { .qbar__mini { flex-basis: 100%; } }
@media (max-width: 560px) {
  .qbar__nav { flex: 1; }
  .qbar__nav .qbar__next { flex: 1; justify-content: center; min-height: 52px; }
}
.qtalk { margin: 1.4rem 0 0; font-size: .88rem; color: var(--ink-soft); text-align: center; }
.qtalk a { color: var(--navy); font-weight: 600; }


/* the estimate (step 4, the summary panel and the success echo) */
.qresult { display: grid; gap: .8rem; margin-top: .6rem; }
.qresult:empty { display: none; }
.qrange { background: var(--navy); color: #C7D2DE; border-radius: var(--radius); padding: 1.2rem 1.3rem 1.25rem; }
.qrange__kicker { display: block; font-size: .74rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: #9FB0C2; }
.qrange__num { margin: .35rem 0 0; font-family: var(--font-head); font-weight: 700; font-size: clamp(2.1rem, 5vw, 2.9rem); line-height: 1.05; color: #fff; letter-spacing: -.02em; }
.qrange__num small { font-family: var(--font-body); font-size: .95rem; font-weight: 500; color: #C7D2DE; letter-spacing: 0; }
.qrange__line { margin: .45rem 0 0; font-family: var(--font-mono); font-size: .88rem; color: #E8EDF3; }
.qrange__label { display: inline-block; margin: .7rem 0 0; font-size: .78rem; font-weight: 600; color: var(--navy); background: #C7D2DE; padding: .15rem .5rem; border-radius: 999px; }
.qrange__note, .qrange__incl { margin: .6rem 0 0; font-size: .86rem; line-height: 1.5; }
.qrange__incl { padding-top: .6rem; border-top: 1px solid rgba(255,255,255,.12); }
.qrange__review { margin: .4rem 0 0; font-family: var(--font-head); font-weight: 700; font-size: 1.1rem; color: #fff; line-height: 1.35; }
.qowner { background: var(--alt); border-radius: var(--radius); padding: 1.05rem 1.2rem; }
.qowner__title { margin: 0 0 .5rem; font-family: var(--font-head); font-weight: 700; color: var(--navy); }
.qowner__list { margin: 0; padding: 0; list-style: none; display: grid; gap: .45rem; }
.qowner__list li { display: grid; gap: .05rem; font-size: .9rem; }
.qowner__list b { color: var(--navy); }
.qowner__list span { color: var(--ink-soft); }
.qowner__list .qowner__range { color: var(--navy); font-family: var(--font-head); font-weight: 700; }
.qsum .qowner__list .qowner__range { color: #fff; }
.qowner__fine { margin: .7rem 0 0; font-size: .82rem; color: var(--ink-soft); }
.qresult__actions { display: flex; flex-wrap: wrap; gap: 0 1.3rem; margin: .6rem 0 0; }
.qest { margin-top: .4rem; }
.qsend { margin-top: 1.6rem; padding-top: 1.4rem; border-top: 1px solid var(--line); }
.qsend[hidden] + * { margin-top: 0; }
.qsend__title { margin: 0 0 .3rem; font-family: var(--font-head); font-weight: 700; font-size: 1.2rem; line-height: 1.25; color: var(--navy); letter-spacing: -.01em; }
.qsend .qstep__sub { margin-bottom: 1rem; }
.qlink { display: inline-flex; align-items: center; background: none; border: 0; padding: .45rem 0; min-height: 44px; font: inherit; font-size: .92rem; font-weight: 600; color: var(--navy); cursor: pointer; text-decoration: underline; text-decoration-color: rgba(var(--navy-rgb), .3); text-underline-offset: 3px; }
.qlink:hover { text-decoration-color: var(--orange); }
.qshare-note { margin: .2rem 0 0; font-size: .84rem; color: var(--ink-soft); word-break: break-all; }
.qshare-note:empty { display: none; }

/* summary panel (desktop) */
/* The page around it is navy (2026-10-05 block), so the panel is a card on
   navy: navy-raised with a white/10% edge and a dark drop, like the form card
   beside it. The owner list inside drops to navy, an inset well. */
.qsum { position: sticky; top: calc(var(--nav-h) + 1.2rem); background: var(--navy-raised); color: #C7D2DE; border: 1px solid rgba(255,255,255,.1); border-radius: var(--radius-lg); padding: 1.4rem 1.4rem 1.3rem; box-shadow: 0 30px 60px -30px rgba(0,0,0,.55); }
.qsum__title { margin: 0 0 .7rem; font-size: .74rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: #9FB0C2; }
.qsum__facts { margin: 0 0 .9rem; padding: 0; list-style: none; font-size: .9rem; color: #fff; display: grid; gap: .2rem; }
.qsum__empty { margin: 0; color: #C7D2DE; }
.qsum .qrange { padding: 0; background: none; }
.qsum .qrange__num { font-size: 2.2rem; }
.qsum .qrange__incl, .qsum .qrange__label { display: none; }
.qsum .qowner { background: var(--navy); border: 1px solid rgba(255,255,255,.1); margin-top: .9rem; }
.qsum .qowner__title, .qsum .qowner__list b { color: #fff; }
.qsum .qowner__list span, .qsum .qowner__fine { color: #C7D2DE; }
/* one line per add-on in the panel (name and range); the reasoning lives on the estimate */
.qsum .qowner__list li > span:not(.qowner__range), .qsum .qowner__fine, .qsum .qrange__note { display: none; }
.qsum .qowner { padding: .8rem 1rem; }
.qsum__fine { margin: 1rem 0 0; padding-top: .9rem; border-top: 1px solid rgba(255,255,255,.12); font-size: .8rem; line-height: 1.5; color: #9FB0C2; }

/* success */
.qsuccess { text-align: left; }
.qsuccess:focus { outline: none; }
.qsuccess__title { margin: 0 0 .4rem; font-size: clamp(1.6rem, 3vw, 2.1rem); }
.qsuccess > p { color: var(--ink); }
.qsuccess__next { margin: 1rem 0 1.2rem; padding-left: 1.2rem; display: grid; gap: .35rem; color: var(--ink); }
.qsuccess .form-success__next { justify-items: start; margin: 1.3rem 0 0; max-width: none; }

@media print {
  .nav, .footer, .skip-link, .qhead .crumbs, .qprog, .qprog__label, .qbar, .qtalk, .qalt, .qresult__actions, .qshare-note, .qsum, .askr-launch, .textus { display: none !important; }
  .qstep[data-step="contact"] > :not(legend):not(.qest) { display: none !important; }
  .page-quote .qhead, .qpage { background: #fff; padding: 0; }
  .qform { box-shadow: none; padding: 0; }
  .qrange { background: #fff; color: #000; border: 2px solid #000; }
  .qrange__num, .qrange__line, .qrange__review, .qrange__kicker { color: #000; }
  .qest::after { content: "RPMTX · rpmtx.com/quote · (512) 866-6695 · Illustrative estimate, final rate set after a free property walk."; display: block; margin-top: 1rem; font-size: .8rem; }
}

/* ---------- quote form (two steps) ---------- */
.quote-form {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 2rem 1.8rem; box-shadow: var(--shadow);
}
.quote-form__title { margin-bottom: .3rem; }
.quote-form__sub { color: var(--ink-soft); font-size: .95rem; margin-bottom: 1.5rem; }
.quote-form__fine { text-align: center; font-size: .8rem; color: var(--ink-soft); margin: .8rem 0 0; }
.form-step[hidden] { display: none; }
.form-step__label {
  font-family: var(--font-head); font-weight: 700; font-size: .74rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft);
  margin: 0 0 .8rem;
}
.form-step--optional { margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px dashed var(--line); }
.form-step__more { margin: 1rem 0 0; }
.form-step__toggle {
  background: none; border: 0; padding: .4rem .1rem; cursor: pointer;
  font: inherit; font-weight: 600; font-size: .95rem; color: var(--navy);
  display: inline-flex; align-items: center; gap: .45rem;
}
.form-step__toggle::before {
  content: "+"; display: inline-grid; place-items: center;
  width: 1.25rem; height: 1.25rem; border-radius: 50%;
  border: 1.5px solid currentColor; font-size: .9rem; line-height: 1;
}
.form-step__toggle[aria-expanded="true"]::before { content: "\2212"; }
.form-step__toggle:hover { text-decoration: underline; text-underline-offset: 3px; }

.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.1rem; }
.field--full { grid-column: 1 / -1; }
@media (max-width: 560px) { .field-grid { grid-template-columns: 1fr; } .field--full { grid-column: auto; } }
.field label {
  display: block; font-weight: 600; font-size: .87rem;
  color: var(--navy); margin-bottom: .35rem;
}
.field input, .field select, .field textarea {
  width: 100%; font: inherit; font-size: .98rem; color: var(--ink);
  padding: .68rem .8rem; border: 1.5px solid #7C8B9A; border-radius: 9px;   /* 3.5:1 edge, as the calculator fields (audit m4) */
  background: #fff; transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.field textarea { resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--orange);
  box-shadow: 0 0 0 1px var(--orange);
}
/* keyboard focus: the site's 3px orange ring, not just a 1px edge (audit n8) */
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }
.field input.is-invalid, .field select.is-invalid, .field textarea.is-invalid {
  border-color: #D93025; box-shadow: 0 0 0 3px rgba(217,48,37,.12);
}
.form-error { color: #B3261E; font-weight: 600; font-size: .92rem; margin: 1rem 0 0; }
#form-submit { margin-top: 1.3rem; }
.hp { position: absolute; left: -9999px; }

/* contract check: extra fields revealed when the topic is "Contract check" */
.contract-fields { border: 0; padding: 0; margin: 1.1rem 0 0; min-width: 0; }
.contract-fields[hidden] { display: none; }
/* Never float the legend: a float beside the grid makes the grid shrink to
   min-content next to it instead of dropping below. The divider rides on
   the legend instead. */
.contract-fields legend {
  display: block; width: 100%; box-sizing: border-box;
  font-family: var(--font-head); font-weight: 700; font-size: .95rem;
  color: var(--navy); padding: 1.1rem 0 0; margin: 0 0 .7rem;
  border-top: 1px dashed var(--line);
}
.contract-fields__note { margin: .8rem 0 0; font-size: .85rem; color: var(--ink-soft); }

.form-success { text-align: center; padding: 2.5rem 1rem; }
.form-success h3 { margin-top: 1rem; font-size: 1.5rem; }
/* direct children only: as a descendant rule (0,1,1) it also hit the estimate
   echoed inside the navy .qrange card, leaving the price grey on navy at
   2.93:1 (audit M4) */
.form-success > p { color: var(--ink-soft); max-width: 30em; margin-inline: auto; }
.form-success__next {
  list-style: none; margin: 1.4rem auto 0; padding: 1.2rem 0 0; max-width: 30em;
  border-top: 1px solid var(--line); display: grid; gap: .2rem; justify-items: center;
}
.form-success__next .link-arrow { white-space: normal; }

/* ---------- CTA bands (contract check, final) ---------- */
.ctaband { background: var(--orange); padding: clamp(2.6rem, 6vw, 4.2rem) 0; }
.ctaband__inner {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 1.5rem;
}
.ctaband h2 { color: var(--navy); margin: 0; }
.ctaband__copy { max-width: 44em; }
.ctaband .eyebrow { color: var(--navy); margin-bottom: .5rem; }
.ctaband__sub { color: var(--navy); font-size: 1.05rem; margin: .7rem 0 0; text-wrap: pretty; }  /* no lone "day." (audit m11) */
.ctaband--final { padding: var(--space-section) 0; }
.ctaband--final h2 { font-size: clamp(2rem, 4.2vw, 3rem); }
.ctaband__actions { display: flex; flex-direction: column; align-items: flex-start; gap: .7rem; }
.ctaband__call {
  color: var(--navy); font-weight: 600; font-size: .95rem;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(var(--navy-rgb), .5);
}
.ctaband__call:hover { text-decoration-color: var(--navy); }

/* ---------- FAQ ---------- */
.faq { display: grid; gap: .65rem; }
.faq__more { margin: 1.2rem 0 0; color: var(--ink-soft); font-size: .95rem; }
.faq__item {
  background: var(--bg); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow);
}
.faq__item[open] { border-color: rgba(var(--navy-rgb), .3); }
.faq__q {
  cursor: pointer; list-style: none; position: relative;
  padding: 1rem 3rem 1rem 1.3rem;
  font-family: var(--font-head); font-weight: 700; font-size: 1.05rem; color: var(--navy);
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "+"; position: absolute; right: 1.1rem; top: 50%; transform: translateY(-50%);
  width: 1.5rem; height: 1.5rem; border-radius: 50%; display: grid; place-items: center;
  background: var(--alt); color: var(--navy); font-size: 1.1rem; line-height: 1;
}
.faq__item[open] > .faq__q::after { content: "\2212"; }
.faq__q:hover { text-decoration: underline; text-decoration-color: var(--orange); }
.faq__a { padding: 0 1.3rem 1.2rem; color: var(--ink-soft); font-size: .97rem; }
.faq__a p { margin: 0 0 .7em; }
.faq__a p:last-child { margin-bottom: 0; }
.faq__item--ops .faq__q { color: var(--ink-soft); }
.ops { margin: 0; display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: .55rem 1.2rem; }
.ops dt { font-family: var(--font-head); font-weight: 700; color: var(--navy); font-size: .92rem; }
.ops dd { margin: 0; font-size: .93rem; }
@media (max-width: 560px) {
  .ops { grid-template-columns: 1fr; gap: .1rem; }
  .ops dd { margin-bottom: .7rem; }
}

/* ---------- personas ---------- */
.who { display: grid; gap: 1.2rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.who__card {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.5rem 1.4rem 1.3rem; box-shadow: var(--shadow);
}
.who__card h3 { font-size: 1.1rem; margin-bottom: .4rem; }
.who__outcome { margin: 0 0 .5rem; font-weight: 600; color: var(--navy); font-size: 1rem; }
.who__card p:last-child { margin: 0; color: var(--ink-soft); font-size: .95rem; }
@media (max-width: 860px) { .who { grid-template-columns: 1fr; } }

/* ---------- owners (/about/) ---------- */
.owners__grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2.4vw, 1.75rem); margin-top: .6rem;
}
.owner-card {
  position: relative; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
}
.owner-card__photo {
  min-height: 17rem; height: 100%; display: grid; place-items: center;
  background:
    linear-gradient(160deg, rgba(var(--navy-rgb), .06), rgba(var(--navy-rgb), .16)),
    repeating-linear-gradient(-45deg, transparent 0 10px, rgba(var(--navy-rgb), .04) 10px 11px);
  color: rgba(var(--navy-rgb), .45); font: 600 .75rem/1 var(--font-head); letter-spacing: .14em; text-transform: uppercase;
}
.owner-card__body { padding: clamp(1.2rem, 2.4vw, 1.8rem); display: flex; flex-direction: column; }
.owner-card__role {
  margin: 0 0 .35rem; font: 700 .75rem/1.2 var(--font-head); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-soft);
}
/* side by side, both roles reserve two lines, so the names and bios start on
   the same line when only one role wraps (audit n1) */
@media (min-width: 901px) { .owner-card__role { min-height: 2.4em; } }
.owner-card__name { margin: 0 0 .7rem; font-size: clamp(1.3rem, 2.2vw, 1.6rem); }
.owner-card__handles { margin: 0 0 .8rem; font: 500 .9rem/1.4 var(--font-head); color: var(--navy); }
.owner-card__bio { margin: 0 0 1.2rem; color: var(--ink-soft); }
.owner-card__line {
  margin: auto 0 0; padding-top: 1rem; border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: .9rem; color: var(--navy);
}
.owner-card__line span {
  display: block; font: 600 .7rem/1.4 var(--font-head); letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-soft);
}
/* Unfilled placeholder text reads as a draft on dev, never as finished copy. */
.owner-card[data-placeholder] .owner-card__name,
.owner-card[data-placeholder] .owner-card__bio,
.owner-card[data-placeholder] .owner-card__role,
.owner-card[data-placeholder] .owner-card__handles,
.owner-card[data-placeholder] .owner-card__line { opacity: .72; }
.owner-card[data-placeholder] { border-style: dashed; border-color: rgba(var(--navy-rgb), .28); }
.owner-card__photo picture, .owner-card__photo img { display: block; width: 100%; height: 100%; }
.owner-card__photo img { object-fit: cover; object-position: center 20%; }
.owner-card:not([data-placeholder]) { border: 0; background: var(--alt); box-shadow: none; }
.owner-card:not([data-placeholder]) .owner-card__photo { min-height: 20rem; background: var(--navy); }
.owners__reach { margin: 1.4rem 0 0; color: var(--ink); }
.owners__reach a { color: var(--navy); font-weight: 600; }
@media (max-width: 900px) { .owners__grid { grid-template-columns: 1fr; } }
@media (max-width: 520px) {
  .owner-card { grid-template-columns: 1fr; }
  .owner-card__photo, .owner-card:not([data-placeholder]) .owner-card__photo { min-height: 0; aspect-ratio: 4 / 3; }
  /* the 720x900 portrait rendered 438px tall in a 263px box and printed over
     the role, name and bio: the box clips and the picture fills it (audit B6) */
  .owner-card__photo { position: relative; overflow: hidden; }
  .owner-card__photo picture { position: absolute; inset: 0; }
}

/* ---------- full-screen sections (owner, 2026-09-30 / 2026-10-01) ----------
   Every main section fills at least one screen (minus the nav) at EVERY width,
   so the colour takes the whole page, with its content centred. The content
   is scroll-linked (main.js "scroll stage"): it rises in from below as the
   section arrives and keeps rising and fades as it leaves, and runs backwards
   on the way up. The one-line outcome band on service pages keeps its
   natural height. */
@media (min-height: 520px) {
  main > .section:not(.svc-outcome), main > .ctaband {
    min-height: calc(100svh - var(--nav-h));
    display: flex; flex-direction: column; justify-content: center;
  }
  .footer { min-height: calc(100svh - var(--nav-h)); display: flex; flex-direction: column; }
  .footer__grid { margin-block: auto; }
}
.stage-on > .container { transform: translate3d(0, var(--sy, 0px), 0); opacity: var(--so, 1); will-change: transform, opacity; }
/* continuous upward drift on every text block (main.js "text drift") */
.drift { translate: 0 var(--dy, 0px); }

/* ---------- content pages (/pricing/, /how-it-works/, /about/): compact navy header ---------- */
.page-hero { padding-bottom: clamp(2.4rem, 5vw, 3.6rem); }
.page-hero h1 { max-width: 22ch; }
.page-hero .hero__sub { max-width: 46em; }

/* ---------- article pages (cost, what-is, suburbs): one readable column ---------- */
.article__body { max-width: 46rem; }
.article__body h2 { font-size: clamp(1.35rem, 2.4vw, 1.75rem); margin: 2.2rem 0 .7rem; }
.article__body h2:first-child { margin-top: 0; }
.article__body p { color: var(--ink); line-height: 1.7; margin: 0 0 1rem; }
.article__list { margin: 0 0 1.2rem; padding-left: 1.2rem; display: grid; gap: .45rem; line-height: 1.6; }
.article__list li::marker { color: var(--navy); }

/* ---------- comparison table ("questions to ask any vendor") ---------- */
.compare { margin-top: 1.4rem; overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: #fff; }
.compare__table { width: 100%; border-collapse: collapse; font-size: .95rem; }
.compare__table caption { text-align: left; padding: .9rem 1.1rem; font: 600 .78rem/1.4 var(--font-head); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.compare__table th, .compare__table td { text-align: left; vertical-align: top; padding: .85rem 1.1rem; border-top: 1px solid var(--line); line-height: 1.5; }
.compare__table thead th { background: var(--navy); color: #fff; font: 600 .9rem/1.3 var(--font-head); border-top: 0; }
.compare__table tbody th { font: 600 .95rem/1.4 var(--font-head); color: var(--navy); width: 26%; }
.compare__table td:nth-child(2) { color: var(--ink); font-weight: 500; }
.compare__table td:nth-child(3) { color: var(--ink-soft); }
@media (max-width: 700px) {
  .compare__table thead { display: none; }
  .compare__table tr { display: block; padding: .6rem 0; border-top: 1px solid var(--line); }
  .compare__table th, .compare__table td { display: block; border: 0; padding: .3rem 1rem; width: auto; }
  .compare__table tbody th { width: auto; }  /* the 26% above (0,1,2) out-ranked the reset: one word per line (audit M6) */
  .compare__table td::before { content: attr(data-label); display: block; font: 600 .7rem/1.4 var(--font-head); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
}

/* ---------- resident portal (/residents/#portal): sign-in UI ---------- */
.portal { background: var(--bg); color: var(--ink); padding: clamp(2.4rem, 6vw, 5rem) 0 clamp(3rem, 7vw, 6rem); }
.portal__grid { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.portal__intro h2 { color: var(--navy); font-size: clamp(2rem, 4vw, 3rem); margin: 0 0 .8rem; }
.portal .eyebrow { color: var(--ink-soft); }
.portal__lede { font-size: 1.15rem; margin: 0 0 1.4rem; }
.portal__perks { list-style: none; margin: 0 0 1.6rem; padding: 0; display: grid; gap: .6rem; }
.portal__perks li { position: relative; padding-left: 1.7rem; }
.portal__perks li::before { content: ""; position: absolute; left: 0; top: .45em; width: .7rem; height: .7rem; border-radius: 50%; background: var(--orange); }
.portal__help { font-size: .95rem; }
.portal__help a { color: var(--navy); }
.portal__card { background: #fff; color: var(--ink); border-radius: var(--radius); padding: clamp(1.4rem, 3vw, 2rem); box-shadow: var(--shadow-lift); border: 1px solid var(--line); }
.portal__title { font-size: 1.4rem; margin: 0 0 1.1rem; }
.portal__sso { display: grid; gap: .6rem; }
.portal__sso-btn {
  display: flex; align-items: center; justify-content: center; gap: .6rem; width: 100%;
  padding: .8rem 1rem; border: 1px solid #C9D2DC; border-radius: var(--radius-btn); background: #fff; cursor: pointer;
  font: 600 .95rem/1.2 var(--font-body); color: #1F1F1F;
}
.portal__sso-btn:hover { background: var(--alt); }
.portal__sso-btn--apple { background: #000; color: #fff; border-color: #000; }
.portal__sso-btn--apple:hover { background: #1c1c1c; }
.portal__or { display: flex; align-items: center; gap: .8rem; margin: 1.2rem 0; color: var(--ink-soft); font-size: .85rem; }
.portal__or::before, .portal__or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.portal__form { display: grid; gap: .9rem; }
.portal__pw-row { display: flex; justify-content: space-between; align-items: baseline; }
.portal__forgot { font-size: .85rem; }
.portal__notice { margin-top: 1rem; padding: .9rem 1rem; border-radius: 10px; background: var(--alt); border-left: 4px solid var(--orange); font-size: .92rem; }
.portal__notice p { margin: 0 0 .5rem; }
.portal__notice p:last-child { margin: 0; }
.portal__new { margin: 1rem 0 0; font-size: .85rem; color: var(--ink-soft); text-align: center; }
.portal__error { margin: 0; color: #B3261E; font-weight: 600; font-size: .92rem; }
.portal__reset-lede { margin: 0; font-size: .95rem; }
.portal__back { margin: 0; text-align: center; font-size: .9rem; }
.portal__alt { margin: 1rem 0 0; font-size: .85rem; color: var(--ink-soft); }
.portal__alt a, .portal__back a { color: var(--navy); }
@media (max-width: 860px) { .portal__grid { grid-template-columns: 1fr; } }

/* ---------- service pages (/services/<slug>/, generated) ---------- */
.crumbs {
  display: flex; flex-wrap: wrap; gap: .45rem; align-items: center;
  margin: 0 0 1.4rem; font-size: .85rem; color: var(--ink-soft);
}
.crumbs a { color: var(--navy); text-decoration: none; }
.crumbs a:hover, .crumbs a:focus-visible { text-decoration: underline; text-decoration-color: var(--orange); }
.crumbs [aria-current] { color: var(--ink); }
.svc-hero__grid {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(1.6rem, 4vw, 3.5rem); align-items: start; /* photo top lines up with the copy (owner: alignment) */
}
.svc-hero--type .svc-hero__grid { grid-template-columns: minmax(0, 1fr); }
.svc-hero--type h1 { max-width: 18ch; }
.svc-hero__media { margin: 0; border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-lift); }
.svc-hero__media img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
@media (max-width: 900px) { .svc-hero__grid { grid-template-columns: 1fr; } }

.svc-outcome { padding-block: clamp(2.4rem, 5vw, 3.6rem); }
.svc-outcome__line {
  margin: 0; padding-left: clamp(1rem, 2vw, 1.6rem); border-left: 5px solid var(--navy);
  font: 700 clamp(1.5rem, 3.2vw, 2.4rem)/1.15 var(--font-head); letter-spacing: -.015em;
  color: var(--navy); text-wrap: balance;
}

.svc-included {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem 2rem;
}
.svc-included li {
  position: relative; padding: 1rem 1.1rem 1rem 3rem; background: #fff;
  border: 1px solid var(--line); border-radius: 12px; color: var(--ink);
}
.svc-included li::before {
  content: ""; position: absolute; left: 1.1rem; top: 1.2rem; width: 1.1rem; height: 1.1rem;
  border-radius: 50%; background: var(--navy);
}
.svc-included li::after {
  content: ""; position: absolute; left: 1.47rem; top: 1.47rem; width: .32rem; height: .55rem;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
}
@media (max-width: 700px) { .svc-included { grid-template-columns: 1fr; } }

.svc-steps {
  list-style: none; counter-reset: step; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 1.2rem;
}
.svc-step {
  counter-increment: step; position: relative; padding: 1.4rem 1.3rem 1.3rem;
  border-top: 3px solid var(--navy); background: var(--alt); border-radius: 0 0 12px 12px;
}
.svc-step::before {
  content: counter(step, decimal-leading-zero); display: block; margin-bottom: .6rem;
  font: 500 .8rem/1 var(--font-mono); color: var(--ink-soft); letter-spacing: .08em;
}
.svc-step h3 { font-size: 1.1rem; margin: 0 0 .45rem; }
.svc-step p { margin: 0; color: var(--ink-soft); font-size: .95rem; }

.svc-related { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; }
.svc-related__card {
  display: flex; flex-direction: column; gap: .35rem; padding: 1.3rem 1.3rem 1.2rem;
  border: 1px solid var(--line); border-radius: var(--radius); background: #fff;
  text-decoration: none; color: var(--ink); box-shadow: var(--shadow);
}
.svc-related__name { font: 700 1.1rem/1.2 var(--font-head); color: var(--navy); text-wrap: balance; }
.svc-related__name::after { content: "\00a0\2192"; color: var(--navy); }  /* the arrow never wraps alone (audit m11) */
.svc-related__line { color: var(--ink-soft); font-size: .95rem; }

/* service named above the quote form when arriving from /?service= */
.quote-form__service {
  display: inline-block; margin: 0 0 .8rem; padding: .3rem .7rem; border-radius: 999px;
  background: var(--alt); color: var(--navy); font: 600 .82rem/1.3 var(--font-head);
}

/* ---------- residents ---------- */
.timeline {
  list-style: none; counter-reset: tl; margin: 2.6rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.4rem;
}
@media (max-width: 980px) { .timeline { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .timeline { grid-template-columns: 1fr; } }
.timeline li {
  position: relative; background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.5rem 1.4rem 1.2rem;
  box-shadow: var(--shadow);
}
.timeline__time {
  display: inline-block; font-family: var(--font-head); font-weight: 700;
  font-size: .8rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--navy); background: var(--alt);
  padding: .3rem .65rem; border-radius: 999px; margin-bottom: .9rem;
}
.timeline h3 { font-size: 1.1rem; }
.timeline p { margin: 0; color: var(--ink-soft); font-size: .95rem; }
.residents__report { margin-top: 2rem; font-size: 1.05rem; }
.residents__report a { font-weight: 600; }

/* ---------- sticky CTAs ----------
   Desktop: a pill in the corner once #hero has scrolled out (main.js toggles
   `hidden`). Mobile: a fixed bottom bar, CSS only. */
.sticky-cta { position: fixed; right: 1.4rem; bottom: 1.4rem; z-index: 90; translate: 0 var(--dock, 0px); }
.sticky-cta[hidden] { display: none; }
.sticky-cta__btn { box-shadow: 0 10px 28px -8px rgba(var(--navy-rgb), .45); padding: .8rem 1.4rem; }
.mobile-bar { display: none; }
@media (max-width: 820px) {
  .sticky-cta { display: none; }
  /* room for the bar AND the Dessa launcher parked above it (5.2rem + 3.6rem),
     so neither sits on the insurance line at the very end (audit M11) */
  body:has(.mobile-bar) .footer { padding-bottom: calc(9.6rem + env(safe-area-inset-bottom, 0px)); }
  .mobile-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
    display: grid; grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr) minmax(0, 1fr); gap: .5rem;
    padding: .6rem .9rem calc(.6rem + env(safe-area-inset-bottom, 0px));
    /* opaque, no blur: at 96% white the headings and navy cards under it
       ghosted through as grey text (audit m2) */
    background: #fff;
    border-top: 1px solid rgba(var(--navy-rgb), .16);
    box-shadow: 0 -8px 24px -16px rgba(var(--navy-rgb), .3);
  }
  .mobile-bar__btn { text-align: center; padding: .8rem .6rem; font-size: .95rem; white-space: nowrap; }
  .mobile-bar__btn:hover { transform: none; }
}
/* 320px (400% zoom): "Price my property" overflowed its button (audit m40) */
@media (max-width: 359px) {
  .mobile-bar { gap: .4rem; padding-inline: .6rem; }
  .mobile-bar__btn { padding-inline: .3rem; font-size: .86rem; }
}

@media (max-width: 820px) {
  .mobile-bar, .askr-launch { transition: transform .25s var(--ease-out), opacity .25s var(--ease-out); }
}
@media (max-width: 820px) and (prefers-reduced-motion: reduce) { .mobile-bar, .askr-launch { transition: none; } }

/* ---------- click-to-text dialog (desktop; see main.js) ---------- */
.textus {
  border: 0; padding: 0; border-radius: 16px; width: min(360px, calc(100vw - 2rem));
  background: #fff; color: var(--ink); box-shadow: 0 30px 70px -24px rgba(var(--navy-rgb), .55);
}
.textus::backdrop { background: rgba(var(--navy-rgb), .55); }
.motion .textus[open] { animation: textus-in 240ms var(--ease-out); }
@keyframes textus-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }
.textus__inner { position: relative; padding: 1.7rem 1.6rem 1.4rem; text-align: center; }
.textus__close {
  position: absolute; top: .45rem; right: .45rem; width: 40px; height: 40px;
  border: 0; border-radius: 8px; background: none; cursor: pointer;
  font-size: 1.7rem; line-height: 1; color: var(--ink-soft);
}
.textus__close:hover { background: var(--alt); color: var(--navy); }
.textus__title { margin: 0 0 1rem; font-size: 1.35rem; color: var(--navy); }
.textus__qr { display: block; width: 200px; height: 200px; margin: 0 auto 1rem; }
.textus__lede { margin: 0 0 1.1rem; font-size: .95rem; }
.textus__actions { display: grid; gap: .55rem; }
.textus__actions .btn { width: 100%; }
.textus__note { margin: .9rem 0 0; font-size: .8rem; color: var(--ink-soft); }
.textus__status { margin: .4rem 0 0; min-height: 1em; font-size: .8rem; color: var(--navy); font-weight: 600; }
.textus__status:empty { margin: 0; min-height: 0; }
.textus__legal { margin: .8rem 0 0; padding-top: .8rem; border-top: 1px solid var(--line); font-size: .72rem; line-height: 1.45; color: var(--ink-soft); }
.textus__legal a { color: var(--ink-soft); }

/* ---------- "Ask Dessa" launcher + chat panel (see main.js, js/chat.js) ----------
   Design pass (2026-10-14, outside review the owner accepted: "a more
   integrated appearance"). Dessa's portrait is used exactly as supplied; only
   its FRAME changed, from a loose circle to one navy tile everywhere
   (launcher, panel header, beside every reply), so she reads as part of the
   angular RPMTX system rather than a stock chat bubble.
   Launcher: a compact navy key with the site's 10px button radius, a hairline
   white edge so it still reads on navy sections and the footer (never
   navy-on-navy), and a navy-tinted shadow. It never covers a form: main.js
   tucks it away while a form control sits in its corner (.askr-tuck), and CSS
   tucks it while one has focus (the phone keyboard). /quote/ has no launcher. */
.askr-launch {
  position: fixed; right: 1.4rem; bottom: 1.4rem; z-index: 95;
  display: inline-flex; align-items: center; gap: .65rem;
  height: 48px; padding: 0 1.05rem 0 5px; border: 0; border-radius: 10px;
  background: var(--navy); color: #fff;
  font-family: var(--font-head); font-weight: 700; font-size: .95rem; line-height: 1; letter-spacing: -.005em;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.18), 0 1px 2px rgba(var(--navy-rgb), .18), 0 14px 30px -14px rgba(var(--navy-rgb), .6);
  cursor: pointer;
  transition: background-color var(--d1) var(--ease), transform var(--d2) var(--ease-out),
              opacity var(--d2) var(--ease-out), visibility 0s linear 0s;
}
/* the portrait tile: a navy-raised square, the badge inside it untouched */
.askr-launch__avatar { position: relative; display: block; flex: none; width: 38px; height: 38px; border-radius: 7px; background: var(--navy-raised); }
.askr-launch__avatar img { display: block; width: 100%; height: 100%; }
.askr-launch__avatar::after {
  content: ""; position: absolute; right: -2px; bottom: -2px; width: 10px; height: 10px; border-radius: 50%;
  background: #3DDC84; box-shadow: 0 0 0 2px var(--navy);
}
.askr-launch:hover { background: var(--navy-deep); transform: translateY(-2px); }
.askr-launch[aria-expanded="true"] { background: var(--navy-deep); }
.askr-launch:focus-visible { outline: 3px solid var(--orange); outline-offset: 3px; }
/* tucked: slides down out of the way and leaves the tab order (visibility),
   never while the chat is open or while the launcher itself has focus */
.askr-tuck .askr-launch:not([aria-expanded="true"]):not(:focus-visible),
html:has(main :is(input, select, textarea):focus) .askr-launch:not([aria-expanded="true"]) {
  opacity: 0; visibility: hidden; transform: translateY(calc(100% + 1.4rem)); pointer-events: none;
  transition: transform var(--d2) var(--ease-in), opacity var(--d1) var(--ease-in), visibility 0s linear var(--d2);
}
/* the homepage's floating quote pill sits just left of the launcher */
.has-askr .sticky-cta { right: calc(1.4rem + var(--askr-w, 140px)); }
@media (min-width: 821px) { .has-askr .footer { padding-bottom: calc(2rem + 4.2rem); } }
/* phones: the launcher (1rem + 3rem) would otherwise sit on the footer's
   insurance line at max scroll (audit M11); the homepage rule above, with its
   mobile bar, out-ranks this one */
@media (max-width: 820px) { .has-askr .footer { padding-bottom: calc(2rem + 4.6rem + env(safe-area-inset-bottom, 0px)); } }
@media (max-width: 820px) {
  /* a 48px tile on phones: the portrait alone; the name stays in its aria-label */
  .askr-launch { right: 1rem; bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); width: 48px; padding: 0; justify-content: center; }
  .askr-launch__label { display: none; }
  body:has(.mobile-bar) .askr-launch { bottom: calc(5.2rem + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: reduce) {
  .askr-launch, .askr-launch:hover { transition: none; transform: none; }
  .askr-tuck .askr-launch:not([aria-expanded="true"]):not(:focus-visible),
  html:has(main :is(input, select, textarea):focus) .askr-launch:not([aria-expanded="true"]) { transform: none; transition: none; }
}

/* Dessa's panel (owner, 2026-10-01: "an AI concierge, not a support widget").
   Sized by its content; the site's card radius, flat 8px bubbles and keys with
   one squared corner toward the speaker, Space Grotesk for names, and orange
   only for action and accent: the send key, focus rings, the arrows on her
   links and the spark on navy. */
.askr {
  /* --askr-b: just above the launcher, wherever the launcher is parked */
  --askr-b: calc(1.4rem + 48px + .75rem);
  position: fixed; right: 1.4rem; bottom: var(--askr-b); z-index: 96;
  width: min(384px, calc(100vw - 2.8rem)); height: auto; max-height: min(580px, calc(100svh - var(--nav-h) - var(--askr-b) - 1rem));
  display: flex; flex-direction: column; overflow: hidden;
  background: #fff; color: var(--ink); border-radius: var(--radius);
  box-shadow: 0 0 0 1px rgba(var(--navy-rgb), .08), 0 2px 6px rgba(var(--navy-rgb), .08), 0 32px 64px -24px rgba(var(--navy-rgb), .55);
  opacity: 0; transform: translateY(8px); transform-origin: bottom right;
  transition: opacity var(--d1) var(--ease-out), transform var(--d2) var(--ease-out);
}
.askr[hidden] { display: none; }
.askr.is-open { opacity: 1; transform: none; }
.askr__head {
  display: flex; align-items: center; gap: .75rem; padding: .8rem .7rem .8rem .9rem;
  background: var(--navy); color: #fff;
}
.askr__avatar { position: relative; display: block; flex: none; width: 46px; height: 46px; border-radius: var(--radius-sm); background: var(--navy-raised); box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); }
.askr__avatar img { display: block; width: 100%; height: 100%; }
.askr__titles { flex: 1; min-width: 0; }
.askr__title { margin: 0; font-size: 1.15rem; line-height: 1.15; color: #fff; letter-spacing: -.01em; }
.askr__spark { color: var(--orange); }
.askr__sub { margin: .2rem 0 0; font-size: .8rem; line-height: 1.2; color: #C7D2DE; display: flex; align-items: center; gap: .1rem; }
.askr__online { display: inline-block; width: 7px; height: 7px; margin: 0 .25rem 0 .15rem; border-radius: 50%; background: #3DDC84; box-shadow: 0 0 0 3px rgba(61,220,132,.18); }
.askr__close {
  flex: none; display: grid; place-items: center; width: 40px; height: 40px; border: 0; border-radius: var(--radius-sm);
  background: none; color: #fff; font-size: 1.6rem; line-height: 1; cursor: pointer;
  transition: background-color var(--d1) var(--ease);
}
.askr__close:hover { background: var(--navy-raised); }
.askr__log { flex: 1 1 auto; min-height: 130px; overflow-y: auto; overscroll-behavior: contain; padding: 1rem .9rem 1.1rem; background: var(--alt); display: flex; flex-direction: column; gap: .8rem; }
.askr__msg { max-width: 92%; }
.askr__msg--bot { align-self: flex-start; display: flex; align-items: flex-start; gap: .55rem; }
.askr__msg--user { align-self: flex-end; max-width: 82%; }
.askr__face { display: block; flex: none; width: 30px; height: 30px; border-radius: 6px; background: var(--navy); }
.askr__face img { display: block; width: 100%; height: 100%; }
.askr__body { min-width: 0; }
.askr__name { margin: 0 0 .3rem; font: 700 .76rem/1 var(--font-head); color: var(--navy); letter-spacing: .01em; }
/* small orange on the tint fails contrast: the spark by her name goes navy here */
.askr__name .askr__spark { color: var(--navy); }
.askr__text { margin: 0; padding: .65rem .85rem; border-radius: var(--radius-sm); font-size: .9375rem; line-height: 1.5; white-space: pre-line; }
.askr__msg--bot .askr__text { background: #fff; color: var(--ink); border-top-left-radius: 2px; box-shadow: 0 1px 2px rgba(var(--navy-rgb), .06); }
.askr__msg--user .askr__text { background: var(--navy); color: #fff; border-top-right-radius: 2px; }
.askr__actions { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5rem; }
.askr__action {
  display: inline-flex; align-items: center; gap: .4rem; min-height: 36px; padding: .4rem .75rem; border-radius: var(--radius-sm); border: 0;
  background: #fff; color: var(--navy); font: 600 .84rem/1.2 var(--font-body); text-decoration: none;
  box-shadow: inset 0 0 0 1.5px rgba(var(--navy-rgb), .2);
  transition: background-color var(--d1) var(--ease), color var(--d1) var(--ease);
}
.askr__action::after { content: "\2192"; color: var(--orange); font-weight: 700; }
.askr__action:hover { background: var(--navy); color: #fff; box-shadow: none; }
.askr__src { margin: .45rem 0 0; font-size: .75rem; color: var(--ink-soft); }
.askr__src a { color: var(--ink-soft); }
/* suggestions: squared keys aligned under her text, a breath below her hello */
.askr__starters { display: flex; flex-wrap: wrap; gap: .4rem; margin: .1rem 0 0 calc(30px + .55rem); }
.askr__chip {
  min-height: 38px; padding: .5rem .8rem; border-radius: var(--radius-sm); border: 0; background: #fff; color: var(--navy);
  font: 600 .86rem/1.25 var(--font-body); text-align: left; cursor: pointer;
  box-shadow: 0 1px 2px rgba(var(--navy-rgb), .06), inset 0 0 0 1.5px rgba(var(--navy-rgb), .14);
  transition: background-color var(--d1) var(--ease), color var(--d1) var(--ease), transform var(--d1) var(--ease);
}
.askr__chip:hover { background: var(--navy); color: #fff; transform: translateY(-1px); }
.askr__chip--role { background: transparent; box-shadow: inset 0 0 0 1.5px rgba(var(--navy-rgb), .32); }
.askr__chip:focus-visible, .askr__action:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }
.askr__typing .askr__dots { display: inline-flex; gap: .3rem; padding: .8rem .9rem; background: #fff; border-radius: var(--radius-sm); border-top-left-radius: 2px; }
.askr__dots span { width: 6px; height: 6px; border-radius: 1px; background: var(--navy); opacity: .3; }
.motion .askr__dots span { animation: askr-dot 1s var(--ease) infinite; }
.motion .askr__dots span:nth-child(2) { animation-delay: .15s; }
.motion .askr__dots span:nth-child(3) { animation-delay: .3s; }
@keyframes askr-dot { 50% { opacity: .9; transform: translateY(-3px); } }
/* each new line from Dessa arrives with a small lift */
.motion .askr__msg { animation: askr-in var(--d2) var(--ease-out) both; }
@keyframes askr-in { from { opacity: 0; transform: translateY(6px); } }
.askr__form { display: flex; align-items: flex-end; gap: .5rem; padding: .75rem .75rem .4rem; border-top: 1px solid var(--line); }
.askr__input {
  flex: 1; min-height: 44px; max-height: 120px; resize: none; padding: .7rem .85rem;
  border: 1.5px solid rgba(var(--navy-rgb), .18); border-radius: 10px; font: .95rem/1.35 var(--font-body); color: var(--ink); background: #fff;
}
.askr__input::placeholder { color: var(--ink-soft); }
.askr__input:focus { outline: none; border-color: var(--navy); }
.askr__input:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }  /* the site's focus ring (audit n8) */
.askr__send {
  flex: none; width: 44px; height: 44px; border: 0; border-radius: 10px; cursor: pointer;
  background: var(--orange); color: var(--navy); display: grid; place-items: center;
  transition: background-color var(--d1) var(--ease), color var(--d1) var(--ease);
}
.askr__send:hover { background: var(--navy); color: #fff; }
.askr__send:disabled { opacity: .5; cursor: default; }
.askr__fine { margin: 0; padding: .15rem .9rem .75rem; font-size: .72rem; line-height: 1.45; color: var(--ink-soft); }
.askr__fine a { color: var(--navy); font-weight: 600; }
@media (max-width: 820px) {
  .askr { right: 1rem; --askr-b: calc(1rem + 48px + .75rem + env(safe-area-inset-bottom, 0px)); }
  body:has(.mobile-bar) .askr { --askr-b: calc(5.2rem + 48px + .75rem + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 600px) {
  .askr { inset: 0; width: 100%; height: 100dvh; max-height: none; border-radius: 0; box-shadow: none; z-index: 210; }
  .askr__head { padding-top: calc(.8rem + env(safe-area-inset-top, 0px)); }
  .askr__fine { padding-bottom: calc(.75rem + env(safe-area-inset-bottom, 0px)); }
  .askr-open body { overflow: hidden; }
}
@media (prefers-reduced-motion: reduce) {
  .askr { transition: none; transform: none; }
  .askr__msg, .askr__dots span { animation: none; }
}

/* ---------- footer ---------- */
.footer { background: var(--navy); color: #B9C6D2; padding: 3.5rem 0 2rem; border-top: 1px solid rgba(255,255,255,.08); }
.footer__grid {
  display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 3fr) minmax(0, 3fr) minmax(0, 4fr); /* 6fr: brand column clears 360px at full width, so the full lockup shows */
  gap: 2.5rem; padding-bottom: 2.5rem;
  border-bottom: 1px solid rgba(255,255,255,.12);
}
.footer__head {
  color: var(--orange); /* group titles set apart (owner, 2026-09-30); 5.25:1 on navy */ font-size: .82rem; letter-spacing: .12em; text-transform: uppercase;
  margin: 0 0 .4rem; line-height: 1.3;
}
.footer__head a { color: inherit; text-decoration: none; }
.footer__head a:hover { text-decoration: underline; }
.footer__head--area { margin-top: 1.6rem; }
/* the nine cities, inline: every one clickable (a guide or its /service-area/ row) */
.footer__area { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0 1rem; max-width: 30rem; }
.footer__area li { display: inline-flex; align-items: center; }
.footer__area a { color: #C7D2DE; text-decoration: none; font-size: .9rem; padding: .3rem .15rem; display: inline-block; min-height: 32px; }
.footer__area a:hover { color: var(--orange); }
/* 541-820px: two newspaper columns, not a 2x2 grid. In the grid, Company
   waited for row 2 under the tall Services list and left ~250px of dead navy
   under the brand block (audit m31); columns keep the reading order
   (brand, services | company, contact) and balance the heights. */
@media (min-width: 541px) and (max-width: 820px) {
  .footer__grid { display: block; columns: 2; column-gap: 2rem; }
  .footer__grid > * { break-inside: avoid; margin-bottom: 2rem; }
  .footer__grid > :last-child { margin-bottom: 0; }
}
@media (max-width: 540px) { .footer__grid { grid-template-columns: 1fr; gap: 2rem; } }
/* Full lockup only where it gets 360px or more; the wordmark below that. */
.footer__brand { container-type: inline-size; }
.footer__logo img { height: auto; }
.footer__logo-full { width: 360px; display: none; }
.footer__logo-mark { width: 210px; display: block; }
@container (min-width: 360px) {
  .footer__logo-full { display: block; }
  .footer__logo-mark { display: none; }
}
.footer__tag { margin-top: 1.75rem; font-size: .95rem; color: #8296A9; }
.footer__nav { display: grid; gap: .5rem; align-content: start; }
.footer__head--sub { margin-top: 1.2rem; }
.footer__nav a, .footer__contact a {
  color: #E8EDF3; text-decoration: none;
  font-family: var(--font-head); font-weight: 500; font-size: .97rem;
  display: inline-block; padding: .3rem 0; min-height: 32px;   /* 32px touch floor */
}
.footer__nav a:hover, .footer__contact a:hover { color: var(--orange); }
.footer__contact { display: grid; gap: .5rem; align-content: start; }
.footer__contact p { margin: .4rem 0 0; font-size: .9rem; color: #8296A9; }
.footer__contact .footer__sms { margin: -.2rem 0 .2rem; font-size: .75rem; }
.footer__social { display: flex; gap: .3rem; list-style: none; margin: .6rem 0 0 -.6rem; padding: 0; }
.footer__contact .footer__social a { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 10px; color: #9FB0C2; }
.footer__contact .footer__social a:hover, .footer__contact .footer__social a:focus-visible { color: var(--orange); background: rgba(255,255,255,.06); }
.footer__contact .footer__sms a { display: inline; font-size: inherit; color: inherit; text-decoration: underline; text-decoration-color: rgba(255,255,255,.35); }
.footer__legal {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: .5rem 2rem; padding-top: 1.6rem; font-size: .85rem; color: #8296A9;
}
.footer__legal p { margin: 0; }
.footer__legal a { color: inherit; text-decoration-color: rgba(255,255,255,.35); white-space: nowrap; }  /* never "SMS / terms" (audit n3) */
/* a phone number never splits as "(512) 866- / 6695" (audit n3) */
a[href^="tel:"] { white-space: nowrap; }
.footer__legal a:hover { color: var(--orange); text-decoration-color: var(--orange); }

/* =====================================================================
   MOTION SYSTEM
   Direction: editorial calm. Stillness is the default; motion marks
   arrival, orientation, a change of state, and ONE signature: the nightly
   report "walks the route" once, door by door (.mock: the homepage
   preview and /sample-report/).
   Gate: an inline script in <head> sets html.motion (animate) or html.rm
   (reduced motion or ?noanim). Without JS nothing is ever hidden.
   Rules for everything in this system: transform/translate and opacity carry
   every movement; the only other transitions are small colour changes on
   hover (link and card border colour, dropdown item background) under 300ms.
   The system never animates box-shadow, size, position, filter or clip-path
   (older UI states outside it keep theirs: button hover shadow, form focus
   ring, skip-link slide-in);
   no pointer tracking, no scroll-jacking, no count-ups (numbers are facts).
   ===================================================================== */
:root {
  --e-stamp: cubic-bezier(.34,1.56,.64,1);  /* route ticks only, ~6% overshoot */
  --stagger: 80ms;                          /* sibling stagger, capped at index 3 */
}
.noanim *, .noanim *::before, .noanim *::after { transition: none !important; animation: none !important; }

@keyframes rise { from { opacity: 0; transform: translateY(10px); } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes faq-in { from { opacity: 0; transform: translateY(-4px); } }

/* ----- section reveals: header groups read 0/80/160ms, grids up to 240ms ----- */
.motion .reveal {
  --rd: calc(min(var(--i, 0), 3) * var(--stagger));
  opacity: 0; transform: translateY(12px);
  /* hover lift uses the separate `translate` property, so it never borrows this timing */
  transition: opacity 700ms var(--ease-out) var(--rd), transform 700ms var(--ease-out) var(--rd),
              translate 280ms var(--ease), border-color 280ms var(--ease);
}
.motion .reveal.is-in { opacity: 1; transform: none; }
.motion .reveal.is-past { transition: none; }  /* already scrolled past on load */
/* never hide something the keyboard is on (WCAG 2.4.7); main.js also reveals on focusin */
.motion .reveal:focus-within { opacity: 1; transform: none; }
/* owner photo wells: opacity only, slower */
.motion .owner-card__photo { opacity: 0; transition: opacity 1000ms var(--ease); }
.motion .owner-card.is-in .owner-card__photo { opacity: 1; }

/* ----- hero arrival on load (no observer: above-the-fold never waits) ----- */
.motion .hero .reveal { opacity: 1; transform: none; transition: none; animation: rise 700ms var(--ease-out) both; }
.motion .hero .crumbs, .motion .hero .eyebrow { animation-delay: 0ms; }
@keyframes rise-t { from { transform: translateY(10px); } }
/* h1.reveal / .hero__sub.reveal: must out-rank `.motion .hero .reveal` (0,3,0) */
.motion .hero h1.reveal { animation-name: rise-t; animation-delay: 0ms; }  /* LCP: opaque from the first frame */
.motion .hero .hero__sub.reveal { animation-name: rise-t; animation-delay: 60ms; }
.motion .hero .hero__badge, .motion .hero .hero__ctas { animation-delay: 220ms; }
.motion .hero .hero__proof, .motion .hero .hero__call { animation-delay: 300ms; }
.motion .hero .hero__side.reveal { animation: none; }
.motion .svc-hero__media.reveal { animation: fade-in 900ms var(--ease) 120ms both; }

/* ----- switch plan: the line draws, the steps follow it like a timeline ----- */
.motion .switchplan::before { transform: scaleX(0); transform-origin: left center; transition: transform 1000ms var(--ease-io); }
.motion .switchplan.is-drawn::before { transform: scaleX(1); }
.motion .plan__step.reveal { --rd: calc(100ms + var(--i, 0) * 150ms); }

/* ----- SIGNATURE: the route pass (.mock) -----
   One class (.is-routed) fires once when the door log is a third on screen.
   Row r is reached at t(r) = 150ms + r * 200ms (JS sets --r on each row and
   --rows on the report). An orange route line runs through the status marks
   in two halves per row (above and below the mark's centre), so it survives
   rows wrapping on narrow screens. On the homepage preview each exception
   card arrives as the route reaches its door (its --r is set inline), and
   the totals fade in after the last door, never counting. Zero per-frame JS. */
.mock__check, .mock__flag, .mock__none, .mock__gapdot { z-index: 1; }
.motion .mock__rows .mock__row::before, .motion .mock__rows .mock__row::after {
  content: ""; position: absolute; left: calc(var(--pad) + 7px); width: 2px;
  background: var(--orange); transform: scaleY(0); transform-origin: top center;
  pointer-events: none;
}
.motion .mock__rows .mock__row::before { top: 50%; bottom: 0; transition: transform 100ms linear calc(150ms + var(--r, 0) * 200ms); }
.motion .mock__rows .mock__row::after { top: -1px; height: calc(50% + 1px); transition: transform 100ms linear calc(50ms + var(--r, 0) * 200ms); }
.motion .mock__rows .mock__row:first-child::after, .motion .mock__rows .mock__row:last-child::before { display: none; }
.motion .mock.is-routed .mock__row::before, .motion .mock.is-routed .mock__row::after { transform: scaleY(1); }
/* the skipped stretch of the log: the route line goes dashed instead of the dots */
.motion .mock__rows .mock__row--gap::before, .motion .mock__rows .mock__row--gap::after { background: repeating-linear-gradient(to bottom, var(--orange) 0 3px, transparent 3px 7px); }
.motion .mock__rows .mock__row--gap .mock__gapdot { color: transparent; }
.motion .mock__rows .mock__check, .motion .mock__rows .mock__flag, .motion .mock__rows .mock__none, .motion .mock__rows .mock__gapdot {
  opacity: .35; transform: scale(.6);
  transition: transform 260ms var(--e-stamp) calc(150ms + var(--r, 0) * 200ms), opacity 200ms var(--ease) calc(150ms + var(--r, 0) * 200ms);
}
.motion .mock__rows .mock__check::after, .motion .mock__rows .mock__flag::after { opacity: 0; transition: opacity 160ms var(--ease) calc(210ms + var(--r, 0) * 200ms); }
.motion .mock__rows .mock__time, .motion .mock__rows .mock__cam { opacity: .35; transition: opacity 200ms var(--ease) calc(150ms + var(--r, 0) * 200ms); }
.motion .mock__pane .mock__exc { opacity: 0; transform: translateY(8px); transition: opacity 420ms var(--ease-out) calc(260ms + var(--r, 0) * 200ms), transform 420ms var(--ease-out) calc(260ms + var(--r, 0) * 200ms); }
.motion .mock.is-routed .mock__rows .mock__check, .motion .mock.is-routed .mock__rows .mock__flag,
.motion .mock.is-routed .mock__rows .mock__none, .motion .mock.is-routed .mock__rows .mock__gapdot,
.motion .mock.is-routed .mock__pane .mock__exc { opacity: 1; transform: none; }
.motion .mock.is-routed .mock__rows .mock__check::after, .motion .mock.is-routed .mock__rows .mock__flag::after,
.motion .mock.is-routed .mock__rows .mock__time, .motion .mock.is-routed .mock__rows .mock__cam { opacity: 1; }
/* the preview totals itself after the last door (the full sample shows its totals from the start) */
.motion .mock:not(.mock--full) { --td: calc(250ms + var(--rows, 8) * 200ms); }
.motion .mock:not(.mock--full) .mock__stat strong { opacity: 0; transform: translateY(6px); transition: opacity 500ms var(--ease-out) var(--td), transform 500ms var(--ease-out) var(--td); }
.motion .mock:not(.mock--full) .mock__stat:nth-child(2) strong { transition-delay: calc(var(--td) + 80ms); }
.motion .mock:not(.mock--full) .mock__stat:nth-child(3) strong { transition-delay: calc(var(--td) + 160ms); }
.motion .mock:not(.mock--full) .mock__stat:nth-child(4) strong { transition-delay: calc(var(--td) + 240ms); }
.motion .mock:not(.mock--full) .mock__meter { transform: scaleX(0); transition: transform 900ms var(--ease-io) var(--td); }
.motion .mock.is-routed .mock__stat strong, .motion .mock.is-routed .mock__meter { opacity: 1; transform: none; }
.motion .mock.is-instant *, .motion .mock.is-instant *::before, .motion .mock.is-instant *::after { transition: none !important; }

/* ----- hover: only things that navigate respond; info cards stay still ----- */
@media (hover: hover) and (pointer: fine) {
  .motion .bento__tile[href]::after, .motion .svc-related__card::after, .motion .hub__card::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    box-shadow: var(--shadow-lift); opacity: 0; transition: opacity 280ms var(--ease);
  }
  .motion .bento__tile[href]:hover, .motion .svc-related__card:hover, .motion .hub__card:hover { translate: 0 -3px; }
  .motion .bento__tile[href]:hover::after, .motion .svc-related__card:hover::after, .motion .hub__card:hover::after { opacity: 1; }
  .motion .bento__media img { transition: transform 700ms var(--ease-out); }
  .motion .bento__tile:hover .bento__media img { transform: scale(1.03); }
}
.svc-related__card { position: relative; }

/* ----- small moments ----- */
.motion .faq__item[open] > .faq__a { animation: faq-in 260ms var(--ease-out); }
.motion .mobile-menu__sub:not([hidden]) { animation: rise 260ms var(--ease-out) both; }
.motion .sticky-cta { opacity: 0; transform: translateY(8px); transition: opacity 200ms var(--ease-in), transform 200ms var(--ease-in); }
.motion .sticky-cta.is-shown { opacity: 1; transform: none; transition: opacity 480ms var(--ease-out), transform 480ms var(--ease-out); }
.rm .sticky-cta { opacity: 0; transition: opacity 120ms linear; }
.rm .sticky-cta.is-shown { opacity: 1; }

/* ----- logo draw-in (homepage, once per visit; owner request 2026-09-30) -----
   The one sanctioned effect on the logo: its own outline paths are traced in
   white, filled white, then the orange parts warm to their final colour. Paint
   properties (stroke, fill) animate here, on a ~360px element, once. */
.logo-draw { pointer-events: none; overflow: visible; }
.logo-draw path {
  fill: rgba(255,255,255,0); stroke: #fff; stroke-width: 1.4; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation:
    logo-stroke 900ms var(--ease-io) var(--d, 0ms) forwards,
    logo-fill 450ms var(--ease) 1250ms forwards,
    logo-final 650ms var(--ease) 1850ms forwards;
}
@keyframes logo-stroke { to { stroke-dashoffset: 0; } }
@keyframes logo-fill { to { fill: #fff; stroke-opacity: 0; } }
@keyframes logo-final { from { fill: #fff; stroke-opacity: 0; } to { fill: var(--final); stroke-opacity: 0; } }

/* ----- cross-page navigation (service pages): a quiet 240ms crossfade,
   nav held still. Browsers without support ignore it. ----- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 240ms; animation-timing-function: var(--ease); }
  .nav { view-transition-name: site-nav; }
  ::view-transition-old(site-nav) { display: none; }
  ::view-transition-new(site-nav) { animation: none; }
}

/* ----- nav condense timings: expand is the base, condense on .is-scrolled ----- */
.motion .nav::before, .motion .nav__inner { transition: transform 520ms var(--ease-io); }
.motion .nav__logo-full { transition: transform 520ms var(--ease-io), opacity 160ms linear; }
.motion .nav__logo-compact { transition: transform 520ms var(--ease-io), opacity 160ms linear 140ms; }
.motion .nav.is-scrolled::before, .motion .nav.is-scrolled .nav__inner { transition: transform 420ms var(--ease-io); }
.motion .nav.is-scrolled .nav__logo-full { transition: transform 420ms var(--ease-io), opacity 160ms linear 120ms; }
.motion .nav.is-scrolled .nav__logo-compact { transition: transform 420ms var(--ease-io), opacity 140ms linear; }
/* reduced motion: the state still changes (logo swap, bar height) but instantly,
   with a short crossfade on the logos only */
.rm .nav::before, .rm .nav__inner, .rm .nav::after { transition: none; }
.rm .nav__logo img { transition: opacity 120ms linear; }
.rm .nav.is-scrolled .nav__logo-full { transform: none; }
.rm .nav__logo-compact, .rm .nav.is-scrolled .nav__logo-compact { transform: none; }
.rm .nav__dd-panel, .rm .nav__dd-panel.is-open { transform: none; transition: opacity 120ms linear, visibility 0s linear 120ms; }
.rm .nav__dd-panel.is-open { transition: opacity 120ms linear, visibility 0s; }
.rm .mobile-menu { transform: none; transition: opacity 120ms linear; }


/* One title per page (owner, 2026-10-01): where a breadcrumb already names the
   page, the eyebrow above the H1 repeated it ("Home / FAQ", "FAQ", then the
   H1). The breadcrumb stays; the repeat goes. */
.page-hero .crumbs ~ .eyebrow, .svc-hero .crumbs ~ .eyebrow, .residents-hero .crumbs ~ .eyebrow { display: none; }

/* ---------- voice-test switch: dev and funny previews only (main.js) ---------- */
.voice-pill { position: fixed; left: 1.4rem; bottom: 1.4rem; z-index: 96; display: flex; gap: 2px; padding: 3px; border-radius: 999px; background: var(--navy); box-shadow: var(--shadow-lift); font-size: .82rem; font-weight: 600; line-height: 1; }
.voice-pill a { padding: .55rem .9rem; border-radius: 999px; color: rgba(255,255,255,.85); text-decoration: none; }
.voice-pill a:hover { color: #fff; }
.voice-pill a[aria-current] { background: #fff; color: var(--navy); }
.voice-pill a:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
@media (max-width: 820px) {
  .voice-pill { left: .75rem; bottom: calc(4.9rem + env(safe-area-inset-bottom, 0px) + .5rem); transition: bottom .25s ease; }
  .in-hero .voice-pill { bottom: calc(10rem + env(safe-area-inset-bottom, 0px)); }  /* clear the hero's example report card */
}
@media print { .voice-pill { display: none; } }

/* =====================================================================
   OWNER, 2026-10-05: "no light on light", stacking pages, the plan route,
   a one-line hero. Appended last so it wins the cascade; one place to read.
   ===================================================================== */

/* ---------- 1. hero: the tagline on ONE line across the skyline ----------
   The line is ~11.9em wide in Space Grotesk 700 at -.035em tracking, so it
   is sized to the container width and never wraps. */
.fly__title {
  max-width: none; white-space: nowrap; text-wrap: nowrap;
  font-size: min(6.6rem, calc(min(1280px, 100vw - 2.5rem) / 12.2));
}
@media (max-width: 820px) { .fly__title { font-size: calc((100vw - 2.5rem) / 12.2); } }
/* phones (owner, 2026-10-14): the tagline wraps to two balanced lines at a
   readable size instead of shrinking to ~28px on one line */
@media (max-width: 560px) { .fly__title { white-space: normal; text-wrap: balance; font-size: clamp(2.4rem, 11vw, 2.9rem); line-height: 1.02; } }
/* the beat chips line up with the kicker pill: same top line, same pill */
.fly__beats { top: clamp(1.25rem, 6vh, 3.5rem); right: max(1.25rem, calc((100vw - 1280px) / 2)); }
.fly__beats li { padding: .32rem .7rem; background: rgba(var(--navy-rgb), .9); font-size: .8rem; line-height: 1.2; }
.fly__kicker { line-height: 1.2; }
.fly__kicker .hl, .fly__kicker-hl { color: var(--orange); }
@media (max-width: 820px) { .fly__beats { left: 1.25rem; right: auto; } }

/* ---------- 2. navy cards: every box that sat light-on-light ----------
   White text, soft-white body, orange labels and numerals. Scoped away from
   navy sections, where a navy card would vanish. */
:root :where(.bento__tile:not(.bento__tile--cta), .stops__item, .promise__rule, .plan__step, .integ__card,
       .makegood, .who__card, .owner-card:not([data-placeholder]), .hub__card, .svc-step,
       .svc-related__card, .timeline li, .price-facts div, .faq__item, .contract-mini, .math__col, .math__note):not(.section--navy *) {
  background: var(--navy); color: #C7D2DE; border-color: transparent;
  box-shadow: var(--shadow-card);
}
:root :where(.bento__name, .stops__item h3, .promise__rule dt, .integ__card h3, .makegood__title, .makegood__steps b,
       .who__card h3, .who__outcome, .owner-card__name, .owner-card__handles, .owner-card__line, .hub__name, .hub__more,
       .svc-step h3, .svc-related__name, .timeline h3, .price-facts dt, .faq__q, .ops dt, .plan__what,
       .math__row b, .math__row--total b, .math__note strong):not(.section--navy *) { color: #fff; }
:root :where(.bento__line, .stops__item p, .promise__rule dd, .integ__card p, .makegood__steps li, .who__card p:last-child,
       .owner-card__bio, .hub__line, .svc-step p, .svc-related__line, .timeline p, .price-facts dd, .faq__a,
       .faq__item--ops .faq__q, .math__row, .math__note p):not(.section--navy *) { color: #C7D2DE; }
:root :where(.bento__badge, .plan__when, .owner-card__role, .owner-card__line span, .svc-step::before,
       .makegood .eyebrow, .math__label, .integ__meta):not(.section--navy *) { color: var(--orange); }
.bento__badge--core, .integ__level { background: var(--orange); color: var(--navy); }
.integ__level::before { color: var(--navy); }
.integ__meta { border-top-color: rgba(255,255,255,.14); }
.integ__meta b { color: #fff; }
.integ__card + .integ__card::before { color: var(--orange); }
.bento__links a, .faq__a a, .math__note a, .contract-mini a, .owner-card a { color: #fff; text-decoration-color: var(--orange); }
.bento__media { background: var(--navy); }
.svc-related__name::after, .hub__more::after { color: var(--orange); }
.svc-step { border-top-color: var(--orange); }
.stops__item { border-top-color: var(--orange); }
.timeline__time { background: var(--orange); color: var(--navy); }
.makegood { border-color: var(--navy); }
.makegood__steps li::before { background: var(--orange); color: var(--navy); }
.owner-card__line { border-top-color: rgba(255,255,255,.14); }
.math__row { border-bottom-color: rgba(255,255,255,.12); }
.math__row--total { border-top-color: var(--orange); }
.math__note { border-left-color: var(--orange); }
.faq__q::after, .section:not(.section--alt):not(.section--navy) .faq__q::after { background: rgba(255,255,255,.12); color: #fff; }
.faq__item[open] { border-color: transparent; box-shadow: 0 0 0 2px var(--orange), 0 18px 40px -22px rgba(var(--navy-rgb), .55); }
.section:not(.section--alt):not(.section--navy) .faq__item { background: var(--navy); }
/* one orange accent per group: the headline fact, the finish line */
.hub__group--core .hub__card, .bento__tile--cta {
  background: var(--orange); color: var(--navy);
}
.hub__group--core .hub__name, .hub__group--core .hub__line, .hub__group--core .hub__more,
.bento__tile--cta .bento__cta-line, .bento__tile--cta .bento__all { color: var(--navy); }
.hub__group--core .hub__more::after { color: var(--navy); }
.bento__tile--cta .btn--primary { background: var(--navy); color: #fff; border-color: var(--navy); }
.bento__tile--cta .btn--primary:hover { background: #fff; color: var(--navy); }
/* the "already under contract?" line becomes a call to action */
.contract-mini { border: 0; color: #fff; }
/* comparison table: a navy data panel */
.compare { background: var(--navy); border-color: transparent; }
.compare__table caption { color: var(--orange); }
.compare__table thead th { background: var(--orange); color: var(--navy); }
.compare__table th, .compare__table td { border-top-color: rgba(255,255,255,.1); }
.compare__table tbody th { color: #fff; }
.compare__table td:nth-child(2) { color: #fff; }
.compare__table td:nth-child(3) { color: #C7D2DE; }
@media (max-width: 700px) {
  .compare__table tr { border-top-color: rgba(255,255,255,.1); }
  .compare__table td::before { color: var(--orange); }
}

/* ---------- 3. tool panels stay white; the page around them goes navy ---------- */
#math, .page-quote .qhead, .qpage, .portal { background: var(--navy); color: #C7D2DE; }
#math h2, #math h3, .page-quote .qhead h1, .portal__intro h2 { color: #fff; }
#math .eyebrow, .page-quote .qhead .eyebrow { color: #9FB0C2; }
#math .section__lede, #math > .container > p, .page-quote .qhead p, .portal__lede, .portal__perks li, .portal__help { color: #C7D2DE; }
#math .math__legal, #math .calc__example > summary, #math .calc__example > summary::after { color: #C7D2DE; }
.portal__help a, .page-quote .qhead a, #math > .container a:not(.btn) { color: #fff; text-decoration-color: var(--orange); }
.page-quote .qhead .crumbs a, .page-quote .qhead .crumbs { color: #C7D2DE; }
.calc, .qform, .qsuccess, .portal__card { box-shadow: 0 30px 60px -30px rgba(0,0,0,.55); border-color: transparent; }
#math .contract-mini { background: var(--orange); color: var(--navy); }
#math .contract-mini a { color: var(--navy); text-decoration-color: var(--navy); }
/* quote options: navy cards in the white form, orange when picked */
.qcard__body { background: var(--navy); border-color: var(--navy); }
.qcard__name { color: #fff; }
.qcard__desc, .qcard__badge { color: #C7D2DE; }
.qcard:hover .qcard__body { border-color: var(--orange); }
.qcard input:checked + .qcard__body { background: var(--orange); border-color: var(--orange); }
.qcard input:checked + .qcard__body .qcard__name { color: var(--navy); }
.qcard input:checked + .qcard__body .qcard__desc, .qcard input:checked + .qcard__body .qcard__badge { color: var(--navy); }

/* ---------- 4. the switch plan: a numbered route, 1 -> 2 -> 3 -> 4 -> 5 ---------- */
.switchplan { padding-top: 1.6rem; }
.switchplan::before { display: none; }
.plan { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 2.2rem; }
.plan__step { position: relative; border-radius: var(--radius); padding: 2.4rem 1.15rem 1.3rem; }
.section--alt .plan__step { box-shadow: 0 18px 40px -22px rgba(var(--navy-rgb), .55); }
.plan__step::before {
  position: absolute; top: -1.4rem; left: 1.15rem; margin: 0;
  width: 2.8rem; height: 2.8rem; font-size: 1.25rem;
  background: var(--orange); color: var(--navy);
  box-shadow: 0 0 0 5px var(--bg);
}
.section--alt .plan__step::before { box-shadow: 0 0 0 5px var(--alt); }
.plan__step:not(:last-child)::after {
  content: "\2192"; position: absolute; top: 50%; right: -1.75rem; translate: 0 -50%;
  width: 1.3rem; text-align: center;
  font: 700 1.5rem/1 var(--font-head); color: rgba(var(--navy-rgb), .35);
}
.plan__when { font-size: .78rem; margin-bottom: .4rem; }
.plan__what { font-family: var(--font-head); font-weight: 700; font-size: 1.02rem; line-height: 1.35; }
@media (max-width: 1100px) {
  /* phones and tablets: a vertical route with a rail */
  .plan { grid-template-columns: 1fr; gap: 1.1rem; padding-left: 3.6rem; position: relative; }
  .plan::before { content: ""; position: absolute; left: 1.35rem; top: .6rem; bottom: .6rem; width: 3px; border-radius: 2px; background: repeating-linear-gradient(180deg, rgba(var(--navy-rgb), .3) 0 10px, transparent 10px 18px); }
  .plan__step { padding: 1.1rem 1.15rem 1.15rem; }
  .plan__step::before { top: 50%; left: -3.6rem; translate: 0 -50%; }
  .plan__step:not(:last-child)::after { content: none; }
}

/* ---------- 5. stacking pages (owner: "the new page sticking and the text
   moving from bottom to top") ----------
   Each full-screen section pins when it fills the screen and the next one
   slides up over it; the incoming section's text rises from the bottom
   faster than the page, and the covered section's text lifts and fades.
   main.js sets each section's sticky `top` (the nav height, or negative for
   a section taller than the screen so its end is read before it pins). */
.motion main > .stage-on { position: sticky; }
.motion main > .stage-on + .stage-on { box-shadow: 0 -28px 50px -26px rgba(0,0,0,.5); }
.stage-on > .container { transform: translate3d(0, var(--sy, 0px), 0) scale(var(--ss, 1)); transform-origin: 50% 0; }

/* ---------- 6. less dead space in the closing band and the make-good ---------- */
.ctaband--final .ctaband__copy h2 { font-size: var(--fs-statement); line-height: 1; letter-spacing: -.03em; max-width: 14ch; }
.ctaband--final .ctaband__inner { gap: clamp(1.6rem, 4vw, 3rem); }
.promise__title { font-size: var(--fs-statement); line-height: 1.02; }
.promise__rule { padding: 1.4rem 1.5rem; }
.promise__rule dt .num { font-size: clamp(2.6rem, 4.4vw, 3.4rem); }
/* fixes from the first screenshot pass */
:root .bento__badge--core, :root .integ__level { color: var(--navy); }
#math .calc h2, #math .calc h3, #math .calc__title { color: var(--navy); }
#math > .container > .contract-mini { color: var(--navy); }
.page-quote .qhead .crumbs [aria-current], .page-quote .qhead .crumbs span { color: #fff; }
/* a stacked page must be opaque: plain sections had no background of their
   own (the white came from <body>), so the pinned page showed through */
:where(.motion main > .stage-on) { background-color: var(--bg); }

/* the plan, illustrated (owner, 2026-10-05: "add more illustrative 1->2"):
   one line icon per step, orange on navy, navy on the orange finish */
:root .plan__step { background-repeat: no-repeat; background-position: right 1rem top 1rem; background-size: 2.4rem; }
@media (min-width: 1101px) { .plan__step { padding: 2.6rem 1.3rem 1.5rem; min-height: 11.5rem; } .plan__what { font-size: 1.12rem; } }
.plan__step:nth-child(1) { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='none' stroke='%23F45313' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M7 25c6 0 5-9 11-9s5 9 9 9'/><circle cx='7' cy='9' r='3'/><path d='M7 12v6'/><circle cx='25' cy='7' r='3'/><path d='M25 10v6'/></svg>"); }
.plan__step:nth-child(2) { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='none' stroke='%23F45313' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='4' y='8' width='24' height='16' rx='2'/><path d='m5 10 11 8 11-8'/></svg>"); }
.plan__step:nth-child(3) { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='none' stroke='%23F45313' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 12h14l-1.5 15h-11z'/><path d='M7 12h18'/><path d='M13 8h6'/><path d='M4 6h5M7 4l2 2-2 2'/><path d='M28 6h-5M25 4l-2 2 2 2'/></svg>"); }
.plan__step:nth-child(4) { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='none' stroke='%23F45313' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='7' y='6' width='18' height='22' rx='2'/><path d='M12 6V4h8v2'/><path d='m11 18 4 4 7-8'/></svg>"); }
.plan__step:nth-child(5) { background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='none' stroke='%23F45313' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 4h10l6 6v18H9z'/><path d='M19 4v6h6'/><path d='M13 16h8M13 20h8M13 24h5'/></svg>"); }
@media (max-width: 1100px) { .switchplan { margin-top: 1.4rem; padding-top: .4rem; } :root .plan__step { padding-right: 4rem; background-position: right 1rem center; background-size: 2rem; } }
/* bigger promise cards so the pinned page reads full */
.promise__rules { gap: 1rem; } .promise__rule dd { font-size: 1.08rem; line-height: 1.55; }
@media (max-width: 1100px) { .switchplan.plan::before { display: block; height: auto; right: auto; } }

/* ---------- service icons (owner, 2026-10-05): one sprite, recoloured per surface ----------
   site/img/icons/services.svg?v=039a0953; the white part is currentColor, the accent is
   --icon-accent (orange by default, white on orange surfaces). */
.svc-ic { display: block; flex: none; color: #fff; --icon-accent: var(--orange); }
.hub__ic { width: 2.8rem; height: 2.8rem; margin-bottom: .35rem; }
.hub__group--core .hub__ic { color: var(--navy); --icon-accent: #fff; }
.nav__dd-list a { grid-template-columns: auto minmax(0, 1fr); column-gap: .75rem; align-items: center; }
.nav__dd-list a > span { grid-column: 2; }
.nav__dd-ic { grid-row: 1 / span 2; width: 1.9rem; height: 1.9rem; color: var(--navy); }
.qcard__ic { width: 2.2rem; height: 2.2rem; margin-bottom: .5rem; }
.qcard input:checked + .qcard__body .qcard__ic { color: var(--navy); --icon-accent: #fff; }
.bento__ic {
  width: 3.4rem; height: 3.4rem; padding: .35rem; margin: -2.6rem 0 .2rem; position: relative; z-index: 1;
  border-radius: 14px; background: var(--navy); box-shadow: 0 10px 24px -10px rgba(0,0,0,.6), 0 0 0 3px rgba(255,255,255,.08);
}
.bento__tile:not(.bento__tile--photo):not(.bento__tile--lead) .bento__ic { margin-top: 0; padding: 0; width: 2.8rem; height: 2.8rem; box-shadow: none; background: none; }
.bento__lnk-ic { display: inline-block; width: 1.25em; height: 1.25em; margin-right: .45em; vertical-align: -.25em; }

/* ---------- hero, two-phase (owner, 2026-10-05) ----------
   The tagline is the highest thing on the page; everything else waits at the
   bottom left with a lot of sky between. Scrolling first lifts that block up
   under the tagline (flyover.js --lift, camera holds), THEN the camera moves
   (--p) and the scene captions take over the bottom left. */
/* Design review (2026-10-14): the tagline and its block read as ONE unit,
   no sky between them, so flyover.js finds nothing to lift and the camera
   answers the first scroll. The hero is shorter by the lift phase it lost
   (the camera keeps the same scroll distance). */
.fly { height: 240vh; }
.fly__content {
  top: clamp(1.5rem, 6vh, 3.5rem); bottom: clamp(2rem, 7vh, 4.5rem);
  display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start;
  gap: clamp(1.1rem, 2.6vh, 1.75rem);
}
.fly__lower { transform: translate3d(0, calc(var(--lift, 0) * var(--lift-d, 0px)), 0); will-change: transform; }
.fly__lower .fly__kicker { margin: 0 0 1rem; }
.fly__lower .fly__sub { margin-top: 0; }
/* scene captions: bottom left, only once the camera is rolling */
.fly__beats { top: auto; right: auto; bottom: clamp(2rem, 7vh, 4.5rem); left: max(1.25rem, calc((100vw - 1280px) / 2)); text-align: left; }
.fly__beats li { left: 0; right: auto; }
.fly__beats { transition: opacity .3s var(--ease-out); }
.fly:not(.fly--rolling) .fly__beats { opacity: 0; }
.fly--static .fly__lower { transform: none; }
@media (max-width: 820px) {
  .fly { height: 215vh; }
  .fly__content { bottom: 2rem; }
  .fly.fly--rolling .fly__beats { opacity: 1; bottom: 1.2rem; left: 1.25rem; }
}
.fly__beats { bottom: clamp(4.6rem, 10vh, 6rem); }
@media (max-width: 820px) {
  /* preview pill: every part of the phone hero is used by the moving text, so it waits until the hero has scrolled away */
  .in-hero .voice-pill { opacity: 0; pointer-events: none; }
  .voice-pill { transition: opacity .25s ease, bottom .25s ease; }
}

/* =====================================================================
   PRE-LAUNCH AUDIT FIXES (2026-10-05). Appended after the owner's
   2026-10-05 block on purpose: several of these have to win the same
   cascade fights it did. Ids are the audit's (B blocker, M major,
   m minor, n nit).
   ===================================================================== */

/* B7: the static hero (reduced motion, Save-Data, 2G/3G, ?noanim) is one
   screen tall. The two-phase heights above (300vh, 260vh at 820px) came
   after `.fly--static { height: auto }` and won, leaving 1,400-1,900px of
   empty navy under the stage. (0,2,0) also beats the 820px rule. */
.fly.fly--static { height: auto; }

/* M10, phones with the flyover running: the caption pill used to hang below
   a zero-height list (top: 0) at bottom: 1.2rem and was clipped by the stage;
   now it stands on that line, 1.2rem inside. The 1px scroll cue crossed the
   CTAs and the first caption. */
@media (max-width: 820px) {
  .fly__beats li { top: auto; bottom: 0; }
  .fly__cue { display: none; }
}
/* At 900px and below the report slip shares the bottom-left corner with the
   captions: once it is on, the captions bow out. flyover.js measures the same
   overlap and holds the slip until the last caption has had its moment. */
@media (max-width: 900px) { .fly.slip-on .fly__beats { opacity: 0; } }

/* M2: the service-page checklist ("What your property gets") joins the navy
   cards; it was white bordered cards on the tint, the light-on-light box the
   owner banned. The check badge flips to orange with a navy tick. */
:root .svc-included li:not(.section--navy *) {
  background: var(--navy); color: #E8EDF3; border-color: transparent;
  box-shadow: 0 18px 40px -22px rgba(var(--navy-rgb), .55);
}
:root .svc-included li:not(.section--navy *)::before { background: var(--orange); }
:root .svc-included li:not(.section--navy *)::after { border-color: var(--navy); }

/* M4: navy-card text the :where() pass above could not reach: it loses to
   older, more specific rules, and a pseudo-element is invalid inside :where()
   (so .svc-step::before was silently dropped from its list). */
.who__card p:last-child:not(.section--navy *) { color: #C7D2DE; }   /* "Who this is for" bodies, 2.93:1 before */
:root .math__row b i:not(.section--navy *) { color: #C7D2DE; }       /* "/mo", "/yr" in the worked example */
:root .svc-step:not(.section--navy *)::before { color: var(--orange); }   /* step numerals 01-04 */
/* "Instant estimate" stays a white pill with a navy label on the navy card;
   `.qcard__badge` in the 2026-10-05 block turned its label #C7D2DE (1.53:1).
   On a picked (orange) card the pill goes navy, or it would vanish. */
.qcard__badge.qcard__badge--instant { color: var(--navy); }
.qcard input:checked + .qcard__body .qcard__badge.qcard__badge--instant { background: var(--navy); color: #fff; }

/* m8: the step and "stops" cards keep their orange top bar; the navy-card
   rule's `border-color: transparent` (0,2,0) erased it and left square top
   corners over rounded bottom ones. */
:root .svc-step:not(.section--navy *), :root .stops__item:not(.section--navy *) { border-top-color: var(--orange); }

/* M5: the contract-check link on the orange strip is navy, like every label
   on orange (white on this orange is 3.45:1). `#math > .container a:not(.btn)`
   in the 2026-10-05 block has the same specificity, so this comes after it.
   The strip also gets room before "Where these numbers come from" (0px gap,
   Gemini review). */
#math > .container .contract-mini a { color: var(--navy); text-decoration-color: var(--navy); }
#math .contract-mini .link-arrow::after { color: var(--navy); }
.contract-mini + .sources { margin-top: 1.6rem; }
/* the disclosure itself: a quiet toggle like "Nerd out on the 400-door
   worked example" above it, small print under it */
#math .sources { font-size: .9rem; line-height: 1.55; color: #B9C6D2; }
#math .sources > summary { cursor: pointer; padding: .4rem .1rem; font: 600 1rem/1.3 var(--font-head); color: #E8EDF3; }
#math .sources > summary:hover { text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: 3px; }
#math .sources > p { margin: .5rem 0 .6rem; }
#math .sources ul { margin: 0; padding-left: 1.2rem; display: grid; gap: .3rem; }
/* #math is navy by id, not .section--navy, so the navy-card rule turned the
   worked example's cards navy on navy. On navy they are navy-raised with a
   white/10% edge, as every other card on navy. */
#math .math__col, #math .math__note { background: var(--navy-raised); border: 1px solid rgba(255,255,255,.1); box-shadow: none; }
#math .math__note { border-left: 4px solid var(--orange); }

/* M4 follow-up, the quote success screen every lead sees: `.form-success`
   (centred, 1rem side padding) came after `.qsuccess` (left, card padding)
   and won, so the numbered next steps sat centred beside left-hanging
   numbers. Back to the intended left-aligned card. */
.form-success.qsuccess { text-align: left; padding: clamp(1.2rem, 3.2vw, 2.2rem); }
.form-success.qsuccess > p { margin-inline: 0; max-width: 40em; }

/* m6: homepage services bento. The text-only tiles stretch to their photo
   neighbours' height. The URO tile's copy now sits at the bottom, level with
   the copy under the photos beside it, and the "rest of the to-do list" links
   become four tappable cards that fill their tile instead of four lines over
   ~200px of empty navy. Cards on navy: navy-raised with a white/10% edge. */
.bento > .bento__tile:not(.bento__tile--lead):not(.bento__tile--photo):not(.bento__tile--more):not(.bento__tile--cta) .bento__badge { margin-top: auto; }
.bento__tile--more .bento__links { flex: 1 1 auto; grid-auto-rows: 1fr; gap: .6rem; margin-top: .5rem; }
.bento__tile--more .bento__links li { display: flex; }
.bento__tile--more .bento__links a {
  flex: 1; display: flex; align-items: center; padding: .8rem 1rem; border-radius: var(--radius-sm);
  background: var(--navy-raised); border: 1px solid rgba(255,255,255,.1); text-decoration: none;
  transition: border-color var(--d1) var(--ease);
}
.bento__tile--more .bento__links a:hover { border-color: var(--orange); text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: 3px; }

/* m11: the closing band's giant H2 (line-height 1) put its descenders 3px
   from the subline. */
.ctaband--final .ctaband__copy h2 { line-height: 1.06; }
.ctaband--final .ctaband__sub { margin-top: 1.1rem; }

/* =====================================================================
   PRE-LAUNCH FIXES, ROUND 2 (2026-10-06): quote-form texting consent,
   the longer footer texting line, and the last m11 wrap rules.
   ===================================================================== */

/* m11: headings already balance (h1-h3 above); these are the card titles
   that set their own font, and the hero ledes that should never end on a
   lone word. */
.svc-step h3, .svc-related__name { text-wrap: balance; }
.svc-hero p { text-wrap: pretty; }
/* the closing band: a touch more air between the giant H2 and its subline */
.ctaband--final .ctaband__sub { margin-top: 1.3rem; }

/* Texting consent on the quote form (A2P 10DLC): p.qhelp.qconsent, the last
   row of the contact grid, holds label[for=f-sms] (the box and the whole
   disclosure) and then the SMS terms and Privacy links. Small print on a
   tinted panel (it sits on the white form card); the box lines up with the
   first line; the label's ::after covers the panel, so the whole panel is
   the tap target and only the two links sit above it; the box gets the
   site's orange focus ring. Written against .qconsent alone, so it also
   holds if the row becomes a div or the links move inside the label. */
.qform .qconsent {
  position: relative; margin: 1.3rem 0 0; padding: .8rem 1rem .85rem 3.1rem;
  border-radius: var(--radius-sm); background: var(--alt);
  font: 400 .84rem/1.55 var(--font-body); color: var(--ink); text-wrap: pretty;
  transition: box-shadow var(--d1) var(--ease);
}
.qform .field-grid > .qconsent { margin-top: .3rem; }
.qform .qconsent label { display: inline; margin: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; }
.qform .qconsent label::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.qform .qconsent b, .qform .qconsent strong { font-weight: 600; color: var(--navy); }
.qform .qconsent input[type="checkbox"] {
  position: absolute; z-index: 1; left: 1rem; top: calc(.8rem + (1.302rem - 24px) / 2);   /* centred on the first line */
  width: 24px; height: 24px; margin: 0; padding: 0; border: 0; border-radius: 4px;
  background: none; box-shadow: none; accent-color: var(--navy); cursor: pointer;
}
.qform .qconsent input[type="checkbox"]:focus { box-shadow: none; }
.qform .qconsent input[type="checkbox"]:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }
.qform .qconsent:has(input:checked) { box-shadow: inset 0 0 0 2px var(--navy); }
.qform .qconsent a {
  position: relative; z-index: 1; color: var(--navy); font-weight: 600; white-space: nowrap;
  text-decoration: underline; text-decoration-color: var(--orange); text-decoration-thickness: 2px; text-underline-offset: 2px;
}
.qform .qconsent a:hover { text-decoration-color: var(--navy); }

/* Footer: the texting line now carries frequency, rates, STOP/HELP and two
   links. Small print, but legible: a touch larger, real line height, links
   in the body face and never split ("SMS / terms"). */
.footer__contact .footer__sms { margin: -.2rem 0 .3rem; font-size: .8rem; line-height: 1.5; max-width: 30em; text-wrap: pretty; }
.footer__contact .footer__sms a { font-family: inherit; font-weight: 500; padding: 0; min-height: 0; white-space: nowrap; }
.footer__legal p { line-height: 1.6; text-wrap: pretty; }

/* ---------- PRE-LAUNCH VERIFY FIXES (2026-10-06) ---------- */
/* The site's focus ring is orange, which vanishes on an orange ground (WCAG 2.4.7):
   on every orange band or card, focus goes navy. */
.ctaband :focus-visible, .bento__tile--cta :focus-visible,
#math .contract-mini :focus-visible, .plan__step:last-child :focus-visible { outline-color: var(--navy); }
/* "All services" arrow was orange on the orange strip */
.bento__tile--cta .link-arrow::after { color: var(--navy); }

/* =====================================================================
   DESIGN REVIEW (2026-10-14): one system, fewer competing sections.
   Tokens are at the top of this file (--fs-*, --space-*, --radius-btn,
   --radius-card, --card-pad, --shadow-card). This block applies them to the
   shared components and lays out the homepage's merged sections. The
   report (#report, .mock, .statuses), the quote flow (.q*) and Dessa
   (.askr*) are deliberately not touched here.
   ===================================================================== */

/* ---------- cards: one radius, one shadow, no accent bars ---------- */
:root :where(.stops__item, .plan__step, .integ__card, .who__card, .hub__card, .svc-step, .svc-related__card,
       .timeline li, .faq__item, .svc-included li, .math__col, .contract-mini, .makegood):not(.section--navy *) {
  border-radius: var(--radius-card);
}
:root .svc-step:not(.section--navy *), :root .stops__item:not(.section--navy *) { border-top: 0; }
/* labels on cards and eyebrows share one size */
.bento__badge, .plan__when, .owner-card__role, .integ__level, .math__label, .calc__label,
.timeline__time, .compare__table caption, .fly__slip-tag { font-size: var(--fs-label); }

/* ---------- a section's closing row (services: the line, the action, the index) ---------- */
.section__foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: .9rem 1.6rem;
  margin-top: var(--space-head); padding-top: 1.5rem; border-top: 1px solid rgba(var(--navy-rgb), .14);
}
.section__foot-line { flex: 1 1 22rem; margin: 0; font: 700 1.15rem/1.35 var(--font-head); color: var(--navy); }
/* One CTA on screen (owner, 2026-10-14): the services row points at the
   header's "Price my property" (the bottom bar's on phones) instead of
   repeating it, and main.js pulses that button when the row arrives. */
.cta-cue { display: inline-flex; align-items: center; gap: .5rem; font: 700 1rem/1.2 var(--font-head); color: var(--navy); text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: .25em; }
.cta-cue__down { display: none; }
.cta-cue__arrow::before { content: "\2191"; display: inline-block; color: var(--orange); font-size: 1.2rem; }
@media (max-width: 820px) {
  .cta-cue__up { display: none; }
  .cta-cue__down { display: inline; }
  .cta-cue__arrow::before { content: "\2193"; }
}
html.motion .cta-cue__arrow::before { animation: cue-up 1.6s var(--ease-io) infinite; }
@media (max-width: 820px) { html.motion .cta-cue__arrow::before { animation-name: cue-down; } }
@keyframes cue-up { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes cue-down { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
html.motion .cta-ping { animation: cta-ping .55s var(--ease-out) 2; }
@keyframes cta-ping { 0%, 100% { transform: scale(1); } 45% { transform: scale(1.08); } }

/* ---------- homepage: why switch, an editorial split ---------- */
.why { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-head) clamp(2rem, 5vw, 4.5rem); align-items: start; }
.why__head h2 { margin: 0; }
.why .stops { grid-template-columns: 1fr; margin: 0; gap: .9rem; }
.why .stops__item { padding: var(--card-pad); }
.why .stops__item h3 { margin: 0 0 .4rem; }
@media (max-width: 900px) { .why { grid-template-columns: 1fr; } }

/* ---------- homepage: the switch plan and the make-good, one story ----------
   The steps first, then the promise that backs every night after launch, as
   ONE navy panel on the tint (the section's accent; no orange fills). */
#switch-plan .switchplan__foot { margin-top: 1.6rem; }
.promise {
  margin-top: var(--space-head); padding: clamp(1.6rem, 4vw, 3rem);
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 1.4rem clamp(2rem, 5vw, 4.5rem); align-items: center;
  background: var(--navy); color: #C7D2DE; border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
}
.promise .eyebrow { color: #9FB0C2; }
.promise .promise__title { color: #fff; }
.promise .promise__rules { gap: 0; }
#switch-plan .promise__rule {
  background: none; box-shadow: none; border-radius: 0; padding: 1.15rem 0;
  border-top: 1px solid rgba(255,255,255,.14); grid-template-columns: 8.5rem minmax(0, 1fr);
}
#switch-plan .promise__rule:first-child { border-top: 0; padding-top: 0; }
#switch-plan .promise__rule:last-child { padding-bottom: 0; }
#switch-plan .promise__rule dt { color: #fff; }
#switch-plan .promise__rule dt .num { font-size: clamp(2.2rem, 3.6vw, 2.9rem); }
#switch-plan .promise__rule dd { color: #C7D2DE; font-size: 1.02rem; }
.promise .promise__more { margin-top: .4rem; }
.promise .link-arrow { color: #fff; }
@media (max-width: 860px) { .promise { grid-template-columns: minmax(0, 1fr); } .promise .promise__more { grid-column: auto; } }
@media (max-width: 480px) { #switch-plan .promise__rule { grid-template-columns: 1fr; gap: .25rem; } }

/* ---------- the closing band: one link each to the FAQ and pricing ---------- */
.ctaband__sub a { color: var(--navy); font-weight: 600; text-decoration-color: var(--navy); text-decoration-thickness: 1.5px; }
.ctaband__sub a:hover { text-decoration-thickness: 2.5px; }

/* ---------- owner, 2026-10-13 ----------
   Hero: the subhead and the value line run the width of the block (the title
   keeps its 11ch column); the since-2012 pill closes the block under the
   buttons, orange with navy text (5.25:1), where "Prefer a human?" was.
   Around the property: four photo cards with the icon over the picture. */
.fly__lower .fly__sub { max-width: none; width: min(100%, 66rem); margin-bottom: 1rem; }
.fly__lower .fly__value { max-width: none; margin: 0 0 1.6rem; }
/* owner, 2026-10-14: room between the tagline and the block under it, and
   "Still weirdly into it." in orange beside (not inside) the navy pill */
.fly__lower { margin-top: clamp(1.4rem, 3.2vw, 2.6rem); }
.fly__since { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem .85rem; margin: 0 0 1rem; }
.fly__since .fly__kicker { margin: 0; }
.fly__since-hl {
  display: inline-block; padding: .32rem .75rem; border-radius: 999px; background: rgba(var(--navy-rgb), .9);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12);
  font: 700 .95rem/1.2 var(--font-head); color: var(--orange);
}
/* the punchline lands a beat after the pill: transform and opacity only */
html.motion .fly__since-hl { animation: since-punch .55s var(--ease-out) .9s both; }
@keyframes since-punch { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: none; } }
/* owner, 2026-10-14: the since-2012 pill and "Prefer a human?" line are back
   as on the funny branch: navy pill under the subline, orange value dots */
@media (max-width: 1100px) { .fly__lower .fly__sub, .fly__lower .fly__value { max-width: 34em; } }
/* phones: the three value points stack as a short list, and the two buttons
   share one width, so the block reads as a column, not a ragged wrap */
@media (max-width: 560px) {
  .fly__lower .fly__value { flex-direction: column; gap: .3rem; margin-bottom: 1.3rem; }
  .fly__lower .fly__value span, .fly__lower .fly__value span + span:last-child {
    white-space: normal; padding-left: 1.05rem; text-indent: -1.05rem;
  }
  .fly__value span::before, .fly__value span + span::before {
    content: ""; display: inline-block; width: 5px; height: 5px; margin-right: calc(1.05rem - 5px); border-radius: 50%;
    background: rgba(255,255,255,.5); vertical-align: .2em;
  }
  .fly__ctas { flex-direction: column; align-items: stretch; width: 100%; max-width: 22rem; }
  .fly__ctas .btn { text-align: center; }
}

.bento__tile--more .bento__links { gap: .9rem; margin-top: .8rem; }
.bento__tile--more .bento__links a {
  position: relative; flex-direction: column; align-items: flex-start; justify-content: flex-end;
  min-height: 11rem; padding: 1rem 1.1rem; overflow: hidden; isolation: isolate; border-color: rgba(255,255,255,.14);
}
.bento__lnk-img {
  position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover;
  opacity: .5; transition: transform 700ms var(--ease-out), opacity 300ms var(--ease);
}
.bento__tile--more .bento__links a::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(var(--navy-rgb), .2) 0%, rgba(var(--navy-rgb), .78) 60%, rgba(var(--navy-rgb), .94) 100%);
}
.bento__tile--more .bento__links a:hover .bento__lnk-img { transform: scale(1.04); opacity: .62; }
.bento__tile--more .bento__lnk-ic { width: 2.6rem; height: 2.6rem; margin: 0 0 .55rem; vertical-align: 0; filter: drop-shadow(0 2px 6px rgba(0,0,0,.5)); }
.bento__lnk-txt { display: block; line-height: 1.3; }
.bento__lnk-txt b { display: block; font-family: var(--font-head); font-weight: 700; font-size: 1.08rem; color: #fff; }
.bento__lnk-txt small { display: block; margin-top: .15rem; font-size: .86rem; font-weight: 500; color: #D5DEE8; }
.bento__tile--more .bento__links a:hover .bento__lnk-txt b { text-decoration: underline; text-decoration-color: var(--orange); text-underline-offset: 3px; }
.bento__tile--more .bento__links a:hover { text-decoration: none; }
@media (max-width: 600px) { .bento__tile--more .bento__links a { min-height: 8.5rem; } }

/* /services/ hub cards carry the service photo (owner, 2026-10-13), the icon
   overlapping it the way the homepage photo tiles do. */
.hub__card--photo { padding-top: 0; overflow: hidden; }
.hub__media { display: block; margin: 0 -1.35rem .2rem; }
.hub__media img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.hub__card--photo .hub__ic {
  width: 3.4rem; height: 3.4rem; padding: .35rem; margin: -2.4rem 0 .2rem; position: relative; z-index: 1;
  border-radius: 14px; background: var(--navy); box-shadow: 0 10px 24px -10px rgba(0,0,0,.6), 0 0 0 3px rgba(255,255,255,.08);
  color: #fff; --icon-accent: var(--orange);
}
.hub__group--core .hub__card--photo .hub__ic { box-shadow: 0 10px 24px -10px rgba(0,0,0,.6), 0 0 0 3px rgba(var(--navy-rgb),.15); }
.motion .hub__media img { transition: transform 700ms var(--ease-out); }
.motion .hub__card:hover .hub__media img { transform: scale(1.03); }

/* =====================================================================
   Design critique fixes (owner approved, 2026-10-14)
   ===================================================================== */
/* closing bands: the button sits right under the headline at full size,
   with call and text beside it, on every page */
.ctaband__inner { flex-direction: column; align-items: flex-start; justify-content: flex-start; }
.ctaband__actions { flex-direction: row; flex-wrap: wrap; align-items: center; gap: .9rem 1.5rem; }
.ctaband__actions .btn { padding: 1rem 1.75rem; font-size: 1.05rem; }
/* pricing: orange only for the button and the closing band */
#math .contract-mini, #math > .container > .contract-mini { background: var(--navy-deep); color: #fff; box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); }
#math .contract-mini a, #math > .container .contract-mini a { color: #fff; text-decoration-color: var(--orange); }
#math .contract-mini .link-arrow::after { color: var(--orange); }
#math .contract-mini :focus-visible { outline-color: var(--orange); }
.compare__table caption { color: #C7D2DE; }
.compare__table thead th { background: var(--navy-deep); color: #fff; }
/* services hub: the core service and what's included share one row */
@media (min-width: 821px) {
  .hub > .container { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(1rem, 2.4vw, 1.6rem); }
  .hub__group--addon, .hub__group--seasonal { grid-column: 1 / -1; }
  .hub__group--included { margin-top: 0 !important; }
  .hub__group--core .hub__grid, .hub__group--included .hub__grid { grid-template-columns: minmax(0, 1fr); }
}
/* sample report on phones: exceptions first, the building table folds */
.mock__fold > summary { list-style: none; cursor: default; }
.mock__fold > summary::-webkit-details-marker { display: none; }
@media (max-width: 620px) {
  .mock--full { display: flex; flex-direction: column; }
  .mock--full .mock__section--exs { order: 1; }
  .mock--full .mock__body { order: 2; }
  .mock--full .mock__summary { order: 3; }
  .mock--full .mock__foot { order: 4; }
  .mock__fold > summary { cursor: pointer; display: flex; align-items: center; justify-content: space-between; }
  .mock__fold > summary::after { content: "+"; font: 700 1.2rem/1 var(--font-head); color: var(--navy); padding-left: .6rem; }
  .mock__fold[open] > summary::after { content: "\2212"; }
}
/* hero: white "Prefer a human?" so it holds over the lit wall */
.fly__call { color: #fff; }
/* homepage: one orange CTA on screen; the header button waits until the
   hero's own button has scrolled away */
.nav__cta { transition: opacity var(--d2) var(--ease-out), transform var(--d2) var(--ease-out), visibility 0s; }
html.hero-cta-on .nav__cta { opacity: 0; transform: translateY(-6px); visibility: hidden; transition: opacity var(--d2) var(--ease-out), transform var(--d2) var(--ease-out), visibility 0s var(--d2); }
/* residents portal: the perks are labelled as coming (brand review, 2026-10-14) */
.portal__coming { margin: 1rem 0 .4rem; font: 700 .8rem/1.3 var(--font-head); letter-spacing: .12em; text-transform: uppercase; color: #C7D2DE; }
/* hero value points: a short stacked list below 1100px, so no line ever
   starts with a separator dot (design critique, 2026-10-14) */
@media (max-width: 1100px) {
  .fly__lower .fly__value { flex-direction: column; gap: .3rem; }
  .fly__lower .fly__value span, .fly__lower .fly__value span + span:last-child { white-space: normal; padding-left: 1.05rem; text-indent: -1.05rem; }
  .fly__value span::before, .fly__value span + span::before {
    content: ""; display: inline-block; width: 5px; height: 5px; margin-right: calc(1.05rem - 5px); border-radius: 50%;
    background: rgba(255,255,255,.5); vertical-align: .2em;
  }
}
/* hero: the text column stays left of the downtown skyline (owner,
   2026-10-15): the subline and pills wrap onto more lines instead of
   running across the towers; the tagline keeps its full width in the sky */
@media (min-width: 561px) {
  .fly__lower { max-width: max(min(40%, 32rem), 24rem); }
  .fly__lower .fly__sub { width: auto; }
}
/* the since-2012 pill never breaks, and the value points are a stacked list
   at every width now that the column is narrow (owner, 2026-10-15) */
.fly__kicker { white-space: nowrap; }
.fly__lower .fly__value { flex-direction: column; gap: .3rem; }
.fly__lower .fly__value span, .fly__lower .fly__value span + span:last-child { white-space: normal; padding-left: 1.05rem; text-indent: -1.05rem; }
.fly__lower .fly__value span::before, .fly__lower .fly__value span + span::before {
  content: ""; display: inline-block; width: 5px; height: 5px; margin-right: calc(1.05rem - 5px); border-radius: 50%;
  background: rgba(255,255,255,.5); vertical-align: .2em;
}

/* owner, 2026-10-15: back to the 10-05 sequence. The text block starts at
   the bottom left, over the dark left building, with the skyline clear; the
   first stretch of scroll lifts it up under the tagline while the camera
   holds (flyover.js measures the gap and turns the lift phase on), then the
   camera flies. The hero gets its lift distance back. */
.fly { height: 300vh; }
@media (max-width: 820px) { .fly { height: 260vh; } }
.fly__content { justify-content: space-between; gap: 0; }
.fly__lower { margin-top: 0; }
/* the punchline under the tagline (owner, 2026-10-15): small italic orange,
   right-aligned to the tagline's end, typed once by main.js */
.fly__head { max-width: 100%; }
@media (min-width: 561px) { .fly__head { width: fit-content; } }
.fly__aside {
  margin: .4rem 0 0; text-align: right; color: var(--orange);
  font: italic 400 clamp(1.05rem, 1.7vw, 1.45rem)/1.3 var(--font-body); letter-spacing: .005em;
  text-shadow: 0 1px 12px rgba(var(--navy-rgb), .7);
}
.fly__ch { opacity: 0; }
.fly__ch.on { opacity: 1; }
.fly__caret { display: inline-block; width: 0; height: 1.05em; margin-left: 1px; border-left: 2px solid var(--orange); vertical-align: -.17em; animation: caret-blink .55s steps(1) infinite; }
@keyframes caret-blink { 50% { opacity: 0; } }
/* punchline style (owner pick, 2026-10-15): a navy text bubble, like a reply
   to the tagline; white italic, one squared corner toward the tagline. The
   bubble fades in, then the words type inside it (main.js). */
.fly__aside { color: #fff; font-size: clamp(1.05rem, 1.8vw, 1.5rem); text-shadow: none; }
.fly__bubble {
  display: inline-block; padding: .45rem .9rem; border-radius: 14px 4px 14px 14px;
  background: rgba(var(--navy-rgb), .92); box-shadow: inset 0 0 0 1px rgba(255,255,255,.16), 0 10px 24px -12px rgba(0,0,0,.7);
}
.fly__aside .fly__caret { border-left-color: #fff; }
html.motion .fly__bubble { animation: bubble-in .4s var(--ease-out) .6s both; }
@keyframes bubble-in { from { opacity: 0; transform: translateY(6px) scale(.97); } to { opacity: 1; transform: none; } }

