/* Sagashi — design tokens. Light first, dark under prefers-color-scheme.
   The palette is "Sumi" (ink): near-black ink for filled controls, one blue
   for text links, warm greys. Green, amber and red are reserved for verdicts
   (fits, can't tell, ruled out) and used for nothing else. The approved design
   is docs/design/v2-sagashi.html, and v3-wide.html above a phone's width. */

:root {
  --paper: #f3f2ee;
  --surface: #f8f7f4;
  --surface-raised: #ffffff;
  --ink: #1c1f21;
  --ink-soft: #5e625f;
  /* 4.99:1 on paper, 5.22 on surface, 5.59 on white: WCAG AA for small text.
     Size and weight, not a colour too light to read, carry the difference
     from --ink-soft. */
  --ink-faint: #656963;
  --line: #dcdbd4;
  --line-strong: #c6c5bd;
  /* Filled controls: buttons, selected chips and segments, sliders. */
  --accent: #1f2326;
  --accent-soft: #e8e7e1;
  --accent-ink: #1c1f21;
  /* Text links, text-styled buttons and focus rings. Ink cannot be a link
     colour: a link must read as one without being underlined. 6.43:1 on paper. */
  --link: #2a5a88;
  /* A picked item's fill: a pale tint of the link colour (map-pick-style). */
  --link-soft: #e4edf6;
  --hazard: #a5342a;
  --hazard-soft: #f3dbd7;
  --caution: #885b20;
  --caution-soft: #f1e3c9;
  --clear: #366b4c;
  --clear-soft: #dbe9df;
  --on-accent: #ffffff;

  /* Spacing, on a 4px grid. Every margin, padding, gap and offset uses one of
     these (server/test/stylesheet-scale.test.ts). */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;

  /* Type, in six steps. Every font size uses one of these. */
  --text-xs: 12px;
  --text-sm: 13px;
  --text-md: 15px;
  --text-lg: 17px;
  --text-xl: 22px;
  --text-2xl: 28px;
  --leading-tight: 1.25;
  --leading-body: 1.45;

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-pill: 999px;

  /* The smallest area a finger can reliably hit (Apple HIG, WCAG 2.5.5). */
  --touch: 44px;

  /* Widths above a phone (app-layout; docs/design/v3-wide.html). One
     readable column: about 75 characters of body text. The list beside a
     home: a card's price and address each on one line at the body size. */
  --column: 680px;
  --list-width: 420px;

  /* What Sagashi draws on a map. Google's tiles are light in either theme, so
     these are not redefined for dark: lines and outlines in ink, each way of
     travelling its own colour, the destination's pin in amber. */
  --map-ink: #1f2326;
  --map-walk: #6b7680;
  --map-cycle: #2f6f4f;
  --map-ride: #5b6b7a;
  --map-destination: #b5651d;
  --map-destination-edge: #7a4213;
  --map-glyph: #ffffff;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #121416; --surface: #1b1e20; --surface-raised: #22262a;
    --ink: #eceae4; --ink-soft: #a3a6a1;
    /* 5.69:1 on paper, 4.70 on surface-raised. */
    --ink-faint: #8c908b;
    --line: #2d3033; --line-strong: #3b3f42;
    --accent: #eceae4; --accent-soft: #2a2e31; --accent-ink: #eceae4;
    --link: #8db4dc; --link-soft: #1d2a38;
    --hazard: #e2887c; --hazard-soft: #3a2523;
    --caution: #dcb26e; --caution-soft: #3a3122;
    --clear: #8fc4a4; --clear-soft: #223229;
    --on-accent: #16191b;
  }
}


* { box-sizing: border-box; }

/* Components below set their own `display`, which would otherwise beat the
   [hidden] attribute's `display: none`. The router hides chrome with `hidden`,
   so this has to win. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--paper);
  color: var(--ink);
  font: var(--text-md)/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* The app fills the window at every width, with no drawn device frame
   (app-layout). Three layouts, switched here and nowhere else: a phone, up to
   540px, exactly as the app has always been; one centred column from 541px;
   and from 1024px the list screens show a home beside the list. The browser
   reads which applies from --layout (app/js/layout.js), so no script holds a
   width of its own. */
.app {
  --layout: phone;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  overflow: hidden;
  position: relative;
}

/* ---------- nav ---------- */
.navbar {
  flex: none;
  height: 48px;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
  background: var(--paper);
  position: relative;
}
.navbar.bordered { border-bottom: 1px solid var(--line); }

.nav-back, .nav-action {
  background: none; border: 0; padding: 0 var(--space-2); cursor: pointer; min-height: var(--touch);
  color: var(--link); font: inherit; font-size: var(--text-md);
  display: inline-flex; align-items: center; gap: var(--space-1);
}
.nav-action { margin-left: auto; }
/* The bell sits just before the account control and takes the push to the
   right; the control then follows it directly. */
.nav-bell {
  position: relative; margin-left: auto; background: none; border: 0; cursor: pointer;
  min-width: var(--touch); min-height: var(--touch); color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center;
}
.nav-bell:not([hidden]) + .nav-action { margin-left: 0; }
.nav-action.nav-icon { min-width: var(--touch); justify-content: center; color: var(--ink); }
.bell-badge {
  position: absolute; top: var(--space-1); right: var(--space-1);
  min-width: var(--space-4); padding: 0 var(--space-1); border-radius: var(--radius-pill);
  background: var(--accent); color: var(--paper); font-size: var(--text-xs); font-weight: 700;
  line-height: var(--space-4); text-align: center;
}
.nav-title {
  position: absolute; left: 50%; transform: translateX(-50%);
  font-size: var(--text-md); font-weight: 600; color: var(--ink);
  white-space: nowrap; max-width: 60%; overflow: hidden; text-overflow: ellipsis;
}

/* ---------- progress ---------- */
.progress { flex: none; padding: var(--space-1) var(--space-4) var(--space-3); background: var(--paper); }
.steps { display: flex; gap: var(--space-1); margin-bottom: var(--space-2); }
.steps i { flex: 1; height: 3px; border-radius: 2px; background: var(--line-strong); }
.steps i.done { background: var(--accent); }
.steps-label { font-size: var(--text-xs); color: var(--ink-faint); letter-spacing: .01em; }

/* ---------- viewport ---------- */
.viewport { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: var(--space-1) var(--space-4) var(--space-5); }
.viewport.flush { padding-left: 0; padding-right: 0; }

