/* PropertyLane. Implements DESIGN.md - warm paper under cool glass.
   Glass throughout at 84% opacity so contrast holds over any background, and
   one sheet per section rather than one panel per row: a list is a single
   compositing layer, which is what keeps it smooth on a phone. */

:root {
  --bg:        oklch(0.970 0.006  75);
  --page-bg:   radial-gradient(120% 90% at 15% -10%, oklch(0.985 0.014 85) 0%, transparent 55%),
               radial-gradient(100% 80% at 100% 0%, oklch(0.955 0.020 200) 0%, transparent 60%),
               var(--bg);
  --surface:   oklch(0.995 0.004  75);
  --text:      oklch(0.250 0.012  60);
  --text-mute: oklch(0.500 0.010  60);
  --border:    oklch(0.880 0.008  70);
  --accent:    oklch(0.520 0.110 195);
  --accent-dim:oklch(0.520 0.110 195 / 0.10);

  --state-pass:       oklch(0.480 0.070 150);
  --state-fail:       oklch(0.500 0.100  30);
  --state-no-reserve: var(--accent);
  --state-review:     oklch(0.480 0.080  85);

  --glass-tint: 84%;
  --glass-blur: 24px;

  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, monospace;
  --ease: cubic-bezier(0.25, 1, 0.5, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:        oklch(0.215 0.010 60);
    --page-bg:   radial-gradient(120% 90% at 15% -10%, oklch(0.280 0.022 85) 0%, transparent 55%),
                 radial-gradient(100% 80% at 100% 0%, oklch(0.265 0.030 200) 0%, transparent 60%),
                 var(--bg);
    --surface:   oklch(0.285 0.010 60);
    --text:      oklch(0.945 0.005 75);
    --text-mute: oklch(0.700 0.008 70);
    --border:    oklch(0.400 0.012 65);
    --accent:    oklch(0.760 0.100 195);
    --accent-dim:oklch(0.760 0.100 195 / 0.14);
    --state-pass:   oklch(0.780 0.080 150);
    --state-fail:   oklch(0.740 0.100  30);
    --state-review: oklch(0.800 0.090  85);
    --glass-tint: 78%;
  }
}

:root[data-theme="dark"] {
  --bg:        oklch(0.215 0.010 60);
  --page-bg:   radial-gradient(120% 90% at 15% -10%, oklch(0.280 0.022 85) 0%, transparent 55%),
               radial-gradient(100% 80% at 100% 0%, oklch(0.265 0.030 200) 0%, transparent 60%),
               var(--bg);
  --surface:   oklch(0.285 0.010 60);
  --text:      oklch(0.945 0.005 75);
  --text-mute: oklch(0.700 0.008 70);
  --border:    oklch(0.400 0.012 65);
  --accent:    oklch(0.760 0.100 195);
  --accent-dim:oklch(0.760 0.100 195 / 0.14);
  --state-pass:   oklch(0.780 0.080 150);
  --state-fail:   oklch(0.740 0.100  30);
  --state-review: oklch(0.800 0.090  85);
  --glass-tint: 78%;
}

:root[data-theme="light"] {
  --bg:        oklch(0.970 0.006  75);
  --page-bg:   radial-gradient(120% 90% at 15% -10%, oklch(0.985 0.014 85) 0%, transparent 55%),
               radial-gradient(100% 80% at 100% 0%, oklch(0.955 0.020 200) 0%, transparent 60%),
               var(--bg);
  --surface:   oklch(0.995 0.004  75);
  --text:      oklch(0.250 0.012  60);
  --text-mute: oklch(0.500 0.010  60);
  --border:    oklch(0.880 0.008  70);
  --accent:    oklch(0.520 0.110 195);
  --accent-dim:oklch(0.520 0.110 195 / 0.10);
  --state-pass:   oklch(0.480 0.070 150);
  --state-fail:   oklch(0.500 0.100  30);
  --state-review: oklch(0.480 0.080  85);
  --glass-tint: 84%;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0; min-height: 100vh;
  background: var(--page-bg) fixed;
  color: var(--text); font-family: var(--sans);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Measured by app.js, because both bars are fixed and both grow with the OS
     text size. The literals are the fallback for a first paint and for no-JS. */
  padding-bottom: calc(var(--nav-h, 4.6rem) + 0.9rem);
}

