/* properties.php — only what's unique to this page. Shared tokens, topbar,
   .hint, .btn, .badge, .form-status all live in ../app.css now. */

body { display: flex; flex-direction: column; height: 100vh; }
.page { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; padding: 0; overflow: hidden; }

.topbar-status { color: rgba(255,255,255,0.75); font-size: 12.5px; display: flex; align-items: center; }
.language-picker { font-size: 12.5px; color: rgba(255,255,255,0.75); margin-right: 14px; }
.language-picker select { font-size: 12px; margin-left: 4px; padding: 1px 2px; }
.manage-searches-link { display: block; margin: 6px 0 0; }

/* Data health strip (Part 5, 2026-09-06) — read-only, makes the SSH-only
   maintenance jobs' state visible without running anything. Figures in
   mono; a linked count gets a dotted underline instead of a solid one, to
   read as "click for more" rather than a plain hyperlink. */
.data-health {
  flex: 0 0 auto;
  padding: 7px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--line-soft);
  font-size: 12.5px;
  color: var(--ink-3);
}
.data-health .stat { color: var(--ink); font-weight: 600; font-family: PlexM, monospace; }
.data-health .stat.watch { color: var(--watch); }
.data-health .sep { margin: 0 10px; color: var(--line); }
.data-health a { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--ink-3); }
.data-health a:hover { color: var(--ink); border-bottom-style: solid; }
.data-health[hidden] { display: none; }

/* Results / Searches — a page-level tab strip, distinct from the mode-bar
   below it (which only ever applies to the Results view, and never
   changes data, unlike Searches which can delete it). */
.view-tabs {
  flex: 0 0 auto;
  display: flex;
  gap: 4px;
  padding: 8px 16px 0;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.view-tab {
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 7px 14px;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--ink-3);
  cursor: pointer;
}
.view-tab:hover { color: var(--ink); }
.view-tab.active { color: var(--ink); font-weight: 600; border-bottom-color: var(--ink); }

/* Part 4 (2026-09-06): search management folded into this page as the
   Searches tab — was only reachable from a small link buried in the
   filter rail before. Same api/searches.php endpoint, no separate page. */
.searches-view {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 0 16px 40px;
  max-width: 900px;
  margin: 0 auto;
  width: 100%;
}
.searches-view .intro { max-width: 100%; margin: 16px 0; line-height: 1.6; }
.searches-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 8px;
  font-size: 13px;
}
.searches-table th {
  text-align: left;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-3);
  padding: 8px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.searches-table td { padding: 8px; border-bottom: 1px solid var(--line-soft); vertical-align: top; font-size: 13px; }
.searches-table td.col-num, .searches-table th.col-num { text-align: right; font-family: PlexM, monospace; }
.search-name { font-weight: 500; }
.search-meta { color: var(--ink-3); font-size: 11px; margin-top: 2px; }

.delete-btn {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
  border: 1px solid var(--bad);
  border-radius: var(--r);
  background: #fff;
  color: var(--bad);
  cursor: pointer;
  margin-right: 6px;
}
.delete-btn:hover { background: var(--bad-bg); }
.delete-btn:disabled { opacity: 0.5; cursor: default; }

.view-btn {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: #fff;
  color: var(--ink);
  cursor: pointer;
}
.view-btn:hover { background: var(--paper); }

.row-status { font-size: 11px; color: var(--ink-3); margin-top: 4px; }
.row-status.success { color: var(--good); }
.row-status.error { color: var(--bad); }

/* Mode selector — "changes the view, never the data", so it's styled
   distinctly from both the blue search form and the amber free filter
   rail: neutral dark, since it's neither spending money nor re-slicing —
   it's just a lens over the same rows. */
/* Phase 5 Part 1 — one toolbar, inside the results panel (was: a mode-bar
   of four buttons floating above the filter rail, disconnected from the
   list it controlled, plus click-only column-header sorting). Sticky
   within .table-wrap's own scroll so it stays reachable on long lists. */
