/* PropertyPartner app — the design-handoff tokens (ENGINEERING-HANDOFF §4) as a small shared CSS layer, PLUS the
   ADR-0045 Tabler token-override layer: Tabler/Bootstrap loads first (Layout.ShellHead), this file overrides only our
   brand look-and-feel. Inter (the kit's native face) for the app shell; Instrument Sans / Geist Mono kept for the
   marketing/legal islands (which also load this file); the app-dashboard palette and 8/9/12/14 radii; pill filters.
   The :root brand palette below is the LIGHT look-and-feel AND the marketing/legal island fallback; a
   :root[data-bs-theme="dark"] block re-points every brand token onto the equivalent themed --tblr-* token, so an app
   page renders fully dark instead of half-dark (ADR-0045 D6). Component rules read the brand tokens, so they follow. */

/* ── Self-hosted fonts (latin subset) ────────────────────────────────────────────────────────────── */
/* Inter (ADR-0045 D3) — the kit's native face, self-hosted (@fontsource/inter 5.3.0), scoped to the app shell below. */
@font-face { font-family:'Inter'; font-style:normal; font-weight:400; font-display:swap; src:url(/assets/vendor/inter-5.3.0/inter-latin-400-normal.woff2) format('woff2'); }
@font-face { font-family:'Inter'; font-style:normal; font-weight:500; font-display:swap; src:url(/assets/vendor/inter-5.3.0/inter-latin-500-normal.woff2) format('woff2'); }
@font-face { font-family:'Inter'; font-style:normal; font-weight:600; font-display:swap; src:url(/assets/vendor/inter-5.3.0/inter-latin-600-normal.woff2) format('woff2'); }
@font-face { font-family:'Inter'; font-style:normal; font-weight:700; font-display:swap; src:url(/assets/vendor/inter-5.3.0/inter-latin-700-normal.woff2) format('woff2'); }
/* Instrument Sans / Geist Mono — KEPT: the marketing/legal islands (and --mono) still reference them (ADR-0045 D3). */
@font-face { font-family:'Instrument Sans'; font-style:normal; font-weight:400; font-display:swap; src:url(/assets/fonts/instrument-sans-400.woff2) format('woff2'); }
@font-face { font-family:'Instrument Sans'; font-style:normal; font-weight:500; font-display:swap; src:url(/assets/fonts/instrument-sans-500.woff2) format('woff2'); }
@font-face { font-family:'Instrument Sans'; font-style:normal; font-weight:600; font-display:swap; src:url(/assets/fonts/instrument-sans-600.woff2) format('woff2'); }
@font-face { font-family:'Instrument Sans'; font-style:normal; font-weight:700; font-display:swap; src:url(/assets/fonts/instrument-sans-700.woff2) format('woff2'); }
@font-face { font-family:'Geist Mono'; font-style:normal; font-weight:400; font-display:swap; src:url(/assets/fonts/geist-mono-400.woff2) format('woff2'); }
@font-face { font-family:'Geist Mono'; font-style:normal; font-weight:500; font-display:swap; src:url(/assets/fonts/geist-mono-500.woff2) format('woff2'); }

:root {
  --blue:#2f5ce5; --blue-hover:#2449c2; --blue-tint:#eef2fe; --blue-border:#dbe4fc;
  --ink:#1f1e1b; --app-bg:#f6f5f2; --surface:#fff; --subtle:#fafaf8;
  --border:#e9e7e2; --border-soft:#e3e1dc; --row-border:#f5f4f1; --hair:#f0efeb;
  --muted:#8a887f; --secondary:#5a5954; --secondary-dark:#4d4c48;
  --orange:#b3541e; --orange-tint:#fdf1e7; --orange-row:#fdf6f0;
  --red:#b3261e; --red-tint:#fdecea;
  --green:#2f7d4f; --gray-pill:#f0efeb;
  --mono:'Geist Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --sans:'Instrument Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
}

* { box-sizing:border-box; }
html,body { margin:0; padding:0; }
body { font-family:var(--sans); color:var(--ink); background:var(--app-bg); -webkit-font-smoothing:antialiased; }
a { color:inherit; text-decoration:none; }
.mono { font-family:var(--mono); }

/* ── App shell — Tabler kit AS SHIPPED (ADR-0045) ────────────────────────────────────────────────────
   The sidebar (with its footer user menu + theme toggle) and the impersonation banner are the vendored Tabler
   navbar/dropdown/alert components (Layout.cs), so the hand-rolled .app/.sidebar/.nav-item/.topbar/.user-menu/.content chrome is
   DELETED here (D6: delete old CSS as it converts). What remains is the brand token-override layer + a few small
   bespoke shell classes, each with a reason. Tabler loads before this file, so these win by load order (D1). */
