/* Desktop-first analytical layout that still works on a phone: tables scroll
   sideways inside their panel, the map goes full-bleed, filters wrap. */

:root {
  --bg:       #f2f5f7;
  --surface:  #ffffff;
  --text:     #13222c;
  --dim:      #5c6b76;
  --line:     #d6dee3;
  --grid:     #e3e9ed;
  --accent:   #0b7a85;
  --accent-soft: #d5edf0;
  --on-accent: #ffffff;
  --rent:     #d4602f;
  --good:     #1a7f37;
  --thin:     #8a5a00;
  --bad:      #b3261e;
  --radius:   10px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:       #0f1a21;
    --surface:  #16242d;
    --text:     #e7edf1;
    --dim:      #93a3ae;
    --line:     #2a3a45;
    --grid:     #223039;
    --accent:   #3fb8c4;
    --accent-soft: #12343a;
    --on-accent: #06181b;
    --rent:     #f0834f;
    --good:     #57c26d;
    --thin:     #ffc266;
    --bad:      #ff6b5e;
  }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}
a { color: var(--accent); }
h2 { font-size: 1.15rem; margin: 0 0 4px; letter-spacing: -0.01em; }
h3 { font-size: 0.95rem; margin: 18px 0 6px; }
h4 { font-size: 0.8rem; margin: 12px 0 4px; color: var(--dim); text-transform: uppercase; letter-spacing: 0.05em; }
small { color: var(--dim); font-size: 0.8em; }

/* ---------------------------------------------------------------- topbar */

.topbar {
  position: sticky; top: 0; z-index: 20;
  padding: max(10px, env(safe-area-inset-top)) 16px 10px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.topbar-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
h1 { margin: 0; font-size: 1.15rem; letter-spacing: -0.01em; }
.freshness { font-size: 0.78rem; color: var(--dim); white-space: nowrap; }

.filters { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 8px; }
.field { display: flex; flex-direction: column; gap: 2px; font-size: 0.75rem; color: var(--dim); }
.field span { text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.68rem; }
select, input[type=number], input[type=search] {
  font: inherit; font-size: 0.95rem; color: var(--text);
  background: var(--bg); border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 10px; min-height: 40px;
}
input[type=number] { width: 7.5em; }
.check { display: flex; align-items: center; gap: 6px; font-size: 0.85rem; align-self: end; min-height: 40px; }

.tabs {
  position: sticky; top: 0; z-index: 19;
  display: flex; gap: 4px; padding: 6px 16px 0;
  background: var(--surface); border-bottom: 1px solid var(--line);
  overflow-x: auto;
}
/* The header height isn't fixed (filters wrap), so the tab strip just stacks
   under it in flow; sticky here keeps it pinned once the header scrolls off. */
.tab {
  font: inherit; font-size: 0.9rem; font-weight: 600; color: var(--dim);
  background: none; border: 0; border-bottom: 3px solid transparent;
  padding: 8px 12px 10px; cursor: pointer; white-space: nowrap;
}
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }

main { max-width: 1180px; margin: 0 auto; padding: 16px; }
.status { color: var(--dim); text-align: center; padding: 40px 0; }
.lede { color: var(--dim); max-width: 80ch; margin: 0 0 14px; }
.note { font-size: 0.82rem; color: var(--dim); margin: 4px 0 10px; }
.empty { color: var(--dim); text-align: center !important; padding: 18px !important; }

/* ---------------------------------------------------------------- panels */

