/* ════════════════════════════════════���═════════════════════════════════════���
   Blue Belmont - Data Tables, Property Cards & Specialized Components
   ════════════��══════════════���═══════════════════════════════════════════════ */

/* ── Icon System ─────────────────────────────────────────────────────────
   All UI icons are inline SVGs drawn at 24×24 with currentColor strokes.
   They inherit text color and font-size from their parent so a button,
   menu item, or label can size them with a single rule.
   ────────────────────────────────────────────────────────────────────── */
.ui-icon {
    display: inline-block;
    flex-shrink: 0;
    vertical-align: -0.125em;
    color: currentColor;
}
.ui-icon-wrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* ── Data Tables ─────────────────────────────────────────────────────────
   Premium tabular layout. The table is the workhorse of the platform -
   results, lists, comps, sales history all flow through here, so the
   typography hierarchy is tuned for a serious analyst, not a spreadsheet
   export. Numbers are weight 600 in the body color (not muted gray) so
   they read first; headers are uppercase microcopy in muted gold so they
   never compete with the data.                                          */
.data-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-lg);
    background: var(--surface-card);
    box-shadow: var(--shadow-card);
    /* The wrapper provides the scroll container; the table itself can
       still try to fit but if it overflows, the wrapper scrolls. Without
       max-width:100% the wrapper would never know to enable scrolling on
       narrow viewports.
       Force width:100% so the wrapper ALWAYS fills its parent - without
       this, the wrap was rendering half-width on the Search results
       pane because flex stretching wasn't being honored under certain
       sibling layouts (MountainLoader + skeleton table side by side). */
    display: block;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}
.data-table {
    /* auto layout lets each column size to its content (the right call
       for variable-width property data) but we still set width:100% so
       narrow tables fill the wrapper instead of left-aligning. */
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: var(--text-base);
    color: var(--text);
}
.data-table thead {
    /* Desktop/tablet: the search-sticky-header above the table already
       pins the Lead-Lists chips + toolbar, so the column-header row
       doesn't need extra sticky behavior. It stays at its natural
       position and scrolls with the rows. The phone override lives in
       the Property Search block below - it's scoped to .split-right so
       it doesn't affect tables on other pages. */
    background: var(--surface-inset);
}
.data-table thead tr { background: var(--surface-inset); }
.data-table th {
    background: var(--surface-inset);
    border-bottom: 0.125rem solid var(--gold, #b5942a);
    padding: 0.625rem var(--space-4);
    text-align: left;
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    /* Darker headers so they're clearly visible against cream rows -
       the old muted-on-surface tone made them disappear at a glance. */
    color: var(--slate, #1c2331);
    white-space: nowrap;
    user-select: none;
    vertical-align: middle;
}
/* First and last columns get reduced gutters so the table content
   visually aligns with surrounding card padding instead of looking
   indented twice. */
.data-table th:first-child,
.data-table td:first-child { padding-left: var(--space-5); }
.data-table th:last-child,
.data-table td:last-child { padding-right: var(--space-5); }
.data-table th.sortable { cursor: pointer; transition: color var(--anim-fast) var(--easing); }
.data-table th.sortable:hover { color: var(--gold-dark); }
.data-table th .sort-arrow {
    display: inline-block;
    margin-left: var(--space-1);
    opacity: 0.35;
    font-size: 0.5rem;
    vertical-align: middle;
    transition: transform var(--anim-fast) var(--easing), opacity var(--anim-fast) var(--easing);
}
.data-table th.sort-asc .sort-arrow,
.data-table th.sort-desc .sort-arrow { opacity: 1; color: var(--gold); }
.data-table th.sort-desc .sort-arrow { transform: rotate(180deg); }

.data-table td {
    padding: var(--space-3) var(--space-4);
    border-bottom: 0.0625rem solid var(--border-light);
    color: var(--text);
    vertical-align: middle;
    font-size: var(--text-base);
    /* line-height for cells - slightly tighter than body so multi-line
       cells stay compact and inline badges/buttons line up vertically. */
    line-height: 1.4;
    /* Long unbroken content (parcel ids, no-space business names) used
       to push the column past its allotted width and force the entire
       table to scroll horizontally. ``overflow-wrap: anywhere`` lets the
       browser break inside the word as a last resort, so each cell
       respects its column. Cells that explicitly want single-line
       truncation use ``.truncate`` which sets ``white-space: nowrap``
       and overrides this rule's wrapping behaviour. */
    overflow-wrap: anywhere;
    word-break: normal;
}
.data-table td.truncate {
    /* The truncate variant disables the wrap rule above so the
       single-line ellipsis pattern still works. */
    overflow-wrap: normal;
    word-break: normal;
}
.data-table tbody tr {
    transition: background var(--anim-fast) var(--easing),
                box-shadow var(--anim-fast) var(--easing);
}
.data-table tbody tr:hover {
    background: var(--bg-hover);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr.selected {
    background: var(--gold-muted);
    box-shadow: inset 0.1875rem 0 0 var(--gold);
}

/* Numeric / monospace cells - use the body font size, not the old shrunk
   0.75rem mono. Numbers are the headline of every row, so they get weight
   600 in the full text color. */
.data-table td.mono {
    font-family: var(--font-mono);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--text);
    /* Keep parcel IDs and codes on one line - they're identifiers,
       not prose, so mid-value wrapping is confusing. */
    white-space: nowrap;
}
.data-table td.number {
    text-align: right;
    font-family: var(--font-mono);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    font-variant-numeric: tabular-nums;
    color: var(--text);
    /* Formatted currency and measurements should never wrap mid-value
       (e.g. "$1,234,\n567" reads as two different numbers). */
    white-space: nowrap;
}
.data-table td.center,
.data-table th.center {
    text-align: center;
}
.data-table td.muted {
    color: var(--muted);
    font-size: var(--text-sm);
}
.data-table td.primary {
    font-weight: var(--weight-semibold);
    color: var(--text);
}
.data-table td.truncate {
    /* Cap at 18rem on desktop but never let the cell take more than
       60% of the viewport on a phone - that combination kept the
       Owner / Jurisdiction columns from forcing the entire table to
       overflow horizontally on a 22.5em (≈360 device-px) screen. */
    max-width: min(18rem, 60vw);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.data-table td.actions {
    text-align: right;
    white-space: nowrap;
}
/* When the actions cell hosts a row of icon buttons, keep them aligned
   to the right edge with a uniform gap. */
.data-table td.actions > * + * { margin-left: var(--space-2); }
.data-table td.actions .btn-icon { vertical-align: middle; }

/* Optional zebra striping for very long result sets */
.data-table.striped tbody tr:nth-child(even) {
    background: var(--bg-subtle);
}
.data-table.striped tbody tr:nth-child(even):hover {
    background: var(--bg-hover);
}

/* Compact density variant for embedded result lists (e.g. comparable sales
   inside a property detail). */
.data-table.compact th { padding: var(--space-2) var(--space-3); }
.data-table.compact td { padding: var(--space-2) var(--space-3); font-size: var(--text-sm); }

/* Row checkbox - fixed-width column that hosts a centered checkbox.
   The width is generous enough to give the checkbox a comfortable hit
   target on touch but still narrow enough not to dominate a row of
   compact data columns. */
.data-table td.row-check,
.data-table th.row-check {
    width: 2.5rem;
    text-align: center;
    padding-left: var(--space-3);
    padding-right: var(--space-3);
    vertical-align: middle;
}
.data-table .row-check input {
    accent-color: var(--gold);
    width: 1rem;
    height: 1rem;
    cursor: pointer;
    /* Lift the checkbox a hair so it sits on the visual baseline of the
       row text instead of the box-model baseline. */
    vertical-align: middle;
    margin: 0;
}

/* ── Responsive column hiding ───────────────────────────────────────
   Columns with hideBelow get a CSS class that hides them at the named
   breakpoint. `!important` is required because mobile-first.css sets
   `.data-table th, .data-table td { display: table-cell }` inside the
   same @media (max-width: 48em) block - that rule has higher
   specificity than `.hide-below-md` and was silently overriding this
   one, keeping EVERY column visible on phones and collapsing the
   layout into overlapping cells.

   `.hide-below-xl` was missing entirely, so any column tagged with
   `hideBelow: 'xl'` (saved-lists uses this for county + acreage)
   stayed visible at every breakpoint. Added below to match the
   design-system 80em tier. */
@media (max-width: 80em) { .hide-below-xl { display: none !important; } }
@media (max-width: 64em) { .hide-below-lg { display: none !important; } }
@media (max-width: 48em) { .hide-below-md { display: none !important; } }
@media (max-width: 30em) { .hide-below-sm { display: none !important; } }

/* Table toolbar - sits above .data-table-wrap. Buttons, search inputs,
   filter chips, and counts all live here. The container uses align-items:
   center so a row of mixed-height controls (badge + button + input) reads
   as a single horizontal band.

   CRITICAL: Every child (count + Sort + Save + Export + Search) must
   be visible at every viewport width. We wrap rather than scroll so
   nothing is discoverable only by sideways drag. */
.table-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-3) var(--space-4);
    border-bottom: 0.0625rem solid var(--border-light);
    gap: var(--space-3);
    flex-wrap: wrap;
    /* Use the buttons' rendered height as the min-height so a Sort
       select / Save / Export / Search row can never overflow the
       toolbar's bottom edge and clip into the table-header row below
       it. 2.5rem matches .btn-sm + small select hover/focus halos. */
    min-height: 2.5rem;
    background: var(--warm-white);
    /* Establish a stacking context with a low z so a sticky table
       thead (z 3 on phones, 10 in this stylesheet's other rule) always
       paints ABOVE the toolbar when they cross during scroll. */
    position: relative;
    z-index: 1;
    overflow: visible;
}
/* Defensive safety belt: make sure the toolbar children are never
   display:none (e.g. from a stale inline style) and never clipped.
   Some earlier rules used `display: inline-flex` without `min-width: 0`
   which let long children overflow without wrapping - this forces
   wrap-friendly flex behavior. */
.table-toolbar-left,
.table-toolbar-right {
    display: flex !important;
    flex-wrap: wrap;
    min-width: 0;
}
.table-toolbar-right .btn,
.table-toolbar-right button {
    display: inline-flex !important;
    visibility: visible !important;
}
.table-toolbar-left {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
    flex-wrap: wrap;
}
.table-toolbar-title {
    font-family: var(--font-display);
    font-size: var(--text-md);
    font-weight: var(--weight-bold);
    color: var(--slate);
}
.table-toolbar-right {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
    flex-wrap: wrap;
    justify-content: flex-end;
}
/* Below 48rem, drop the auto margin so the toolbar wraps cleanly under
   the count instead of squeezing into one truncated row. The sort
   select has an inline min-width that we override here so it can
   shrink without blowing past the viewport edge. Every action button
   (Save / Export / Search) must remain visible - never hidden or
   clipped - because they're the primary actions on the search page. */
@media (max-width: 48em) {
    .table-toolbar {
        padding: var(--space-3);
        gap: var(--space-2);
        flex-wrap: wrap;
    }
    .table-toolbar-left {
        width: 100%;
        flex-wrap: wrap;
    }
    .table-toolbar-right {
        margin-left: 0;
        width: 100%;
        justify-content: flex-start;
        gap: var(--space-2);
        flex-wrap: wrap;
    }
    .table-toolbar-right .form-input,
    .table-toolbar-right select.form-input {
        flex: 1 1 100%;
        min-width: 0 !important;
        width: 100% !important;
    }
    .table-toolbar-right .btn {
        flex: 1 1 calc(33% - var(--space-2));
        min-width: 0;
        min-height: 2.5rem;
        white-space: nowrap;
    }
}
@media (max-width: 30em) {
    .table-toolbar-right .btn {
        /* Two buttons per row at ultra-narrow so each stays readable. */
        flex: 1 1 calc(50% - var(--space-2));
        font-size: 0.75rem;
    }
}
.table-count {
    font-size: 0.75rem;
    color: var(--muted);
    font-weight: var(--weight-medium);
}
.table-count strong {
    font-family: var(--font-mono);
    color: var(--text);
}

/* Bulk actions bar */
.bulk-actions {
    display: none;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    background: var(--gold-muted);
    border-bottom: 0.0625rem solid var(--gold-border);
}
.bulk-actions.active { display: flex; }
.bulk-actions-count {
    font-size: 0.75rem;
    font-weight: var(--weight-semibold);
    color: var(--gold-dark);
}
.bulk-actions-btns {
    display: flex;
    gap: 0.375rem;
    margin-left: auto;
}

/* ── Pagination ── */
.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    padding: var(--space-3);
    flex-wrap: wrap;
}
.pagination-btn {
    /* Square aspect that follows the control-h-sm rhythm so a paginator
       sitting under a table reads as part of the same metric grid. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--control-h-sm);
    height: var(--control-h-sm);
    padding: 0 var(--space-2);
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-sm);
    background: var(--warm-white);
    color: var(--text-secondary);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    cursor: pointer;
    transition: border-color var(--anim-fast) var(--easing),
                color var(--anim-fast) var(--easing),
                background var(--anim-fast) var(--easing);
    font-family: var(--font-mono);
    -webkit-tap-highlight-color: transparent;
}
.pagination-btn:hover { border-color: var(--gold); color: var(--gold-dark); }
.pagination-btn:focus-visible {
    outline: none;
    border-color: var(--gold);
    box-shadow: var(--shadow-gold);
}
.pagination-btn.active {
    background: var(--gold);
    color: var(--slate);
    border-color: var(--gold);
    font-weight: var(--weight-bold);
}
.pagination-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.pagination-info {
    font-size: var(--text-xs);
    color: var(--muted);
    padding: 0 var(--space-3);
    line-height: var(--control-h-sm);
}
@media (pointer: coarse) {
    .pagination-btn { min-width: var(--control-h-lg); height: var(--control-h-lg); }
    .pagination-info { line-height: var(--control-h-lg); }
}

/* ── Property Cards ────────────────────────────────────────────────────
   The premium card pattern. Hierarchy is built from a large gold value
   ("headline metric") down through a 4-cell stat grid, an owner row,
   and a footer with parcel id + action. The whole card lifts on hover
   and the lead-score chip in the corner gives an instant read on tier. */
.property-card {
    background: var(--surface-card);
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    transition: border-color var(--anim-fast) var(--easing),
                box-shadow var(--anim-fast) var(--easing),
                transform var(--anim-fast) var(--easing);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    box-shadow: var(--shadow-card);
    position: relative;
}
.property-card:hover {
    border-color: var(--gold-border);
    box-shadow: var(--shadow-card-hover);
    transform: translateY(-0.0625rem);
}

/* Top - title block + lead-score chip */
.property-card-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
}
.property-card-titles { min-width: 0; flex: 1; }
.property-card-address {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--weight-semibold);
    color: var(--slate);
    line-height: var(--leading-tight);
    letter-spacing: -0.01em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* min-width:0 lets a flex parent shrink this child below its
       intrinsic content width - without it a long address would push
       the card past its grid track and break the row. */
    min-width: 0;
}
.property-card-city {
    font-size: var(--text-sm);
    color: var(--muted);
    font-weight: var(--weight-medium);
    margin-top: var(--space-1);
}