.results-toolbar {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 10px 16px;
}
.toolbar-row1 { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.toolbar-row2 { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.toolbar-field { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-3); font-weight: 500; }
.toolbar-field select {
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: #fff;
}
.toolbar-count { font-family: PlexM, monospace; font-size: 12.5px; color: var(--ink-3); }
.risk-direction-toggle { display: flex; gap: 10px; }
.risk-direction-toggle .cb-inline { font-size: 11px; color: var(--ink-3); }
/* Same [hidden]-vs-author-display bug as .layout/.mode-bar hit in Phase 4
   Part 4 — needs its own explicit override again here. */
.risk-direction-toggle[hidden] { display: none; }

/* 2026-09-14 — the filter-toggle button's mobile dropdown (Filter
   results / Search properties). Desktop only ever sees the plain
   "☰ Filters" label and never opens this menu (properties.js's click
   handler branches on window.innerWidth, not this CSS) — the label swap
   below just keeps the button's own text honest at each width. */
.mobile-menu-wrap { position: relative; }
.filter-toggle-label-mobile { display: none; }
.mobile-toolbar-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 10;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 4px;
  box-shadow: 0 4px 16px rgba(20, 32, 43, 0.16);
  min-width: 180px;
}
.mobile-toolbar-menu[hidden] { display: none; }
.mobile-toolbar-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  font-size: 13.5px;
  color: var(--ink);
  background: none;
  border: none;
  padding: 10px 10px;
  border-radius: var(--r);
  cursor: pointer;
  text-decoration: none;
}
.mobile-toolbar-menu-item:hover { background: var(--paper); }

.column-picker-wrap { position: relative; margin-left: auto; }
.column-picker-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 10;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 8px 10px;
  box-shadow: 0 4px 16px rgba(20, 32, 43, 0.16);
  min-width: 200px;
  max-height: 320px;
  overflow-y: auto;
}
.column-picker-menu label { display: flex; align-items: center; gap: 6px; font-size: 12px; padding: 4px 0; white-space: nowrap; }

/* The AI ranking button is the one filled/primary control in the toolbar —
   everything else here is a quiet outline or a plain select. */
#comparativeBtn {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 7px 16px;
  border: none;
  border-radius: var(--r);
  background: var(--ai);
  color: #fff;
  cursor: pointer;
}
#comparativeBtn:hover { filter: brightness(1.1); }
#comparativeBtn:disabled { opacity: 0.5; cursor: not-allowed; filter: none; }

.comparative-result {
  background: var(--ai-bg);
  border-bottom: 1px solid var(--line);
  padding: 12px 16px;
  font-size: 12.5px;
}
.comparative-result-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.comparative-result h3 { margin: 0; font-size: 13px; font-weight: 600; color: var(--ink); }
.comparative-result-meta { color: var(--ink-3); font-size: 11px; }
#clearComparative {
  font: inherit;
  font-size: 11px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: #fff;
  color: var(--ai);
  cursor: pointer;
}
.pick-list { margin: 0 0 10px; }
.pick {
  display: flex;
  gap: 10px;
  padding: 7px 4px;
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
}
.pick:last-child { border-bottom: none; }
.pick:hover { background: rgba(255,255,255,0.5); }
.pick-rank { font-family: PlexM, monospace; font-weight: 600; color: var(--ai); flex: 0 0 16px; }
.pick-body { flex: 1 1 auto; min-width: 0; }
.pick-title-row { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.pick-title-row a { color: var(--ink); font-weight: 600; text-decoration: underline; text-decoration-color: var(--line); }
.pick-title-row a:hover { text-decoration-color: var(--ink); }
.pick-price { font-family: PlexM, monospace; font-weight: 600; white-space: nowrap; }
.pick-reason { color: var(--ink-2); font-size: 12.5px; margin-top: 2px; max-width: 64ch; }
.pick-jump {
  flex: 0 0 auto;
  align-self: center;
  font-size: 16px;
  color: var(--ai);
  text-decoration: none;
  padding: 0 4px;
}
.comparative-result-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
#showOnlyPicksBtn {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
  border: 1px solid var(--ai);
  border-radius: var(--r);
  background: #fff;
  color: var(--ai);
  cursor: pointer;
}
#showOnlyPicksBtn:hover { background: #fff; filter: brightness(0.97); }

/* The one orchestrated, non-user-triggered moment in the product (Phase 6
   Part 5): when an AI pick's ↗ arrow scrolls its row into view, it fades
   from the AI tint back to transparent over 2s — a highlight, not a flash. */
tbody tr.jump-highlight { animation: jump-flash 2s ease-out; }
@keyframes jump-flash {
  0% { background: var(--ai-bg); }
  100% { background: transparent; }
}

/* Removable "Show only these N" filter chip, above the table. */
.filter-chip-row { padding: 8px 16px 0; }
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 500;
  padding: 3px 4px 3px 10px;
  border-radius: 12px;
  background: var(--ai-bg);
  color: var(--ai);
}
.filter-chip button {
  border: none;
  background: none;
  color: var(--ai);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 50%;
}
.filter-chip button:hover { background: rgba(74, 90, 138, 0.15); }