.lede { font-size: var(--text-md); color: var(--ink-soft); margin: var(--space-1) 0 var(--space-4); }
.sub-h { font-size: var(--text-xs); font-weight: 650; text-transform: uppercase;
         letter-spacing: .06em; color: var(--ink-faint); margin: 0 0 var(--space-2); }
.sub-h.spaced { margin-top: var(--space-5); }

/* ---------- footer ---------- */
.foot {
  flex: none; padding: var(--space-3) var(--space-4) calc(var(--space-4) + env(safe-area-inset-bottom));
  background: var(--paper); border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.btn {
  width: 100%; min-height: var(--touch); padding: var(--space-3) var(--space-4); border: 0; border-radius: var(--radius-md);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  background: var(--accent); color: var(--on-accent);
  font: inherit; font-size: var(--text-md); font-weight: 600; cursor: pointer;
}
.btn:disabled { opacity: .42; cursor: not-allowed; }
.btn.ghost { background: none; color: var(--link); padding: var(--space-2); font-weight: 500; }
/* A way out that isn't the step's next move: said quietly. */
.btn.ghost.quiet { color: var(--ink-faint); }
/* A ghost button inside a note, left-aligned with its text. */
.btn.ghost.inline { margin-top: var(--space-2); text-align: left; padding: 0; }
/* The heading of a screen that says something is done or sent. */
.done-title { margin: 0 0 var(--space-2); font-size: var(--text-xl); }
/* A note's opening question, above its choices. */
.note-lead { margin: 0 0 var(--space-2); }
.btn.secondary { background: var(--accent-soft); color: var(--accent-ink); }

/* ---------- form primitives ---------- */
.fieldset { margin-bottom: var(--space-4); }
.flabel { display: block; font-size: var(--text-xs); font-weight: 650; text-transform: uppercase;
          letter-spacing: .06em; color: var(--ink-faint); margin-bottom: var(--space-2); }

.finput {
  display: flex; align-items: center; gap: var(--space-2);
  background: var(--surface-raised); border: 1px solid var(--line);
  border-radius: var(--radius-md); padding: 0 var(--space-3); color: var(--ink-soft);
}
.finput:focus-within { border-color: var(--accent); }
.finput input, .finput select {
  flex: 1; min-width: 0; border: 0; background: none; color: var(--ink);
  font: inherit; font-size: var(--text-md); outline: none; min-height: var(--touch);
}
.finput input::placeholder { color: var(--ink-faint); }

.chiprow { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.chip {
  border: 1px solid var(--line-strong); background: var(--surface-raised);
  color: var(--ink-soft); border-radius: var(--radius-pill); padding: 0 var(--space-4);
  min-height: var(--touch); min-width: var(--touch);
  display: inline-flex; align-items: center; justify-content: center;
  font: inherit; font-size: var(--text-sm); cursor: pointer;
}
.chip.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.chip:disabled { opacity: .38; cursor: not-allowed; }

.seg { display: grid; gap: var(--space-1); background: var(--surface); border: 1px solid var(--line);
       border-radius: var(--radius-md); padding: var(--space-1); }
.seg.c2 { grid-template-columns: repeat(2, 1fr); }
.seg.c3 { grid-template-columns: repeat(3, 1fr); }
.seg.c4 { grid-template-columns: repeat(4, 1fr); }
.seg button {
  border: 0; background: none; color: var(--ink-soft); font: inherit; font-size: var(--text-sm);
  padding: 0 var(--space-1); min-height: var(--touch); border-radius: var(--radius-sm); cursor: pointer;
}
.seg button.on { background: var(--accent); color: var(--on-accent); font-weight: 600; }

.list { display: flex; flex-direction: column; gap: 1px; background: var(--line);
        border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; }
.steprow { display: flex; align-items: center; justify-content: space-between;
           background: var(--surface-raised); padding: var(--space-3) var(--space-3); }
.steprow .lab { font-size: var(--text-md); }
.stepper { display: flex; align-items: center; gap: var(--space-3); }
.stepper button {
  width: var(--touch); height: var(--touch); border-radius: 50%; border: 1px solid var(--line-strong);
  background: var(--surface-raised); color: var(--ink); font-size: var(--text-lg); line-height: 1;
  cursor: pointer;
}
.stepper .n { min-width: 36px; text-align: center; font-size: var(--text-md); font-variant-numeric: tabular-nums; }
.stepper .n.unset { color: var(--ink-faint); }

.ta {
  width: 100%; min-height: 128px; resize: vertical;
  background: var(--surface-raised); border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-3); font: inherit; font-size: var(--text-md); color: var(--ink); outline: none;
}
.ta:focus { border-color: var(--accent); }
.ta-count { text-align: right; font-size: var(--text-xs); color: var(--ink-faint); margin-top: var(--space-1); }

/* budget range */
.budget-val { display: block; font-size: var(--text-xl); font-weight: 650; margin-bottom: var(--space-3); }
.budget-val.unset { font-size: var(--text-md); font-weight: 500; color: var(--ink-faint); }
.range-pair { position: relative; height: 30px; }
.range-track { position: absolute; top: var(--space-3); left: 0; right: 0; height: 4px;
               background: var(--line-strong); border-radius: 2px; }
.range-fill { position: absolute; top: 0; bottom: 0; background: var(--accent); border-radius: 2px; }
/* A range nobody has set yet is drawn faint, so it never reads as a choice. */
.range-fill.unset { opacity: .3; }
.range-pair input[type=range] {
  position: absolute; top: 0; left: 0; width: 100%; height: 30px; margin: 0;
  background: none; pointer-events: none; -webkit-appearance: none; appearance: none;
}
.range-pair input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; pointer-events: auto; width: 22px; height: 22px;
  border-radius: 50%; background: var(--surface-raised); border: 2px solid var(--accent);
  cursor: grab;
}
.range-ends { display: flex; justify-content: space-between; font-size: var(--text-xs);
              color: var(--ink-faint); margin-top: var(--space-1); }

/* ---------- address suggestions ---------- */
.suggest {
  margin-top: var(--space-2); border: 1px solid var(--line); border-radius: var(--radius-md);
  background: var(--surface-raised); overflow: hidden;
}
.suggest-row {
  display: block; width: 100%; text-align: left; border: 0; cursor: pointer;
  background: none; color: var(--ink); font: inherit; font-size: var(--text-md);
  padding: var(--space-3) var(--space-3); border-bottom: 1px solid var(--line);
}
.suggest-row:last-child { border-bottom: 0; }
.suggest-row:hover { background: var(--accent-soft); }
.suggest-none { padding: var(--space-3) var(--space-3); font-size: var(--text-sm); color: var(--ink-faint); }

