/* TraceBIM — shared stylesheet for the standalone static marketing pages
   (segment landing pages, the proof page, the permit-set checklist).
   =====================================================================

   WHY THIS FILE EXISTS
   --------------------
   These pages live in `apps/web/public/` and are served straight out of it.
   They are NOT Vite build inputs, so they cannot import a hashed bundle and
   cannot reach the <style> block inside `apps/web/index.html`. Before this
   file, the only way to make a new page look like the homepage was to
   copy-paste the homepage's CSS into it — which is how a design system rots:
   five pages, five drifting copies of `--accent`.

   So: one plain .css file, referenced with <link rel="stylesheet" href="/site.css">.

   THE CONTRACT WITH index.html
   ----------------------------
   The tokens and component class names below are deliberately IDENTICAL to the
   ones in `apps/web/index.html`. That is the point. A page author can lift a
   block of markup out of the homepage — the nav, a `.feature-card`, the CTA
   panel, the footer — drop it into a new static page, and it renders the same.
   If you change a token here, change it in index.html in the same commit, or
   the homepage and the landing pages start looking like two products.

   Cached like any static asset with no content hash: see `public/_headers`.
   `/site.css` is not listed there, so it gets Cloudflare's default. If a token
   change ever needs to land instantly alongside an HTML change, add a
   `no-cache` rule for it there rather than inventing a `?v=` query string —
   the _headers comment explains why query-string busting is banned site-wide.

   HOW THE PAGES ARE EXPECTED TO BE STRUCTURED
   -------------------------------------------
     <header id="nav"> .container.nav-inner > .nav-brand + .nav-links + .nav-auth + .nav-burger
     <div id="mobile-menu">                     (toggled by adding .open — 6 lines of inline JS)
     <section class="page-hero">                (shorter than the homepage's #hero; no demo reel)
     <section> / <section class="band-surface"> / <section class="band-dark">
     <footer>  .container > .footer-grid + .footer-legal

   NO-JS IS THE DEFAULT HERE
   -------------------------
   The homepage runs `landing.ts`, which adds `.scrolled` to the nav, swaps the
   auth buttons for an account chip, and drives scroll-reveal. These pages ship
   no module. Everything below therefore renders correctly with zero JavaScript;
   the JS-driven states (`.scrolled`, `.open`, `.reveal.in`) are still honoured
   so a page CAN opt in, but nothing depends on them.
*/

/* ── Tokens ──────────────────────────────────────────────────────────────
   Copied verbatim from index.html. Do not "improve" one copy in isolation. */
:root {
  --paper:        #faf9f7;   /* warm architectural paper */
  --surface:      #ffffff;
  --ink:          #17181c;
  --ink-soft:     #3c4046;
  --muted:        #5f646c;
  --dim:          #6b7079;   /* 4.73:1 on --paper. Was #8a8f97 = 3.09:1, and this
                                token colours .source, .footer-disclaimer and every
                                claims caveat, so it must clear AA. */
  --hairline:     #e7e4de;
  --hairline-2:   #efece6;

  --accent:       #d15408;
  --accent-hover: #b8480a;
  --accent-soft:  #fdf0e6;
  --accent-line:  #f3d9c4;

  --redline:      #b91c1c;
  --blueprint:    #29527a;
  --go:           #1a7f37;   /* the "verified / included" green used on the homepage */

  --dark-bg:      #14171c;
  --dark-panel:   #1b1f26;
  --dark-line:    #2a2f38;
  --dark-text:    #e9ecef;
  --dark-muted:   #9aa2ad;

  --font-ui:      'Inter', 'Segoe UI', system-ui, sans-serif;
  --font-display: 'Fraunces', Georgia, serif;
  --font-mono:    'Cascadia Code', 'SFMono-Regular', Consolas, monospace;

  --radius:       10px;
  --radius-lg:    16px;
  --shadow-card:  0 1px 2px rgba(23,24,28,0.05), 0 8px 28px rgba(23,24,28,0.07);
  --shadow-pop:   0 12px 48px rgba(23,24,28,0.18);
  --container:    1120px;

  /* Pin the UA to the light palette. WHY: these pages must match the homepage,
     and the homepage is a fixed warm-paper design — it has no system dark mode.
     Without this, iOS/Android auto-darkening recolours form controls, <hr> and
     scrollbars on the landing pages only, and the family breaks. Dark is a
     deliberate SECTION treatment here (`.band-dark`, `.cta-panel`), exactly as
     on the homepage — not a whole-page system flip.

     This is intentionally different from privacy.html / terms.html / aup.html,
     which DO follow `prefers-color-scheme`. Those are legal documents read for
     content; these are storefront pages read for brand. Different jobs. */
  color-scheme: light;
}