:root {
  --tblr-primary:#2f5ce5; --tblr-primary-rgb:47,92,229;      /* brand blue (repoints the kit's #066fd1) */
  --tblr-font-sans-serif:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --tblr-body-font-family:var(--tblr-font-sans-serif);
}
/* ── Dark theme (ADR-0045 D6 — dark ships via the kit's own theme mechanism, never half-dark) ─────────────────────────
   The :root brand palette above is the LIGHT look-and-feel and the island fallback (marketing/legal load this file
   WITHOUT the kit, so they never match this selector and keep the literals). On an app page the shell sets
   data-bs-theme on <html>, so THIS block re-points every brand token onto the equivalent --tblr-* token. Tabler 1.5.1
   defines each of those with light-dark(), so a var(--tblr-*) reference resolves to its DARK value HERE (this scope is
   color-scheme:dark); component rules read the brand tokens, so body + .card + every legacy component go dark rather
   than half-dark. RULE 8: the kit's dark palette is WCAG-AA by construction. The one brand exception is a lightened
   primary (#7aa2ff so active nav/links clear AA on the dark ground — #2f5ce5 ≈ 2.9:1, #7aa2ff ≈ 6.3:1); solid-fill
   buttons keep a darker brand blue just below so a white label still clears AA. Specificity ([data-bs-theme=dark] adds
   an attribute) beats the kit's own dark rule and our light :root, so these win on a dark page and nothing else. */
:root[data-bs-theme="dark"] {
  --tblr-primary:#7aa2ff; --tblr-primary-rgb:122,162,255;
  --blue:var(--tblr-primary); --blue-hover:#2449c2; --blue-tint:var(--tblr-primary-lt); --blue-border:rgba(var(--tblr-primary-rgb),.3);
  --ink:var(--tblr-body-color); --app-bg:var(--tblr-body-bg); --surface:var(--tblr-bg-surface); --subtle:var(--tblr-bg-surface-secondary);
  --border:var(--tblr-border-color); --border-soft:var(--tblr-border-color); --row-border:var(--tblr-border-color-translucent); --hair:var(--tblr-bg-surface-tertiary);
  --muted:var(--tblr-secondary); --secondary:var(--tblr-secondary); --secondary-dark:var(--tblr-body-color);
  --orange:var(--tblr-warning); --orange-tint:var(--tblr-warning-lt);
  --red:var(--tblr-danger); --red-tint:var(--tblr-danger-lt);
  --green:var(--tblr-success); --gray-pill:var(--tblr-bg-surface-secondary);
}
/* .btn-primary is a solid-fill button with a white label: in dark keep a brand blue dark enough that #fff clears AA
   (#2f5ce5 ≈ 6.5:1), not the lightened link-blue --blue (#7aa2ff → white ≈ 2.5:1). The .pp-brand-mark glyph is decorative. */