/* ---------- suburb picker ---------- */
.tokens { display: flex; flex-wrap: wrap; gap: var(--space-2); list-style: none; margin: 0 0 var(--space-2); padding: 0; }
.tokens:empty { display: none; }
.token {
  display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer;
  border: 1px solid var(--accent); background: var(--accent); color: var(--on-accent);
  border-radius: var(--radius-pill); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3); font: inherit; font-size: var(--text-sm);
}
.token .x { font-size: var(--text-lg); line-height: 1; opacity: .8; }
.token:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.suggest-row[aria-selected="true"] { background: var(--accent-soft); }
.suggest-row .pc { margin-left: var(--space-2); font-size: var(--text-sm); color: var(--ink-faint); }

/* ---------- the Family step (family-step-clarity) ---------- */
/* Each question says what it does: a filter, or shown only. The labels are
   neutral (ink and soft ink), never a verdict colour. */
.q { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.q + .q { padding-top: var(--space-4); border-top: 1px solid var(--line); }
.q-head { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
.q-title { margin: 0; font-size: var(--text-lg); font-weight: 650; color: var(--ink); }
.q-kind { font-size: var(--text-xs); font-weight: 600; padding: 0 var(--space-2); border-radius: var(--radius-pill); line-height: 1.6; }
.q-kind.filter { background: var(--accent); color: var(--on-accent); }
.q-kind.shown { background: var(--accent-soft); color: var(--ink-soft); }
.q-sub { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-2); }
.hint { margin: 0; font-size: var(--text-sm); color: var(--ink-soft); text-align: left; }
.school-cards { display: flex; flex-direction: column; gap: var(--space-2); list-style: none; margin: 0 0 var(--space-2); padding: 0; }
.school-cards:empty { display: none; }
.school-card { display: flex; align-items: center; gap: var(--space-3); min-height: var(--touch);
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-4); background: var(--surface-raised);
  border: 1px solid var(--line); border-radius: var(--radius-md); }
.school-card-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.school-card-meta, .suggest-meta { font-size: var(--text-sm); color: var(--ink-soft); }
.suggest-meta { display: block; }
.school-card-x { display: grid; place-items: center; width: var(--touch); height: var(--touch); flex: none;
  border: 0; background: none; color: var(--ink-soft); cursor: pointer; border-radius: var(--radius-sm); }
.school-card-x:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.picker-hint { margin-top: var(--space-2); }
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: 1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap;
}

/* Explicit hour / minute / am-pm rather than <input type=time>, whose
   rendering is locale-dependent and cannot be guaranteed to show am first. */
.timepick { display: flex; align-items: center; gap: var(--space-2); }
.timepick select {
  background: var(--surface-raised); border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-2); font: inherit; font-size: var(--text-md); color: var(--ink); cursor: pointer;
}
.timepick select:focus { outline: none; border-color: var(--accent); }
.timepick-sep { color: var(--ink-faint); }
.timepick-period { flex: 1; }

/* single-handle slider shares the range styling but needs no second thumb */
.range-pair.single input[type=range] { pointer-events: auto; }

/* ---------- notes ---------- */
.note {
  font-size: var(--text-sm); line-height: 1.55; color: var(--ink-soft);
  background: var(--accent-soft); border-radius: var(--radius-md); padding: var(--space-3) var(--space-3); margin-top: var(--space-3);
}
.note.plain { background: var(--surface); border: 1px solid var(--line); }
.note.warn { background: var(--caution-soft); color: var(--ink); }
.note em { color: var(--ink-faint); font-style: normal; display: block; margin-top: var(--space-1); font-size: var(--text-xs); }

/* ---------- category rows (overview) ---------- */
.catrow {
  display: flex; align-items: center; gap: var(--space-3); width: 100%; text-align: left;
  background: var(--surface-raised); border: 0; padding: var(--space-2) var(--space-4); font: inherit; cursor: pointer;
  min-height: calc(var(--space-7) + var(--space-2));
}
/* A section's icon (icons.js), in a tinted circle. */
.cat-ic { width: calc(var(--space-6) + var(--space-1)); height: calc(var(--space-6) + var(--space-1)); border-radius: 50%;
  background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; flex: none; }
.cat-main { flex: 1; min-width: 0; }
.cat-name { display: block; font-size: var(--text-md); font-weight: 600; color: var(--ink); }
.cat-sum { display: block; font-size: var(--text-sm); color: var(--ink-soft); margin-top: var(--space-1); }
.cat-sum.unset { color: var(--ink-faint); font-style: italic; }
.chev { color: var(--ink-faint); flex: none; }

/* ---------- parse buckets ---------- */
.parse-grp { margin-bottom: var(--space-5); }
.parse-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.parse-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
/* Neutral on purpose: green, amber and red mean a verdict, and none of these is one. */
.parse-grp.checked .parse-dot { background: var(--ink); }
.parse-grp.shown .parse-dot { background: var(--ink-soft); }
.parse-grp.cannot .parse-dot { background: var(--ink-faint); }
.parse-title { font-size: var(--text-sm); font-weight: 650; }
.prow { display: flex; align-items: center; gap: var(--space-2); background: var(--surface-raised); padding: var(--space-2) var(--space-3); }
.parse-grp.cannot .prow { opacity: .72; }
.quote { font-size: var(--text-sm); font-weight: 600; }
.maps { font-size: var(--text-sm); color: var(--ink-soft); margin-left: auto; text-align: right; }

/* ---------- account ---------- */
.provider {
  display: flex; align-items: center; justify-content: center; gap: var(--space-2);
  width: 100%; padding: var(--space-3); border-radius: var(--radius-md); cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--surface-raised);
  color: var(--ink); font: inherit; font-size: var(--text-md); font-weight: 600;
}
.divider { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-4) 0;
           color: var(--ink-faint); font-size: var(--text-xs); }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.err { color: var(--hazard); font-size: var(--text-sm); margin-top: var(--space-2); min-height: 16px; }