/* Fraunces + Inter are loaded by each page's own <link> to Google Fonts (same
   two families and weights as index.html). The stacks above degrade to Georgia
   and the system UI font if that request is blocked, so text never reflows into
   something unreadable. */

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

html { scroll-behavior: smooth; }
/* Anchored sections must stop BELOW the fixed nav, not under it. */
section[id], h2[id], h3[id] { scroll-margin-top: 84px; }

body {
  font-family: var(--font-ui);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Belt and braces against a wide child (a long URL, an over-wide table)
     dragging the whole document sideways on a phone. */
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }
button { font-family: inherit; cursor: pointer; }

/* Keyboard focus must stay visible everywhere. The homepage relies on the UA
   ring; state it explicitly here so the accent-coloured surfaces below don't
   swallow it. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Visible to a screen reader, not on screen. Used for the <legend> on the
   seats form and the <label> on the checklist's email field — both are real
   labels that the visual design already answers with surrounding copy, so
   hiding them keeps the page readable without leaving the control unnamed.
   Both spellings are defined because both are already in the markup; they are
   the same rule, not two components. `clip-path` is what current browsers
   honour, `clip` is kept for older WebKit. Never put an interactive element in
   here without a matching `:focus` escape — a keyboard user would lose it. */
.sr-only,
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  /* Side gutter also clears the notch on a landscape iPhone, since the pages
     use `viewport-fit=cover` like index.html does. */
  padding-left: max(24px, env(safe-area-inset-left));
  padding-right: max(24px, env(safe-area-inset-right));
}
/* Narrow measure for long-form reading (the checklist and the proof write-up).
   ~68ch is where line length stops fighting the reader. */
.container-narrow { max-width: 780px; }

/* ── Buttons ─────────────────────────────────────────────────────────────
   Same API as the homepage: .btn + one of .btn-primary/.btn-ghost/.btn-dark,
   optionally .btn-lg/.btn-sm. Works on <a> and <button> alike. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 22px;
  border-radius: 8px;
  font-size: 14.5px; font-weight: 600;
  border: 1px solid transparent;
  transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.15s, box-shadow 0.15s;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: var(--accent-hover); color: #fff;
  box-shadow: 0 1px 2px rgba(209,84,8,0.35), 0 6px 18px rgba(209,84,8,0.22);
}
.btn-primary:hover { background: #9c3d08; }
.btn-ghost {
  background: transparent; color: var(--ink-soft);
  border-color: var(--hairline);
}
.btn-ghost:hover { border-color: var(--dim); color: var(--ink); background: var(--surface); }
.btn-dark { background: var(--ink); color: #fff; }
.btn-dark:hover { background: #2b2e35; }
.btn-lg { padding: 14px 28px; font-size: 15.5px; border-radius: 10px; }
.btn-sm { padding: 8px 16px; font-size: 13.5px; }
/* A CTA row that wraps instead of overflowing when two long labels meet a
   360px screen. */
.btn-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* ── Nav ─────────────────────────────────────────────────────────────────
   Structurally identical to the homepage header so the markup is copy-able.
   One deliberate difference: the hairline is ALWAYS on. The homepage hides it
   until `landing.ts` adds `.scrolled`; these pages run no script, so a border
   that never arrives would leave the nav floating over the content. */
#nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: rgba(250,249,247,0.92);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid var(--hairline);
  padding-top: env(safe-area-inset-top);
}
.nav-inner { display: flex; align-items: center; gap: 28px; height: 64px; }
.nav-brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 16.5px; letter-spacing: -0.2px; }
.nav-brand img, .nav-brand svg { width: 26px; height: 26px; }
.nav-brand img { border-radius: 7px; }
.nav-links { display: flex; align-items: center; gap: 4px; margin-left: 8px; }
.nav-links a {
  padding: 8px 12px; border-radius: 8px;
  font-size: 14px; font-weight: 500; color: var(--muted);
  transition: color 0.12s, background 0.12s;
}
.nav-links a:hover { color: var(--ink); background: var(--hairline-2); }
/* The page you are already on. Saves a visitor re-clicking their own segment. */
.nav-links a[aria-current="page"] { color: var(--ink); background: var(--hairline-2); }
.nav-auth { margin-left: auto; display: flex; align-items: center; gap: 10px; }