.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
a { color: inherit; text-decoration: none; }

/* Announced, not shown. */
.sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
      overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ---- glass ------------------------------------------------------------- */
.panel {
  background: color-mix(in oklch, var(--surface) var(--glass-tint), transparent);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
  border: 1px solid color-mix(in oklch, var(--border) 65%, transparent);
  border-radius: 14px;
}
@media (prefers-reduced-transparency: reduce) {
  .panel, .bar { background: var(--surface); backdrop-filter: none;
                 -webkit-backdrop-filter: none; }
}

/* ---- chrome ------------------------------------------------------------ */
.bar {
  position: fixed; left: 0; right: 0; z-index: 10;
  background: color-mix(in oklch, var(--surface) var(--glass-tint), transparent);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
}
header.bar {
  top: 0; display: flex; align-items: center; gap: 0.5rem 0.75rem; flex-wrap: wrap;
  padding: 0.7rem clamp(0.9rem, 3vw, 1.6rem);
  border-bottom: 1px solid color-mix(in oklch, var(--border) 60%, transparent);
}
.wordmark { font-weight: 620; letter-spacing: -0.015em; font-size: 1rem; flex: 0 0 auto; }
/* Shrinkable, so the bar stays one row on a phone and wraps only when the text
   size makes one row genuinely impossible. It was costing 93px of an 844px
   triage screen. */
.version { margin-left: auto; flex: 0 1 auto; min-width: 0;
           font-size: 0.6875rem; color: var(--text-mute);
           font-family: var(--mono); text-align: right; line-height: 1.35; }
.iconbtn {
  border: 1px solid var(--border); background: transparent; color: var(--text-mute);
  border-radius: 8px; padding: 0.32rem 0.55rem; font: inherit; font-size: 0.75rem;
  cursor: pointer; min-height: 32px;
}
.iconbtn:hover { color: var(--text); }
.iconbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* auto-fit, not repeat(4): at large OS text sizes four fixed columns are
   narrower than the word "Assumptions" and the bar overflowed the viewport by
   8px. Fewer, wider columns and a second row instead. */
nav.bar {
  bottom: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(4.5rem, 1fr));
  padding: 0.35rem 0.3rem calc(0.35rem + env(safe-area-inset-bottom));
  border-top: 1px solid color-mix(in oklch, var(--border) 60%, transparent);
}
nav.bar a {
  font-size: 0.78125rem; color: var(--text-mute); padding: 0.6rem 0.2rem;
  min-height: 44px; border-radius: 10px; text-align: center; white-space: nowrap;
  display: flex; align-items: center; justify-content: center; gap: 0.3rem;
  transition: color 180ms var(--ease), background 180ms var(--ease);
}
nav.bar a[aria-current="page"] { color: var(--accent); background: var(--accent-dim);
                                 font-weight: 550; }
nav.bar a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
nav.bar .n { font-family: var(--mono); font-variant-numeric: tabular-nums;
             font-size: 0.75rem; opacity: 0.8; }

main { padding: calc(var(--header-h, 4.5rem) + 0.4rem) clamp(0.75rem, 3vw, 1.6rem) 0;
       max-width: 1300px; margin: 0 auto; }

/* ---- furniture --------------------------------------------------------- */
.eyebrow {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--text-mute); font-weight: 560; margin: 1.5rem 0 0.5rem;
  display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap;
}
.eyebrow .count { font-family: var(--mono); letter-spacing: 0; }
.eyebrow .switch { margin-left: auto; display: flex; gap: 0.3rem; letter-spacing: 0; }
.eyebrow .switch a { font-size: 0.6875rem; padding: 0.15rem 0.5rem; border-radius: 6px;
                     border: 1px solid color-mix(in oklch, var(--border) 70%, transparent);
                     text-transform: none; }