.banner { border-radius: var(--radius-md); padding: var(--space-3) var(--space-3); font-size: var(--text-sm); line-height: 1.5; margin-bottom: var(--space-4); }
.banner.info { background: var(--accent-soft); color: var(--accent-ink); }
.banner.bad { background: var(--hazard-soft); color: var(--hazard); }
.banner.good { background: var(--clear-soft); color: var(--clear); }

.welcome { padding: calc(var(--space-7) + var(--space-2)) var(--space-2) 0; }
.brand { display: flex; align-items: center; gap: var(--space-3); color: var(--ink); margin-bottom: var(--space-1); }
.welcome .meaning { margin: var(--space-3) 0 0; color: var(--ink-soft); font-size: var(--text-lg); }
.welcome .small { margin-top: var(--space-4); font-size: var(--text-sm); color: var(--ink-faint); }
/* What Sagashi does, as three steps: icons and a word or two, not sentences. */
.strip { list-style: none; margin: var(--space-5) 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }
.strip li { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-1);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-md);
  font-size: var(--text-sm); font-weight: 600; text-align: center; color: var(--ink); }
.welcome p { font-size: var(--text-md); line-height: 1.6; color: var(--ink-soft); margin: var(--space-4) 0 0; }

.done-mark { width: var(--space-7); height: var(--space-7); border-radius: 50%; background: var(--clear-soft);
             color: var(--clear); display: flex; align-items: center; justify-content: center;
             margin-bottom: var(--space-4); }

/* ---------- listings (home, ruled out) ---------- */
.lst-group { display: flex; flex-direction: column; gap: 1px; background: var(--line);
             border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; }
.lst, .out { display: block; background: var(--surface-raised); padding: var(--space-3); }
/* On a public page a row is a link to the agency's page: it reads as a row, not as link text. */
.lst, a.out { text-decoration: none; color: inherit; }
/* Rows open Sagashi's own listing screen, so they are buttons: reset what a
   button brings with it so they read exactly as the rows they replaced. */
button.lst, button.out { width: 100%; border: 0; text-align: left; font: inherit; cursor: pointer; }
.banner.warn { background: var(--caution-soft); color: var(--ink); }
.lst-title { margin: 0 0 var(--space-1); font-size: var(--text-lg); line-height: 1.3; color: var(--ink); }
p.lst-price, p.lst-spec { margin: 0 0 var(--space-1); }
.cm { border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface-raised); padding: var(--space-2) var(--space-3); }
.cm p { margin: 0 0 var(--space-2); font-size: var(--text-sm); line-height: 1.5; color: var(--ink); }
.cm p:last-child { margin-bottom: 0; }
.cm .cm-check { color: var(--ink-soft); }
.cm .cm-note { font-size: var(--text-xs); color: var(--ink-faint); }
.cm .cm-disagree { background: var(--caution-soft); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-2); }
.cm .cm-times { font-size: var(--text-sm); }
.cm-steps { margin: var(--space-1) 0 var(--space-2); padding-left: var(--space-5); }
.cm-step { font-size: var(--text-sm); line-height: 1.45; color: var(--ink); margin: 0 0 var(--space-1); }
.cm-step.walk { color: var(--ink-soft); }
.cm-step-detail { display: block; font-size: var(--text-xs); color: var(--ink-soft); }
/* A map inside a listing's row. Without a height Google draws into nothing and the
   dock shows an empty band. The route map is a little taller than the numbered ones. */
.row-map:not(:empty) { height: 260px; border-radius: var(--radius-md); overflow: hidden; margin: var(--space-2) 0 var(--space-1);
  border: 1px solid var(--line); }
.row-map.route:not(:empty) { height: 280px; margin-bottom: var(--space-2); }
/* Under a map drawn from another source's data: its credit, beside Google's own. */
.map-credit { margin: calc(-1 * var(--space-1)) 0 var(--space-2); font-size: var(--text-xs); color: var(--ink-faint); }
/* nearby-embedded-map: one chip per kind, then Google's own map for the chosen one. */
.kinds { display: flex; gap: var(--space-2); overflow-x: auto; padding-bottom: var(--space-1); scrollbar-width: none; }
.kind { flex: none; min-height: var(--touch); padding: 0 var(--space-4); border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill); background: var(--surface-raised); color: var(--ink); font: inherit; font-size: var(--text-sm); cursor: pointer; }
.kind[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.kind:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.nearby-frame { display: block; width: 100%; height: 360px; border: 1px solid var(--line); border-radius: var(--radius-md);
  margin: var(--space-2) 0 var(--space-1); background: var(--surface); }
.lst-addr { flex: 1; min-width: 0; font-size: var(--text-md); font-weight: 600; color: var(--ink); }
.lst-src { flex: none; font-size: var(--text-xs); color: var(--ink-faint); }
.lst-price { display: block; font-size: var(--text-sm); font-weight: 600; color: var(--accent-ink);
             margin-top: var(--space-1); }
.lst-price em { font-style: normal; font-weight: 500; color: var(--ink-faint); }
.lst-spec { display: block; font-size: var(--text-xs); color: var(--ink-soft); margin-top: var(--space-1); }
.catrow.spaced { margin-top: var(--space-4); border-radius: var(--radius-md); border: 1px solid var(--line); }
.linkish { background: none; border: 0; padding: 0; font: inherit; font-size: var(--text-sm);
           font-weight: 600; color: var(--link); text-decoration: underline;
           cursor: pointer; margin-top: 0; display: inline-flex; align-items: center; min-height: var(--touch);
           text-align: left; }
.banner-acts { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-1); }
.banner-acts .linkish { color: inherit; }
.banner .err { margin: var(--space-2) 0 0; }

/* ── explanations, one tap away (explain() in js/ui.js) ─────────────────── */
.explain { margin: var(--space-3) 0 0; }
.explain-btn { display: inline-flex; align-items: center; gap: var(--space-2); background: none; border: 0;
  padding: 0; min-height: var(--touch); color: var(--link); font: inherit; font-size: var(--text-sm); cursor: pointer; }
.explain-body { font-size: var(--text-sm); color: var(--ink-soft); background: var(--accent-soft);
  border-radius: var(--radius-md); padding: var(--space-3) var(--space-3); margin-top: var(--space-2); }
.explain-body p { margin: 0 0 var(--space-2); }
.explain-body p:last-child { margin: 0; }

/* A data layer's source and date: always visible, kept small. */
.src { font-size: var(--text-xs); color: var(--ink-faint); margin: var(--space-2) 0 0; }