/* Lead score chip - circular for "hot", flatter pill for warm/cold. */
.property-card-score {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    border-radius: var(--radius-lg);
    background: var(--bg-subtle);
    border: 0.0625rem solid var(--border-light);
    box-shadow: var(--shadow-card);
}
.property-card-score-num {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    color: var(--text);
    line-height: 1;
}
.property-card-score-label {
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    margin-top: 0.125rem;
}
.property-card-score--hot {
    background: rgba(212, 175, 55, 0.1);
    border-color: var(--gold);
}
.property-card-score--hot .property-card-score-num { color: var(--gold-dark); }
.property-card-score--hot .property-card-score-label { color: var(--gold-dark); }
.property-card-score--warm {
    background: var(--warning-light);
    border-color: rgba(245, 124, 0, 0.3);
}
.property-card-score--warm .property-card-score-num { color: var(--warning); }
.property-card-score--cold .property-card-score-num { color: var(--muted); }

/* Headline metric - the most prominent number on the card. */
.property-card-headline {
    padding: var(--space-3) var(--space-4);
    background: linear-gradient(135deg, var(--bg-subtle) 0%, var(--gold-muted) 100%);
    border: 0.0625rem solid var(--gold-border);
    border-radius: var(--radius-md);
}
.property-card-headline-label {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--gold-dark);
    margin-bottom: var(--space-1);
}
.property-card-headline-value {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: var(--weight-bold);
    color: var(--slate);
    line-height: var(--leading-tight);
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

/* Secondary stat grid */
.property-card-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3) var(--space-4);
}
.property-card-grid-cell {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}
.property-card-grid-label {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--faint);
}
.property-card-grid-value {
    font-family: var(--font-body);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--text);
    font-variant-numeric: tabular-nums;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Owner row */
.property-card-owner-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding-top: var(--space-3);
    border-top: 0.0625rem solid var(--border-light);
}
.property-card-owner {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-secondary);
    font-weight: var(--weight-medium);
    min-width: 0;
    flex: 1;
}
.property-card-owner-icon {
    color: var(--gold);
    font-size: 0.75rem;
    flex-shrink: 0;
}
.property-card-owner-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    /* Flex item shrink - required so the parent .property-card-owner
       can squeeze a long business name under its column width
       instead of overflowing the card. */
    flex: 1 1 0;
}

/* Flag pills (absentee, sheriff, flood, etc.) */
.property-card-flags {
    display: flex;
    gap: var(--space-1);
    flex-wrap: wrap;
    min-height: 1.25rem;
}
.property-card-flags:empty { display: none; }
.property-card-flag {
    display: inline-flex;
    align-items: center;
    /* Locked height - flags sit inside dense result rows and card grids;
       padding-driven sizing inherits variable line-height and distorts
       row height.  Matches .badge height. */
    height: 1.25rem;
    min-height: 1.25rem;
    padding: 0 var(--space-2);
    background: var(--bg-subtle);
    border: 0.0625rem solid var(--border-light);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    vertical-align: middle;
    white-space: nowrap;
}
.property-card-flag.is-warn {
    background: var(--warning-light);
    border-color: rgba(245, 124, 0, 0.3);
    color: var(--warning);
}
.property-card-flag.is-info {
    background: var(--info-light);
    border-color: rgba(21, 101, 192, 0.18);
    color: var(--info);
}

/* Footer - parcel id + action affordance */
.property-card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-top: var(--space-3);
    border-top: 0.0625rem solid var(--border-light);
}
.property-card-id {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    color: var(--faint);
    font-variant-numeric: tabular-nums;
}
.property-card-action {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    color: var(--gold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    transition: color var(--anim-fast) var(--easing);
}
.property-card:hover .property-card-action { color: var(--gold-dark); }

/* Compact variant for sidebars / dashboards (no headline block) */
.property-card.is-compact .property-card-headline { display: none; }
.property-card.is-compact { padding: var(--space-4); gap: var(--space-3); }
.property-card.is-compact .property-card-grid { gap: var(--space-2) var(--space-3); }

/* Responsive */
@media (max-width: 30em) {
    .property-card { padding: var(--space-4); }
    .property-card-headline-value { font-size: var(--text-xl); }
    .property-card-grid { grid-template-columns: 1fr 1fr; }
}

/* ── Mini Property Row (for lists) ── */
.property-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-bottom: 0.0625rem solid var(--border-light);
    cursor: pointer;
    transition: background var(--anim-fast) var(--easing);
    min-height: calc(var(--control-h) + var(--space-2));
}
.property-row:hover { background: var(--bg-hover); }
.property-row:last-child { border-bottom: none; }
/* Static rows - same layout as property-row but without the clickable
   affordance (no pointer cursor, no hover background shift). Used for
   read-only lists like the activity feed timeline. */
.property-row-static { cursor: default; }
.property-row-static:hover { background: transparent; }
.property-row-check { flex-shrink: 0; display: flex; align-items: center; }
.property-row-check input {
    accent-color: var(--gold);
    cursor: pointer;
    width: 1rem;
    height: 1rem;
    margin: 0;
}
.property-row-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.property-row-address {
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--text);
    line-height: var(--leading-tight);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.property-row-meta {
    font-size: var(--text-xs);
    color: var(--muted);
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
    line-height: var(--leading-snug);
}
.property-row-value {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    color: var(--text);
    flex-shrink: 0;
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ── Filter Panel ── */
.filter-panel {
    background: var(--warm-white);
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
/* Filter sections - collapsible panels in the search drawer.
   The header is generously padded so it never feels like a GIS toolbar
   row, the icon is a 1.75rem tinted square that flips to gold when open,
   and the count chip uses tabular numbers so it always reads cleanly. */
.filter-section {
    border-bottom: 0.0625rem solid var(--border-light);
    transition: background var(--anim-fast) var(--easing);
}
.filter-section:last-child { border-bottom: none; }
.filter-section.open { background: var(--bg-subtle); }

.filter-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-3) var(--space-4);
    cursor: pointer;
    user-select: none;
    transition: background var(--anim-fast) var(--easing);
    gap: var(--space-3);
}
.filter-section-header:hover { background: var(--bg-hover); }
.filter-section.open .filter-section-header {
    background: transparent;
}

.filter-section-title {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    color: var(--text);
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    flex: 1;
    min-width: 0;
    text-transform: none;
    letter-spacing: 0;
}
.filter-section-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    background: var(--gold-muted);
    color: var(--gold-dark);
    border: 0.0625rem solid var(--gold-border);
    border-radius: var(--radius-md);
    font-size: var(--text-md);
    font-weight: var(--weight-semibold);
    flex-shrink: 0;
    transition: background var(--anim-fast) var(--easing),
                color var(--anim-fast) var(--easing),
                border-color var(--anim-fast) var(--easing);
}
.filter-section-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.25rem;
    min-height: 1.25rem;
    padding: 0 var(--space-2);
    background: var(--surface-card);
    border: 0.0625rem solid var(--border-light);
    color: var(--muted);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    font-family: var(--font-body);
    font-variant-numeric: tabular-nums;
    line-height: 1;
    text-transform: none;
    letter-spacing: 0;
    vertical-align: middle;
    flex-shrink: 0;
}
.filter-section.has-active .filter-section-count {
    background: var(--gold);
    border-color: var(--gold-dark);
    color: #fff;
}
.filter-section-chevron {
    font-size: var(--text-sm);
    color: var(--faint);
    transition: transform var(--anim-normal) var(--easing),
                color var(--anim-fast) var(--easing);
    flex-shrink: 0;
}
.filter-section.open .filter-section-chevron {
    transform: rotate(180deg);
    color: var(--gold);
}
.filter-section.open .filter-section-icon {
    background: var(--gold);
    border-color: var(--gold-dark);
    color: #fff;
    box-shadow: 0 0.0625rem 0.25rem rgba(181, 148, 42, 0.3);
}
.filter-section-body {
    display: none;
    padding: 0 var(--space-4) var(--space-4);
    background: var(--bg-subtle);
}
.filter-section.open .filter-section-body {
    display: block;
    animation: filterOpen var(--anim-normal) var(--easing);
}
@keyframes filterOpen {
    from { opacity: 0; transform: translateY(-0.25rem); }
    to { opacity: 1; transform: translateY(0); }
}

/* Multi-select chip group (filter section) */
.multiselect-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}
.multiselect-chip {
    display: inline-flex;
    align-items: center;
    /* Locked height keeps filter chip rows from jittering when selections
       change - matches .badge height. */
    height: 1.25rem;
    min-height: 1.25rem;
    padding: 0 0.5rem;
    background: var(--cream);
    border: 0.0625rem solid var(--border);
    border-radius: var(--radius-pill);
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: var(--weight-semibold);
    line-height: 1;
    color: var(--text);
    cursor: pointer;
    transition: background var(--anim-fast) var(--easing), color var(--anim-fast) var(--easing), border-color var(--anim-fast) var(--easing);
    white-space: nowrap;
    vertical-align: middle;
}
.multiselect-chip:hover {
    border-color: var(--gold);
    background: var(--warm-white);
}
.multiselect-chip.active {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--slate);
}

/* Filter pills */
.filter-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin-bottom: 0.75rem;
}
.filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    height: 1.25rem;
    min-height: 1.25rem;
    padding: 0 0.5rem;
    border-radius: var(--radius-pill);
    background: var(--gold-muted);
    border: 0.0625rem solid var(--gold-border);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    line-height: 1;
    color: var(--gold-dark);
    vertical-align: middle;
    white-space: nowrap;
}
.filter-pill-remove {
    cursor: pointer;
    font-size: 0.75rem;
    line-height: 1;
    opacity: 0.6;
}
.filter-pill-remove:hover { opacity: 1; }

