* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Helvetica Neue', Arial, sans-serif;
}
.serif { font-family: Georgia, 'Iowan Old Style', serif; }
.mono {
  font-family: ui-monospace, 'JetBrains Mono', 'SFMono-Regular', Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
}
h1, h2, h3 { text-wrap: balance; margin: 0; }
button, input, select { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.app { height: 100vh; min-height: 620px; display: grid; grid-template-rows: auto 1fr; }

.topbar {
  display: flex; align-items: center; gap: 20px; padding: 0 20px; height: 56px;
  border-bottom: 1px solid var(--line); background: var(--panel);
}
.wordmark { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.wordmark .name { font-family: Georgia, 'Iowan Old Style', serif; font-size: 19px; }
.wordmark .place { font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-dim); }
.topbar .spacer { flex: 1; }
.search {
  display: flex; align-items: center; gap: 8px; width: 300px; max-width: 40vw;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px;
  padding: 7px 11px; font-size: 13px;
}
.search input { flex: 1; background: none; border: none; outline: none; color: var(--ink); }
.search input::placeholder { color: var(--ink-dim); }

.main { display: grid; grid-template-columns: 320px 1fr; min-height: 0; }
.sidebar {
  border-right: 1px solid var(--line); background: var(--panel); overflow-y: auto;
  padding: 16px; display: flex; flex-direction: column; gap: 18px;
}
.section { display: flex; flex-direction: column; gap: 9px; }
.section-label { font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-dim); }

.brand-list { display: flex; flex-direction: column; gap: 6px; }
.brand-row {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2);
}
.brand-row .swatch { width: 11px; height: 11px; border-radius: 3px; flex: none; }
.brand-row .info { flex: 1; min-width: 0; cursor: pointer; }
.brand-row .bname { font-size: 13.5px; }
.brand-row .bsub { font-size: 11px; color: var(--ink-dim); }
.brand-row .icon-btn { border: none; background: none; color: var(--ink-dim); cursor: pointer; padding: 2px 4px; }

.toggle { width: 30px; height: 17px; border-radius: 999px; background: var(--line); position: relative; flex: none; border: none; cursor: pointer; }
.toggle::after { content: ""; position: absolute; top: 2px; left: 2px; width: 13px; height: 13px; border-radius: 999px; background: var(--panel); transition: transform .15s ease; }
.toggle.on { background: var(--accent); }
.toggle.on::after { transform: translateX(13px); background: var(--accent-ink); }

.ghost-btn { border: 1px dashed var(--line); background: none; border-radius: 8px; padding: 8px 10px; color: var(--ink-dim); font-size: 12.5px; text-align: left; cursor: pointer; }
.ghost-btn:hover { border-color: var(--accent); color: var(--accent); }
.solid-btn { border: none; background: var(--accent); color: var(--accent-ink); border-radius: 7px; padding: 8px 12px; font-size: 12.5px; cursor: pointer; }
.link-btn { border: none; background: none; color: var(--accent); font-size: 11.5px; cursor: pointer; padding: 0; text-align: left; }

.segmented { display: flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.segmented button { flex: 1; border: none; background: var(--panel-2); padding: 7px 6px; font-size: 12px; color: var(--ink-dim); cursor: pointer; border-left: 1px solid var(--line); }
.segmented button:first-child { border-left: none; }
.segmented button.active { background: var(--accent); color: var(--accent-ink); }

.gap-form { display: flex; flex-direction: column; gap: 6px; font-size: 12.5px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 10px; }
.gap-form .row { display: flex; align-items: center; gap: 8px; }
.gap-form select { flex: 1; background: var(--panel); border: 1px solid var(--line); border-radius: 5px; padding: 5px 7px; font-size: 12.5px; }
.gap-form .arrow { color: var(--ink-dim); }

.filter-row { display: flex; flex-direction: column; gap: 6px; }
.filter-row select { background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px; font-size: 13px; }

.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.stat-card { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 10px 11px; }
.stat-card .num { font-size: 19px; }
.stat-card .lbl { font-size: 10.5px; color: var(--ink-dim); margin-top: 2px; }
.stat-card.sold .num { color: var(--sold); }
.stat-card.unsold .num { color: var(--unsold); }
.penetration-bar { height: 7px; border-radius: 999px; background: var(--unsold-bg); overflow: hidden; grid-column: 1 / -1; }
.penetration-bar > div { height: 100%; background: var(--sold); }

.legend { display: flex; flex-direction: column; gap: 7px; font-size: 12.5px; }
.legend-row { display: flex; align-items: center; gap: 9px; color: var(--ink-dim); }
.legend-row .dot { width: 9px; height: 9px; border-radius: 999px; flex: none; }
.legend-swatch { width: 22px; height: 8px; border-radius: 3px; flex: none; }

.map-pane { position: relative; overflow: hidden; }
#leaflet-map { width: 100%; height: 100%; }
.map-toolbar { position: absolute; top: 14px; left: 14px; right: 14px; display: flex; justify-content: space-between; align-items: flex-start; z-index: 500; pointer-events: none; }
.map-toolbar > * { pointer-events: auto; }
.scale-note { background: var(--panel); border: 1px solid var(--line); border-radius: 9px; box-shadow: var(--shadow); padding: 8px 12px; font-size: 11px; color: var(--ink-dim); max-width: 230px; }

.detail-panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: 300px; z-index: 700;
  background: var(--panel); border-left: 1px solid var(--line); box-shadow: var(--shadow);
  overflow-y: auto; padding: 16px;
}
.detail-panel[hidden] { display: none; }
.detail-close {
  position: absolute; top: 12px; right: 12px; width: 26px; height: 26px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2);
  color: var(--ink-dim); font-size: 16px; line-height: 1; cursor: pointer;
}
.detail-close:hover { border-color: var(--accent); color: var(--accent); }