.layout {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}
/* [hidden]'s UA-stylesheet display:none loses to this class's own
   explicit display:flex at equal specificity (author beats UA) — needs
   its own explicit override now that Part 4 toggles this via [hidden]. */
.layout[hidden] { display: none; }

.table-wrap {
  flex: 1 1 auto;
  overflow: auto;
  background: var(--surface);
}

.filter-rail {
  flex: 0 0 240px;
  background: var(--surface);
  border-right: 1px solid var(--line);
  overflow-y: auto;
  padding: 16px;
}

.filter-rail h2 { font-size: 15px; font-weight: 600; margin: 0 0 4px; }
.filter-rail .hint { font-size: 11.5px; color: var(--ink-3); margin: 4px 0 14px; }

.filter-group { margin-bottom: 18px; }
.filter-group h3 {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-3);
  margin: 0 0 6px;
}

.filter-checkboxes { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.filter-checkboxes label { display: flex; align-items: center; gap: 5px; }
.cb-inline { display: flex; align-items: flex-start; gap: 5px; font-size: 12px; line-height: 1.4; }

/* Mode 1 (Bargain) — a positive/opportunity signal, so it borrows --good. */
.motivated-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 2px;
  background: var(--good-bg);
  color: var(--good);
  margin-left: 4px;
}

/* Mode 2 (Renovation) — a cost/caution signal, so it borrows --watch. */
.walkup-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 2px;
  background: var(--watch-bg);
  color: var(--watch);
  margin-left: 4px;
}

/* Column visibility per mode — see pages/properties.js applyModeColumns(). */
.col-mode-hidden { display: none; }

.filter-row { display: flex; gap: 6px; }
.filter-row input {
  width: 0;
  flex: 1 1 auto;
  font: inherit;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: var(--r);
}

.filter-group select {
  width: 100%;
  font: inherit;
  font-size: 12px;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: #fff;
}

#clearFilters {
  font: inherit;
  font-size: 12px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r);
  background: #fff;
  cursor: pointer;
}
#clearFilters:hover { background: var(--bg-alt); }

table {
  border-collapse: collapse;
  width: 100%;
  white-space: nowrap;
  font-size: 13px;
}

thead th {
  position: sticky;
  top: 0;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  text-align: left;
  padding: 8px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-3);
  z-index: 1;
}

th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { background: var(--line-soft); }
th.sortable.sort-asc::after { content: " \25B2"; font-size: 9px; }
th.sortable.sort-desc::after { content: " \25BC"; font-size: 9px; }

th.col-num, td.col-num { text-align: right; font-family: PlexM, monospace; font-variant-numeric: tabular-nums; }
/* 2026-09-14 — widened from 52px to fit the bigger .thumb below (Idealista-
   style restyle: a real glance at the property, not a 40x30px hint). */
th.col-thumb, td.col-thumb { width: 100px; }
/* 2026-09-14 — widened from 48px (a bare icon's width) to fit a real,
   labeled "📊 Analyze" button. */
th.col-links, td.col-links { width: 110px; white-space: nowrap; text-align: right; }
.row-analyze-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-2);
  text-decoration: none;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  white-space: nowrap;
}
.row-analyze-link:hover { color: var(--ink); background: var(--paper); border-color: var(--ink-3); }

/* Phase 6 "one bold move" — the headline column (per view: Under median €
   in Bargain, Reno headroom € in Renovation, Severity in Risk, Score in
   All) is the only place a proportional tinted bar appears, so 300 rows
   read at a glance without reading a single number. Every other column
   stays plain. */