/* ── visual-refresh: the approved layout (docs/design/v2-refresh.html) ─── */
.summary { display: flex; flex-direction: column; gap: var(--space-1); margin: 0 0 var(--space-3); }
.home-h { margin: 0; font-size: var(--text-xl); line-height: var(--leading-tight); color: var(--ink); }
.sum-kept { margin: 0; font-weight: 600; color: var(--ink); }
.sum-kept.none { color: var(--ink-soft); }
.badge-line, .foot-line, .sec-row { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--space-3); }
.badge-line .explain, .foot-line .explain, .sec-row .explain { display: contents; }
.badge-line .explain-body, .foot-line .explain-body, .sec-row .explain-body { flex-basis: 100%; margin-bottom: var(--space-2); }
.foot-line { margin-top: var(--space-5); } .foot-line .note { margin: 0; }
.sec-row { justify-content: space-between; margin-top: var(--space-5); } .sec-row .sub-h { margin: 0; }
.explain-btn .icon { flex: none; }

.lst { display: flex; flex-direction: column; gap: var(--space-1); width: 100%; text-align: left; border: 0;
  padding: var(--space-4); font: inherit; cursor: pointer; }
.lst-group .lst-price, .lst > .lst-price { font-size: var(--text-lg); font-weight: 700; margin: 0; }
.lst-price.big { font-size: var(--text-xl); margin: 0 0 var(--space-1); }
.lst-addr { font-size: var(--text-md); font-weight: 500; }
.lst-facts { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); }
.lst-facts .lst-spec { margin: 0; font-size: var(--text-sm); }


.out { display: flex; flex-direction: column; gap: var(--space-2); width: 100%; text-align: left; border: 0;
  padding: var(--space-3) var(--space-4); font: inherit; cursor: pointer; }
.out .lst-top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); }
.out .lst-addr { font-weight: 600; }
/* A price can be a sentence ("Auction Saturday 5 December, 4pm - In rooms"): it
   wraps within its share of the line, and never squeezes the address. */
.out .lst-src { flex: 0 1 auto; max-width: 45%; font-size: var(--text-sm); color: var(--ink-soft); text-align: right; }
.out-reason { font-size: var(--text-sm); color: var(--ink-soft); }

.cat-ic.danger { background: var(--hazard-soft); color: var(--hazard); }
.portal-link { margin: var(--space-2) 0 var(--space-4); text-decoration: none; }
.cm-live { display: flex; align-items: flex-start; gap: var(--space-2); }
.spaced-b { margin-bottom: var(--space-4); }
/* A button that follows a list needs room, or it reads as part of the list. */
.list + .btn { margin-top: var(--space-5); }

/* The buyer's alert address: what they paste into their portal saved searches.
   Monospace so every character of the token reads unambiguously, and allowed
   to wrap at any character rather than push the copy button off the screen. */
.alert-addr { margin-block: var(--space-4); }
.addr-row { display: flex; align-items: center; gap: var(--space-2); margin-block: var(--space-2); }
.addr { flex: 1; min-width: 0; overflow-wrap: anywhere; font: var(--text-sm)/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--surface-raised); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); color: var(--ink); }
.btn.ghost.copy-btn { width: auto; display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--touch); padding: 0 var(--space-3); }
/* What to do with it: a caption to the address, not a card of its own. */
.addr-hint { margin: 0 0 var(--space-2); font-size: var(--text-sm); color: var(--ink-soft); }
/* A filter a listing could not be checked on, said under its verdict. */
/* The home screen's title: the small mark and the wordmark. */
.brand-nav { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--ink); }

.reg-list { list-style: none; margin: 0; padding: 0; }
.reg-row { padding: var(--space-3) 0; border-bottom: 1px solid var(--line); }
.reg-row:last-child { border-bottom: 0; }
.reg-name { font-weight: 700; margin-right: var(--space-2); }
.reg-line { margin: var(--space-1) 0 0; }
.dev-bands { margin: var(--space-1) 0 0; color: var(--ink-soft); }
.dev-list { list-style: none; margin: var(--space-2) 0 0; padding: 0; }
.dev-row { padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.dev-row:last-child { border-bottom: 0; }
.act-row { width: 100%; text-align: left; }
.act-when { display: block; font-size: var(--text-xs); color: var(--ink-faint); margin-top: var(--space-1); }
.act-code-line { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2); }
.act-code-value { font-size: var(--text-lg); letter-spacing: .12em; }
.alert-sub { font-size: var(--text-md); color: var(--ink-soft); margin: var(--space-1) 0 0; }

/* The privacy policy and terms (privacy.html, terms.html): long prose, so a
   readable measure and spacing between sections. Links are the one blue. */
.legal { font-size: var(--text-sm); line-height: 1.55; }
.legal h1 { font-size: var(--text-xl); margin: var(--space-3) 0 var(--space-1); }
.legal .sub-h { margin: var(--space-5) 0 var(--space-2); }
.legal p, .legal ul { margin: 0 0 var(--space-3); }
.legal ul { padding-left: var(--space-5); }
.legal li { margin-bottom: var(--space-1); }
.legal a { color: var(--link); }
.legal .src { margin-bottom: var(--space-4); }
.legal-back { color: var(--link); font-size: var(--text-md); text-decoration: none;
              min-height: var(--touch); display: inline-flex; align-items: center; }
.legal-links { text-align: center; font-size: var(--text-sm); color: var(--ink-faint); margin: var(--space-2) 0 0; }
.legal-links a { color: var(--link); display: inline-flex; align-items: center; min-height: var(--touch); padding: 0 var(--space-2); }

/* ── calm-screens: the verdict mark, the row, the tag ─────────────────────
   One look for a verdict wherever it appears (mark() in js/ui.js): the row's
   icon circle, tinted with the verdict's colour. Green, amber and red appear
   here and nowhere else. */
.cat-ic.v-ok { background: var(--clear-soft); color: var(--clear); }
.cat-ic.v-out { background: var(--hazard-soft); color: var(--hazard); }
.cat-ic.v-unsure { background: var(--caution-soft); color: var(--caution); }
/* A card's verdict: the mark beside its one line. */
.lst-verdict { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-2);
  font-size: var(--text-sm); line-height: 1.45; color: var(--ink-soft); }