/* Sticky header that contains the Lead List chips + count + Save/
   Export/Search toolbar. The whole block pins to the top of the
   scrolling .split-right container so those controls are visible at
   every scroll position and every screen width - nothing overlaps it.
   Backed with an opaque warm-white so table rows underneath don't
   bleed through. */
.search-sticky-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--warm-white);
    border-bottom: 0.0625rem solid var(--border-light);
    box-shadow: 0 0.125rem 0.5rem rgba(28, 35, 49, 0.04);
    flex-shrink: 0;
}
/* ═══════════════════════════════════════════════════════════════════
   PROPERTY SEARCH - PHONE BEHAVIOR
   ═══════════════════════════════════════════════════════════════════
   On narrow viewports the user wants:
   - The Lead-Lists chips + Sort/Save/Export toolbar to scroll away
     with the rest of the page instead of sitting there permanently.
   - The results table to SCROLL HORIZONTALLY when columns don't fit
     - never collide or overlap cell contents into each other.
   The sticky thead row is attempted as a "nice to have" (best-effort)
   but cannot compete with the table's own horizontal-scroll container,
   so browser behavior may vary. Data legibility wins over sticky. */
@media (max-width: 48em) {
    /* Unstick the Lead-Lists chips + toolbar so they travel up with
       the rest of the page as the user scrolls. */
    .search-sticky-header {
        position: static;
        top: auto;
        box-shadow: none;
    }

    /* Best-effort sticky for the column-header row. Browsers that
       honor axis-aware sticky inside an overflow-x scope will pin it;
       others will let it scroll with the table. Either way data stays
       legible - that's what matters. */
    .split-right .data-table thead th {
        position: sticky;
        top: 0;
        /* Above the toolbar (z 1) so when the user scrolls and the
           toolbar slides up past the thead, the column-header row
           cleanly covers the toolbar buttons instead of letting their
           rounded bottoms peek through the sticky boundary. */
        z-index: 5;
        background: var(--surface-inset);
    }

    /* Force the results table to actually scroll horizontally on phones.
       The previous setup nominally worked but had three usability bugs:
         (a) scrollbars hidden by default on touch devices, so the user
             had no idea horizontal scroll existed
         (b) `overflow-y: hidden` on the wrap clipped the table at the
             pane's bottom even though the parent .split-right scrolls
             vertically - visually "split" the table in half on narrow
             screens because rows past the visible viewport were gone
         (c) no edge shadows, so even after scrolling the user couldn't
             tell whether they'd reached the leftmost or rightmost edge
       The block below fixes all three: visible scrollbar, vertical
       overflow visible (let the parent pane handle vertical scroll),
       and gradient edge shadows that fade in/out based on scroll
       position so "there's more content to the right" is unmistakable. */
    .split-right .data-table-wrap {
        overflow-x: auto;
        /* Vertical overflow is visible so the table extends naturally
           and .split-right (the parent) scrolls the page vertically.
           The previous `overflow-y: hidden` was the source of the
           "splits vertically in two" symptom - rows past the wrap's
           own height were getting clipped instead of being reachable
           by scrolling the page. */
        overflow-y: visible;
        -webkit-overflow-scrolling: touch;
        touch-action: pan-x pan-y;
        overscroll-behavior-x: contain;
        /* Always show a thin scrollbar at the bottom so the user knows
           horizontal scroll is available. Standard scrollbar widget is
           mostly invisible on macOS / iOS / Android by default. */
        scrollbar-width: thin;
        scrollbar-color: var(--border) transparent;
        /* Edge fade indicator - a subtle shadow on the right edge that
           tells the eye "more content over there". Pure CSS, no JS. */
        background:
            linear-gradient(to right, var(--surface-card), var(--surface-card)) left center / 1.5rem 100% no-repeat,
            linear-gradient(to right, rgba(28,35,49,0.10), rgba(28,35,49,0)) left center / 1.5rem 100% no-repeat,
            linear-gradient(to left,  var(--surface-card), var(--surface-card)) right center / 1.5rem 100% no-repeat,
            linear-gradient(to left,  rgba(28,35,49,0.10), rgba(28,35,49,0)) right center / 1.5rem 100% no-repeat,
            var(--surface-card);
        background-attachment: local, scroll, local, scroll;
        position: relative;
    }
    /* Webkit scrollbar - make it visible enough to discover. */
    .split-right .data-table-wrap::-webkit-scrollbar {
        height: 0.5rem;
    }
    .split-right .data-table-wrap::-webkit-scrollbar-thumb {
        background: var(--border);
        border-radius: 0.25rem;
    }
    .split-right .data-table-wrap::-webkit-scrollbar-thumb:hover {
        background: var(--gold);
    }
    .split-right .data-table {
        min-width: 44rem;
    }
}
/* Inner chip/toolbar bars lose their own border so the outer wrapper
   owns the separator visually. */
.search-sticky-header .smart-list-bar,
.search-sticky-header .table-toolbar {
    border-bottom: 0;
    background: transparent;
}
.search-sticky-header .table-toolbar {
    border-top: 0.0625rem solid var(--border-light);
}

/* Smart-list chip bar - horizontal scrollable strip above search results.
   Matches .table-toolbar vertical padding (--space-3) for rhythm. */
.smart-list-bar {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.625rem 1rem;
    border-bottom: 0.0625rem solid var(--border-light);
    background: var(--warm-white);
    /* Wrap into two rows instead of horizontally scrolling so every
       preset is ALWAYS visible - users shouldn't have to discover
       chips by scrolling a sideways rail. */
    flex-wrap: wrap;
    overflow: visible;
}
.smart-list-bar-label {
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--faint);
    align-self: center;
    flex-shrink: 0;
    margin-right: var(--space-2);
}

/* On narrow screens every preset chip stays visible by wrapping onto
   multiple rows - users shouldn't have to discover chips by scrolling
   a sideways rail. Slightly smaller padding/gap so 3–4 rows stay
   compact and don't eat too much vertical space. */
@media (max-width: 48em) {
    .smart-list-bar {
        flex-wrap: wrap;
        overflow: visible;
        padding: 0.5rem 0.75rem;
        gap: 0.3125rem;
        row-gap: 0.375rem;
    }
    .smart-list-chip {
        /* Tighten chip padding so all 10+ presets fit on a phone
           without pushing the results table below the fold. */
        padding: 0 0.5625rem;
        font-size: 0.75rem;
    }
    .smart-list-bar-label {
        /* Full-width label sitting above the chip rows so "Lead Lists:"
           reads as a section heading for the row group. */
        flex-basis: 100%;
        margin-right: 0;
        margin-bottom: 0.25rem;
    }
}
@media (max-width: 30em) {
    /* Ultra-narrow: drop the label entirely (redundant with the chips)
       and shrink chip padding further so every one fits. */
    .smart-list-bar-label {
        flex-basis: auto;
        margin-right: 0;
        margin-bottom: 0;
        position: absolute;
        width: 0.0625rem; height: 0.0625rem;
        padding: 0;
        clip: rect(0, 0, 0, 0);
        overflow: hidden;
    }
    .smart-list-chip {
        padding: 0 0.5rem;
        font-size: 0.6875rem;
        height: 1.625rem;
        min-height: 1.625rem;
        line-height: 1.625rem;
    }
}

/* Smart list preset chips (search page) */
.smart-list-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    /* Explicit height + line-height so the label always has vertical
       room regardless of font loading state. Previously chips could
       render taller than the text, making them read as "empty boxes"
       if the font hadn't swapped in. */
    height: 1.75rem;
    min-height: 1.75rem;
    padding: 0 0.75rem;
    border-radius: var(--radius-pill);
    background: var(--warm-white);
    border: 0.0625rem solid var(--border);
    font-family: var(--font-body);
    font-size: 0.8125rem;
    font-weight: var(--weight-semibold);
    line-height: 1.75rem;
    color: var(--text);
    cursor: pointer;
    white-space: nowrap;
    vertical-align: middle;
    flex-shrink: 0;
    transition: background var(--anim-fast) var(--easing), color var(--anim-fast) var(--easing), border-color var(--anim-fast) var(--easing);
}
.smart-list-chip:hover {
    background: var(--cream);
    border-color: var(--gold);
    color: var(--gold-dark);
}
.smart-list-chip:active { transform: none; }
.smart-list-chip.active {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--slate);
    box-shadow: 0 0.125rem 0.375rem rgba(181, 148, 42, 0.25);
}

/* Range input group */
.range-group {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.range-group .form-input {
    flex: 1;
    text-align: center;
    font-family: var(--font-mono);
    font-size: 0.75rem;
}
.range-separator {
    color: var(--faint);
    font-size: 0.75rem;
    font-weight: var(--weight-semibold);
}

/* ── Charts ── */
.chart-container {
    position: relative;
    width: 100%;
}
.chart-container svg {
    width: 100%;
    height: auto;
    display: block;
}
.chart-title {
    font-family: var(--font-display);
    font-size: 0.875rem;
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin-bottom: 0.75rem;
}
.chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.5rem;
}
.chart-legend-item {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: var(--text-xs);
    color: var(--muted);
}
.chart-legend-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Sparkline */
.sparkline {
    display: inline-block;
    vertical-align: middle;
}
.sparkline svg { display: block; }

/* ── Metric Highlight ── */
.metric-highlight {
    display: flex;
    align-items: baseline;
    gap: 0.375rem;
}
.metric-value {
    font-family: var(--font-mono);
    font-size: 1.25rem;
    font-weight: var(--weight-medium);
    color: var(--slate);
}
.metric-unit {
    font-size: 0.75rem;
    color: var(--muted);
}
.metric-change {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    margin-left: 0.25rem;
}
.metric-change.up { color: var(--success); }
.metric-change.down { color: var(--error); }

/* ── Progress Bar ── */
.progress {
    height: 0.375rem;
    background: var(--border-light);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.progress-bar {
    height: 100%;
    min-width: 0.25rem;
    background: var(--gold);
    border-radius: var(--radius-pill);
    transition: width var(--anim-slow) var(--easing);
}
.progress-bar.success { background: var(--success); }
.progress-bar.warning { background: var(--warning); }
.progress-bar.error { background: var(--error); }

/* ── Tooltip ── */
.tooltip {
    position: relative;
}
.tooltip::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 0.375rem);
    left: 50%;
    transform: translateX(-50%);
    background: var(--slate);
    color: #fff;
    padding: 0.25rem 0.5rem;
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition);
    z-index: 100;
}
.tooltip:hover::after,
.tooltip:focus-visible::after { opacity: 1; }

/* ── Dropdown ── */
.dropdown {
    position: relative;
    display: inline-block;
}
.dropdown-menu {
    display: none;
    position: absolute;
    top: calc(100% + 0.25rem);
    right: 0;
    min-width: 10rem;
    background: var(--warm-white);
    border: 0.0625rem solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    z-index: 100;
    overflow: hidden;
}
.dropdown.open .dropdown-menu { display: block; }
.dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background var(--transition);
    border: none;
    background: none;
    width: 100%;
    text-align: left;
    font-family: var(--font-body);
}
.dropdown-item:hover { background: var(--bg-hover); }
.dropdown-divider { height: 0.0625rem; background: var(--border-light); margin: 0.25rem 0; }

/* ── Activity Feed ── */
.activity-feed { display: flex; flex-direction: column; }
.activity-item {
    display: flex;
    gap: 0.75rem;
    padding: 0.625rem 0;
    border-bottom: 0.0625rem solid var(--border-light);
}
.activity-item:last-child { border-bottom: none; }
.activity-icon {
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 0.75rem;
    background: var(--bg-subtle);
    color: var(--muted);
}
.activity-icon.search { background: var(--info-light); color: var(--info); }
.activity-icon.list { background: var(--gold-muted); color: var(--gold); }
.activity-icon.view { background: var(--success-light); color: var(--success); }
.activity-icon.export { background: var(--warning-light); color: var(--warning); }
.activity-content { flex: 1; min-width: 0; }
.activity-text { font-size: var(--text-sm); color: var(--text); line-height: 1.4; }
.activity-text strong { font-weight: var(--weight-semibold); }
.activity-time { font-size: var(--text-xs); color: var(--faint); margin-top: 0.125rem; }