.modal-backdrop { position: fixed; inset: 0; background: rgba(10,15,12,0.45); display: flex; align-items: center; justify-content: center; z-index: 1000; }
.modal-backdrop[hidden] { display: none; }
.modal { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow); width: 460px; max-width: 92vw; max-height: 86vh; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 14px; }
.modal h2 { font-family: Georgia, 'Iowan Old Style', serif; font-size: 17px; }
.modal label { font-size: 12px; color: var(--ink-dim); display: block; margin-bottom: 4px; }
.modal input[type="text"], .modal input[type="file"] { width: 100%; background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px; font-size: 13px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.field { display: flex; flex-direction: column; gap: 4px; }
.hint { font-size: 11px; color: var(--ink-dim); }
.warn-list { font-size: 11.5px; color: var(--unsold); max-height: 100px; overflow-y: auto; }

.chip { font-size: 10.5px; padding: 3px 7px; border-radius: 999px; background: var(--sold-bg); color: var(--sold); display: inline-block; }
.chip.unsold { background: var(--unsold-bg); color: var(--unsold); }

.review-row { display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--line); border-radius: 8px; padding: 10px; font-size: 12.5px; }
.review-row .conf { color: var(--ink-dim); font-size: 11px; }
.review-actions { display: flex; gap: 8px; }
.review-actions button { flex: 1; border: 1px solid var(--line); background: var(--panel-2); border-radius: 6px; padding: 6px; font-size: 12px; cursor: pointer; }
.review-actions button.confirm:hover { border-color: var(--sold); color: var(--sold); }
.review-actions button.reject:hover { border-color: var(--unsold); color: var(--unsold); }

.sidebar-toggle-btn {
  display: none; border: 1px solid var(--line); background: var(--panel-2); color: var(--ink);
  border-radius: 7px; width: 34px; height: 34px; font-size: 16px; cursor: pointer; flex: none;
}
.sidebar-backdrop { display: none; }

/* Andrew, 2026-08-21: below this width the fixed 320px sidebar (see .main
   above) would leave the actual map only a sliver wide -- confirmed
   unusable on a real phone screen when Andrew asked whether a colleague
   could use this on their phone. Sidebar becomes an off-canvas drawer
   (hidden by default, slides in over the map) instead of a permanent
   column; the map fills the full width underneath it either way. */
@media (max-width: 820px) {
  .sidebar-toggle-btn { display: flex; align-items: center; justify-content: center; }
  .wordmark .place { display: none; } /* reclaim topbar width for the toggle + search on a narrow screen */
  /* min-width:0 is the real fix here, not the width reset above --
     flex items default to min-width:auto, which refuses to shrink below
     the input's own intrinsic content width (~170px+) and was forcing
     the whole topbar, and with it the page's layout viewport, wider than
     the phone's actual 390px-ish screen (confirmed live: window.innerWidth
     was reporting 469 instead of 390 with this missing). */
  /* min-width:0 on every link in this flex/grid chain -- .app (grid),
     .topbar (flex), and .spacer/.search (flex items) all default to
     min-width:auto, which at each level refuses to shrink below its own
     content's natural minimum. Missing it at ANY link was enough to force
     the whole page's layout viewport wider than the phone's real screen
     (confirmed live via window.innerWidth). .spacer also stops competing
     for space on mobile -- its only job is pushing search rightward when
     there's room to spare, which isn't true here. */
  .app, .topbar { min-width: 0; }
  .topbar { gap: 10px; padding: 0 12px; }
  .wordmark { min-width: 0; }
  .spacer { flex: 0 1 0%; min-width: 0; }
  .search { width: auto; flex: 1 1 auto; min-width: 0; max-width: none; }
  .search input { min-width: 0; }

  .main { display: block; position: relative; height: 100%; }
  .sidebar {
    position: absolute; top: 0; bottom: 0; left: 0; width: min(320px, 88vw);
    z-index: 900; transform: translateX(-100%); transition: transform .22s ease;
    box-shadow: var(--shadow);
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-backdrop.open {
    display: block; position: absolute; inset: 0; z-index: 800;
    background: rgba(10,15,12,0.45);
  }
  .map-pane { position: absolute; inset: 0; }
}

/* Always, not just mobile -- a 300px fixed-width absolute panel can run
   off the edge of a genuinely narrow phone screen either way. */
.detail-panel { width: min(300px, 92vw); }