.lst-verdict-text { flex: 1; min-width: 0; }
.lst-verdict-text b { color: var(--ink); }
/* A listing's rows: each opens in place (row() in js/ui.js). */
.rows { margin: var(--space-3) 0 var(--space-4); }
.rows .cat-sum { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The verdict's line wraps: what was not checked is said on it, never cut off. */
.rows [data-row="verdict"] .cat-sum { white-space: normal; }
/* A portal row's step to do now is the point of the row: it wraps, never cut off. */
.rows [data-portal] .cat-sum { white-space: normal; }
.row + .row { border-top: 1px solid var(--line); }
.catrow .chev .icon { transition: transform .15s; }
.catrow[aria-expanded="true"] .chev .icon { transform: rotate(180deg); }
.row-body { background: var(--surface-raised); padding: var(--space-3) var(--space-4) var(--space-4); font-size: var(--text-sm); color: var(--ink-soft);
  /* A new formatting context, so a first child's top margin stays inside the
     body rather than showing the list's grey behind it. */
  display: flow-root; }
/* The body's own padding is the space above its first line, the same in every row. */
.row-body > :first-child, .row-body > :first-child > :first-child { margin-top: 0; }
/* So does what follows a map dock with no map drawn in it. */
.row-body > .map-dock:first-child:not(:has(> :not(:empty))) + * { margin-top: 0; }
.row-body p { margin: var(--space-2) 0 0; }
.row-body .reg-row { padding: var(--space-2) 0; }
.row-body .reg-row:first-child { padding-top: 0; }
.row-body .reg-name { display: block; color: var(--ink); }
/* A short neutral fact inside an opened row: never a verdict colour, never a control. */
.tag { display: inline-block; font-size: var(--text-xs); font-weight: 600; border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2); margin-left: var(--space-2); background: var(--accent-soft); color: var(--ink); vertical-align: 1px; }
.tag.t-new { background: var(--accent); color: var(--on-accent); margin: 0 var(--space-2) 0 0; }
/* A list item's number, the same number its pin carries on the map. */
.pin-n { display: inline-grid; place-items: center; flex: none; min-width: var(--space-5); height: var(--space-5);
  border-radius: var(--radius-pill); background: var(--accent-soft); color: var(--ink); font-size: var(--text-xs); margin-right: var(--space-2); }
.dev-row { display: flex; align-items: baseline; flex-wrap: wrap; padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.dev-row:last-child { border-bottom: 0; }
.row-body .fam-links { margin: 0 0 var(--space-1) var(--space-4); font-size: var(--text-sm); color: var(--ink-faint); }
.fam-links a { color: var(--link); display: inline-flex; align-items: center; min-height: var(--touch); }
/* A school's name takes the line beside its number; its tags wrap below it. */
/* A school's name, or an application's line, takes the line beside its
   number; its tags wrap below it rather than squeezing it. */
.dev-list .pick > span[data-content] { flex: 1 1 calc(100% - var(--space-5) - var(--space-4)); }
.fam-part + .fam-part { margin-top: var(--space-4); }
/* A part heading with an icon stays one line high, like one without. */
.fam-part > .sub-h { display: flex; align-items: center; gap: var(--space-1); }
.fam-kind { margin: var(--space-3) 0 0; font-weight: 600; color: var(--ink); }
.fam-services { list-style: none; margin: 0; padding: 0; }
.fam-service { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-2) 0; }
.fam-service-name { font-weight: 600; min-width: 0; }
.fam-rating { font-size: var(--text-sm); color: var(--ink-soft); }

/* Charts (chart-view.js): HTML, never SVG. Neutral ink for this place, the
   faint ink for Greater Sydney or NSW, never a verdict colour. Both fills meet
   3:1 against the row in light and dark (WCAG non-text contrast). */
.scale { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-1); }
.scale-step { height: var(--space-2); border-radius: var(--radius-pill); border: 1px solid var(--ink-faint); }
.scale-step.on { background: var(--accent); border-color: var(--accent); }
.pbar { display: flex; flex-direction: column; gap: var(--space-1); margin-top: var(--space-3); }
.pbar-label, .crime-name, .pbar-none, .rbar-head { margin: 0; }
.pbar-label { font-size: var(--text-sm); }
.pbar-none, .rbar-head { font-size: var(--text-sm); color: var(--ink-soft); }
.pbar-row, .rbar { display: flex; align-items: center; gap: var(--space-2); }
.pbar-tracks { flex: 1; display: flex; gap: var(--space-1); min-width: 0; }
.bar-track { flex: 1; height: var(--space-2); border-radius: var(--radius-pill); background: var(--accent-soft); overflow: hidden; }
.bar-fill { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--accent); }
.bar-fill.sydney { background: var(--ink-faint); }
.pbar-n, .rbar-n { flex: none; min-width: var(--space-7); text-align: right; font-size: var(--text-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
.sydney .pbar-n, .rbar.sydney .rbar-n, .rbar.sydney .rbar-label { color: var(--ink-soft); font-weight: 400; }
.pbar-key { display: flex; gap: var(--space-4); margin: var(--space-3) 0 0; font-size: var(--text-xs); color: var(--ink-soft); }
.pbar-key > span { display: inline-flex; align-items: center; gap: var(--space-1); }
.key-swatch { width: var(--space-3); height: var(--space-2); border-radius: var(--radius-pill); background: var(--accent); }
.key-swatch.sydney { background: var(--ink-faint); }
.crime { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-1); }
.crime-name { font-weight: 600; }
.cols { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-2); align-items: end;
  height: calc(var(--space-7) + var(--space-5)); }
.col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; gap: var(--space-1); }
.col-n { font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.col-area { flex: 1; width: 100%; display: flex; align-items: flex-end; }
.col-bar { width: 100%; border-radius: var(--space-1) var(--space-1) 0 0; background: var(--accent); }
.col-years { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--space-2);
  font-size: var(--text-xs); color: var(--ink-soft); text-align: center; font-variant-numeric: tabular-nums; }
.rbars { display: flex; flex-direction: column; gap: var(--space-1); margin-top: var(--space-2); }
.rbar-label { flex: none; width: calc(var(--space-7) + var(--space-6)); font-size: var(--text-sm); overflow-wrap: anywhere; }