/* ── Split Layout - used by search and lists. ──
   Desktop: filter / sidebar on the left, content on the right.
   Tablet:  filter becomes a slide-in drawer behind a toggle button.
   Mobile:  drawer takes the whole screen, content fills below. */
.split-layout {
    display: flex;
    /* Notch-safe fill. Subtracting env() keeps the layout's top edge flush
       with the bottom of the fixed nav on notched phones - without it
       the "Lead Lists" row would sit behind the nav at the top by
       exactly safe-top pixels. 100dvh variant handles iOS Safari's
       collapsing chrome. */
    height: calc(100vh - var(--top-nav-h) - env(safe-area-inset-top, 0rem));
    height: calc(100dvh - var(--top-nav-h) - env(safe-area-inset-top, 0rem));
    overflow: hidden;
    background: var(--surface-canvas);
}
.split-left {
    width: 22rem;
    flex-shrink: 0;
    border-right: 0.0625rem solid var(--border-light);
    overflow-y: auto;
    background: var(--surface-card);
    display: flex;
    flex-direction: column;
}
.split-right {
    flex: 1;
    width: 100%;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

/* Toggle button only shown on tablet/mobile via media query below.
   The `left` offset respects --sidebar-gap so the button clears the
   pinned rail/full sidebar instead of disappearing behind it. */
.split-toggle {
    display: none;
    position: fixed;
    bottom: calc(var(--space-5) + var(--safe-bottom, 0rem));
    left: calc(var(--sidebar-gap, 0rem) + var(--space-5));
    z-index: 1175;  /* above the filter drawer (1170) so it stays tappable */
    background: var(--slate);
    color: #fff;
    border: 0.0625rem solid var(--gold);
    border-radius: var(--radius-pill);
    padding: var(--space-3) var(--space-5);
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    cursor: pointer;
    box-shadow: 0 0.625rem 1.5rem rgba(28, 35, 49, 0.32), 0 0 0 0.0625rem rgba(212, 175, 55, 0.35);
    align-items: center;
    gap: var(--space-2);
    min-height: 2.75rem;
    transition: transform var(--anim-fast) var(--easing),
                background var(--anim-fast) var(--easing),
                box-shadow var(--anim-fast) var(--easing);
    -webkit-tap-highlight-color: transparent;
}
.split-toggle:hover {
    background: var(--slate-light);
    box-shadow: 0 0.75rem 1.75rem rgba(28, 35, 49, 0.38), 0 0 0 0.0625rem rgba(212, 175, 55, 0.5);
}
.split-toggle:active { transform: none; }
.split-toggle:focus-visible {
    outline: none;
    box-shadow: 0 0.625rem 1.5rem rgba(28, 35, 49, 0.32), 0 0 0 0.1875rem var(--gold-muted), 0 0 0 0.0625rem var(--gold);
}
.split-toggle .split-toggle-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    height: 1.25rem;
    padding: 0 var(--space-2);
    background: var(--gold);
    color: var(--slate);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    margin-left: var(--space-1);
    font-variant-numeric: tabular-nums;
}

/* ── Tablet (≤64rem) ── filter becomes a slide-in drawer.
   The drawer's left edge is anchored to the ACTUAL rendered sidebar
   width (not --sidebar-gap, which can lag behind when the user
   manually expands the sidebar to "full" on a medium viewport). Without
   this the drawer slid out underneath the expanded sidebar - the
   sidebar's z-index (9500) is far higher than the drawer (1170), so
   the overlapping portion of the drawer was hidden and the user saw
   "the main sidebar overlapping the saved-properties drawer." */
@media (max-width: 64em) {
    .split-layout { position: relative; }
    /* Derive the real left offset from the body's sidebar mode class.
       Defaults to --sidebar-gap so the drawer still works on routes
       that haven't switched modes yet. */
    .split-layout { --split-drawer-left: var(--sidebar-gap, 0); }
    body.sb-drawer .split-layout,
    body.sb-hide-on-route .split-layout { --split-drawer-left: 0; }
    body.sb-rail   .split-layout { --split-drawer-left: var(--sidebar-collapsed-w); }
    body.sb-full   .split-layout { --split-drawer-left: var(--sidebar-w); }
    .split-left {
        position: fixed;
        top: var(--top-nav-h);
        left: var(--split-drawer-left, var(--sidebar-gap, 0));
        bottom: 0;
        /* Shrink width so drawer + sidebar fit even when the sidebar
           is in "full" mode on a 60em viewport (15rem sidebar +
           22rem drawer = 37rem > available width on a 60em screen
           minus chrome). The min() guarantees no overflow. */
        width: min(22rem, calc(100vw - var(--split-drawer-left, 0px) - 1rem));
        z-index: 1170;  /* above sidebar overlap area, below mobile nav drawer (9500) */
        transform: translateX(-100%);
        transition: transform var(--anim-normal) var(--easing),
                    left var(--anim-normal) var(--easing),
                    width var(--anim-normal) var(--easing);
        box-shadow: var(--shadow-modal);
        border-right: 0.0625rem solid var(--border);
    }
    .split-layout.drawer-open .split-left {
        transform: translateX(0);
    }
    .split-right { width: 100%; }
    .split-toggle { display: inline-flex; }
    .split-layout.drawer-open::before {
        content: '';
        position: fixed;
        /* Overlay dims everything to the right of the sidebar so the
           sidebar itself stays fully interactive and visible next to
           the drawer. */
        top: var(--top-nav-h);
        right: 0;
        bottom: 0;
        left: var(--split-drawer-left, var(--sidebar-gap, 0));
        background: var(--surface-overlay);
        backdrop-filter: blur(0.125rem);
        -webkit-backdrop-filter: blur(0.125rem);
        z-index: 1165;
    }
}

/* ── Mobile (≤40rem) ── slightly tighter drawer + bottom toggle. */
@media (max-width: 40em) {
    .split-left { width: 100%; max-height: calc(100vh - var(--top-nav-h, 3.5rem)); max-height: calc(100dvh - var(--top-nav-h, 3.5rem)); }
    .split-toggle { left: 50%; transform: translateX(-50%); bottom: var(--space-4); }
}

/* ── Key-Value Pairs ── */
.kv-list { display: flex; flex-direction: column; gap: 0; }
.kv-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.375rem 0;
    border-bottom: 0.0625rem solid var(--border-light);
}
.kv-row:last-child { border-bottom: none; }
.kv-label {
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
    flex-shrink: 0;
}
.kv-value {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: var(--weight-medium);
    color: var(--text);
    text-align: right;
    word-break: break-word;
}
.kv-value.large {
    font-size: 1rem;
    font-weight: var(--weight-medium);
    color: var(--slate);
}

/* ── Section Divider ── */
.section-divider {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: var(--space-6) 0 var(--space-4);
}
.section-divider-line { flex: 1; height: 0.0625rem; background: var(--border-light); }
.section-divider-text {
    font-size: 0.625rem;
    font-weight: var(--weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--faint);
    flex-shrink: 0;
}

/* ── Color Dots (for lists) ── */
.color-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    flex-shrink: 0;
}
.color-dot-lg { width: 0.75rem; height: 0.75rem; }

/* ── Confidence Indicator ── */
.confidence {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
}
.confidence-high { color: var(--success); }
.confidence-medium { color: var(--warning); }
.confidence-low { color: var(--error); }
.confidence-bar {
    width: 2.5rem;
    height: 0.25rem;
    background: var(--border-light);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.confidence-bar-fill { height: 100%; border-radius: var(--radius-pill); }
.confidence-high .confidence-bar-fill { background: var(--success); }
.confidence-medium .confidence-bar-fill { background: var(--warning); }
.confidence-low .confidence-bar-fill { background: var(--error); }

/* ── Trial / Upgrade Banner ── */
.dash-upgrade-banner {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1.5rem; padding: 1.5rem 2rem;
    background: linear-gradient(135deg, var(--slate) 0%, var(--slate-light) 100%);
    border-radius: var(--radius-lg); border: 0.0625rem solid rgba(181,148,42,0.18);
    box-shadow: var(--shadow-card);
}
.dash-upgrade-banner.is-urgent {
    border-color: rgba(212, 175, 55, 0.45);
    background: linear-gradient(135deg, #1c2331 0%, #3a2918 100%);
    box-shadow: 0 0.75rem 2rem rgba(28, 35, 49, 0.22), 0 0 0 0.0625rem rgba(212, 175, 55, 0.12);
}
.dash-upgrade-content { flex: 1; min-width: 0; }
.dash-upgrade-title {
    font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-bold);
    color: var(--gold-light); margin-bottom: 0.25rem;
    letter-spacing: -0.005em;
}
.dash-upgrade-text {
    font-size: 0.875rem;
    color: rgba(255,255,255,0.62);
    line-height: var(--leading-relaxed);
}
.dash-upgrade-text strong { color: var(--gold-light); font-weight: var(--weight-bold); }
.dash-upgrade-banner .btn { flex-shrink: 0; }

/* ── Boot-progress banner ──
   Inline progress chip shown inside the Platform Data Scale card while
   the server is reading on-disk county files into RAM at boot. The
   wording is intentionally "Indexing files from disk" not "Loading"
   so the user doesn't think we're downloading from the internet. */
.dash-load-banner {
    margin-bottom: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, var(--gold-muted) 0%, rgba(181, 148, 42, 0.04) 100%);
    border: 0.0625rem solid var(--gold-border);
}
.dash-load-banner-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
}
.dash-load-banner-label {
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--gold-dark);
}
.dash-load-banner-pct {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    font-weight: var(--weight-bold);
    color: var(--slate);
    font-variant-numeric: tabular-nums;
}
.dash-load-banner-hint {
    font-size: var(--text-xs);
    color: var(--muted);
    margin-top: var(--space-2);
    line-height: var(--leading-snug);
}
.dash-load-banner-hint code {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    background: var(--bg-subtle);
    padding: 0.0625rem 0.3125rem;
    border-radius: var(--radius-sm);
    color: var(--text);
    border: 0.0625rem solid var(--border-light);
}

/* ── Dashboard Metrics Row - see dashboard.css for full definitions ── */
.dash-action-icon { font-size: var(--text-lg); opacity: 0.4; width: 1.5rem; text-align: center; flex-shrink: 0; }

/* ── Dashboard Welcome ── */
.dash-welcome-date { font-size: var(--text-sm); color: rgba(255,255,255,0.35); font-weight: var(--weight-medium); }
.dash-welcome-actions { flex-shrink: 0; }
.dash-county-select { background: rgba(255,255,255,0.06); border: 0.0625rem solid rgba(255,255,255,0.1); color: #fff; }
.dash-county-select option { background: var(--slate); color: #fff; }

/* ── Dashboard Coverage ── */
.dash-coverage-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.5rem; }
.dash-coverage-item { text-align: center; }
.dash-coverage-label { font-size: 0.625rem; font-weight: var(--weight-bold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-bottom: 0.25rem; }
.dash-coverage-value { font-family: var(--font-mono); font-size: var(--text-lg); font-weight: var(--weight-medium); color: var(--slate); }
.progress-lg { height: 0.5rem; }

/* ── Property Page Responsive ── */
@media (max-width: 64em) {
    .dash-metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .dash-coverage-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 48em) {
    .dash-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .dash-upgrade-banner { flex-direction: column; text-align: center; }
    .dash-coverage-grid { grid-template-columns: 1fr 1fr; }
}
/* bp-sm: on phone widths, metrics and coverage go single-column. */
@media (max-width: 40em) {
    .dash-metrics { grid-template-columns: 1fr; }
    .dash-coverage-grid { grid-template-columns: 1fr; }
}

/* ════════════════════════════════════════════════════════════════════
   LEAD LIST CARDS - /lead-lists hub
   PropStream-class catalog of pre-built filter presets, rendered as
   a responsive grid of clickable cards. Each card has the icon, name,
   one-line tagline, longer description, an estimated coverage %, and
   a primary CTA. Whole-card click + button click both navigate.
   ──────────────────────────────────────────────────────────────────── */
.lead-list-card {
    display: flex;
    flex-direction: column;
    border-radius: var(--radius-lg);
    transition: transform var(--anim-fast) var(--easing), box-shadow var(--anim-fast) var(--easing), border-color var(--anim-fast) var(--easing);
    border: 0.0625rem solid var(--border-light);
    background: var(--white);
    cursor: pointer;
    height: 100%;
}
.lead-list-card:hover {
    transform: translateY(-0.0625rem);
    border-color: var(--gold);
    box-shadow: var(--shadow-elevated);
}
.lead-list-card .card-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    height: 100%;
}
.lead-list-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}
.lead-list-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.14) 0%, rgba(181, 148, 42, 0.05) 100%);
    color: var(--gold);
    border: 0.0625rem solid rgba(212, 175, 55, 0.22);
}
.lead-list-card-title {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: var(--weight-bold);
    color: var(--slate);
    line-height: var(--leading-snug);
    margin: 0;
}
.lead-list-card-tagline {
    font-size: 0.75rem;
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--gold);
    line-height: var(--leading-snug);
}
.lead-list-card-desc {
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    color: var(--text-secondary);
    margin: 0 0 0.5rem 0;
    flex: 1;
}
.lead-list-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding-top: 0.5rem;
    border-top: 0.0625rem solid var(--border-light);
    margin-top: auto;
}
.lead-list-card-pct {
    display: flex;
    flex-direction: column;
    line-height: 1;
}
.lead-list-card-pct-value {
    font-family: var(--font-mono);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--slate);
}
.lead-list-card-pct-label {
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    margin-top: 0.125rem;
}
.lead-list-run-btn {
    flex-shrink: 0;
}