th.headline { background: #F7F9FA; color: var(--ink); font-weight: 600; }
td.headline {
  position: relative;
  text-align: right;
  font-family: PlexM, monospace;
  font-weight: 600;
  font-size: 13px;
  background: #FCFDFD;
}
.headline-bar { position: absolute; left: 0; top: 6px; bottom: 6px; z-index: 0; border-left: 2px solid transparent; }
.headline-value { position: relative; z-index: 1; }
td.headline.headline-good { color: var(--good); }
td.headline.headline-good .headline-bar { background: var(--good-bg); border-left-color: var(--good); }
td.headline.headline-bad { color: var(--bad); }
td.headline.headline-bad .headline-bar { background: var(--bad-bg); border-left-color: var(--bad); }
td.headline.headline-watch { color: var(--watch); }
td.headline.headline-watch .headline-bar { background: var(--watch-bg); border-left-color: var(--watch); }
td.headline.headline-neg { color: var(--neg); }
td.headline.headline-neg .headline-bar { background: var(--neg-bg); border-left-color: var(--neg); }
/* Long AI-summary titles were stretching this column to ~2900px under the
   table's global nowrap — capped to ~30% of that (2026-09-02), confirmed
   live before shipping. A width/max-width on the <th>/<td> itself doesn't
   work in auto table layout: wrappable content has no hard minimum, so the
   layout algorithm just shrinks it to nothing to satisfy the OTHER
   (nowrap, non-negotiable) columns — measured this collapsing to ~124px in
   testing. A definite `width` (not max-width) on a plain block div inside
   the cell does work — a definite size counts as the column's real min-
   content width, so the table grows past its container via the existing
   horizontal scroll (.table-wrap) exactly like the nowrap columns already
   do, instead of the flexible column absorbing all the squeeze. Wraps to
   multiple lines rather than truncating, so nothing in the summary is
   hidden. Cut from 870px to 420px 2026-09-06 (was far wider than needed). */
.title-wrap { display: block; width: 420px; white-space: normal; word-wrap: break-word; }
/* 2026-09-14 — Idealista-style facts line (beds · baths · m² · floor)
   under the title, present in every view regardless of which numeric
   columns are toggled on — see the `title` column's cell() in properties.js. */
.title-facts { font-size: 12px; color: var(--ink-3); margin-top: 3px; white-space: normal; }

/* No zebra striping — hairlines only (Phase 6). Row height 42px via
   vertical padding on td, not a fixed height, so wrapped titles still grow. */
tbody tr {
  border-bottom: 1px solid var(--line-soft);
  cursor: pointer;
}

tbody tr:hover { background: #FAFCFD; }

td { padding: 10px 8px; }

/* 2026-09-14 — sized up from 40x30 to a real Idealista-list-sized thumbnail
   (Rickard's request: "more like how idealista presents the properties to
   get a better overview"). Row height grows to match (via td padding, not
   a fixed row height) rather than cropping the photo down to fit the old
   row. */
.thumb {
  width: 84px;
  height: 64px;
  object-fit: cover;
  border-radius: 6px;
  display: block;
  background: var(--line-soft);
  border: 1px solid var(--line);
}
.thumb.thumb-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: var(--ink-3);
  opacity: 0.5;
}

.muted { color: var(--ink-3); }

/* 2026-09-14 — bolder/larger, Idealista-style price treatment inside the
   existing sortable Price column (cell only, no column/structure change). */
.price-cell { font-weight: 700; font-size: 14.5px; color: var(--ink); }

.score-badge {
  display: inline-block;
  font-family: PlexM, monospace;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 2px;
  background: var(--line-soft);
  color: var(--ink-2);
}
.score-badge.good { background: var(--good-bg); color: var(--good); }

.status-pill {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 2px;
  font-size: 11px;
  background: var(--line-soft);
  color: var(--ink-2);
}

.loading, .empty {
  text-align: center;
  color: var(--ink-3);
  padding: 24px;
}

/* phase2 Part 7: cross-portal duplicate resolution — informational, not a
   risk/opportunity signal, so it stays neutral rather than borrowing one
   of the four signal colours. */
.dup-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  padding: 0 5px;
  border-radius: 2px;
  background: var(--line-soft);
  color: var(--ink-2);
}
/* =========================================================================
 * Mobile, 2026-09-14 (Rickard's request) — the filter rail becomes a
 * collapsible drawer, the detail panel becomes a full-screen overlay, and
 * the results table reflows into a stack of Idealista-style cards (photo,
 * title+facts, price, flags up front; everything else — €/m², vs median,
 * status, source, days, yield, etc. — as a small wrapped meta line). No
 * data or functionality is dropped: sort still works via the toolbar's own
 * Sort dropdown (the sortable column headers just aren't needed to reach
 * it, so the <thead> is hidden rather than squeezed).
 * ========================================================================= */
/* Filter rail show/hide — 2026-09-14, works at every viewport width via
   the real `hidden` attribute (properties.js's setFilterRailOpen()), not a
   CSS class whose meaning flips per breakpoint. Given this project's own
   repeated history of a `[hidden]`-vs-author-`display` bug (CLAUDE.md has
   hit this at least four times across earlier phases), this rule is
   explicit rather than assumed — .filter-rail itself declares no own
   `display` today, so the UA stylesheet's default would likely already
   win, but a future edit adding one could silently break this again. */
.filter-rail[hidden] { display: none; }