.dev-row > span[data-content] { flex: 1; min-width: 0; }
/* What is being filtered on: plain small text, not a badge. */
.fline { margin: 0; font-size: var(--text-sm); color: var(--ink-soft); }
/* A required statement that is not a notice: one plain small line. */
.fine { margin: var(--space-3) 0 0; font-size: var(--text-xs); color: var(--ink-soft); text-align: center; }
/* A field label with its explanation beside it, the body opening below both. */
.flabel-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; column-gap: var(--space-3); }
.flabel-row .explain { display: contents; }
.flabel-row .explain-body { flex-basis: 100%; margin-bottom: var(--space-2); }
.flabel-row .flabel { margin-bottom: 0; }
.row-body .chiprow { padding-top: var(--space-3); }
/* ── connect-alerts: each portal's steps, and preferences' Alerts section ── */
.setup-steps { list-style: none; margin: var(--space-3) 0; padding: 0; }
.setup-step { display: flex; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--line); }
.setup-step:last-child { border-bottom: 0; }
.setup-step-main { flex: 1; min-width: 0; }
.setup-step-title { margin: 0; font-weight: 600; color: var(--ink); }
.setup-step-detail { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--ink-soft); }
/* The step a portal is up to, from what arrived: marked like a picked pin, in
   the link colour, never a verdict colour (portal-progress). */
.setup-step.current .pin-n { background: var(--link); color: var(--surface-raised); }
.setup-step.current .setup-step-title { color: var(--link); }
/* Inside a step the address takes the full width and Copy moves below it, so
   the address never breaks mid-word beside the button. */
.setup-step .addr-row { flex-wrap: wrap; }
.setup-step .addr-row .addr { flex: 1 1 100%; }
/* A done step's number becomes a tick; a step Sagashi can't see is a dashed
   ring. Neutral shapes and the link colour only: whether alerts arrive is not
   a verdict on a listing (alert-setup-in-preferences). */
.setup-step.m-done .pin-n { background: var(--accent); color: var(--on-accent); }
.setup-step.m-unseen .pin-n { background: none; border: 1.5px dashed var(--line-strong); color: var(--ink-faint); }
.setup-step-seen { margin: var(--space-1) 0 0; font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft); }
.setup-pic { display: block; margin-top: var(--space-3); }
.setup-pic img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: var(--radius-md); }
.alerts-section { margin: var(--space-4) 0; }
.alerts-section .rows { margin-top: var(--space-3); }
/* A portal row's three marks, read out as words (aria-label). */
.step-marks { display: inline-flex; gap: var(--space-1); flex: none; margin-left: var(--space-2); }
.step-mark { width: 10px; height: 10px; border-radius: var(--radius-pill); border: 1.5px solid var(--line-strong); }
.step-mark.m-done { background: var(--accent); border-color: var(--accent); }
.step-mark.m-current { border-color: var(--link); background: var(--link); }
.step-mark.m-unseen { border-style: dashed; }
/* ── shorter-lists: the compact card. Price and address share a line, the
   address giving way (ellipsis) so the price never does. */
.lst { padding: var(--space-3) var(--space-4); gap: var(--space-1); }
.lst-head { display: flex; align-items: baseline; gap: var(--space-2); min-width: 0; }
.lst-group .lst-head .lst-price, .lst-head .lst-price { flex: none; font-size: var(--text-md); font-weight: 700; margin: 0; }
.lst-head .lst-addr { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lst .lst-verdict { margin-top: 0; }
.fine.left { text-align: left; }
/* ── map-list-highlight: numbered pins match the list's number marks. Never a
   verdict colour; the selected one is the link blue. */
.map-pin { position: relative; display: grid; place-items: center; min-width: var(--space-6); height: var(--space-6); padding: 0 var(--space-1);
  border-radius: var(--radius-pill); background: #ffffff; color: #1f2326; border: 2px solid #1f2326;
  font: 700 var(--text-xs)/1 system-ui, sans-serif; box-shadow: 0 1px 2px rgba(0, 0, 0, .25); }
.map-pin.major { background: #1f2326; color: #ffffff; }
.map-pin.selected { background: #2a5a88; border-color: #2a5a88; color: #ffffff; transform: scale(1.15); box-shadow: 0 2px 6px rgba(0, 0, 0, .35); }
/* The picked pin's name, beside it (map-pick-style). Fixed colours, as the pins'. */
.map-pin-tag { position: absolute; left: calc(100% + var(--space-1)); top: 50%; transform: translateY(-50%);
  max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-pill); background: #ffffff; color: #1f2326; border: 1px solid #c6c5bd;
  font: 600 var(--text-xs)/1.2 system-ui, sans-serif; box-shadow: 0 1px 3px rgba(0, 0, 0, .25); pointer-events: none; }
/* map-house-and-dock: the property's pin, red with a house icon — the owner's one
   exception to verdict colours, and the only red thing on a map. */
.home-pin { display: flex; flex-direction: column; align-items: center; }
.home-pin-head { display: grid; place-items: center; width: calc(var(--space-6) + var(--space-2)); height: calc(var(--space-6) + var(--space-2));
  border-radius: 50%; background: #c62828; color: #ffffff; border: 2px solid #ffffff; box-shadow: 0 2px 6px rgba(0, 0, 0, .35); }
.home-pin::after { content: ''; border: var(--space-2) solid transparent; border-top-color: #c62828; border-bottom: 0; }
/* The map draws light in both themes, so its selected pin keeps the light
   theme's link blue above; the list's own selection follows the theme. */
.dev-row { display: block; padding: 0; }
.pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); width: 100%; min-height: var(--touch);
  padding: var(--space-2) var(--space-2); margin: 0; background: none; border: 0; border-radius: var(--radius-sm);
  font: inherit; color: inherit; text-align: left; cursor: pointer; }
.pick > span[data-content] { flex: 1; min-width: 0; }
.pick:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
/* Picked: filled across the row, never a bar on one edge (map-pick-style). */
.pick[aria-pressed="true"] { background: var(--link-soft); border-radius: var(--radius-sm); }
.pick[aria-pressed="true"] .pin-n { background: var(--link); color: var(--surface-raised); }
/* The map sticks while its row's list scrolls; a picked item lands below it. */
.list.rows { overflow: clip; --dock-head: calc(var(--space-7) + var(--space-4)); }
/* Every row's header is one height, docked or not; only the verdict's line wraps. */
.list.rows > .row:not([data-row="verdict"]) > .catrow { height: var(--dock-head); }
/* map-house-and-dock: a row with a numbered map docks its header, and the map below it,
   at the top while its list scrolls. --dock-head is every row header's height, fixed here so
   the map's band can sit exactly below; the negative top closes the viewport's padding band. */
.row:has(.map-dock) > .catrow { position: sticky; top: calc(-1 * var(--space-1)); z-index: 3; height: var(--dock-head); }
/* !important because Google's library sets position: relative inline on the map's element, which beats any ordinary rule. */
/* map-pick-style: the map stays a rounded card, inside a solid band that docks under the
   header. The band sticks, not the map: Google sets position: relative inline on the map's
   own element. With no map drawn the band has nothing in it and takes no space. */
.map-dock:has(> :not(:empty)) { position: sticky; top: calc(var(--dock-head) - var(--space-1)); z-index: 2;
  margin: 0 calc(-1 * var(--space-4)) var(--space-2); padding: var(--space-2) var(--space-4) var(--space-3);
  background: var(--surface-raised); box-shadow: 0 2px 6px rgba(0, 0, 0, .18); }
.map-dock > .row-map:not(:empty) { margin: 0; }
.row-body .pick { scroll-margin-top: calc(var(--dock-head) + 260px + var(--space-2) + var(--space-3) + var(--space-2)); }

/* ---------- above a phone (app-layout) ----------
   Last in the file, so these override the phone rules above them. */
/* One centred column of a readable width, never stretched across the window. */
.adm-means { color: var(--ink-soft); font-size: var(--text-sm); margin: 0 0 var(--space-3); }
.adm-filters { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
.adm-bulk { margin-bottom: var(--space-4); }
.adm-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.btn.adm-small { width: auto; }
.adm-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); margin-bottom: var(--space-2); }
.adm-all { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--touch); font-size: var(--text-sm); }
.adm-list { border-top: 1px solid var(--line); }
.adm-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--line); align-items: start; }
.adm-pick { width: var(--space-4); height: var(--space-4); margin-top: var(--space-1); }
.adm-office { font-weight: 600; }
.adm-origin { display: block; font-size: var(--text-sm); overflow-wrap: anywhere; }
.adm-state, .adm-detail { font-size: var(--text-sm); overflow-wrap: anywhere; }
.adm-detail { color: var(--ink-soft); }
.adm-error { color: var(--ink); font-weight: 600; }
.btn.ghost.adm-edit { width: auto; display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--touch); padding: 0 var(--space-2); }
.adm-form { display: grid; gap: var(--space-3); margin-bottom: var(--space-4); }
.adm-field { display: grid; gap: var(--space-1); font-size: var(--text-sm); }
.adm-problems { margin: var(--space-2) 0 0; padding-left: var(--space-4); }
/* The admin area's two pages, as tabs at the top of each. */
.adm-tabs { margin-bottom: var(--space-4); }
/* The crawl report (crawl-report): its rows are the admin page's, a night opens in place. */
.crw-heading { font-size: var(--text-md); margin: var(--space-4) 0 var(--space-2); }
.crw-row { grid-template-columns: minmax(0, 1fr); }
.crw-night { border-bottom: 1px solid var(--line); }
.crw-summary { display: grid; gap: var(--space-1); padding: var(--space-3) 0; min-height: var(--touch); cursor: pointer; }
.crw-sites { padding-left: var(--space-3); border-top: 1px solid var(--line); }
.crw-sites .crw-row:last-child { border-bottom: 0; }