/* ── Lead-list banner that surfaces in /search when applied via URL ──
   Pinned directly under the top-nav so the active lead-list name + tagline
   stay on screen as the user scrolls the results table. Works with the
   sticky .table-toolbar below it - the toolbar's top offset is bumped so
   both stack without overlap. */
.lead-list-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.625rem 1rem;
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.12), rgba(212, 175, 55, 0.04)), var(--warm-white);
    border-bottom: 0.0625rem solid rgba(212, 175, 55, 0.28);
    border-left: 0.1875rem solid var(--gold);
    /* Scrolls naturally with the page - previously sticky-pinned under
       the top nav, but that covered the first rows of the results table
       as users scrolled. Same rationale as the toolbar unsticking. */
}
.lead-list-banner-text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    flex: 1;
}
.lead-list-banner-text strong {
    font-family: var(--font-display);
    font-size: var(--text-base);
    color: var(--slate);
    font-weight: var(--weight-bold);
}
.lead-list-banner-text span {
    font-size: 0.75rem;
    color: var(--text-secondary);
    line-height: var(--leading-snug);
}

/* ════════════════════════════════════════════════════════════════════
   HELP & ACADEMY - /help
   Sticky section nav, accordion articles, glossary <dl>, shortcut <table>.
   ──────────────────────────────────────────────────────────────────── */
.help-section-nav {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    padding: 0.75rem 0;
    margin-bottom: 1.5rem;
    border-bottom: 0.0625rem solid var(--border-light);
    position: sticky;
    top: 0;
    background: var(--cream);
    z-index: 10;
}
.help-section-nav-link {
    display: inline-flex;
    align-items: center;
    padding: 0.375rem 0.75rem;
    border-radius: var(--radius-pill);
    font-size: 0.75rem;
    font-weight: var(--weight-semibold);
    color: var(--text-secondary);
    background: var(--white);
    border: 0.0625rem solid var(--border-light);
    text-decoration: none;
    transition: background var(--anim-fast) var(--easing), color var(--anim-fast) var(--easing), border-color var(--anim-fast) var(--easing);
    cursor: pointer;
}
.help-section-nav-link:hover {
    color: var(--gold);
    border-color: var(--gold);
    background: rgba(212, 175, 55, 0.06);
}
.help-section {
    margin-bottom: 2.5rem;
    padding-top: 0.5rem;
    scroll-margin-top: 4.5rem;
}
.help-section-header {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    margin-bottom: 1.25rem;
    padding-bottom: 0.75rem;
    border-bottom: 0.0625rem solid var(--border-light);
}
.help-section-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.18), rgba(181, 148, 42, 0.06));
    color: var(--gold);
    border: 0.0625rem solid rgba(212, 175, 55, 0.28);
    flex-shrink: 0;
}
.help-section-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin: 0;
    line-height: var(--leading-snug);
}
.help-section-blurb {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-top: 0.125rem;
    line-height: var(--leading-relaxed);
}
.help-article {
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-md);
    background: var(--white);
    margin-bottom: 0.625rem;
    overflow: hidden;
}
.help-article-toggle {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
    background: transparent;
    border: 0;
    text-align: left;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: var(--weight-semibold);
    color: var(--slate);
    transition: background var(--anim-fast) var(--easing);
}
.help-article-toggle:hover {
    background: rgba(212, 175, 55, 0.04);
}
.help-article-toggle[aria-expanded="true"] {
    background: rgba(212, 175, 55, 0.05);
    border-bottom: 0.0625rem solid var(--border-light);
}
.help-article-chevron {
    display: inline-flex;
    color: var(--muted);
    transition: transform var(--anim-fast) var(--easing);
    flex-shrink: 0;
}
.help-article-toggle[aria-expanded="true"] .help-article-chevron {
    transform: rotate(180deg);
    color: var(--gold);
}
.help-article-body {
    padding: 1rem 1.25rem 1.25rem;
    font-size: 0.875rem;
    line-height: var(--leading-relaxed);
    color: var(--text-secondary);
}
.help-article-body p { margin: 0 0 0.75rem 0; }
.help-article-body p:last-child { margin-bottom: 0; }
.help-article-body ol,
.help-article-body ul { padding-left: 1.25rem; margin: 0 0 0.75rem 0; }
.help-article-body li { margin-bottom: 0.375rem; }
.help-article-body strong { color: var(--slate); }
.help-article-body code {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    background: var(--bg-subtle);
    padding: 0.0625rem 0.3125rem;
    border-radius: var(--radius-sm);
    border: 0.0625rem solid var(--border-light);
    color: var(--text);
}
.help-article-body a {
    color: var(--gold);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    border-bottom: 0.0625rem dashed var(--gold);
}
.help-article-body a:hover { border-bottom-style: solid; }

.help-glossary { margin: 0; }
.help-glossary dt {
    font-family: var(--font-display);
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin-top: 0.625rem;
    font-size: 0.875rem;
}
.help-glossary dt:first-child { margin-top: 0; }
.help-glossary dd {
    margin: 0.125rem 0 0.375rem 0;
    color: var(--text-secondary);
    line-height: var(--leading-relaxed);
    font-size: var(--text-sm);
}

.help-shortcuts {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}
.help-shortcuts thead th {
    text-align: left;
    text-transform: uppercase;
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    font-weight: var(--weight-bold);
    color: var(--muted);
    padding: 0.5rem 0.75rem;
    border-bottom: 0.0625rem solid var(--border-light);
}
.help-shortcuts tbody td {
    padding: 0.5rem 0.75rem;
    border-bottom: 0.0625rem solid var(--border-light);
    color: var(--text);
}
.help-shortcuts tbody tr:last-child td { border-bottom: 0; }
.help-shortcuts kbd {
    display: inline-block;
    padding: 0.125rem 0.4375rem;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    color: var(--slate);
    background: var(--bg-subtle);
    border: 0.0625rem solid var(--border-light);
    border-bottom-width: 0.125rem;
    border-radius: var(--radius-sm);
    margin: 0 0.125rem;
}

/* ════════════════════════════════════════════════════════════════════
   MARKET INSIGHTS - /insights
   Magazine-style article feed: featured card, category chips, grid.
   ──────────────────────────────────────────────────────────────────── */
.insight-featured {
    /* Fallback slate fill before the cover image loads. The actual
       photo + overlay is applied inline from insights.js
       (_buildFeaturedCard sets background-image) so each article gets
       a unique real photo from the Picsum CC0 catalog instead of the
       old static gradient. */
    background-color: var(--slate);
    color: #fff;
    padding: 2rem 2.25rem;
    border-radius: var(--radius-lg);
    margin-bottom: 1.75rem;
    border: 0.0625rem solid rgba(212, 175, 55, 0.18);
    cursor: pointer;
    overflow: hidden;
    transition: transform var(--anim-fast) var(--easing), box-shadow var(--anim-fast) var(--easing), border-color var(--anim-fast) var(--easing);
}
.insight-featured:hover {
    transform: translateY(-0.0625rem);
    border-color: rgba(212, 175, 55, 0.4);
    box-shadow: var(--shadow-popover);
}
.insight-featured-meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(255, 255, 255, 0.6);
    font-weight: var(--weight-semibold);
    margin-bottom: 0.75rem;
}
.insight-featured-cat {
    color: var(--gold-light);
    font-weight: var(--weight-bold);
}
.insight-featured-dot { color: rgba(255, 255, 255, 0.3); }
.insight-featured-title {
    font-family: var(--font-display);
    font-size: 1.875rem;
    font-weight: var(--weight-bold);
    color: #fff;
    line-height: var(--leading-tight);
    margin: 0 0 0.5rem 0;
}
.insight-featured-subtitle {
    font-size: 1rem;
    color: rgba(255, 255, 255, 0.78);
    line-height: var(--leading-snug);
    margin: 0 0 0.75rem 0;
    font-weight: var(--weight-regular);
}
.insight-featured-preview {
    font-size: var(--text-base);
    color: rgba(255, 255, 255, 0.7);
    line-height: var(--leading-relaxed);
    margin: 0 0 1.25rem 0;
}
.insight-featured-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-top: 1rem;
    border-top: 0.0625rem solid rgba(255, 255, 255, 0.1);
}
.insight-featured-author {
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.55);
    font-weight: var(--weight-medium);
}

.insights-category-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 1.5rem 0;
    padding-bottom: 1rem;
    border-bottom: 0.0625rem solid var(--border-light);
}
.insights-category-chip {
    display: inline-flex;
    align-items: center;
    height: 1.625rem;
    min-height: 1.625rem;
    padding: 0 0.75rem;
    border-radius: var(--radius-pill);
    font-size: 0.75rem;
    font-weight: var(--weight-semibold);
    line-height: 1;
    color: var(--text-secondary);
    background: var(--white);
    border: 0.0625rem solid var(--border-light);
    cursor: pointer;
    vertical-align: middle;
    white-space: nowrap;
    transition: background var(--anim-fast) var(--easing), color var(--anim-fast) var(--easing), border-color var(--anim-fast) var(--easing);
}
.insights-category-chip:hover {
    color: var(--gold);
    border-color: var(--gold);
}
.insights-category-chip.active {
    color: #fff;
    background: var(--slate);
    border-color: var(--slate);
}

.insights-grid-wrap { margin-top: 0.5rem; }
.insights-grid-head { margin-bottom: 1rem; }
.insights-grid-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin: 0;
}

.insight-card {
    cursor: pointer;
    border-radius: var(--radius-lg);
    transition: transform var(--anim-fast) var(--easing), box-shadow var(--anim-fast) var(--easing), border-color var(--anim-fast) var(--easing);
    border: 0.0625rem solid var(--border-light);
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden; /* clip the cover image to the card's rounded corners */
}
.insight-card-cover-wrap {
    /* 16:9 aspect ratio - matches the proportion Picsum returns for
       800x450 requests and keeps the grid tidy even before the image
       resolves. background tint is the eventual loaded color so the
       transition from skeleton to photo isn't jarring. */
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: linear-gradient(135deg, #e8e2d4 0%, #d5cfc5 100%);
    overflow: hidden;
}
.insight-card-cover {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.4s var(--easing);
}
.insight-card:hover .insight-card-cover {
    transform: scale(1.03);
}
.insight-card:hover {
    transform: translateY(-0.0625rem);
    border-color: var(--gold);
    box-shadow: var(--shadow-elevated);
}
.insight-card .card-body {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    padding: var(--space-5);
    height: 100%;
}
.insight-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.625rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: var(--weight-bold);
    margin-bottom: 0.25rem;
}
.insight-card-cat { color: var(--gold); }
.insight-card-date { color: var(--muted); }
.insight-card-title {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: var(--weight-bold);
    color: var(--slate);
    line-height: var(--leading-snug);
    margin: 0;
}
.insight-card-subtitle {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    font-weight: var(--weight-medium);
    line-height: var(--leading-snug);
}
.insight-card-preview {
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    color: var(--text-secondary);
    margin: 0;
    flex: 1;
}
.insight-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding-top: 0.625rem;
    margin-top: auto;
    border-top: 0.0625rem solid var(--border-light);
    font-size: var(--text-xs);
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: var(--weight-semibold);
}
.insight-card-arrow { color: var(--gold); font-size: 0.875rem; }