:root[data-bs-theme="dark"] .btn-primary { background:#2f5ce5; }
/* .officer-banner and .error-box carry literal tint backgrounds; the login .error-box reuses them on a kit-less
   Document page (always light), so the light literals stay ITS fallback — on a dark app page re-tint from the kit's soft
   semantic surfaces (their text colours are brand tokens, already themed above). */
:root[data-bs-theme="dark"] .officer-banner { background:var(--tblr-success-lt); border-color:transparent; }
:root[data-bs-theme="dark"] .error-box { border-color:transparent; }
/* App shell = Inter (ADR-0045 D3, the kit's native face). Declaring font-family HERE — not only overriding --sans —
   makes the WHOLE shell subtree recompute to Inter: font-family is inherited, so .page computes it to Inter and every
   descendant that doesn't re-declare it (the navbar-brand, .nav-link, .page-title, plain .pp-content body copy) inherits
   Inter, while .btn/.field/.btn-link that DO re-declare font-family:var(--sans) also resolve to Inter in this subtree.
   Scoped to Tabler's .page (only the authenticated shell), so marketing/legal (no .page) keep body's --sans = Instrument Sans. */
.page { --sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; font-family:var(--sans); }
/* Vertical rhythm the removed .content wrapper gave page bodies (Tabler's page-body/container supply the padding). */
.pp-content { display:flex; flex-direction:column; gap:16px; }
/* Brand chip inside the sidebar navbar-brand — the blue rounded mark, now within the kit's brand element. */
.pp-brand-mark { width:26px; height:26px; border-radius:7px; background:var(--tblr-primary); display:inline-flex; align-items:center; justify-content:center; flex:none; margin-right:8px; }
.pp-brand-mark .icon { width:15px; height:15px; color:#fff; }
/* The Leads List/Map sub-nav is the kit's nested vertical dropdown now (ADR-0045 D6), indented by Tabler's
   .navbar-vertical .navbar-collapse .dropdown-menu .dropdown-item rule — the bespoke .pp-subnav layer is deleted. */
/* Login brand mark — KEPT: login is a Document page (no kit), reusing .brand-mark. */
.brand-mark { width:26px; height:26px; border-radius:7px; background:var(--blue); display:flex; align-items:center; justify-content:center; flex:none; }
.brand-mark svg { width:14px; height:14px; stroke:#fff; stroke-width:2.4; }

/* RULE 8 (ADR-0045): a visible brand focus ring on the shell's interactive elements, in both themes (the kit ships
   :focus-visible; this pins a brand-blue ring on our shell links/buttons/toggles too). */
.navbar :focus-visible, .dropdown-menu :focus-visible, .pp-impersonation :focus-visible {
  outline:2px solid var(--tblr-primary); outline-offset:2px; border-radius:6px;
}
/* The impersonation pill beside the avatar in the user menu (ADR-0040 H2; owner 2026-11-05: a pill, not a page-wide banner):
   one short line that never leaves the sidebar / top bar — every flex box from the footer down to the pill may shrink
   (min-width:0), the avatar never does, and a long name is cut with an ellipsis. On a narrow screen (the top bar, below
   Tabler's lg breakpoint) only the icon + "Impersonating" show. The badge's title and the menu header carry the whole name.
   The kit draws a badge inside a navbar link as a notification dot — absolutely placed at the link's corner and pushed half
   its width outward — which carried the pill past the sidebar's edge and over the page (persona round 3) — and the shell's
   own .badge rule (later in this file) made it an inline-block, so its name was clipped without the ellipsis. The pill's
   rules outrank both: it stays in the link's flow, so the link's width is its limit, as a flex row whose text shrinks. */
.navbar-footer, .navbar-footer .navbar-nav, .navbar-footer .nav-item.dropdown, .navbar-footer .nav-item.dropdown > .nav-link { min-width:0; max-width:100%; }
.navbar-footer .nav-item.dropdown > .nav-link > .avatar { flex-shrink:0; }
.navbar .navbar-nav .nav-link .pp-impersonation-pill { position:static; inset:auto; transform:none; display:inline-flex; align-items:center; gap:.25rem; min-width:0; max-width:100%; overflow:hidden; margin:0 0 0 .5rem; }
.pp-impersonation-pill > .icon { flex-shrink:0; }
.pp-impersonation-pill-text { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pp-impersonation { white-space:normal; overflow-wrap:anywhere; max-width:20rem; }
@media (max-width: 991.98px) { .pp-impersonation-pill-name { display:none; } }

/* ── Buttons ─────────────────────────────────────────────────────────────────────────────────────── */
.btn { display:inline-flex; align-items:center; gap:8px; font-family:var(--sans); font-size:13.5px; font-weight:600; border-radius:9px; padding:9px 16px; cursor:pointer; border:1px solid transparent; line-height:1; }
.btn svg { width:14px; height:14px; }
.btn-sm { padding:8px 14px; font-size:13px; }
.btn-primary { background:var(--blue); color:#fff; }
.btn-primary:hover { background:var(--blue-hover); }
.btn-primary svg { stroke:#fff; stroke-width:2; }
.btn-ghost { background:var(--surface); color:var(--secondary-dark); border-color:var(--border); }
.btn-ghost:hover { background:var(--app-bg); }
.btn-ghost svg { stroke:currentColor; stroke-width:2; }
.btn-block { width:100%; justify-content:center; padding:11px 16px; }
.btn-link { background:none; border:none; color:var(--blue); font-weight:600; font-size:13px; cursor:pointer; padding:0; font-family:var(--sans); }
.btn-link:hover { text-decoration:underline; }

/* ── Page head ───────────────────────────────────────────────────────────────────────────────────── */
.page-head { display:flex; flex-wrap:wrap; align-items:flex-start; justify-content:space-between; gap:16px; }
.page-head > * { min-width:0; }
.page-title { font-size:23px; font-weight:700; letter-spacing:-0.01em; margin:0 0 4px; }
.page-sub { font-size:14px; color:var(--muted); }
.page-actions { display:flex; flex-wrap:wrap; gap:10px; align-items:flex-start; }
.save-form, .export-form { display:flex; gap:8px; align-items:center; margin:0; }
/* Phone width (issue #354): the header actions stack under the title, each form takes the row and its control shrinks
   to fit, so nothing is wider than the viewport and the page never scrolls sideways. */
@media (max-width:420px) {
  .page-actions, .page-actions > form { width:100%; }
  .page-actions .field-sm { flex:1 1 auto; width:auto; min-width:0; }
  .page-actions .btn { flex:0 0 auto; }
  .export-form .btn { flex:1 1 auto; justify-content:center; }
}
/* The Discover "Watch" action (ADR-0048 D3): the inline POST form beside Skip trace on the lead detail, and the map card's
   footer row (watch control + "Open lead"). Loaded on the detail, Leads and Map pages via app.css (the shell sheet). */
.pp-watch-form { display:inline-flex; margin:0; }
.pp-card-foot { display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px; }

/* ── List / Map view toggle (segmented; shared by the Leads + Map surfaces) ────────────────────────── */
.view-toggle { display:inline-flex; gap:2px; padding:2px; background:var(--subtle); border:1px solid var(--border); border-radius:9px; }
.view-seg { display:inline-flex; align-items:center; gap:7px; padding:7px 13px; font-size:13px; font-weight:600; color:var(--secondary-dark); border-radius:7px; cursor:pointer; }
.view-seg:hover { background:var(--hair); }
.view-seg.is-active { background:var(--surface); color:var(--blue); box-shadow:0 1px 2px rgba(31,30,27,.09); }
.view-seg.is-active:hover { background:var(--surface); }
.view-seg-ico { display:inline-flex; }
.view-seg-ico svg { width:15px; height:15px; stroke:currentColor; stroke-width:2; }

/* ── Cards / tables ──────────────────────────────────────────────────────────────────────────────── */
.card { background:var(--surface); border:1px solid var(--border); border-radius:12px; }
.notice { background:var(--blue-tint); border:1px solid var(--blue-border); border-radius:12px; padding:14px 18px; font-size:13.5px; color:var(--secondary-dark); }
.notice-cta { margin-top:10px; }
.results-meta { font-size:13px; color:var(--muted); }
.table { overflow:hidden; }
/* A row's content wraps inside its own cell, so wide signal chips or a long owner never push "View details →" past the
   row's right edge, and the action column keeps its whole width (max-content) (issue #650). The signals column has the
   most room — the signal and county columns hold short values — and its chips wrap onto further lines whole. No
   column narrows below its longest word (min-content), so text breaks between words; the seven columns need about a
   1240px window, and below it the row stacks into two columns (the narrow-screen rule), where a word wider than its
   half breaks only then (break-word). */
.tr { display:grid; grid-template-columns:minmax(min-content,.9fr) minmax(min-content,1.6fr) minmax(min-content,1.2fr) minmax(min-content,.7fr) minmax(min-content,1.9fr) minmax(min-content,.8fr) max-content; gap:10px; padding:13px 20px; align-items:center; font-size:13.5px; border-bottom:1px solid var(--row-border); }
/* The Discover table's optional columns (issue #590) sit between the address and the signals, as many as the member picked
   (pp-cols-0 … pp-cols-5), each an equal share that never narrows below its longest word. Each column more needs a wider
   window before the row stacks into two columns: measured with four dated signal badges (#682), a long owner name and
   mailing address (issue #692, tools/discover-check), none needs about 1170px, one 1310px, two 1420px, three 1530px, four
   1700px and five 1800px; each stacks 20px above its need, room for a classic scrollbar (the rules under Narrow screens). */
.table.pp-cols-0 .tr { grid-template-columns:minmax(min-content,.9fr) minmax(min-content,1.6fr) minmax(min-content,1.9fr) minmax(min-content,.8fr) max-content; }
.table.pp-cols-1 .tr { grid-template-columns:minmax(min-content,.9fr) minmax(min-content,1.6fr) minmax(min-content,1fr) minmax(min-content,1.9fr) minmax(min-content,.8fr) max-content; }
.table.pp-cols-2 .tr { grid-template-columns:minmax(min-content,.9fr) minmax(min-content,1.6fr) repeat(2,minmax(min-content,1fr)) minmax(min-content,1.9fr) minmax(min-content,.8fr) max-content; }
.table.pp-cols-3 .tr { grid-template-columns:minmax(min-content,.9fr) minmax(min-content,1.6fr) repeat(3,minmax(min-content,1fr)) minmax(min-content,1.9fr) minmax(min-content,.8fr) max-content; }
.table.pp-cols-4 .tr { grid-template-columns:minmax(min-content,.9fr) minmax(min-content,1.6fr) repeat(4,minmax(min-content,1fr)) minmax(min-content,1.9fr) minmax(min-content,.8fr) max-content; }
.table.pp-cols-5 .tr { grid-template-columns:minmax(min-content,.9fr) minmax(min-content,1.6fr) repeat(5,minmax(min-content,1fr)) minmax(min-content,1.9fr) minmax(min-content,.8fr) max-content; }
.pp-phone-number { white-space:nowrap; }
.pp-phone .badge { margin-left:4px; }
.tr > * { min-width:0; }
.tr .cell-strong, .tr .cell-muted { overflow-wrap:break-word; }
.tr:last-child { border-bottom:none; }
.th { color:var(--muted); font-size:11.5px; font-weight:600; text-transform:uppercase; letter-spacing:.05em; background:var(--subtle); }
.tr-row:hover { background:var(--subtle); }
/* A Discover row (persona round 2026-11-04, F28): its address is the link to the lead, stretched over the whole row, so the
   row opens on a click anywhere as before; the row's own controls — the Watch action and its state — and anything with a
   tooltip sit above the stretched link. */
.tr-row { position:relative; }
.tr-link::after { content:""; position:absolute; inset:0; }
.tr-link:focus-visible { outline:none; }
.tr-link:focus-visible::after { outline:2px solid var(--blue); outline-offset:-2px; }
.tr-row .cell-actions > form, .tr-row .cell-actions > .pp-watch-state, .tr-row .cell-actions > .pp-watch-refused, .tr-row [title] { position:relative; z-index:1; }
.cell-actions { display:flex; align-items:center; justify-content:flex-end; flex-wrap:wrap; gap:6px 10px; }
.pp-watch-refused { font-size:12px; color:var(--secondary); }
.cell-strong { font-weight:600; }
.cell-muted { color:var(--secondary); }
/* The muted second line under a property address: the parcel's type · assessed value · lot size (moved out of the signals cell so a row stays compact). */
.cell-sub { display:block; margin-top:2px; font-size:12px; font-weight:400; line-height:1.35; color:var(--secondary); }
.cell-link { color:var(--blue); font-weight:600; font-size:13px; text-align:right; white-space:nowrap; }
.empty-state { padding:34px 20px; text-align:center; color:var(--muted); font-size:14px; }
.pager { display:flex; align-items:center; justify-content:space-between; padding:4px 2px; font-size:13px; color:var(--muted); }
.pager-info { font-family:var(--mono); font-size:12px; }
.page-btn { border:1px solid var(--border); border-radius:7px; padding:5px 11px; cursor:pointer; color:var(--ink); font-weight:600; }
.page-btn:hover { background:var(--app-bg); }
.page-btn.is-disabled { color:var(--muted); opacity:.55; cursor:default; }

/* ── Badges / chips / pills ──────────────────────────────────────────────────────────────────────── */
.badge { display:inline-block; font-size:12px; font-weight:600; border-radius:100px; padding:4px 11px; margin-right:6px; }
.badge-gray { color:var(--secondary-dark); background:var(--gray-pill); }
.badge-orange { color:var(--orange); background:var(--orange-tint); }
.badge-blue { color:var(--blue); background:var(--blue-tint); }
.badge-red { color:var(--red); background:var(--red-tint); }
.chip { display:inline-block; font-size:11.5px; font-weight:600; color:var(--secondary-dark); background:var(--gray-pill); border-radius:100px; padding:3px 9px; margin:0 6px 4px 0; }
.signals { display:flex; flex-wrap:wrap; align-items:center; gap:2px; }
/* A Discover row's category chips (#587, #650): the first few whole, then the "+N" chip, each on one line, wrapping onto
   further lines rather than cutting a chip's name short. */
.chip-line { display:flex; flex:1 1 100%; flex-wrap:wrap; align-items:center; gap:4px 6px; min-width:0; }
.chip-line .chip { margin:0; flex:0 0 auto; white-space:nowrap; }
.officer { display:inline-block; font-size:12px; font-weight:600; color:var(--green); }
.history { display:block; font-size:12px; color:var(--secondary-dark); }
.case-kind { display:block; font-size:12px; font-weight:600; color:var(--secondary-dark); }
.pp-kind-inferred { text-decoration:underline dotted; text-underline-offset:2px; cursor:help; }
.case-age { display:block; font-size:12px; color:var(--secondary-dark); }
.pill { display:inline-flex; align-items:center; font-size:12.5px; font-weight:500; color:var(--secondary-dark); border:1px solid var(--border-soft); border-radius:100px; padding:5px 12px; cursor:pointer; }
.pill:hover { background:var(--app-bg); }
.pill.is-active { color:var(--blue); background:var(--blue-tint); border-color:var(--blue-border); font-weight:600; }

/* ── Filter bar ──────────────────────────────────────────────────────────────────────────────────── */
.filter-bar { padding:16px 20px; display:flex; flex-direction:column; gap:12px; }
.filter-group { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.filter-label { font-size:12px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--muted); margin-right:4px; min-width:74px; }
.filter-actions { display:flex; justify-content:flex-end; }
.saved-strip { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.saved-chip { display:inline-flex; align-items:center; gap:6px; font-size:12.5px; font-weight:600; color:var(--blue); background:var(--blue-tint); border:1px solid var(--blue-border); border-radius:100px; padding:4px 6px 4px 12px; }
.saved-chip.is-new { box-shadow:0 0 0 2px var(--blue-border); }
/* A saved search's 12-week yield line (issue #863): bars in the chip's colour, a withheld week a dashed outline. */
.pp-yield { display:inline-flex; align-items:center; gap:6px; font-weight:400; }
.pp-yield-bars { display:block; flex:none; }
.pp-yield-note { font-size:11.5px; color:var(--secondary); white-space:nowrap; }
.saved-del { margin:0; display:inline-flex; }
.saved-del button { border:none; background:none; color:var(--blue); cursor:pointer; font-size:12px; padding:0 4px; border-radius:100px; }
.saved-del button:hover { background:var(--blue-border); }

/* ── Active-filter summary line (#302) ─────────────────────────────────────────────────────────────── */
.filter-summary { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:2px 0 4px; }
.filter-summary:empty { display:none; }
.filter-summary-label { font-size:12px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--muted); }
.filter-token { display:inline-flex; align-items:center; gap:4px; font-size:12.5px; font-weight:600; color:var(--blue); background:var(--blue-tint); border:1px solid var(--blue-border); border-radius:100px; padding:3px 4px 3px 12px; }
.filter-token-x { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:100px; color:var(--blue); text-decoration:none; font-size:11px; cursor:pointer; }
.filter-token-x:hover { background:var(--blue-border); }
.filter-summary-clear { font-size:12.5px; font-weight:600; color:var(--secondary); text-decoration:underline; cursor:pointer; }

/* ── Discover facet groups (#344) — collapsible checkbox facets on the filter rail ─────────────────────
   The rail is one column of <section.pp-facet>, each a keyboard-operable header button (family name + a
   selected-count badge + a chevron) over a body of real <input type=checkbox>+<label> options. The server
   renders a group open when it is a default-open family or carries a selection; discover-filters.js layers
   the per-group localStorage memory, the top-N "Show all" split, and the client narrowing box on top. Every
   rule reads the brand tokens, so light + dark both follow (ADR-0045). */
.filter-rail-card.pp-facets { padding:8px 6px; }
.pp-facet { border-bottom:1px solid var(--hair); }
.pp-facet:last-child { border-bottom:none; }
.pp-facet-head { margin:0; font:inherit; }
.pp-facet-toggle { display:flex; align-items:center; gap:8px; width:100%; padding:10px; background:none; border:none; border-radius:8px; cursor:pointer; text-align:left; color:var(--ink); font-family:var(--sans); font-size:13px; font-weight:600; }
.pp-facet-toggle:hover { background:var(--subtle); }
.pp-facet-toggle:focus-visible { outline:2px solid var(--blue); outline-offset:-2px; }
.pp-facet-title { flex:1 1 auto; }
.pp-facet-count { flex:0 0 auto; min-width:18px; height:18px; padding:0 5px; display:inline-flex; align-items:center; justify-content:center; border-radius:100px; font-size:11px; font-weight:700; color:var(--blue); background:var(--blue-tint); border:1px solid var(--blue-border); }
.pp-facet-chev { flex:0 0 auto; display:inline-flex; color:var(--muted); transition:transform .15s ease; }
.pp-facet-chev .icon { width:16px; height:16px; }
.pp-facet-toggle[aria-expanded="true"] .pp-facet-chev { transform:rotate(180deg); }
.pp-facet-body { padding:2px 10px 12px; }
/* Collapse is driven by the SERVER-set data-pp-open, so a closed group is hidden BEFORE first paint (no flash of the
   expanded wall); discover-filters.js toggles the same attribute, and the <noscript> escape un-hides it with no JS. */
.pp-facet[data-pp-open="false"] .pp-facet-body { display:none; }
/* Phone default (#344): the rail stacks above the results with every group collapsed EXCEPT those carrying a selection.
   Armed pre-paint by the server-set .pp-preinit on the rail card and driven by data-pp-selected, so there is no flash;
   discover-filters.js removes .pp-preinit once it has applied the per-viewport open state, after which the base rule
   (data-pp-open, which the script sets viewport-aware) governs, so a group opened on phone is not re-hidden. */
@media (max-width: 991.98px) { .pp-preinit .pp-facet:not([data-pp-selected="true"]) .pp-facet-body { display:none; } }
.pp-facet-narrow { max-width:100%; margin-bottom:8px; }
/* The ZIP group's paste box (#592); the Sources group's source blocks, each a source kind over its record type and that
   type's details (a <details> each, rendered open); and the divider naming Regrid as the property details' source. */
.pp-facet-paste { display:flex; gap:6px; margin-bottom:8px; }
.pp-facet-paste .field { flex:1 1 auto; min-width:0; }
.pp-source { margin-top:10px; padding-top:8px; border-top:1px solid var(--tblr-border-color); }
.pp-source-head, .pp-rail-part { font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--secondary-dark); margin-bottom:4px; }
.pp-source-systems { font-weight:500; text-transform:none; letter-spacing:0; color:var(--tblr-secondary); }
/* The source's count sits right-aligned in its own element, as an option's count does below it. */
.pp-source-head { display:flex; align-items:baseline; gap:6px; padding-right:2px; }
.pp-source-name { flex:1 1 auto; min-width:0; }
.pp-source-head .pp-facet-optcount { text-transform:none; letter-spacing:0; }
.pp-rail-part { margin:14px 0 2px; padding:10px 10px 0; border-top:2px solid var(--tblr-border-color); }
.pp-source .pp-facet-sub { margin-left:6px; }
/* A range never widens the rail (persona round 3: the winning bid's scale pushed the page 2 px sideways at 1280 px): its one
   column is the rail's width, and a scale that still does not fit is cut at the rail's edge. */
.pp-facet-range { display:grid; grid-template-columns:minmax(0, 1fr); gap:2px; }
.pp-range-value { font-size:13px; font-weight:600; }
.pp-range-label { font-size:11px; color:var(--tblr-secondary); }
.pp-range-scale { display:flex; justify-content:space-between; overflow:hidden; font-size:10px; color:var(--tblr-secondary); }
.pp-source-hint { font-size:12px; color:var(--tblr-secondary); margin:2px 0 0 26px; }
.pp-source-asof { font-size:12px; color:var(--tblr-secondary); margin:2px 0 0 26px; font-style:italic; }
.pp-facet-countnote { font-size:12px; color:var(--tblr-secondary); margin:0 0 6px; font-style:italic; }
.pp-facet-sub { margin-top:8px; border-top:1px solid var(--tblr-border-color); padding-top:6px; }
.pp-facet-subhead { display:flex; align-items:center; gap:6px; cursor:pointer; font-size:12px; font-weight:600; color:var(--secondary-dark); padding:2px 0; }
.pp-facet-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:1px; max-height:288px; overflow-y:auto; }
.pp-facet-opt { display:flex; align-items:center; gap:8px; padding:3px 2px; }
.pp-facet-opt[hidden] { display:none; }
/* Top-N split: the options past the visible limit carry .pp-facet-rest and are hidden ONLY once discover-filters.js
   sets data-pp-expanded="false" on the group — so with no JS every option shows (nothing is unreachable), and
   "Show all" flips the attribute back to true. */
.pp-facet[data-pp-expanded="false"] .pp-facet-rest { display:none; }
.pp-facet-check { flex:0 0 auto; width:16px; height:16px; margin:0; accent-color:var(--blue); cursor:pointer; }
.pp-facet-check:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }
.pp-facet-optlabel { flex:1 1 auto; display:flex; align-items:baseline; gap:6px; min-width:0; font-size:12.5px; color:var(--secondary-dark); cursor:pointer; }
.pp-facet-optname { flex:1 1 auto; min-width:0; overflow-wrap:anywhere; }
.pp-facet-check:checked + .pp-facet-optlabel .pp-facet-optname { color:var(--blue); font-weight:600; }
.pp-facet-optcount { flex:0 0 auto; font-size:11.5px; font-weight:500; color:var(--muted); font-variant-numeric:tabular-nums; }
.pp-facet-showall { margin-top:8px; padding:2px; border:none; background:none; font-size:12px; font-weight:600; color:var(--blue); cursor:pointer; text-decoration:underline; }
.pp-facet-showall:focus-visible { outline:2px solid var(--blue); outline-offset:2px; border-radius:4px; }

/* ── Form fields ─────────────────────────────────────────────────────────────────────────────────── */
.field { width:100%; font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:10px 12px; }
.field:focus { outline:none; border-color:var(--blue); box-shadow:0 0 0 3px var(--blue-tint); }
.field-sm { width:auto; padding:8px 12px; font-size:13px; }
.field-label { display:block; font-size:12.5px; font-weight:600; color:var(--secondary-dark); margin-bottom:6px; }

/* ── Login ───────────────────────────────────────────────────────────────────────────────────────── */
.login-wrap { min-height:100vh; display:flex; align-items:center; justify-content:center; padding:24px; background:var(--app-bg); }
.login-card { width:100%; max-width:400px; background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:32px; box-shadow:0 24px 60px -30px rgba(31,30,27,.22); }
.login-brand { display:flex; align-items:center; gap:10px; font-weight:700; font-size:16px; margin-bottom:18px; }
.login-brand .brand-mark svg { stroke:#fff; }
.login-title { font-size:22px; font-weight:700; letter-spacing:-0.01em; margin:0 0 6px; }
.login-sub { font-size:14px; color:var(--secondary); margin:0 0 20px; line-height:1.5; }
.login-form { display:flex; flex-direction:column; gap:8px; margin-bottom:6px; }
.login-form .btn-block { margin-top:8px; }
.login-alt { margin:10px 0 0; text-align:center; }
.error-box { background:var(--orange-tint); border:1px solid #f3ddc9; color:var(--orange); border-radius:8px; padding:10px 12px; font-size:13px; margin-bottom:16px; }

/* ── Lead detail ─────────────────────────────────────────────────────────────────────────────────── */
.detail { display:flex; flex-direction:column; gap:16px; }
.back-link { font-size:13px; font-weight:600; color:var(--blue); }
.facet-row { display:flex; flex-wrap:wrap; align-items:center; gap:2px; }
.officer-banner { background:#e9f5ee; border:1px solid #c9e6d4; color:var(--green); border-radius:10px; padding:12px 16px; font-size:14px; font-weight:600; }
.detail-grid { display:grid; grid-template-columns:1fr 1fr; gap:14px; align-items:start; }
.detail-card { padding:18px 20px; }
.card-title { font-size:15px; font-weight:700; margin-bottom:12px; }
.facts { display:flex; flex-direction:column; gap:14px; }
.fact-label { display:block; font-size:11.5px; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin-bottom:4px; }
.fact-value { font-size:14px; margin-bottom:6px; }
.fact-sub { display:block; font-size:12.5px; color:var(--muted); }
.record { padding:12px 0; border-bottom:1px solid var(--row-border); }
.record:last-child { border-bottom:none; }
.record-head { display:flex; align-items:center; gap:8px; margin-bottom:4px; flex-wrap:wrap; }
.record-title { font-size:14px; font-weight:600; }
.record-tag { font-family:var(--mono); font-size:11.5px; color:var(--secondary); background:var(--gray-pill); border-radius:5px; padding:1px 7px; }
.record-status { font-size:11.5px; font-weight:600; color:var(--secondary-dark); }
.status-warn { color:var(--orange); }
.status-ok { color:var(--green); }
.record-sub { font-size:12.5px; color:var(--muted); }
.record-note { font-size:12.5px; color:var(--secondary); margin-top:6px; font-style:italic; }
.chips { margin-top:8px; }
.timeline { display:flex; flex-direction:column; gap:2px; }
.timeline-row { display:flex; gap:12px; padding:9px 0; border-bottom:1px solid var(--row-border); font-size:13px; }
.timeline-row:last-child { border-bottom:none; }
.timeline-row.is-upcoming .timeline-date { color:var(--green); font-weight:700; }
.timeline-date { font-family:var(--mono); font-size:12px; color:var(--secondary); min-width:96px; }
.timeline-kind { font-weight:600; }
.timeline-meta { color:var(--secondary); margin-left:8px; }
.timeline-raw { display:block; font-size:12px; color:var(--muted); margin-top:2px; }
.inspection-narrative { white-space:pre-line; overflow-wrap:anywhere; }
.prov-row { display:flex; justify-content:space-between; gap:12px; font-size:12.5px; padding:7px 0; border-bottom:1px solid var(--row-border); }
.prov-row:last-child { border-bottom:none; }
.prov-when { color:var(--muted); font-family:var(--mono); font-size:12px; }
.empty-note { font-size:13px; color:var(--muted); padding:6px 0; }
/* Enforcement case list on the lead detail + map card (issue #370): a headed <ul>, each case's violation lines nested. */
.pp-case-h { font-size:11.5px; font-weight:600; line-height:1.4; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin:0 0 4px; }
.pp-cases, .pp-case-lines { list-style:none; margin:0; padding:0; }
.pp-case-lines { margin-top:6px; padding-left:12px; border-left:2px solid var(--row-border); }
.pp-case-line + .pp-case-line { margin-top:2px; }

/* ── Narrow screens ──────────────────────────────────────────────────────────────────────────────── */
@media (max-width:1820px) {
  .table.pp-cols-5 .tr { grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .table.pp-cols-5 .th, .table.pp-cols-5 .tr .cell-link { display:none; }
}
@media (max-width:1720px) {
  .table.pp-cols-4 .tr { grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .table.pp-cols-4 .th, .table.pp-cols-4 .tr .cell-link { display:none; }
}
@media (max-width:1550px) {
  .table.pp-cols-3 .tr { grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .table.pp-cols-3 .th, .table.pp-cols-3 .tr .cell-link { display:none; }
}
@media (max-width:1440px) {
  .table.pp-cols-2 .tr { grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .table.pp-cols-2 .th, .table.pp-cols-2 .tr .cell-link { display:none; }
}
@media (max-width:1330px) {
  .table.pp-cols-1 .tr { grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .table.pp-cols-1 .th, .table.pp-cols-1 .tr .cell-link { display:none; }
}
@media (max-width:1240px) {
  .tr, .table[class*="pp-cols-"] .tr { grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .th, .tr .cell-link { display:none; }
}
/* On a phone a dated signal badge ("Unpaid penalty · May 2026") is wider than half a Discover row: the badges take its whole
   first line (#692). */
@media (max-width:640px) {
  .table[class*="pp-cols-"] .tr > :first-child { grid-column:1 / -1; }
}
@media (max-width:1080px) {
  .detail-grid { grid-template-columns:1fr; }
}
/* The narrow-screen sidebar rule is gone — Tabler's navbar-vertical collapses behind its own toggler (ADR-0045). */

/* ── Mailer columns, skip trace, export dialog, Watching notes (issue #590) ───────────────────────────────────────────── */
.pp-column-picker .dropdown-menu { min-width:220px; padding:6px 0; }
.pp-column-picker .dropdown-item.form-check { display:flex; align-items:center; gap:8px; margin:0; padding:6px 16px; cursor:pointer; }
.pp-column-picker .dropdown-item.form-check .form-check-input { float:none; margin:0; }
.pp-column-actions { padding:8px 16px 4px; }
.pp-skip-trace-counter { font-size:12.5px; color:var(--secondary); }
.pp-skip-trace-strip { padding:14px 18px; margin:14px 0; }
.pp-skip-trace-strip-head { display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:8px; margin-bottom:8px; }
.pp-skip-trace-hint, .pp-skip-trace-reason, .pp-action-reason { font-size:12.5px; color:var(--secondary); margin-top:4px; }
.pp-action-reason { margin-top:0; max-width:320px; }
.pp-skip-trace-compact { display:inline-flex; flex-direction:column; max-width:280px; white-space:normal; }
.pp-skip-trace-contact { font-size:12.5px; overflow-wrap:anywhere; }
.pp-export-facts { display:grid; grid-template-columns:max-content 1fr; gap:8px 16px; margin:0; font-size:13.5px; }
.pp-export-facts dt { font-weight:600; color:var(--secondary-dark); }
.pp-export-facts dd { margin:0; }
.pp-export-columns { margin:0; padding-left:18px; columns:2; column-gap:24px; }
.pp-export-count { display:inline-block; width:7.5em; margin:0 4px; }
.pp-watch-property { min-width:170px; }
/* A table that scrolls inside its card holds what it positions: a visually hidden label in a header cell (the kit places it
   absolutely) was laid out against the card, past the scrolling box, and pushed the whole page sideways on a phone (the
   Monitor worklist at 390 px scrolled 523 px). */
.table-responsive { position:relative; }
/* Watching shows every column at 1280 px with no sideways scroll and no column over another (persona round 4): the owner facts
   share one column, "What changed" keeps a readable width, and the actions are a compact two-column grid — Open lead and Note,
   Skip trace across, Unwatch and the menu. A narrower window scrolls the table inside its card, every column in its place. */
.pp-watch-owner { min-width:150px; max-width:220px; overflow-wrap:anywhere; }
.pp-watch-owner-name { font-weight:500; }
.pp-watch-owner .badge { vertical-align:baseline; }
.pp-watch-changed { min-width:180px; }
.pp-watch-actions { display:grid; grid-template-columns:repeat(2, max-content); gap:4px; justify-content:end; }
.pp-watch-actions > .pp-skip-trace { grid-column:1 / -1; max-width:none; }
.pp-watch-actions .btn { width:100%; }
/* The light undo beside a workflow badge (owner ruling 137): the back arrow and the word, compact enough for a table row (persona
   round 4). */
.btn.pp-undo { margin-left:.5rem; padding:0 .5rem; font-size:.75rem; line-height:1.5rem; vertical-align:middle; }
.btn.pp-undo .icon { width:1rem; height:1rem; margin:0 .25rem 0 -.125rem; }
.pp-watch-note { margin-top:4px; max-width:420px; overflow-wrap:anywhere; }
.pp-watch-note-form { margin-top:6px; max-width:420px; }
@media (max-width:640px) {
  .pp-export-facts { grid-template-columns:1fr; }
  .pp-export-columns { columns:1; }
}
/* The cancel question's free-text box shows under Other once Other is chosen (issue #867). */
.pp-cancel-other { display:none; margin-top:6px; }
.pp-cancel-reason .form-check-input:checked ~ .pp-cancel-other { display:block; }