/* Mobile hamburger. A page opting in toggles `.open` on #mobile-menu and flips
   aria-expanded on the button — the same contract index.html uses. */
.nav-burger {
  display: none;
  margin-left: auto;
  width: 40px; height: 40px;
  background: transparent; border: 1px solid var(--hairline); border-radius: 8px;
  align-items: center; justify-content: center;
}
.nav-burger svg { width: 18px; height: 18px; }
#mobile-menu {
  display: none;
  border-top: 1px solid var(--hairline);
  background: var(--paper);
  padding: 10px 24px 18px;
  /* A long menu on a short phone must scroll rather than run off the screen. */
  max-height: calc(100vh - 64px); overflow-y: auto;
}
#mobile-menu.open { display: block; }
#mobile-menu > a {
  display: block; padding: 11px 4px;
  font-size: 15px; font-weight: 500; color: var(--ink-soft);
  border-bottom: 1px solid var(--hairline-2);
}
#mobile-menu .mobile-auth { display: flex; gap: 10px; padding-top: 14px; }
#mobile-menu .mobile-auth .btn { flex: 1; }

/* Pages that open on plain prose rather than a hero still have to clear the
   64px fixed nav. `.page-hero` carries its own offset, so this is only for the
   other case. */
.below-nav { padding-top: 96px; }

/* ── Page hero ───────────────────────────────────────────────────────────
   The homepage hero is a two-column layout built around the demo reel. These
   pages have no reel, so the hero is a single measured column: eyebrow, title,
   two paragraphs, CTAs, and a caveat line. The caveat is a first-class element
   on purpose — on the homeowner page the permit-rules-are-local line has to be
   above the fold, not in the footer. */
.page-hero {
  position: relative;
  padding: 136px 0 64px;
  overflow: hidden;
}
/* The same faint drafting grid as the homepage hero, masked so it fades out
   before it reaches the body copy. */
.page-hero::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, rgba(41,82,122,0.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(41,82,122,0.05) 1px, transparent 1px);
  background-size: 48px 48px;
  -webkit-mask-image: radial-gradient(ellipse 90% 80% at 50% 0%, #000 40%, transparent 100%);
  mask-image: radial-gradient(ellipse 90% 80% at 50% 0%, #000 40%, transparent 100%);
  pointer-events: none;
}
.page-hero > .container { position: relative; }
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  font-size: 12.5px; font-weight: 600; color: var(--accent-hover);
  letter-spacing: 0.2px;
  margin-bottom: 22px;
}
.hero-eyebrow .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(209,84,8,0.18);
}
.hero-title {
  font-family: var(--font-display);
  font-size: clamp(34px, 4.6vw, 52px);
  font-weight: 600;
  line-height: 1.07;
  letter-spacing: -0.02em;
  max-width: 17em;
  margin-bottom: 22px;
}
.hero-title .accent { color: var(--accent); }
.hero-sub {
  font-size: 17.5px; color: var(--muted);
  max-width: 33em; line-height: 1.65;
  margin-bottom: 20px;
}
.hero-sub:last-of-type { margin-bottom: 32px; }
.hero-note {
  margin-top: 16px;
  font-size: 13px; color: var(--dim);
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
}
.hero-note svg { width: 14px; height: 14px; color: var(--go); flex-shrink: 0; }

/* Breadcrumb back to the homepage. Segment pages are entry points from search,
   so a visitor may land here having never seen "/". */
.crumbs { font-size: 13px; color: var(--dim); margin-bottom: 18px; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--accent-hover); }
.crumbs span { margin: 0 7px; }

/* ── Sections and bands ──────────────────────────────────────────────────
   Three backgrounds, same as the homepage: paper (default), surface (white,
   hairlined top and bottom), and dark. Alternate them; don't stack two of the
   same in a row or the page reads as one undifferentiated column. */