.eyebrow .switch a[aria-current="true"] { color: var(--accent); border-color: var(--accent);
                                          background: var(--accent-dim); }

.caveat {
  font-size: 0.8125rem; line-height: 1.55; color: var(--text-mute);
  padding: 0.85rem 1rem; margin: 0.75rem 0 0; border-radius: 12px;
  background: color-mix(in oklch, var(--surface) 60%, transparent);
  border: 1px dashed color-mix(in oklch, var(--border) 85%, transparent);
}
.caveat strong { color: var(--text); font-weight: 560; }
.caveat + .caveat { margin-top: 0.5rem; }

/* ---- the shared header ------------------------------------------------- */
/* What holds for every row is a property of the set, not of any row in it, so
   it is said once here instead of 58 times below. Measured before this existed:
   the bid, its caption and the badge set were byte-identical across all 58 rows
   and took 44% of each row's area. This is the sheet's header, not a panel of
   its own: nesting a second glass surface inside the list would be a card grid
   with one card. */
.uniform {
  padding: 0.7rem 1rem 0.75rem;
  background: color-mix(in oklch, var(--text) 3.5%, transparent);
  border-bottom: 1px solid color-mix(in oklch, var(--border) 55%, transparent);
}
/* A grid, not a wrapped sentence. Separating the clauses with punctuation or a
   divider leaves an orphaned mark at the start of every wrapped line, and this
   block wraps at almost every width. Columns align instead. */
.uniform .all {
  margin: 0; font-size: 0.8125rem; line-height: 1.4; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
  gap: 0.25rem 1.1rem;
}
.uniform .all + .all { margin-top: 0.55rem; }
.uniform .lead {
  grid-column: 1 / -1;
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.09em;
  font-weight: 560; color: var(--text-mute);
}
.uniform .cl { color: var(--text-mute); text-wrap: pretty; }
/* Prose, not a clause. `.lead` is a label and sets everything uppercase. */
.uniform .note { margin: 0.55rem 0 0; font-size: 0.75rem; line-height: 1.5;
                 color: var(--text-mute); max-width: 60ch; text-wrap: pretty; }
.uniform .cl b { font-weight: 560; color: var(--text); letter-spacing: -0.01em; }
/* The badges are their own row and size to content rather than to the columns. */
.uniform .states { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.uniform .states .lead { flex: 0 0 auto; }

/* ---- rows -------------------------------------------------------------- */
.sheet { overflow: hidden; }
.row {
  display: flex; align-items: stretch;
  border-top: 1px solid color-mix(in oklch, var(--border) 45%, transparent);
  transition: background 160ms var(--ease);
}
.uniform + .row, .row:first-child { border-top: 0; }
.row:hover, .row[aria-selected="true"] { background: color-mix(in oklch, var(--accent) 6%, transparent); }

/* Rank, then who, then the clock. Flex rather than grid so the queue can drop
   the rank column without leaving a gutter behind. */
.rowmain {
  flex: 1 1 auto; min-width: 0; cursor: pointer;
  display: flex; align-items: baseline; gap: 0.7rem;
  padding: 0.7rem 0.4rem 0.75rem 0.85rem;
}
.rowmain:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px;
                         border-radius: 10px; }

.rank { flex: 0 0 1.5rem; text-align: right; font-size: 0.8125rem; font-weight: 500;
        color: var(--text-mute); letter-spacing: -0.02em; }
.who { flex: 1 1 auto; min-width: 0; display: block; }

.addr { font-size: 0.9375rem; font-weight: 500; letter-spacing: -0.005em; display: block; }
.meta { font-size: 0.8125rem; color: var(--text-mute); display: block; margin-top: 0.05rem; }
.meta .ref { font-family: var(--mono); }

/* Figures appear only where they differ across the set. A figure and its label
   are one unit so a wrap never separates them. */