/* ── Insight detail page ── */
.page-narrow {
    max-width: 46rem;
    margin: 0 auto;
}
.insight-back-btn {
    margin-bottom: 1.25rem;
}
.insight-detail-meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    font-weight: var(--weight-semibold);
    margin-bottom: 0.75rem;
}
.insight-detail-cat { color: var(--gold); font-weight: var(--weight-bold); }
.insight-detail-dot { color: var(--border); }
.insight-detail-title {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 800;
    color: var(--slate);
    line-height: var(--leading-tight);
    margin: 0 0 0.5rem 0;
}
.insight-detail-subtitle {
    font-size: 1.0625rem;
    color: var(--text-secondary);
    line-height: var(--leading-snug);
    margin: 0 0 0.75rem 0;
    font-weight: var(--weight-regular);
}
/* ── Author block - used at top and bottom of articles ──────────────── */
.article-author-block {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-5) 0;
    border-top: 0.0625rem solid var(--border-light);
    margin-top: var(--space-2);
}
.article-author-avatar {
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    background: var(--slate);
    color: var(--gold-light);
    font-family: var(--font-body);
    font-weight: var(--weight-bold);
    font-size: var(--text-xs);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    letter-spacing: 0.04em;
    overflow: hidden;
    border: 0.125rem solid var(--border-light);
}
/* When a real photo is available, drop an <img> inside the avatar div.
   The img inherits the circular crop and sizing automatically. */
.article-author-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.article-author-info { min-width: 0; }
.article-author-name {
    font-weight: var(--weight-semibold);
    font-size: var(--text-sm);
    color: var(--slate);
    line-height: var(--leading-snug);
}
.article-author-role {
    font-size: var(--text-xs);
    color: var(--muted);
    line-height: var(--leading-snug);
}
.article-share-btn { margin-left: auto; flex-shrink: 0; }
.article-signoff {
    margin-top: var(--space-8);
    padding-top: 0;
}
.article-signoff .article-author-block {
    border-top: 0.0625rem solid var(--border-light);
    border-bottom: none;
}


/* ── Article body prose ───────────────────────────────────────────── */
.insight-detail-body {
    font-size: 1.0625rem;
    line-height: 1.8;
    color: var(--text);
}
/* Drop cap on the first paragraph for editorial feel */
.insight-detail-body > p:first-of-type::first-letter {
    font-family: var(--font-display);
    font-size: 3.25rem;
    font-weight: 800;
    float: left;
    line-height: 0.8;
    margin: 0.125rem 0.5rem 0 -0.0625rem;
    color: var(--slate);
}
.insight-detail-body h2 {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin: 2.5rem 0 0.75rem 0;
    line-height: var(--leading-snug);
}
.insight-detail-body h3 {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin: 2rem 0 0.5rem 0;
}
.insight-detail-body p { margin: 0 0 1.25rem 0; }
.insight-detail-body ul,
.insight-detail-body ol { padding-left: 1.5rem; margin: 0 0 1.25rem 0; }
.insight-detail-body li { margin-bottom: 0.5rem; }
.insight-detail-body strong { color: var(--slate); font-weight: var(--weight-bold); }
.insight-detail-body code {
    font-family: var(--font-mono);
    font-size: 0.875rem;
    background: var(--bg-subtle);
    padding: 0.0625rem 0.3125rem;
    border-radius: var(--radius-sm);
    border: 0.0625rem solid var(--border-light);
}

/* Blockquote - editorial pull-quote styling */
.insight-detail-body blockquote {
    margin: 2rem 0;
    padding: var(--space-5) var(--space-6);
    border-left: 0.1875rem solid var(--gold);
    background: var(--bg-subtle);
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.insight-detail-body blockquote p {
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-style: italic;
    font-weight: var(--weight-medium);
    color: var(--slate);
    line-height: 1.6;
    margin: 0;
}

/* Horizontal rule - section divider within article body */
.insight-detail-body hr {
    border: none;
    height: 0.0625rem;
    background: var(--border-light);
    margin: 2.5rem 0;
}

/* Figure / image - ready for when image_url is added to articles */
.insight-detail-body figure {
    margin: 2rem 0;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--bg-subtle);
    border: 0.0625rem solid var(--border-light);
}
.insight-detail-body figure img {
    display: block;
    width: 100%;
    height: auto;
}
.insight-detail-body figcaption {
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-xs);
    color: var(--muted);
    font-style: italic;
    line-height: var(--leading-normal);
}

/* ── Related briefings section beneath article detail ──────────────── */
.insight-related {
    margin-top: var(--space-12);
    padding-top: var(--space-8);
    border-top: 0.0625rem solid var(--border-light);
}
.insight-related-title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin-bottom: var(--space-6);
}

/* ════════════════════════════════════════════════════════════════════
   COOKIE CONSENT BANNER + CUSTOMIZE MODAL
   ──────────────────────────────────────────────────────────────────── */
/* When the property action bar is present, shift the cookie consent
   above it so the action buttons remain tappable. The action bar is
   ~3.75rem (60px) tall at its largest. */
.prop-action-bar:not(.hidden) ~ .cookie-consent,
body:has(.prop-action-bar:not(.hidden)) .cookie-consent {
    bottom: 5rem;
}
.cookie-consent {
    position: fixed;
    bottom: 1rem;
    left: 1rem;
    right: 1rem;
    z-index: 9000;
    max-width: 60rem;
    margin: 0 auto;
    background: var(--white);
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: 0 1.25rem 3rem rgba(28, 35, 49, 0.22);
    transform: translateY(150%);
    transition: transform 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
    pointer-events: auto;
}
.cookie-consent-visible { transform: translateY(0); }
.cookie-consent-inner {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 1.25rem;
    align-items: center;
    padding: 1.25rem 1.5rem;
}
.cookie-consent-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.18), rgba(181, 148, 42, 0.06));
    color: var(--gold);
    border: 0.0625rem solid rgba(212, 175, 55, 0.28);
    flex-shrink: 0;
}
.cookie-consent-title {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin: 0 0 0.25rem 0;
}
.cookie-consent-text {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: var(--leading-snug);
    margin: 0;
}
.cookie-consent-link {
    color: var(--gold);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    margin-left: 0.25rem;
    border-bottom: 0.0625rem dashed var(--gold);
}
.cookie-consent-link:hover { border-bottom-style: solid; }
.cookie-consent-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-shrink: 0;
}

/* Customize modal - extends UI.Modal content */
.cookie-customize-intro {
    margin: 0 0 1rem 0;
    font-size: var(--text-sm);
    color: var(--text-secondary);
}
.cookie-category {
    padding: 0.875rem 0;
    border-bottom: 0.0625rem solid var(--border-light);
}
.cookie-category:last-child { border-bottom: 0; padding-bottom: 0; }
.cookie-category:first-child { padding-top: 0; }
.cookie-category-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.25rem;
}
.cookie-category-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    color: var(--slate);
    cursor: pointer;
}
.cookie-category-required {
    font-size: 0.625rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: var(--weight-bold);
    color: var(--muted);
    padding: 0.0625rem 0.375rem;
    border-radius: var(--radius-sm);
    background: var(--bg-subtle);
    border: 0.0625rem solid var(--border-light);
}
.cookie-category-desc {
    font-size: 0.75rem;
    color: var(--text-secondary);
    line-height: var(--leading-relaxed);
}

@media (max-width: 48em) {
    .cookie-consent-inner {
        grid-template-columns: 1fr;
        gap: 0.75rem;
        padding: 1rem;
    }
    .cookie-consent-icon { display: none; }
    .cookie-consent-actions {
        flex-wrap: wrap;
        justify-content: stretch;
    }
    .cookie-consent-actions .btn { flex: 1 1 auto; }
}

/* ════════════════════════════════════════════════════════════════════
   NEWSLETTER WIDGET
   ──────────────────────────────────────────────────────────────────── */