section { padding: 84px 0; }
.band-surface {
  background: var(--surface);
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
.band-dark { background: var(--dark-bg); color: var(--dark-text); }
.band-dark .sec-eyebrow { color: #f0904d; }   /* the accent is unreadable on --dark-bg */
.band-dark .sec-sub, .band-dark p { color: var(--dark-muted); }
.band-dark a { color: #f0904d; }
.band-dark .btn-ghost { color: var(--dark-text); border-color: var(--dark-line); }
.band-dark .btn-ghost:hover { background: var(--dark-panel); border-color: var(--dark-muted); }

.sec-eyebrow {
  font-size: 12.5px; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent);
  margin-bottom: 14px;
}
.sec-title {
  font-family: var(--font-display);
  font-size: clamp(26px, 3.2vw, 38px);
  font-weight: 600; line-height: 1.15; letter-spacing: -0.015em;
  max-width: 22em;
  margin-bottom: 16px;
}
.sec-sub { font-size: 16.5px; color: var(--muted); max-width: 42em; }
.sec-head { margin-bottom: 48px; }
.sec-head.centered { text-align: center; }
.sec-head.centered .sec-title, .sec-head.centered .sec-sub { margin-left: auto; margin-right: auto; }

/* Scroll-reveal, kept for parity. With no script the `.in` class never
   arrives — so the base state must be VISIBLE here, the opposite of the
   homepage, or a no-JS page renders blank. A page that wires up an
   IntersectionObserver can add `.reveal-armed` to <html> to get the animation. */
.reveal { opacity: 1; transform: none; }
.reveal-armed .reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal-armed .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal-armed .reveal { opacity: 1; transform: none; transition: none; }
}

/* ── Stats ribbon ────────────────────────────────────────────────────────
   Four short claims between hero and body. Every number in one of these must
   come from the repo with its caveat attached — see the claims discipline in
   docs/pitch/MARKETING_AUDIT_AND_STRATEGY.md §2.8. If there is no source,
   write a qualitative claim instead of inventing a figure. */
.ribbon {
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  background: var(--surface);
}
.stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; padding: 26px 0; }
.stat b { display: block; font-size: 15.5px; font-weight: 700; letter-spacing: -0.2px; }
.stat span { font-size: 13px; color: var(--muted); }

/* ── Card grid ───────────────────────────────────────────────────────────
   `.card-grid` is the generic three-up; `.feature-grid` is kept as the alias
   the homepage markup already uses, so pasted blocks work unchanged.
   `.cols-2` / `.cols-4` cover the other counts without a new component. */
.card-grid, .feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.card-grid.cols-2, .feature-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.card-grid.cols-4, .feature-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }

.card, .feature-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: 26px 24px;
  transition: box-shadow 0.2s, transform 0.2s, border-color 0.2s;
}
.card:hover, .feature-card:hover { box-shadow: var(--shadow-card); transform: translateY(-2px); border-color: #dcd8d0; }
/* On a `.band-surface` the white card would vanish into a white band, so it
   swaps to paper. Same trick the homepage uses for `.step`. */
.band-surface .card, .band-surface .feature-card { background: var(--paper); }
.band-dark .card, .band-dark .feature-card { background: var(--dark-panel); border-color: var(--dark-line); }
.band-dark .card:hover, .band-dark .feature-card:hover { border-color: #3a4150; }

.card-icon, .feature-icon {
  width: 42px; height: 42px; border-radius: 11px;
  background: var(--accent-soft); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 18px;
}
.card-icon svg, .feature-icon svg { width: 21px; height: 21px; }
.card h3, .feature-card h3 { font-size: 16.5px; font-weight: 650; margin-bottom: 8px; letter-spacing: -0.2px; }
.card p, .feature-card p { font-size: 14px; color: var(--muted); line-height: 1.65; }
.card p + p { margin-top: 10px; }
.band-dark .card h3, .band-dark .feature-card h3 { color: var(--dark-text); }

/* Numbered steps — the "how it works" ladder. `.steps` counts for you; the
   number is markup-free so reordering steps can't leave a stale "3." behind. */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; counter-reset: step; }
.step {
  position: relative;
  counter-increment: step;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: 28px 26px 26px;
}
.band-surface .step { background: var(--paper); }
section:not(.band-surface):not(.band-dark) .step { background: var(--surface); }
.step::before {
  content: counter(step);
  font-family: var(--font-display);
  font-size: 15px; font-weight: 600;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--ink); color: #fff;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 18px;
}
.step h3 { font-size: 17px; font-weight: 650; margin-bottom: 8px; letter-spacing: -0.2px; }
.step p { font-size: 14px; color: var(--muted); line-height: 1.65; }
.step .step-tag {
  display: inline-block; margin-top: 14px;
  font-family: var(--font-mono); font-size: 11px;
  color: var(--blueprint);
  background: rgba(41,82,122,0.07);
  border: 1px solid rgba(41,82,122,0.16);
  padding: 3px 9px; border-radius: 5px;
}