.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 18px; margin: 0 0 16px;
  min-width: 0;
}
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 820px) { .two { grid-template-columns: 1fr; } }
.two .panel { margin: 0; }
.two { margin-bottom: 16px; }

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin: 0 0 16px; }
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; }
.kpi .v { font-size: 1.6rem; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi .l { font-size: 0.75rem; color: var(--dim); margin-top: 4px; }
.kpi.rent .v { color: var(--rent); }

.control-row { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: end; margin: 8px 0 12px; }
.search-wrap { flex: 1 1 220px; }
.search-wrap input { width: 100%; }

/* ---------------------------------------------------------------- tables */

.scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { border-collapse: collapse; width: 100%; font-size: 0.86rem; font-variant-numeric: tabular-nums; }
th, td { text-align: right; padding: 7px 9px; border-bottom: 1px solid var(--line); vertical-align: top; white-space: nowrap; }
th[scope=row], td:first-child, th:first-child { text-align: left; font-weight: 500; }
th[scope=row] small, td small { display: block; font-weight: 400; white-space: normal; }
thead th { font-size: 0.68rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--dim); border-bottom: 2px solid var(--text); position: sticky; top: 0; background: var(--surface); }
tr.total th, tr.total td { border-top: 2px solid var(--text); font-weight: 600; }
thead th.mon { color: var(--accent); }
table.wrap th[scope=row] { white-space: normal; min-width: 16ch; }
td small.inl { display: inline; margin-left: 3px; }

.listings tr.row { cursor: pointer; }
.listings tr.row:hover, .listings tr.row:focus { background: var(--accent-soft); outline: none; }
.listings tr.is-open { background: var(--accent-soft); }
.listings .lname { display: block; max-width: 34ch; overflow: hidden; text-overflow: ellipsis; }
.listings th[scope=row] { min-width: 20ch; }
.badge { color: var(--accent); font-weight: 600; }

.detail-row td { white-space: normal; background: var(--bg); padding: 12px 14px; }
.detail { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; }
.detail-facts { display: flex; flex-direction: column; gap: 2px; font-size: 0.85rem; }
.detail-actions { display: flex; gap: 14px; margin-top: 10px; align-items: center; }
.linkish { font: inherit; color: var(--accent); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { font-size: 0.78rem; padding: 3px 8px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line); }
.chip.low { border-color: var(--bad); color: var(--bad); }
.chip small { display: inline; color: inherit; }

/* score detail: points bars + weekly money + comps */
.detail h4 { margin: 10px 0 4px; font-size: 0.8rem; color: var(--dim); text-transform: uppercase; letter-spacing: 0.04em; }
.detail-wide { grid-column: 1 / -1; }
.detail .bar-row { grid-template-columns: 10em 1fr 5em; }
.money { display: flex; flex-direction: column; gap: 2px; font-size: 0.85rem; max-width: 20em; }
.money-row { display: flex; justify-content: space-between; font-variant-numeric: tabular-nums; }
.money-row.total { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 4px; font-weight: 600; }

.good { color: var(--good); font-weight: 600; }
.thin { color: var(--thin); font-weight: 600; }
.bad  { color: var(--bad);  font-weight: 600; }

.more {
  display: block; width: 100%; margin: 14px 0; padding: 12px;
  font: inherit; font-weight: 600; color: var(--accent);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); cursor: pointer;
}

/* ------------------------------------------------------------------ bars */

.bars { display: flex; flex-direction: column; gap: 4px; }
.bar-row { display: grid; grid-template-columns: 7em 1fr 7em; gap: 8px; align-items: center; font-size: 0.82rem; }
.bar-label { color: var(--dim); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-track { height: 14px; background: var(--grid); border-radius: 3px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--accent); }
.bar-fill.low { background: var(--bad); }
.bar-text { font-variant-numeric: tabular-nums; white-space: nowrap; }
.bar-text small { display: inline; }

/* ----------------------------------------------------------------- chart */

.chart-wrap { margin-top: 6px; }
.chart { width: 100%; height: auto; display: block; }
.grid { stroke: var(--grid); stroke-width: 1; }
.tick { font-size: 11px; fill: var(--dim); font-family: ui-monospace, monospace; }
.pt { fill: var(--accent); stroke: none; cursor: pointer; }
.pt:hover { stroke: var(--text); stroke-width: 1.5; }
.medline { stroke: var(--text); stroke-width: 1.5; stroke-dasharray: 4 3; }

/* ------------------------------------------------------------------- map */