.newsletter-widget {
    background: var(--white);
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-md);
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.newsletter-widget-card {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 1rem 1rem;
    align-items: start;
}
.newsletter-widget-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, rgba(212, 175, 55, 0.18), rgba(181, 148, 42, 0.06));
    color: var(--gold);
    border: 0.0625rem solid rgba(212, 175, 55, 0.28);
    flex-shrink: 0;
    grid-row: 1 / 3;
}
.newsletter-widget-text {
    grid-column: 2;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.newsletter-widget-headline {
    font-family: var(--font-display);
    font-size: var(--text-base);
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin: 0;
}
.newsletter-widget-description {
    font-size: 0.75rem;
    color: var(--text-secondary);
    line-height: var(--leading-relaxed);
    margin: 0;
}
.newsletter-widget-form {
    grid-column: 1 / -1;
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}
.newsletter-widget-form-inline {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: nowrap;
}
.newsletter-widget-input {
    flex: 1;
    min-width: 0;
}
.newsletter-widget-status {
    font-size: 0.75rem;
    color: var(--text-secondary);
    flex-basis: 100%;
    min-height: 1rem;
}
.newsletter-widget-status.is-success { color: var(--success, #2f7d3d); }
.newsletter-widget-status.is-error { color: var(--danger, #c93030); }

.newsletter-widget-banner {
    flex-direction: row;
    align-items: center;
    gap: 1.5rem;
    padding: 1.5rem 1.75rem;
    background: linear-gradient(135deg, var(--slate) 0%, #232b3a 100%);
    color: #fff;
    border: 0.0625rem solid rgba(212, 175, 55, 0.18);
}
.newsletter-widget-banner .newsletter-widget-headline { color: #fff; font-size: 1.0625rem; }
.newsletter-widget-banner .newsletter-widget-description { color: rgba(255, 255, 255, 0.7); font-size: 0.875rem; }
.newsletter-widget-banner-text { display: flex; flex-direction: column; gap: 0.25rem; flex: 1; }

@media (max-width: 48em) {
    .newsletter-widget-card { grid-template-columns: 1fr; }
    .newsletter-widget-icon { display: none; }
    .newsletter-widget-text { grid-column: 1; }
    .newsletter-widget-banner { flex-direction: column; align-items: stretch; text-align: left; }
}

/* ── Saved Properties list header ──
   The list NAME is the page anchor - big Playfair heading at the top,
   then a muted subtitle with count + optional description, then the
   action row. Puts the identifier above the controls so users land on
   "which list am I looking at?" before anything else. */
.saved-list-header {
    padding: 0.75rem 1rem 1rem;
    border-bottom: 0.0625rem solid var(--border-light);
    background: var(--surface-card);
}
.saved-list-header-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.35rem;
}
.saved-list-header-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    flex: 1;
}
.saved-list-name {
    font-family: 'Playfair Display', Georgia, serif;
    font-weight: 700;
    font-size: 1.375rem;
    line-height: 1.15;
    color: var(--slate, #1c2331);
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.saved-list-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    flex-shrink: 0;
}
/* Selection pill - appears in the header-right cluster once one or more
   rows are checked in the parcel table. Lives beside the action buttons
   so users see the exact count that Export / Delete will operate on. */
.saved-list-selection-count {
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--gold-dark, var(--gold, #b5942a));
    background: rgba(212, 175, 55, 0.14);
    border: 0.0625rem solid rgba(212, 175, 55, 0.35);
    padding: 0.1875rem 0.5rem;
    border-radius: 62.4375rem;
    letter-spacing: 0.01em;
    white-space: nowrap;
}
.saved-list-selection-count.hidden { display: none; }
.saved-list-subtitle {
    font-size: 0.75rem;
    color: var(--muted, #706b63);
    letter-spacing: 0.02em;
}
.saved-list-subtitle .table-count {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.6875rem;
}

/* ── Sidebar nav badge variants ── */
.sidebar-nav-badge.sidebar-nav-badge-new {
    background: var(--gold);
    color: var(--slate);
    border: 0;
    font-weight: var(--weight-bold);
}
.sidebar-nav-footer-btn {
    background: transparent;
    border: 0;
    text-align: left;
    cursor: pointer;
    color: inherit;
    font: inherit;
    padding: 0;
}
.sidebar-nav-footer-btn:hover { color: var(--gold); }

/* ════════════════════════════════════════════════════════════════════
   SKIP TRACE - modal result rendered inside the property page
   ──────────────────────────────────────────────────────────────────── */
.skip-trace-empty {
    text-align: left;
    padding: 0.5rem 0;
}
.skip-trace-empty-title {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: var(--weight-bold);
    color: var(--slate);
    margin-bottom: 0.5rem;
}
.skip-trace-empty-text {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: var(--leading-relaxed);
    margin: 0 0 0.75rem 0;
}
.skip-trace-empty-hint {
    font-size: 0.75rem;
    color: var(--text-secondary);
    line-height: var(--leading-relaxed);
    padding: 0.625rem 0.75rem;
    background: var(--bg-subtle);
    border-left: 0.1875rem solid var(--gold);
    border-radius: var(--radius-sm);
}
.skip-trace-empty-hint strong { color: var(--slate); }

.skip-trace-result {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}
.skip-trace-meta {
    padding-bottom: 0.75rem;
    border-bottom: 0.0625rem solid var(--border-light);
    font-size: 0.875rem;
    color: var(--slate);
}
.skip-trace-meta-row {
    display: flex;
    gap: 0.625rem;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
    font-weight: var(--weight-semibold);
    margin-top: 0.25rem;
    align-items: center;
    flex-wrap: wrap;
}
.skip-trace-section h4 {
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: var(--weight-bold);
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin: 0 0 0.375rem 0;
}
.skip-trace-section ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}
.skip-trace-section li {
    padding: 0.5rem 0.75rem;
    background: var(--bg-subtle);
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.skip-trace-section li strong { color: var(--slate); }
.skip-trace-tag {
    display: inline-flex;
    align-items: center;
    height: 1rem;
    min-height: 1rem;
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    padding: 0 0.375rem;
    border-radius: var(--radius-sm);
    background: var(--white);
    border: 0.0625rem solid var(--border-light);
    vertical-align: middle;
    white-space: nowrap;
}
.skip-trace-confidence {
    font-size: var(--text-xs);
    color: var(--muted);
    margin-left: auto;
}

/* ═══════════════════════════════════════════════════════════════════════════
   REUSABLE PATTERNS - extracted from inline styles across views
   ═══════════════════════════════════════════════════════════════════════════ */

/* Section label - deals calculator headers, data labels, stat labels.
   Replaces the 5+ inline copies of uppercase micro-label styling. */
.section-label {
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--faint);
}
.section-label-spaced {
    margin: var(--space-4) 0 var(--space-2);
}

/* Code/mono block - legal descriptions, parcel IDs, raw data displays.
   Replaces the inline style on property.js legal-desc and similar. */
.mono-block {
    font-family: var(--font-mono);
    background: var(--bg-subtle);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    line-height: var(--leading-relaxed);
    color: var(--text-secondary);
    word-break: break-word;
    overflow-wrap: break-word;
}

/* Popup action row - the button bar at the bottom of map popups.
   Replaces the 12-property inline style in app.js and explorer.js. */
.popup-actions {
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 0.0625rem solid var(--border-light);
    display: flex;
    align-items: stretch;
    justify-content: center;
    gap: var(--space-2);
}
/* Match the same layout for the slide-in panel's action bar (selected
   inline in explorer.js via #info-panel-actions). Stretches the three
   buttons (View Details / Save / Analyze Deal) to the same height and
   keeps the anchor centered alongside its <button> siblings. */
#info-panel-actions {
    align-items: stretch !important;
    justify-content: center !important;
}
.popup-action-btn {
    flex: 1 1 0;
    /* width:0 + flex-basis:0 forces every sibling to start from zero and
       grow proportionally - without it the <a> (which renders as an
       inline anchor) computes a wider intrinsic width than the
       <button> siblings and ends up looking off-center next to them.
       The explicit min-width:0 also lets long labels truncate via
       flex shrink instead of pushing the row out of alignment. */
    width: 0;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    /* Anchors get vertical-align:baseline by default which can lift them
       a fraction of a pixel above flex buttons in the same row. Pin to
       middle so the <a> sits flush with its <button> siblings. */
    vertical-align: middle;
    box-sizing: border-box;
    min-height: 2rem;
    background: var(--gold);
    color: var(--slate);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-decoration: none;
    cursor: pointer;
    border: 0.0625rem solid transparent;
    appearance: none;
    -webkit-appearance: none;
}
.popup-action-btn:hover { opacity: 0.9; }
@media (pointer: coarse) {
    .popup-action-btn { min-height: 2.75rem; }
}
.popup-action-btn--secondary {
    background: var(--cream);
    border-color: var(--border);
    color: var(--text);
}

/* Modal loading body - centered spinner/text in a modal shell. */
.modal-loading-body {
    min-height: 8rem;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    font-size: var(--text-base);
}

/* ═══════════════════════════════════════════════════════════════════
   SEARCH LOADING SURFACE - single cohesive card with mountain climber
   on top and vertical skeleton row stack below. Replaces the previous
   stacked "MountainLoader + SkeletonTable" pair which read as two
   disconnected cards on phones (and the SkeletonTable's 44rem min-width
   pushed the in-cell shimmer off-screen so the rows looked empty).
   ═══════════════════════════════════════════════════════════════════ */
.search-loading-card {
    background: var(--surface-card);
    border: 0.0625rem solid var(--border-light);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    overflow: hidden;
    animation: fadeInUp var(--anim-normal) var(--easing) both;
}
/* The MountainLoader brings its own card chrome - strip it so it sits
   flush inside the outer .search-loading-card container. */
.search-loading-card .search-loading-mountain {
    background: transparent !important;
    border: 0 !important;
    border-bottom: 0.0625rem solid var(--border-light) !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    margin-bottom: 0 !important;
}
.search-loading-rows {
    display: flex;
    flex-direction: column;
}
.search-loading-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-bottom: 0.0625rem solid var(--border-light);
}
.search-loading-row:last-child { border-bottom: none; }
.search-loading-row-text {
    flex: 1;
    min-width: 0;
}
.search-loading-row-text .skeleton-line { margin-bottom: var(--space-2); }
.search-loading-row-text .skeleton-line:last-child { margin-bottom: 0; }
@media (max-width: 40em) {
    .search-loading-row { padding: var(--space-3) var(--space-4); gap: var(--space-2); }
}

/* Skeleton table embedded inside the unified loading card. The wrapping
   .data-table-wrap brings its own border/radius/shadow - strip those so
   the table sits flush inside the outer .search-loading-card. */
.search-loading-card .search-loading-table-wrap {
    border: 0 !important;
    border-radius: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
}
/* Responsive column drops - match the loaded DataTable's hideBelow
   behavior so the skeleton has the same column count at the same
   viewport as the loaded data. */
@media (max-width: 48em) {
    .search-loading-card .dt-hide-sm { display: none !important; }
}
@media (max-width: 64em) {
    .search-loading-card .dt-hide-md { display: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   ONBOARDING CARD - first-visit "where do you prospect?" pattern.
   Used on dashboard for new users; the structure can also wrap any
   centered-card empty/setup prompt elsewhere. Token-driven instead of
   inline styles so spacing stays consistent with the rest of the app.
   ═══════════════════════════════════════════════════════════════════ */
.onboard-card-body {
    text-align: center;
    padding: var(--space-10) var(--space-6);
}
.onboard-title {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: var(--weight-bold);
    color: var(--text);
    margin-bottom: var(--space-2);
    line-height: var(--leading-tight);
    letter-spacing: -0.01em;
}
.onboard-text {
    color: var(--text-secondary);
    margin: 0 auto var(--space-5);
    max-width: 28rem;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}
.onboard-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: center;
    max-width: 36rem;
    margin: 0 auto;
}
.onboard-fallback {
    margin-top: var(--space-4);
}
.onboard-fallback .form-input {
    width: auto;
    min-width: 14rem;
    margin: 0 auto;
}

/* Stat meta row - inline metadata under a property or deal card. */
.meta-row {
    display: flex;
    gap: var(--space-3) var(--space-6);
    flex-wrap: wrap;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    min-height: 1.25rem;
    align-items: center;
}

/* Info panel stat grid - used by the explorer slide-in panel and popups
   for the 2×2 owner/acreage/zoning/value layout. Replaced inline
   grid-template-columns so label alignment stays consistent.

   The grid auto-fits to the parent column; cells use minmax(0, 1fr) so
   long owner strings (e.g. "DUNCAN CARL TRUSTEE; CARL A DUNCAN TRUST;
   NANCY DUNCAN…") never force the parent into horizontal scroll. The
   value text wraps onto multiple lines instead. */
.info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
    /* Defensive: this lives inside slide-in panels and popups whose width
       can be narrow. Force the grid items to never demand more width
       than the container provides. */
    min-width: 0;
}
.info-grid > * { min-width: 0; }

.info-grid-cell-label {
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    color: var(--faint);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 0.125rem;
}
.info-grid-cell-value {
    font-size: var(--text-sm);
    color: var(--text);
    font-weight: var(--weight-medium);
    /* Wrap long values so they never punch out of the grid. Tabular
       monetary cells stay short (no whitespace inside formatted dollars)
       and won't wrap; only naturally-wrappable strings (owner names,
       legal descriptions, addresses with semicolons) actually break. */
    overflow-wrap: anywhere;
    word-break: break-word;
    white-space: normal;
    line-height: 1.35;
}
.info-grid-cell-value.is-mono {
    font-family: var(--font-mono);
    /* Numerical values stay on one line; if they ever overflow, ellipsis
       beats horizontal scroll. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.info-grid-cell-sub {
    font-size: var(--text-xs);
    color: var(--muted);
    margin-top: 0.125rem;
    line-height: var(--leading-snug);
    word-break: break-word;
}

/* Narrow viewports - fall to a single column so labels stay readable
   and values always have full width to wrap into. */
@media (max-width: 30em) {
    .info-grid { grid-template-columns: 1fr; gap: var(--space-2) 0; }
}

/* ── Insights / Lead Lists / Help responsive tweaks ── */
@media (max-width: 64em) {
    .insight-featured-title { font-size: 1.5rem; }
    .insight-detail-title { font-size: 1.875rem; }
}
@media (max-width: 48em) {
    .insight-featured { padding: 1.25rem 1.25rem; }
    .insight-featured-title { font-size: 1.25rem; }
    .insight-featured-foot { flex-direction: column; align-items: flex-start; gap: 0.625rem; }
    .insight-detail-title { font-size: 1.5rem; }
    .insight-detail-body > p:first-of-type::first-letter { font-size: 2.5rem; }
    .article-share-btn { display: none; }
    .help-section-nav { padding: 0.5rem 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   BILLING - per-county bundles + paywall
   ═══════════════════════════════════════════════════════════════════════════ */
.billing-pane { display: flex; flex-direction: column; gap: var(--space-6); max-width: 56rem; }
.billing-status-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap; }
.billing-status-label { font-size: var(--text-2xs); font-weight: var(--weight-bold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); margin-bottom: 0.375rem; }
.billing-status-plan { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.billing-status-badge { font-size: 0.875rem; padding: 0.25rem 0.625rem; }
.billing-status-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: var(--space-5); margin-top: var(--space-5); padding-top: var(--space-5); border-top: 0.0625rem solid var(--border-light); }

.billing-bundle-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: var(--space-3); }
.billing-bundle-card { display: flex; flex-direction: column; gap: 0.25rem; padding: 1rem 1.125rem; border: 0.0625rem solid var(--border); border-radius: var(--radius-md); cursor: pointer; background: var(--warm-white); transition: border-color var(--transition), box-shadow var(--transition), background var(--transition); position: relative; }
.billing-bundle-card:hover { border-color: var(--gold); }
.billing-bundle-card.is-selected { border-color: var(--gold); background: var(--gold-muted); box-shadow: 0 0 0 0.1875rem var(--gold-muted); }
.billing-bundle-card input[type=radio] { position: absolute; opacity: 0; pointer-events: none; }
.billing-bundle-price { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: 1.5rem; color: var(--slate); line-height: 1; }
.billing-bundle-price span { font-family: var(--font-body); font-size: 0.75rem; font-weight: var(--weight-semibold); color: var(--muted); margin-left: 0.25rem; letter-spacing: 0.02em; }
.billing-bundle-name { font-weight: var(--weight-bold); color: var(--text); }
.billing-bundle-meta { font-size: var(--text-xs); color: var(--gold-dark); font-weight: var(--weight-semibold); }
.billing-bundle-desc { font-size: var(--text-xs); color: var(--muted); line-height: 1.4; margin-top: 0.25rem; }

.billing-county-picker { margin-top: var(--space-5); padding-top: var(--space-5); border-top: 0.0625rem solid var(--border-light); }
.billing-county-picker-head { display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-3); }
.billing-county-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); gap: 0.375rem 0.75rem; max-height: 16rem; overflow-y: auto; padding: 0.25rem 0.125rem; scrollbar-width: thin; }
.billing-county-option { display: inline-flex; align-items: center; gap: 0.5rem; font-size: var(--text-xs); color: var(--text); padding: 0.25rem 0; cursor: pointer; }
.billing-county-option input[type=checkbox] { accent-color: var(--gold); flex-shrink: 0; }
.billing-county-option input[type=checkbox]:disabled + span { color: var(--faint); text-decoration: line-through; }

.billing-checkout-row { margin-top: var(--space-5); padding-top: var(--space-5); border-top: 0.0625rem solid var(--border-light); display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.billing-checkout-summary { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--text); }

/* County paywall modal - compact 3-card bundle selector. */
.county-paywall-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; margin-top: 0.5rem; }
.county-paywall-card { display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem; border: 0.0625rem solid var(--border); border-radius: var(--radius-md); background: var(--warm-white); cursor: pointer; text-align: left; font-family: inherit; transition: border-color var(--transition), background var(--transition); }
.county-paywall-card:hover { border-color: var(--gold); background: var(--gold-muted); }
.county-paywall-price { font-family: var(--font-display); font-weight: var(--weight-bold); font-size: 1.125rem; color: var(--slate); line-height: 1; }
.county-paywall-price span { font-family: var(--font-body); font-size: 0.625rem; font-weight: var(--weight-semibold); color: var(--muted); margin-left: 0.1875rem; }
.county-paywall-name { font-size: var(--text-xs); font-weight: var(--weight-bold); color: var(--text); }
.county-paywall-meta { font-size: var(--text-2xs); color: var(--gold-dark); font-weight: var(--weight-semibold); }
@media (max-width: 30em) { .county-paywall-grid { grid-template-columns: 1fr; } }

/* ── Billing pane - v2 ───────────────────────────────────────── */
.billing-status-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    flex-shrink: 0;
}
.billing-date-line {
    margin: 0.75rem 0 0;
    font-size: 0.9375rem;
    line-height: 1.5;
    color: var(--text);
}
.billing-date-line strong { color: var(--slate); }

.billing-pending-banner {
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    margin-top: 0.75rem;
    padding: 0.625rem 0.75rem;
    background: #fffbe6;
    border: 0.0625rem solid #f0dfa0;
    border-radius: 0.375rem;
    font-size: 0.8125rem;
    line-height: 1.4;
    color: #6b5a10;
}
.billing-pending-banner svg { flex-shrink: 0; color: #7a6315; margin-top: 0.125rem; }
.billing-pending-banner strong { color: var(--slate); }
.billing-pending-banner button { flex-shrink: 0; align-self: center; }

.billing-county-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.25rem;
}

.billing-how-it-works { padding-top: 1rem; padding-bottom: 1rem; }
.billing-how-list {
    margin: 0.5rem 0 0;
    padding-left: 1.125rem;
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--muted);
}
.billing-how-list li { margin-bottom: 0.375rem; }
.billing-how-list li:last-child { margin-bottom: 0; }
.billing-how-list strong { color: var(--text); }
.billing-how-list em { font-style: italic; color: var(--gold-dark); }