/* ── Prose ───────────────────────────────────────────────────────────────
   For the long-form pages (proof write-up, checklist intro, cost research).
   Scoped under `.prose` so bare tags elsewhere stay under component control.
   Set `max-width` via `.container-narrow` on the wrapper, not here. */
.prose { font-size: 16px; color: var(--ink-soft); line-height: 1.75; }
.prose > * + * { margin-top: 1em; }
.prose h2 {
  font-family: var(--font-display);
  font-size: clamp(24px, 2.6vw, 30px); font-weight: 600;
  line-height: 1.2; letter-spacing: -0.015em; color: var(--ink);
  margin-top: 2.2em; margin-bottom: 0.1em;
}
.prose h3 {
  font-size: 18px; font-weight: 650; letter-spacing: -0.2px; color: var(--ink);
  margin-top: 1.8em; margin-bottom: 0.1em;
}
.prose h4 {
  font-size: 12.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--dim); margin-top: 1.8em; margin-bottom: 0.2em;
}
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.35em; }
.prose li + li { margin-top: 0.4em; }
.prose li::marker { color: var(--dim); }
.prose strong { color: var(--ink); font-weight: 650; }
.prose a { color: var(--accent-hover); font-weight: 550; text-decoration: underline; text-underline-offset: 2px; }
.prose a:hover { color: var(--accent); }
.prose code {
  font: 0.9em/1.4 var(--font-mono);
  background: var(--hairline-2); color: var(--ink);
  padding: 0.12em 0.38em; border-radius: 4px;
  /* A long identifier must break rather than push the page sideways. */
  overflow-wrap: anywhere;
}
.prose blockquote {
  border-left: 3px solid var(--accent);
  background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 16px 20px;
  color: var(--muted);
}
.prose blockquote > * + * { margin-top: 0.7em; }
.prose hr { border: none; border-top: 1px solid var(--hairline); margin: 2.4em 0; }
.prose figcaption, .caption { font-size: 13px; color: var(--dim); margin-top: 8px; }

/* Source line. Every sourced figure carries where it came from and how
   confident it is — the discipline that keeps these pages defensible. */
.source { font-size: 12.5px; color: var(--dim); line-height: 1.6; }
.source a { color: var(--muted); text-decoration: underline; }

/* Unresolved figure. Renders as an obvious red placeholder so a TK can never
   ship quietly as if it were a real number. */
.tk {
  font-family: var(--font-mono); font-size: 0.92em; font-weight: 600;
  color: var(--redline); background: rgba(185,28,28,0.08);
  border: 1px dashed rgba(185,28,28,0.4);
  padding: 0.05em 0.4em; border-radius: 4px;
}

/* ── Tables ──────────────────────────────────────────────────────────────
   Wrap every table in `<div class="table-wrap">`. A comparison table has more
   columns than a 360px screen has room for, and the wrapper is what converts
   that into a scrolling region instead of a horizontally scrolling PAGE. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 1.4em 0; }
table {
  border-collapse: collapse;
  width: 100%;
  min-width: 520px;          /* below this, columns collapse into mush */
  font-size: 14.5px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}