body.is-map main { max-width: none; padding: 0; }
.view-map { position: relative; height: calc(100vh - 150px); min-height: 420px; }
#map { position: absolute; inset: 0; }
.map-panel {
  position: absolute; top: 10px; right: 10px; z-index: 1000;
  background: var(--surface); color: var(--text);
  padding: 10px 12px; border-radius: var(--radius); border: 1px solid var(--line);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .2); max-width: 280px; font-size: 0.85rem;
}
.map-panel-row { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: end; }
.map-panel select { min-height: 34px; padding: 4px 8px; }
.map-panel .check { min-height: 34px; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; font-size: 0.8rem; }
.legend-title { width: 100%; font-weight: 600; color: var(--dim); }
.legend .dot { display: inline-block; width: 11px; height: 11px; border-radius: 50%; border: 1px solid #333; margin-right: 5px; vertical-align: -1px; }
.legend .sq, .rent-pin { display: inline-block; width: 12px; height: 12px; background: #ffd400; border: 2px solid #111; box-shadow: 0 0 0 2px #fff; margin-right: 5px; vertical-align: -1px; }
.rent-pin { margin: 0; width: 14px; height: 14px; }
.map-panel .note { margin: 8px 0 0; }
.leaflet-popup-content { font-size: 13px; line-height: 1.4; }
@media (prefers-color-scheme: dark) {
  .leaflet-popup-content-wrapper, .leaflet-popup-tip { background: var(--surface); color: var(--text); }
  /* Invert the OSM tiles rather than depend on a dark tile provider. */
  .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(0.85) contrast(0.9) saturate(0.6); }
}
@media (max-width: 600px) {
  .map-panel { top: auto; bottom: 10px; left: 10px; right: 10px; max-width: none; }
  .view-map { height: calc(100vh - 190px); }
}

/* Price cuts: rentals whose advertised rent has come down. The map uses a
   distinct pin so a cut is visible without opening anything. */
.cut-pin { display: inline-block; width: 14px; height: 14px; background: #e63946;
           border: 2px solid #111; box-shadow: 0 0 0 2px #fff; border-radius: 50%; }
.legend .cut { display: inline-block; width: 12px; height: 12px; background: #e63946;
               border: 2px solid #111; box-shadow: 0 0 0 2px #fff; border-radius: 50%;
               margin-right: 5px; vertical-align: -1px; }
.cut-down { color: #c1121f; font-weight: 600; }
.cut-up   { color: #2a9d8f; font-weight: 600; }
.spark { display: inline-flex; gap: 2px; align-items: flex-end; height: 16px; vertical-align: -3px; }
.spark i { display: block; width: 4px; background: #888; }
.spark i.last { background: #c1121f; }

/* Booking figures that are partly or wholly extrapolated rather than quoted. */
.est { opacity: .65; font-style: italic; }
td .est small { font-style: normal; }
h3.sub { font-size: 14px; margin: 20px 0 4px; text-transform: uppercase;
         letter-spacing: .06em; color: var(--muted, #9aa3b2); }

/* ------------------------------------------------- per-listing calendar */

#cal-modal { position: fixed; inset: 0; z-index: 400; display: flex; align-items: center; justify-content: center; }
.cal-back { position: absolute; inset: 0; background: rgba(0,0,0,.6); backdrop-filter: blur(2px); }
.cal-box {
  position: relative; background: var(--surface, #151b23); color: var(--text, #e6e9ef);
  border: 1px solid var(--line, #262d38); border-radius: 14px;
  width: min(1040px, 96vw); max-height: 92vh; display: flex; flex-direction: column;
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
}
.cal-head {
  display: flex; align-items: flex-start; gap: 12px; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--line, #262d38);
}
.cal-head b { font-size: 15px; display: block; }
.cal-head small { color: var(--muted, #8b95a5); font-size: 12px; }
.cal-x { border: 0; background: none; color: var(--muted, #8b95a5); font-size: 26px; line-height: 1; cursor: pointer; padding: 0 4px; }
.cal-x:hover { color: var(--text, #e6e9ef); }
.cal-body { padding: 14px 16px 18px; overflow: auto; }

.cal-months { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 16px; }
.cal-month h4 { margin: 0 0 6px; font-size: 12.5px; font-weight: 620; }
.cal-month h4 small { color: var(--muted, #8b95a5); font-weight: 400; }
.cal-dow, .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-dow span { text-align: center; font-size: 10px; color: var(--muted, #8b95a5); padding-bottom: 2px; }
.cal-d {
  aspect-ratio: 1; border-radius: 5px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1px; font-size: 10px; cursor: default;
}
.cal-d i { font-style: normal; font-size: 10.5px; opacity: .75; }
.cal-d b { font-size: 9.5px; font-weight: 600; }
.cal-free   { background: color-mix(in srgb, #3fb950 16%, transparent); color: #3fb950; }
.cal-booked { background: color-mix(in srgb, #f85149 16%, transparent); color: #f85149; }
.cal-booked.cal-watched { outline: 1.5px solid #f85149; outline-offset: -1.5px; }
.cal-none, .cal-pad { background: transparent; }
.cal-key {
  display: inline-block; width: 11px; height: 11px; border-radius: 3px;
  margin: 0 3px 0 10px; vertical-align: -1px;
}
@media (max-width: 700px) {
  .cal-box { width: 100vw; max-height: 100vh; border-radius: 0; border: 0; }
  .cal-months { grid-template-columns: 1fr; }
}

/* Mini calendar inside a map popup. Hidden until the Calendar button is
   pressed - a popup opens on every marker click and most are never opened. */
.mini { display: none; margin-top: 8px; }
.mini.is-open { display: block; }
.mini .cal-d { font-size: 9px; border-radius: 4px; }
.mini .cal-d i { font-size: 9.5px; }
.mini .cal-d b { font-size: 8.5px; }
.mini .cal-grid, .mini .cal-dow { gap: 1.5px; }
.mini-head {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  margin-bottom: 5px; font-size: 12px; font-weight: 600;
}
.mini-head small { display: block; font-weight: 400; color: var(--muted, #8b95a5); font-size: 10.5px; }
.mini-head span { text-align: center; flex: 1; }
.mini-nav {
  border: 1px solid var(--line, #262d38); background: var(--surface-2, #1c232d);
  color: var(--text, #e6e9ef); border-radius: 6px; width: 22px; height: 22px;
  line-height: 1; cursor: pointer; font-size: 14px; padding: 0;
}
.mini-nav[disabled] { opacity: .35; cursor: default; }
.mini-foot { margin-top: 6px; text-align: right; font-size: 11.5px; }

/* Fixed height so the popup never has to resize (see renderMini). */
.mini.is-open { max-height: 260px; overflow-y: auto; }
.leaflet-popup-content { max-height: 420px; overflow-y: auto; }

/* --- calendar modal fixes (13 Sep) ---------------------------------------
   Leaflet's controls sit at z-index 1000 and its panes up to 700, so a modal
   at 400 had the zoom buttons and attribution drawing straight through it.
   On a phone the flex centring also pushed the header off the top of the
   screen when the content was taller than the viewport. */
#cal-modal { z-index: 2000; align-items: flex-start; }
.cal-box { margin: auto; }
.cal-head {
  position: sticky; top: 0; z-index: 2; background: var(--surface, #151b23);
  border-radius: 14px 14px 0 0;
}
@media (max-width: 700px) {
  #cal-modal { align-items: stretch; }
  .cal-box { margin: 0; height: 100dvh; max-height: 100dvh; }
  .cal-head { border-radius: 0; }
}
/* A quote we never had, filled in from the listing's day-of-week rate. */
.cal-d em { font-style: normal; font-size: 8.5px; opacity: .5; }

/* The mini calendar sizes to its content; the popup itself is the scroller.
   An inner scroller hid the "Full calendar" button below the fold. */
.mini.is-open { max-height: none; overflow: visible; }
.mini-foot { margin: 0 0 6px; text-align: center; font-size: 11.5px; }