/* ── Change-plan modal ──────────────────────────────────────────
   Mirrors the signup pricing panel (auth.css) so returning users
   see the same modern plan-picker they chose from at signup. The
   classes below (.plan-options-grid, .plan-option, .county-picker,
   .county-chip, .county-search) are duplicated from auth.css, which
   is not loaded inside the app shell. */
.billing-change-modal { display: flex; flex-direction: column; gap: 1rem; }
.billing-change-head {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.billing-change-headline {
    font-family: 'Playfair Display', Georgia, serif;
    font-weight: 700;
    font-size: 1.125rem;
    line-height: 1.2;
    color: var(--slate, #1c2331);
    margin: 0;
}
.billing-change-sub {
    font-size: 0.8125rem;
    color: var(--muted, #706b63);
    line-height: 1.4;
}
.billing-change-effect {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.625rem 0.75rem;
    background: #f4f9f2;
    border: 0.0625rem solid #c9e0b6;
    border-radius: 0.375rem;
    color: #3a5f1e;
    font-size: 0.8125rem;
    line-height: 1.4;
}
.billing-change-effect svg { flex-shrink: 0; color: #5a8a2a; margin-top: 0.125rem; }
.billing-change-effect strong { font-weight: 700; white-space: nowrap; }

.plan-options-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.625rem;
}
@media (max-width: 40em) { .plan-options-grid { grid-template-columns: 1fr; } }

.plan-option {
    position: relative;
    display: block;
    padding: 0.875rem 0.875rem 0.875rem 2.25rem;
    background: #fff;
    border: 0.0625rem solid rgba(28, 35, 49, 0.12);
    border-radius: 0.5rem;
    cursor: pointer;
    transition: border-color 160ms ease, box-shadow 160ms ease, background 160ms ease;
    outline: none;
}
.plan-option:hover { border-color: var(--gold, #b5942a); background: #fffef7; }
.plan-option:focus-visible { box-shadow: 0 0 0 0.1875rem rgba(181, 148, 42, 0.35); }
.plan-option input[type="radio"] {
    position: absolute;
    top: 0.875rem;
    left: 0.75rem;
    margin: 0;
    accent-color: var(--gold, #b5942a);
    width: 1rem;
    height: 1rem;
    cursor: pointer;
}
.plan-option:has(input:checked) {
    border-color: var(--gold, #b5942a);
    background: #fffdf2;
    box-shadow: 0 0 0 0.0625rem var(--gold, #b5942a);
}
.plan-option:has(input:disabled) { opacity: 0.55; cursor: not-allowed; }
.plan-option-name {
    font-weight: 700;
    font-size: 0.8125rem;
    color: var(--slate, #1c2331);
    letter-spacing: 0.01em;
}
.plan-option-price {
    font-family: 'Playfair Display', Georgia, serif;
    font-weight: 700;
    font-size: 1.25rem;
    color: var(--slate, #1c2331);
    margin-top: 0.125rem;
}
.plan-option-price span {
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 500;
    color: #6b6760;
    margin-left: 0.125rem;
}
.plan-option-note {
    font-size: 0.6875rem;
    color: #6b6760;
    margin-top: 0.25rem;
    line-height: 1.4;
}

/* Brokerage-partner discount block - shown when the change-plan modal
   is opened by a user whose email is on the partner allowlist. Mirrors
   the signup payment-panel styling (auth.css) so a user who saw the
   discount on day one sees the identical visual when they upgrade. */
.plan-option-price.plan-option-price-discounted {
    display: flex;
    align-items: baseline;
    gap: 0.375rem;
    flex-wrap: wrap;
    margin-top: 0.125rem;
}
.plan-option-price-original {
    font-family: var(--font-body);
    font-size: 0.8125rem;
    font-weight: 500;
    color: #a39d92;
    text-decoration: line-through;
    text-decoration-thickness: 0.0625rem;
}
.plan-option-price-final {
    font-family: 'Playfair Display', Georgia, serif;
    font-weight: 700;
    font-size: 1.25rem;
    color: var(--gold, #b5942a);
}
.plan-option-discount-badge {
    display: inline-block;
    margin-top: 0.25rem;
    padding: 0.125rem 0.5rem;
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--gold, #b5942a);
    background: rgba(212, 175, 55, 0.12);
    border: 0.0625rem solid rgba(212, 175, 55, 0.4);
    border-radius: 0.25rem;
    letter-spacing: 0.02em;
}

.county-picker {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
    background: #fafaf7;
    border: 0.0625rem solid rgba(28, 35, 49, 0.1);
    border-radius: 0.5rem;
}
.county-picker-head { display: flex; justify-content: space-between; align-items: baseline; }
.county-picker-label { font-size: 0.8125rem; font-weight: 600; color: var(--slate, #1c2331); }
.county-picker-status { font-size: 0.6875rem; font-weight: 600; color: #6b6660; letter-spacing: 0.02em; }
.county-picker-status.is-complete { color: #3a5f1e; }
.county-search {
    width: 100%;
    padding: 0.5rem 0.625rem;
    font-size: 0.8125rem;
    border: 0.0625rem solid rgba(28, 35, 49, 0.12);
    border-radius: 0.375rem;
    background: #fff;
    color: var(--slate, #1c2331);
    font-family: var(--font-body);
    margin-bottom: 0.375rem;
}
.county-search:focus {
    outline: none;
    border-color: var(--gold, #b5942a);
    box-shadow: 0 0 0 0.1875rem rgba(181, 148, 42, 0.18);
}
.county-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
    gap: 0.375rem;
    max-height: 14rem;
    overflow-y: auto;
    padding: 0.25rem;
    margin: -0.25rem;
    scrollbar-width: thin;
}
.county-chip {
    appearance: none;
    border: 0.0625rem solid rgba(28, 35, 49, 0.12);
    background: #fff;
    color: var(--slate, #1c2331);
    padding: 0.375rem 0.5rem;
    border-radius: 0.3125rem;
    font-size: 0.75rem;
    font-weight: 600;
    font-family: var(--font-body);
    cursor: pointer;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}
.county-chip:hover { border-color: var(--gold, #b5942a); background: #fffef7; }
.county-chip:focus-visible { outline: none; box-shadow: 0 0 0 0.125rem rgba(181, 148, 42, 0.35); }
.county-chip.selected { background: var(--gold, #b5942a); border-color: var(--gold, #b5942a); color: var(--slate, #1c2331); }

.billing-cancel-modal p { margin: 0 0 0.625rem; line-height: 1.5; }
.billing-cancel-modal p:last-child { margin-bottom: 0; }

/* ── Save-to-Lists Modal (UI.SaveToListsModal) ── */
.save-to-lists-wrap { display: flex; flex-direction: column; gap: 0.25rem; }
.save-to-lists-sub { font-size: 0.875rem; color: var(--muted); line-height: 1.5; margin-bottom: 0.75rem; }
.save-to-lists-sub strong { color: var(--text); }
.save-to-lists-empty {
    padding: 0.625rem 0.75rem;
    background: var(--gold-muted);
    border: 0.0625rem solid var(--gold-border);
    border-radius: var(--radius-md);
    font-size: 0.8125rem;
    color: var(--gold-dark);
    margin-bottom: 0.5rem;
}
.save-to-lists-grid {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    max-height: 18rem;
    overflow-y: auto;
    padding-right: 0.25rem;
}
.save-to-lists-row {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.625rem 0.75rem;
    border: 0.0625rem solid var(--border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color var(--anim-fast), background var(--anim-fast);
    background: #ffffff;
}
.save-to-lists-row:hover { border-color: var(--gold); background: var(--cream); }
.save-to-lists-row input[type="checkbox"] { width: 1rem; height: 1rem; accent-color: var(--gold); flex-shrink: 0; margin: 0; }
.save-to-lists-row input[type="checkbox"]:checked + .save-to-lists-dot + .save-to-lists-name { font-weight: var(--weight-semibold); }
.save-to-lists-row:has(input:checked) { border-color: var(--gold); background: var(--gold-muted); }
.save-to-lists-dot {
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--gold);
    border: 0.0625rem solid rgba(0,0,0,0.06);
}
.save-to-lists-name { flex: 1; font-size: 0.875rem; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.save-to-lists-count {
    min-width: 1.75rem;
    padding: 0 0.375rem;
    height: 1.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background: var(--bg-subtle);
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    font-weight: var(--weight-semibold);
    flex-shrink: 0;
}
.save-to-lists-new { margin-top: 0.5rem; }

.act-fanout-note {
    padding: 0.625rem 0.75rem;
    background: var(--gold-muted);
    border: 0.0625rem solid var(--gold-border);
    border-radius: var(--radius-md);
    font-size: 0.8125rem;
    color: var(--gold-dark);
    line-height: 1.5;
}
.act-fanout-note strong { color: var(--text); }