th, td { border-bottom: 1px solid var(--hairline-2); padding: 11px 16px; text-align: left; vertical-align: top; }
th {
  background: var(--hairline-2);
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover td { background: var(--paper); }
td strong { font-weight: 650; color: var(--ink); }
/* Right-align a money/number column with `class="num"` on the th and td. */
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── Callouts ────────────────────────────────────────────────────────────
   `.callout` is neutral. `.callout.warn` is the one that matters: it carries
   the permit-rules-are-local caveat. That caveat is required on every page
   that mentions permits, and leading with it is what makes the rest credible —
   the same posture the in-app attestation dialog takes. */
.callout {
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--blueprint);
  background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 16px 20px;
  font-size: 14.5px; color: var(--ink-soft); line-height: 1.7;
  margin: 1.6em 0;
}
.callout > * + * { margin-top: 0.6em; }
.callout strong { color: var(--ink); }
.callout.warn { border-left-color: var(--accent); background: var(--accent-soft); border-color: var(--accent-line); }
.callout.warn strong { color: var(--accent-hover); }
.callout.limit { border-left-color: var(--redline); background: rgba(185,28,28,0.05); border-color: rgba(185,28,28,0.18); }
.band-surface .callout { background: var(--paper); }
.band-dark .callout { background: var(--dark-panel); border-color: var(--dark-line); color: var(--dark-muted); }
.band-dark .callout strong { color: var(--dark-text); }

/* Small inline label. `.badge.ship` = shipped today, `.badge.soon` = not built.
   Keeping "not built" visually distinct is a claims-discipline tool, not
   decoration: it is how a page can mention a limit without burying it. */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  border: 1px solid var(--hairline); background: var(--surface); color: var(--muted);
  white-space: nowrap;
}
.badge.ship { background: rgba(26,127,55,0.09); border-color: rgba(26,127,55,0.25); color: var(--go); }
.badge.soon { background: var(--hairline-2); border-color: var(--hairline); color: var(--dim); }
.badge.accent { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-hover); }

/* ── Checklist / tick list ───────────────────────────────────────────────
   The permit-set checklist page, and any "what's included" list. The mark is
   CSS, not a checkbox input: this is a reference list to read and print, not a
   form to submit, and a real input would imply state the page cannot save. */