.figs { display: flex; flex-wrap: wrap; gap: 0.15rem 1.2rem; margin-top: 0.45rem; }
.figs .f { display: flex; align-items: baseline; gap: 0.4rem; }
.figs b { font-family: var(--mono); font-variant-numeric: tabular-nums;
          font-size: 1rem; font-weight: 560; letter-spacing: -0.02em; }
.figs b.soft { font-weight: 500; color: var(--text-mute); font-size: 0.9375rem; }
.figs i { font-style: normal; font-size: 0.75rem; color: var(--text-mute); }
.figs i.absent { font-size: 0.8125rem; }
/* Contradicted by the property's own last sale. Marked, not withdrawn: absent
   and doubtful are different facts and 8.2 keeps them apart. */
.figs b.doubted { text-decoration: underline dotted
                  color-mix(in oklch, var(--state-review) 80%, transparent);
                  text-underline-offset: 4px; }

/* The clock. Always present, never coloured, never counting down: Principle 2. */
.edge { flex: 0 0 auto; text-align: right; align-self: center; }
.edge .d { display: block; font-family: var(--mono); font-variant-numeric: tabular-nums;
           font-size: 1.125rem; font-weight: 560; letter-spacing: -0.03em; line-height: 1.1; }
.edge .u { display: block; font-size: 0.6875rem; color: var(--text-mute); line-height: 1.25;
           max-width: 6.5em; }

.tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }

/* ---- state badges: never colour alone ---------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.6875rem; font-weight: 580; letter-spacing: 0.045em;
  text-transform: uppercase; padding: 0.2rem 0.5rem 0.2rem 0.4rem;
  border-radius: 6px; border: 1px solid currentColor; white-space: nowrap;
}
.badge .mark { font-family: var(--mono); font-size: 0.8125rem; line-height: 1; opacity: 0.9; }
.badge.pass      { color: var(--state-pass); }
.badge.fail      { color: var(--state-fail); }
.badge.noreserve { color: var(--state-no-reserve); background: var(--accent-dim); }
.badge.review    { color: var(--state-review); }

.chip {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 0.6875rem; color: var(--text-mute); letter-spacing: 0.02em;
  padding: 0.2rem 0.5rem; border-radius: 6px;
  border: 1px solid color-mix(in oklch, var(--border) 70%, transparent);
}
.chip.window { color: var(--text); border-color: color-mix(in oklch, var(--text) 35%, transparent); }

/* ---- favourite: form, not colour -------------------------------------- */
.fav {
  flex: 0 0 auto; width: 52px; display: grid; place-items: center;
  background: none; border: 0; cursor: pointer; color: var(--text-mute);
  border-radius: 10px; margin: 0.35rem 0.35rem 0.35rem 0;
  transition: color 160ms var(--ease), background 160ms var(--ease);
}
.fav:hover { color: var(--text); background: color-mix(in oklch, var(--text) 7%, transparent); }
.fav:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.fav svg { width: 21px; height: 21px; display: block; }
.fav[aria-pressed="true"] { color: var(--text); }

/* ---- detail ------------------------------------------------------------ */
.detail { padding: 1.15rem 1.15rem 1.35rem; }
.detail h2 { margin: 0; font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em;
             text-wrap: balance; }
.detail .sub { color: var(--text-mute); font-size: 0.875rem; margin: 0.15rem 0 0; }
.detail .badges { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.85rem 0 0; }

.headline { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem 1.5rem;
            margin: 1.25rem 0 0.25rem; }
.headline .big { font-family: var(--mono); font-variant-numeric: tabular-nums;
                 font-size: 1.953rem; font-weight: 600; letter-spacing: -0.035em; }
.headline .big.none { font-size: 1.25rem; font-weight: 400; color: var(--text-mute); }
.headline .lbl { font-size: 0.75rem; color: var(--text-mute); text-transform: uppercase;
                 letter-spacing: 0.08em; }
.headline .beside { font-family: var(--mono); font-variant-numeric: tabular-nums;
                    font-size: 0.9375rem; color: var(--text-mute); }

table { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
th { text-align: left; font-weight: 500; color: var(--text-mute); font-size: 0.75rem;
     text-transform: uppercase; letter-spacing: 0.07em; padding: 0 0 0.4rem; }
th:last-child, td:last-child { text-align: right; }
td { padding: 0.34rem 0; border-top: 1px solid color-mix(in oklch, var(--border) 40%, transparent); }
td.v { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
tr.total td { font-weight: 600;
              border-top: 1.5px solid color-mix(in oklch, var(--text) 30%, transparent); }
/* A range is two figures, not one: at large OS text sizes a nowrap range was
   289px wide in a 390px viewport and took the page 62px past the fold sideways.
   Each figure stays unbroken; the range breaks between them. */
tr.prov td.v { color: var(--text-mute); }
td.v.range, tr.prov td.v { white-space: normal; }
td.v .r { white-space: nowrap; }

.assumed { text-decoration: underline dotted color-mix(in oklch, var(--state-review) 75%, transparent);
           text-underline-offset: 3px; }

/* Comparables. Wide, so it scrolls in its own box rather than pushing the page
   sideways; the first column stays put because the rest is meaningless without
   knowing which sale it belongs to. */
.comps { display: block; overflow-x: auto; white-space: nowrap; font-size: 0.8125rem; }
.comps th, .comps td { padding-right: 0.7rem; }
.comps th:last-child, .comps td:last-child { padding-right: 0; text-align: right; }
.comps td.v { font-size: 0.8125rem; }
/* The rate is the column the table exists to show; the rest is corroboration. */
.comps td.strong { font-weight: 560; color: var(--text); }
/* Fenced out, kept visible. Nothing disappears for failing a test: the reader
   has to be able to see what was excluded and disagree with it. */
.comps tr.excluded td { color: var(--text-mute); text-decoration: line-through;
                        text-decoration-color: color-mix(in oklch, var(--text-mute) 50%, transparent); }
.comps tr.excluded td.strong { font-weight: 500; }
.comps .x { text-decoration: none; display: inline-block; font-size: 0.625rem;
            text-transform: uppercase; letter-spacing: 0.06em; font-weight: 580;
            color: var(--state-review); border: 1px solid currentColor;
            border-radius: 4px; padding: 0 0.25rem; vertical-align: 1px; }
tr.flagged td:first-child { font-weight: 550; }
/* Provenance was in a title attribute, which never fires on touch, and half the
   stated workload is a phone. It is rendered instead, next to the figure it
   qualifies: Principle 4, the caveat lives where the number is read. */
.why { display: block; font-size: 0.6875rem; line-height: 1.4; color: var(--state-review);
       margin-top: 0.05rem; max-width: 34ch; }

.warn { display: flex; gap: 0.5rem; font-size: 0.8125rem; color: var(--text-mute);
        padding: 0.3rem 0; align-items: baseline; }
.warn .m { font-family: var(--mono); color: var(--state-review); flex: 0 0 auto; }

/* The corroboration line. Shown whether it passes or fails, because a check the
   reader only meets on failure is one they cannot calibrate. */
.check { display: flex; gap: 0.55rem; align-items: baseline; margin: 0.55rem 0 0;
         font-size: 0.8125rem; line-height: 1.5; color: var(--text-mute);
         max-width: 62ch; }
.check .m { font-family: var(--mono); flex: 0 0 auto; color: var(--state-pass); }
.check b { font-weight: 560; color: var(--text); }
.check.disputed { color: var(--text); }
.check.disputed .m { color: var(--state-review); }

.actions { display: flex; gap: 0.5rem; margin-top: 1.25rem; }
.btn {
  flex: 1 1 auto; min-height: 44px; border-radius: 10px; font: inherit; font-size: 0.875rem;
  font-weight: 520; cursor: pointer; padding: 0.6rem 1rem;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  border: 1px solid var(--border); background: transparent; color: var(--text);
  transition: background 160ms var(--ease), border-color 160ms var(--ease);
}
.btn:hover { background: color-mix(in oklch, var(--text) 6%, transparent); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.btn svg { width: 18px; height: 18px; }

/* ---- assumptions ------------------------------------------------------- */
.field { display: grid; gap: 0.15rem; padding: 0.8rem 1rem;
         border-top: 1px solid color-mix(in oklch, var(--border) 45%, transparent); }
.field:first-child { border-top: 0; }
.field .top { display: flex; align-items: center; gap: 0.6rem; }
.field .name { font-size: 0.875rem; font-weight: 500; }
.field .val { margin-left: auto; font-family: var(--mono);
              font-variant-numeric: tabular-nums; font-size: 0.875rem; }
.field .src { font-size: 0.75rem; color: var(--text-mute); }
.field .src .flag { color: var(--state-review); font-weight: 550; }

/* ---- empty state ------------------------------------------------------- */
.empty { padding: 2.6rem 1.5rem; text-align: center; }
.empty svg { width: 26px; height: 26px; color: var(--text-mute); opacity: 0.7; }
.empty p { margin: 0.85rem auto 0; max-width: 40ch; font-size: 0.875rem;
           color: var(--text-mute); line-height: 1.6; }
/* An empty state that names the likely cause should also undo it. */
.empty .out { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center;
              margin-top: 1.15rem; }
.empty .out .btn { flex: 0 1 auto; }

/* ---- sign in ----------------------------------------------------------- */
.gate { min-height: 100vh; display: grid; place-items: center; padding: 1.5rem; }
.gate form { width: min(24rem, 100%); padding: 1.6rem; display: grid; gap: 0.85rem; }
.gate h1 { margin: 0; font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em; }
.gate p { margin: 0; font-size: 0.8125rem; color: var(--text-mute); }
.gate input {
  min-height: 44px; padding: 0.55rem 0.7rem; border-radius: 10px; font: inherit;
  color: var(--text); border: 1px solid var(--border);
  background: color-mix(in oklch, var(--surface) 55%, transparent);
}
.gate input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.gate .bad { color: var(--state-fail); }

/* ---- desk layout ------------------------------------------------------- */
@media (min-width: 900px) {
  body { padding-bottom: 1.5rem; }
  .split { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
           gap: 1.1rem; align-items: start; }
  /* The panel is taller than the viewport, so pinning its top alone put the only
     action on it 327px below the fold, first reachable after 12 000px of list
     scroll. It scrolls itself instead. */
  .split .col-detail {
    position: sticky; top: calc(var(--header-h, 4.5rem) + 0.4rem);
    /* The nav sits in the flow above this panel, so before the page is scrolled
       the panel starts below it. Sizing against the header alone left the last
       17px of the panel under the fold at rest. */
    max-height: calc(100dvh - var(--header-h, 4.5rem) - var(--nav-flow-h, 2.5rem) - 1.6rem);
    overflow-y: auto; overscroll-behavior: contain;
  }
  nav.bar { position: static; background: none; backdrop-filter: none;
            -webkit-backdrop-filter: none; border: 0;
            grid-template-columns: repeat(4, max-content); gap: 0.3rem;
            padding: 0 0 0.4rem; }
  nav.bar a { padding: 0.5rem 0.85rem; }
  .desk-hide { display: none; }
}

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ---- filters ------------------------------------------------------------ */
.filters { margin-top: 0.4rem; }
.filters > summary {
  list-style: none; cursor: pointer; padding: 0.75rem 1rem;
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  font-size: 0.875rem; font-weight: 550; min-height: 44px;
}
.filters > summary::-webkit-details-marker { display: none; }
.filters > summary::after {
  content: "▾"; color: var(--text-mute); font-size: 0.8125rem;
  transition: transform 180ms var(--ease);
}
.filters[open] > summary::after { transform: rotate(180deg); }
.filters > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px;
                                   border-radius: 14px; }
.filters .on { font-size: 0.6875rem; font-weight: 580; letter-spacing: 0.04em;
               text-transform: uppercase; color: var(--accent);
               background: var(--accent-dim); padding: 0.15rem 0.45rem; border-radius: 6px; }
.filters .off { font-size: 0.75rem; font-weight: 400; color: var(--text-mute); }
.filters .hits { margin-left: auto; font-family: var(--mono);
                 font-variant-numeric: tabular-nums; font-size: 0.8125rem;
                 font-weight: 400; color: var(--text-mute); }

.filters form {
  display: grid; gap: 0.7rem 0.9rem; padding: 0.2rem 1rem 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  border-top: 1px solid color-mix(in oklch, var(--border) 45%, transparent);
  padding-top: 0.9rem;
}
.filters label, .filters fieldset { display: grid; gap: 0.25rem; margin: 0; padding: 0; border: 0; }
.filters .wide { grid-column: 1 / -1; }
.filters label > span, .filters legend {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-mute); font-weight: 560; padding: 0;
}
.filters fieldset { grid-template-columns: 1fr auto 1fr; align-items: center; gap: 0.25rem 0.4rem; }
.filters fieldset legend { grid-column: 1 / -1; }
.filters .to { font-size: 0.75rem; color: var(--text-mute); }

.filters input, .filters select {
  min-height: 42px; padding: 0.4rem 0.6rem; border-radius: 9px; font: inherit;
  font-size: 0.875rem; color: var(--text); width: 100%;
  border: 1px solid var(--border);
  background: color-mix(in oklch, var(--surface) 60%, transparent);
}
.filters input[type="number"] { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.filters input:focus-visible, .filters select:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
.filters .buttons { grid-column: 1 / -1; display: flex; gap: 0.5rem; flex-wrap: wrap;
                    margin-top: 0.2rem; }
.filters .buttons .btn { flex: 1 1 8rem; text-decoration: none; }

/* The walk-away price. The one number that answers "what is the most I should
   bid", so it is set apart from the tables rather than filed inside one. */
.walkaway { margin: 1.1rem 0 0; padding: 0.85rem 1rem; border-radius: 12px;
            background: color-mix(in oklch, var(--accent) 8%, transparent);
            border: 1px solid color-mix(in oklch, var(--accent) 30%, transparent); }
.walkaway .lbl { display: block; font-size: 0.6875rem; text-transform: uppercase;
                 letter-spacing: 0.09em; font-weight: 560; color: var(--text-mute); }
.walkaway b { display: block; font-family: var(--mono); font-variant-numeric: tabular-nums;
              font-size: 1.5625rem; font-weight: 600; letter-spacing: -0.03em;
              margin-top: 0.15rem; }
.walkaway .why { display: block; margin-top: 0.35rem; font-size: 0.75rem;
                 line-height: 1.5; color: var(--text-mute); max-width: 56ch; }

/* Nearby auctions. Deliberately quieter than a ranked row and never laid out
   like one: these carry no modelled figure, so a reader must not be able to
   mistake one for a listing that does. */
.filters .check { grid-template-columns: auto 1fr; align-items: center; gap: 0.5rem; }
.filters .check input { width: auto; min-height: 0; }
.filters .check > span { text-transform: none; letter-spacing: 0; font-size: 0.8125rem; }

.nearby { margin-top: 1rem; }
.nearby .group {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-mute); font-weight: 560;
  padding: 0.7rem 0.9rem 0.2rem;
}
.near-row { padding: 0.35rem 0.9rem 0.55rem; border-top: 1px solid var(--border); }
.near-row a { font-size: 0.875rem; }
.near-row .d { display: block; font-size: 0.8125rem; color: var(--text-mute); }
.near-row .num { font-family: var(--mono); font-size: 0.75rem; color: var(--text-mute); }

/* The second look, on the shortlist only. Quieter than a ranked row: it is
   corroboration for a figure already on the page, not a figure of its own. */
.deep .deep-row { padding: 0.6rem 0.9rem 0.7rem; border-top: 1px solid var(--border); }
.deep .deep-ref { font-size: 0.875rem; font-weight: 560; margin-bottom: 0.2rem; }
.deep .d { font-size: 0.8125rem; color: var(--text-mute); line-height: 1.5; }
.deep .d b { color: var(--text); font-weight: 560; }
.deep .d i { font-style: italic; }