@media (max-width: 860px) {
  .layout { flex-direction: column; }

  /* The button behind the hamburger menu — icon-only here (JS opens the
     Filter/Search menu on click instead of directly toggling the rail),
     leaving more room for View/Sort/the result count than the desktop
     "☰ Filters" text label needs. */
  .filter-toggle-label-desktop { display: none; }
  .filter-toggle-label-mobile { display: inline; }

  /* The data-health strip (real numbers, but read-only SSH-maintenance
     status — awaiting-enrichment counts, last search, etc.) was the
     second-biggest fixed space cost on a phone screen after the filter
     drawer, at a real measured 90px out of an 812px viewport, for
     information nobody browsing listings on a phone needs at a glance.
     Same info still shows on desktop; not lost, just not competing with
     the property list for room here. */
  .data-health { display: none; }

  /* Filter rail: a full-width drawer instead of a fixed 240px sidebar
     when shown — visibility itself is handled by [hidden] above at every
     width; this is just the mobile-specific shape. */
  .filter-rail {
    flex: 0 0 auto;
    width: 100%;
    max-height: 60vh;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  /* Same higher-specificity-beats-the-shared-fix issue as search.php's
     own inputs (see search.css's own note) — these filter-rail controls
     set their own explicit small font-size, which wins over app.css's
     shared 16px iOS-zoom fix on specificity, not source order. */
  .filter-row input, .filter-group select, #searchFilter, #filterPublished { font-size: 16px; }

  .toolbar-row2 { flex-wrap: wrap; }

  /* ---- Results table -> stacked cards ---- */
  .table-wrap { overflow-x: hidden; }
  #resultsTable { white-space: normal; }
  #resultsTable thead { display: none; } /* the toolbar's own Sort <select> already covers this */
  #resultsTable, #resultsTable tbody { display: block; width: 100%; }
  #resultsTable tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 2px 10px;
    padding: 12px;
    margin: 8px;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
  }
  #resultsTable tbody tr:hover { background: var(--surface); } /* no hover state on touch */
  /* Default: every cell is a small, wrapped "secondary" meta chip (€/m²,
     vs median, size/rooms already shown in the title's own facts line,
     status, source, days, yield, area median, drops, reno headroom, scope,
     blockers, year, floor, lift, tier when it isn't the headline column,
     percentile...) — same information as desktop, lower visual weight.
     The columns that need real prominence override this below, by
     specificity ([data-col="x"] beats a bare element selector), not by a
     long :not() exclusion chain — a first attempt at that chain had a
     whitespace-as-descendant-combinator bug (CSS treats a line-broken
     ":not():not()" as two separate compound selectors joined by a
     descendant combinator, not one continued selector) that silently
     matched nothing and left every "secondary" cell at the CSS default
     order:0, rendering above the primary ones instead of below — caught by
     checking real getBoundingClientRect() positions after deploying, not
     assumed correct from how the file read. */
  #resultsTable td {
    display: inline-block;
    order: 7;
    padding: 0;
    border: none;
    background: none !important;
    text-align: left;
    font-family: Plex, sans-serif;
    font-size: 11.5px;
    color: var(--ink-3);
    margin: 3px 10px 0 0;
  }
  #resultsTable .title-wrap { width: auto; }

  /* Prominent, in reading order: photo + title side by side, then
     municipality, then price, then flags — the same glance order an
     Idealista card uses. */
  #resultsTable td[data-col="score"] { order: 1; width: 100%; font-size: 13px; color: var(--ink); margin: 0; }
  #resultsTable td[data-col="photo"] { order: 2; flex: 0 0 84px; margin: 0; }
  #resultsTable td[data-col="title"] { order: 3; flex: 1 1 180px; min-width: 0; font-size: 13px; color: var(--ink); margin: 0; }
  #resultsTable td[data-col="municipality"] { order: 4; width: 100%; font-size: 12.5px; color: var(--ink-3); margin: 2px 0 0; }
  #resultsTable td[data-col="price"] { order: 5; width: 100%; font-size: 13px; color: var(--ink); margin: 6px 0 0; }
  #resultsTable td[data-col="flags"] { order: 6; width: 100%; font-size: 13px; color: var(--ink); margin: 2px 0 0; }
  #resultsTable td[data-col="links"] {
    order: 8;
    width: 100%;
    font-size: 13px;
    color: var(--ink);
    text-align: right;
    border-top: 1px solid var(--line-soft);
    padding-top: 8px;
    margin-top: 8px;
  }
  /* The one bold move (Phase 6) doesn't fit a reflowed inline chip — the
     bar itself is dropped at this width, the bold figure stays (inherited
     from td.headline's own font-weight, not redeclared here). */
  #resultsTable .headline-bar { display: none; }
}