.checklist { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.checklist li {
  display: flex; align-items: flex-start; gap: 13px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 14px 18px;
}
.band-surface .checklist li { background: var(--paper); }
.checklist li::before {
  content: '';
  flex-shrink: 0; width: 18px; height: 18px; margin-top: 3px;
  border: 1.5px solid var(--dim); border-radius: 4px;
  background: transparent;
}
.checklist li b { display: block; font-size: 15px; font-weight: 650; letter-spacing: -0.1px; }
.checklist li span { font-size: 13.5px; color: var(--muted); line-height: 1.6; }
/* `.done` is for lists describing what the product already produces. The tick
   is an inline data-URI SVG rather than an icon font: one fewer network
   request on a page whose whole job is to load fast from a search result. */
.checklist li.done::before {
  border-color: var(--go); background-color: var(--go);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5 6.3 12 13 4.5'/%3E%3C/svg%3E");
  background-size: 12px 12px; background-position: center; background-repeat: no-repeat;
}

/* Tight tick list for "what's included" inside a card. */
.ticks { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.ticks li { display: flex; gap: 10px; font-size: 13.5px; color: var(--ink-soft); line-height: 1.6; }
.ticks svg { width: 15px; height: 15px; color: var(--accent); flex-shrink: 0; margin-top: 3px; }
.band-dark .ticks li { color: var(--dark-muted); }

/* ── File / download list ────────────────────────────────────────────────
   The proof page publishes real artifacts — sheet PDFs, an IFC file, a Revit
   package. The row leads with the format and the size because "can I open this
   in my software, and how big is it" is the only question a visitor has. */
.file-list { display: flex; flex-direction: column; border: 1px solid var(--hairline); border-radius: var(--radius-lg); overflow: hidden; background: var(--surface); }
.file-row {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--hairline-2);
  transition: background 0.12s;
}
.file-row:last-child { border-bottom: none; }
a.file-row:hover { background: var(--paper); }
.file-fmt {
  flex-shrink: 0; min-width: 62px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; text-align: center;
  color: var(--blueprint);
  background: rgba(41,82,122,0.07); border: 1px solid rgba(41,82,122,0.16);
  padding: 5px 8px; border-radius: 6px;
}
.file-name { font-size: 14.5px; font-weight: 550; letter-spacing: -0.1px; min-width: 0; overflow-wrap: anywhere; }
.file-name span { display: block; font-size: 12.5px; font-weight: 400; color: var(--muted); }
.file-size { margin-left: auto; flex-shrink: 0; font-family: var(--font-mono); font-size: 12px; color: var(--dim); }
.band-dark .file-list { background: var(--dark-panel); border-color: var(--dark-line); }
.band-dark .file-row { border-bottom-color: var(--dark-line); }

/* Sheet index — the drawing-set table of contents, as it reads on a title
   block: number, title, scale. Same three columns the product prints. */
.sheet-index { display: flex; flex-direction: column; }
.sheet-index .row {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 6px;
  border-bottom: 1px solid var(--hairline-2);
  font-size: 13.5px;
}
.sheet-index .row:last-child { border-bottom: none; }
.sheet-index .num { font-family: var(--font-mono); font-size: 12px; color: var(--accent); width: 62px; flex-shrink: 0; }
.sheet-index .scale { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--dim); }
.band-dark .sheet-index .row { border-bottom-color: var(--dark-line); }
.band-dark .sheet-index .num { color: #f0904d; }
.band-dark .sheet-index .scale { color: var(--dark-muted); }

/* Drawing-card frame: any screenshot or sheet thumbnail that should read as a
   piece of paper rather than a UI capture. */
.sheet-card {
  background: #fff;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.sheet-card img, .sheet-card video { width: 100%; height: auto; }

/* Quote/principle block with the accent rule down the left. */
.principle {
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 18px 20px;
}
.principle b { display: block; font-size: 14.5px; font-weight: 650; margin-bottom: 4px; }
.principle span { font-size: 13.5px; color: var(--muted); line-height: 1.65; }
.band-surface .principle { background: var(--surface); }

/* ── FAQ ─────────────────────────────────────────────────────────────────
   <details>/<summary>, so it works with no script and is findable by in-page
   search in browsers that expand closed details. */
.faq-list { max-width: 760px; display: flex; flex-direction: column; gap: 12px; }
.faq-list.centered { margin: 0 auto; }
.faq-list details {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  overflow: hidden;
  transition: border-color 0.15s;
}
.band-surface .faq-list details { background: var(--paper); }
.faq-list details[open] { border-color: #d8d4cc; box-shadow: var(--shadow-card); }
.faq-list summary {
  list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 22px;
  font-size: 15px; font-weight: 600;
  cursor: pointer;
  -webkit-user-select: none; user-select: none;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after {
  content: '+';
  font-size: 20px; font-weight: 400; color: var(--dim);
  transition: transform 0.2s;
  flex-shrink: 0;
}
.faq-list details[open] summary::after { transform: rotate(45deg); }
.faq-list .faq-body { padding: 0 22px 20px; font-size: 14.5px; color: var(--muted); line-height: 1.7; }
.faq-list .faq-body > * + * { margin-top: 0.7em; }
.faq-list .faq-body a { color: var(--accent-hover); font-weight: 550; }
.faq-list .faq-body a:hover { text-decoration: underline; }

/* ── CTA band ────────────────────────────────────────────────────────────
   Identical to the homepage's closing panel. Note it lives inside a section
   with no vertical padding of its own on the bottom edge, so the footer sits
   directly beneath it. */
.cta-section { padding: 0 0 88px; }
.cta-panel {
  position: relative;
  background: var(--dark-bg); color: var(--dark-text);
  border-radius: 22px;
  padding: 64px 32px;
  text-align: center;
  overflow: hidden;
}
.cta-panel::before {
  content: '';
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right, rgba(255,255,255,0.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,0.035) 1px, transparent 1px);
  background-size: 44px 44px;
  pointer-events: none;
}
.cta-panel > * { position: relative; }
.cta-panel h2 {
  font-family: var(--font-display);
  font-size: clamp(27px, 3.4vw, 40px); font-weight: 600;
  letter-spacing: -0.015em; line-height: 1.12;
  margin-bottom: 14px;
}
.cta-panel p { color: var(--dark-muted); font-size: 16px; margin: 0 auto 32px; max-width: 46em; }
.cta-panel .btn-row { justify-content: center; }
.cta-panel .btn-ghost { color: var(--dark-text); border-color: var(--dark-line); }
.cta-panel .btn-ghost:hover { background: var(--dark-panel); border-color: var(--dark-muted); }
/* The caveat under the CTA. Dimmer than the body copy but still legible —
   it is not fine print we are hiding, it is the reason to trust the page. */
.cta-panel .cta-note { font-size: 12.5px; color: var(--dark-muted); margin: 20px auto 0; max-width: 44em; }

/* ── Footer ──────────────────────────────────────────────────────────────
   Same four-column grid as the homepage so the two footers match column for
   column when a visitor moves between them. */
footer {
  border-top: 1px solid var(--hairline);
  background: var(--surface);
  padding: 56px 0 max(36px, env(safe-area-inset-bottom));
}
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 40px; margin-bottom: 44px; }
.footer-brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 16px; margin-bottom: 12px; }
.footer-brand img, .footer-brand svg { width: 24px; height: 24px; }
.footer-brand img { border-radius: 6px; }
.footer-tagline { font-size: 13.5px; color: var(--muted); max-width: 26em; line-height: 1.65; }
.footer-col h4 {
  font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--dim); margin-bottom: 14px;
}
.footer-col a { display: block; padding: 5px 0; font-size: 14px; color: var(--ink-soft); }
.footer-col a:hover { color: var(--accent-hover); }
.footer-legal {
  border-top: 1px solid var(--hairline-2);
  padding-top: 22px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  font-size: 12.5px; color: var(--dim);
  flex-wrap: wrap;
}
/* The standing disclaimer. TraceBIM is a drafting tool, not a licensed design
   professional, and permit rules are local — that belongs on every page. */