@media (min-width: 541px) {
  .app { --layout: middle; }
  .viewport, .progress, .foot { padding-inline: max(var(--space-4), calc((100% - var(--column)) / 2)); }
  .viewport.flush { padding-inline: max(0%, calc((100% - var(--column)) / 2)); }
}

/* A list and the home picked from it side by side, each scrolling on its own.
   The home shown is marked like a picked item, never in a verdict colour. */
@media (min-width: 1024px) {
  .app { --layout: wide; }
  .viewport.split { display: grid; grid-template-columns: var(--list-width) 1fr; min-height: 0; overflow: hidden; padding: 0; }
  .split-list { overflow-y: auto; padding: var(--space-1) var(--space-4) var(--space-5); border-right: 1px solid var(--line); }
  .pane { overflow-y: auto; background: var(--surface); padding: var(--space-5) max(var(--space-5), calc((100% - var(--column)) / 2)); }
  .pane-empty { min-height: 100%; display: grid; place-content: center; text-align: center; color: var(--ink-soft); }
  .pane-empty p { margin: 0 0 var(--space-2); }
  /* On this tint --ink-faint falls just short of 4.5:1 in the dark theme. */
  [data-listing][aria-current="true"] { --ink-faint: var(--ink-soft); background: var(--link-soft); box-shadow: inset 0 0 0 2px var(--link); }
}

/* ---------- a public question page (question-pages) ---------- */
/* The page's own reading column, drawn from the app's tokens. It scrolls as a
   document, and links are full-width targets, as the app's cards are. */
.qp-page { height: auto; }
.qp-main { box-sizing: border-box; max-width: 640px; margin: 0 auto; padding: var(--space-4) var(--space-4) var(--space-6); }
.qp-brand { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--touch); color: var(--ink); }
.qp-title { margin: var(--space-3) 0 var(--space-2); font-size: var(--text-xl); line-height: 1.25; color: var(--ink); }
.qp-answer { margin: 0 0 var(--space-1); color: var(--ink); }
.qp-answer strong { font-weight: 600; }
.qp-part { margin-top: var(--space-5); }
.qp-part a.btn { box-sizing: border-box; text-decoration: none; }
.qp-foot { margin-top: var(--space-5); border-top: 1px solid var(--line); font-size: var(--text-xs); }
.qp-foot a { display: inline-flex; align-items: center; min-height: var(--touch); color: var(--link); }
.qp-answers { margin: var(--space-2) 0 0; }
.qp-answers div { display: flex; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--line); }
.qp-answers dt { flex: none; color: var(--ink-soft); }
.qp-answers dd { margin: 0; text-align: right; color: var(--ink); overflow-wrap: anywhere; }
/* The same rows as the home page's lists of questions: a full-width link with a chevron. */
.qp-related { margin: var(--space-2) 0 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.qp-related li { border-bottom: 1px solid var(--line); }
.qp-related a { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  min-height: var(--touch); padding-block: var(--space-2); color: var(--link); text-decoration: none; font-weight: 600; }
.qp-related a:hover { text-decoration: underline; }
.qp-related svg { flex: none; }