.footer-disclaimer { flex-basis: 100%; line-height: 1.7; color: var(--dim); }

/* ── Responsive ──────────────────────────────────────────────────────────
   Breakpoints match index.html (980 / 780 / 560) so the two surfaces reflow at
   the same widths. A visitor rotating an iPad shouldn't see the homepage and a
   landing page break at different moments. */
@media (max-width: 980px) {
  .card-grid, .feature-grid,
  .card-grid.cols-4, .feature-grid.cols-4 { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .stats-row { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 780px) {
  .nav-links, .nav-auth { display: none; }
  .nav-burger { display: flex; }
  .page-hero { padding-top: 108px; }
  section { padding: 60px 0; }
  .cta-panel { padding: 48px 24px; border-radius: 18px; }
}
@media (max-width: 560px) {
  /* The 16px phone gutter. Anything that sets its own horizontal padding has
     to come down with it, or the content sits on a different margin than the
     nav and footer do. */
  .container { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); }
  #mobile-menu { padding-left: 16px; padding-right: 16px; }
  .card-grid, .feature-grid,
  .card-grid.cols-2, .feature-grid.cols-2,
  .card-grid.cols-4, .feature-grid.cols-4 { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; gap: 28px; }
  .stats-row { grid-template-columns: 1fr; gap: 16px; padding: 20px 0; }
  .hero-title { font-size: clamp(30px, 8.5vw, 38px); }
  .hero-sub { font-size: 16px; }
  .card, .feature-card { padding: 22px 20px; }
  .step { padding: 22px 20px; }
  .file-row { flex-wrap: wrap; gap: 10px 12px; }
  .file-size { margin-left: 0; width: 100%; }
  /* Full-width CTAs: a 44px-tall target spanning the column beats two cramped
     buttons side by side on a phone. */
  .btn-row > .btn { width: 100%; }
}

/* ── Print ───────────────────────────────────────────────────────────────
   The checklist is meant to be taken to a building department, so it has to
   print as a usable sheet: no fixed nav overlapping the first inch, no dark
   bands burning a toner cartridge, and no CTA to click on paper. */
@media print {
  #nav, #mobile-menu, .cta-section, .nav-burger, .btn { display: none !important; }
  body { background: #fff; }
  .page-hero { padding-top: 0; }
  .page-hero::before, .cta-panel::before { display: none; }
  section { padding: 16px 0; }
  .band-surface, .band-dark { background: #fff; color: #000; border: none; }
  .band-dark .sec-sub, .band-dark p { color: #333; }
  .card, .feature-card, .step, .checklist li, .callout, .file-list { break-inside: avoid; box-shadow: none; }
  a[href^="http"]::after { content: ' (' attr(href) ')'; font-size: 10px; color: #555; }
}
