*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --ink: #0f0e0c;
  --paper: #f5f0e8;
  --cream: #ede8dc;
  --accent: #c8401a;
  --accent2: #2d6a4f;
  --gold: #b8860b;
  --muted: #7a7268;
  --border: #d4cec2;
  --card: #faf7f2;
  --sidebar-w: 400px;
}

body {
  font-family: 'Instrument Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 13px;
  color: var(--ink);
  background: var(--paper);
  height: 100vh;
  overflow: hidden;
}

#app {
  display: flex;
  height: 100vh;
}

/* ── Sidebar ──────────────────────────────────────────────────────────────── */
#sidebar {
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  height: 100vh;
  overflow-y: auto;
  background: var(--card);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
}

#sidebar-header {
  background: var(--ink);
  color: var(--paper);
  padding: 0 1.5rem;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 3px solid var(--accent);
  flex-shrink: 0;
  position: sticky;
  top: 0;
  z-index: 100;
}

.logo-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.logo-icon { display: none; }

.logo-text {
  font-family: 'DM Serif Display', serif;
  font-size: 1.4rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--paper);
  line-height: 1;
}

.logo-text em {
  color: var(--accent);
  font-style: italic;
}

.logo-tag {
  display: inline-block;
  margin-top: 0.4rem;
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  background: var(--accent);
  color: white;
  padding: 2px 6px;
  border-radius: 2px;
  letter-spacing: 0.08em;
}

.panel {
  border-bottom: 1px solid var(--border);
  padding: 1.25rem 1.5rem;
}

.panel-label {
  display: block;
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.85rem;
}

.panel-label-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.85rem;
}

.panel-label-row .panel-label { margin-bottom: 0; }

/* Search — three mutually exclusive search types. Typing into one field
   disables and clears the other two, so a query always targets exactly
   one column (address, owner, or account #) and never an ambiguous mix. */
.search-field {
  margin-bottom: 0.7rem;
}

.search-field-label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.6rem;
  row-gap: 0.2rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.4rem;
}

.search-field-hint {
  flex-basis: 100%;
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  font-weight: 400;
  color: var(--muted);
}

.search-type-input {
  width: 100%;
  padding: 0.65rem 1rem;
  border: 1.5px solid var(--border);
  border-radius: 4px;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.88rem;
  background: white;
  color: var(--ink);
  outline: none;
  transition: border-color 0.2s, background 0.2s, opacity 0.2s;
}

.search-type-input:focus { border-color: var(--accent); }

.search-type-input:disabled {
  background: var(--cream);
  color: var(--muted);
  opacity: 0.6;
  cursor: not-allowed;
}

.search-submit-btn {
  width: 100%;
  margin-top: 0.2rem;
}

#search-results {
  margin-top: 0.6rem;
  max-height: 260px;
  overflow-y: auto;
}

/* Stretch the search inputs, submit button, and results list edge-to-edge
   across the sidebar on full-width (desktop) layouts, overriding the
   panel's side padding (1.5rem). On the mobile bottom-sheet the panel
   padding stays as-is. This block must come after the base #search-results
   rule above so its equal-specificity overrides win the cascade. */
@media (min-width: 801px) {
  .search-type-input,
  .search-submit-btn,
  #search-results {
    width: calc(100% + 3rem);
    margin-left: -1.5rem;
  }

  .search-type-input,
  .search-submit-btn {
    border-radius: 0;
  }

  /* Once a search collapses the input fields, let the results list grow to
     fill the rest of the sidebar's height (instead of capping at 260px) so
     it reads as a full-height results panel, scrolling internally if the
     list is longer than the available space. Only while no parcel is
     selected yet — once #detail-panel appears it needs that space instead. */
  #search-panel:has(#search-fields-wrap.hidden):has(~ #detail-panel.hidden) {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  #search-panel:has(#search-fields-wrap.hidden):has(~ #detail-panel.hidden) #search-results {
    flex: 1;
    max-height: none;
    min-height: 0;
  }
}

.search-item {
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.15s;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.search-item:hover { background: var(--cream); }

.search-item .addr { font-size: 0.85rem; font-weight: 500; margin-bottom: 2px; }
.search-item .owner { font-family: 'DM Mono', monospace; color: var(--muted); font-size: 0.72rem; margin-top: 2px; }
.search-item .val { font-family: 'DM Serif Display', serif; color: var(--accent2); font-size: 1rem; }

/* Detail panel */
.detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 8px;
  margin-bottom: 10px;
}

.detail-row { display: contents; }

.detail-label {
  font-family: 'DM Mono', monospace;
  color: var(--muted);
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
  text-transform: uppercase;
}

.detail-value {
  font-size: 0.82rem;
  font-weight: 500;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
  word-break: break-word;
}

.value-box {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0.6rem;
  margin: 10px 0;
}

.value-card {
  background: var(--cream);
  border-radius: 4px;
  padding: 0.65rem 0.75rem;
  text-align: center;
  border: 1px solid var(--border);
}

.value-card.total {
  background: var(--ink);
  border-color: var(--ink);
}

.value-card .vc-label {
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.value-card.total .vc-label { color: #999; }

.value-card .vc-val {
  font-family: 'DM Serif Display', serif;
  font-size: 1.1rem;
  color: var(--ink);
  margin-top: 3px;
}

.value-card.total .vc-val { color: var(--paper); }

.btn-row {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

/* Comparables */
#comps-stats {
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.75rem 1rem;
  margin-bottom: 0.75rem;
  font-size: 0.78rem;
}

#comps-stats .stat-row {
  display: flex;
  justify-content: space-between;
  padding: 2px 0;
}

#comps-stats .stat-label { font-family: 'DM Mono', monospace; font-size: 0.62rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }
#comps-stats .stat-val { font-family: 'DM Serif Display', serif; font-size: 1rem; }
#comps-stats .over { color: var(--accent); }
#comps-stats .under { color: var(--accent2); }

.comp-item {
  padding: 0.7rem 0.9rem;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.15s;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.comp-item:hover { background: var(--cream); }
.comp-item.subject-item { background: #e4f0ea; border-left: 3px solid var(--accent2); }

.comp-item .ci-addr { font-size: 0.82rem; font-weight: 500; }
.comp-item .ci-meta { font-family: 'DM Mono', monospace; color: var(--muted); font-size: 0.68rem; margin-top: 2px; }
.comp-item .ci-val { font-family: 'DM Serif Display', serif; color: var(--accent2); font-size: 1rem; }
.comp-item .ci-diff { font-family: 'DM Mono', monospace; font-size: 0.65rem; margin-left: 4px; }
.comp-item .ci-diff.over { color: var(--accent); }
.comp-item .ci-diff.under { color: var(--accent2); }

/* ── Map ──────────────────────────────────────────────────────────────────── */
#map-container {
  flex: 1;
  position: relative;
}

#map {
  width: 100%;
  height: 100%;
}

#map-legend {
  position: absolute;
  bottom: 24px;
  right: 12px;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: white;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.65rem 0.85rem;
  font-size: 0.7rem;
  z-index: 999;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}

.legend-section + .legend-section {
  border-top: 1px solid var(--border);
  padding-top: 0.4rem;
}

.legend-title {
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.legend-toggle {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  user-select: none;
}
.legend-toggle input { cursor: pointer; }

.legend-row { display: flex; align-items: center; gap: 0.4rem; margin: 0.25rem 0 0; }
.legend-swatch { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.legend-swatch-sq { border-radius: 2px; }

.legend-color-modes {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.65rem;
}
.legend-color-modes label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
  font-weight: normal;
}
.legend-color-modes input { cursor: pointer; }
.legend-swatches { margin-top: 0.4rem; }

#map-loading {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  background: white;
  color: var(--ink);
  border: 1px solid var(--border);
  padding: 0.35rem 1rem;
  border-radius: 20px;
  font-family: 'DM Mono', monospace;
  font-size: 0.7rem;
  z-index: 999;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
button {
  cursor: pointer;
  border: none;
  border-radius: 4px;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.65rem 1rem;
  transition: background 0.2s, opacity 0.15s;
}

button:hover { opacity: 0.88; }

#search-btn {
  background: var(--accent);
  color: #fff;
  white-space: nowrap;
}

.btn-primary {
  flex: 1;
  background: var(--ink);
  color: var(--paper);
}

.btn-protest {
  flex: 1;
  background: var(--accent);
  color: #fff;
}

.btn-secondary {
  background: var(--cream);
  color: var(--ink);
  border: 1px solid var(--border);
}

.btn-map {
  flex: 1;
  background: var(--cream);
  color: var(--ink);
  border: 1px solid var(--border);
}

.btn-small {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  padding: 3px 8px;
  font-size: 0.7rem;
}

/* ── Modal ────────────────────────────────────────────────────────────────── */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(15,14,12,0.55);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-box {
  background: var(--card);
  border-radius: 8px;
  width: 560px;
  max-width: 95vw;
  max-height: 90vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  box-shadow: 0 20px 60px rgba(0,0,0,0.25);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.25rem;
  background: var(--ink);
  color: var(--paper);
  border-bottom: 3px solid var(--accent);
}

.modal-header h2 {
  font-family: 'DM Serif Display', serif;
  font-size: 1rem;
  font-weight: 400;
}

.modal-close {
  background: transparent;
  color: var(--paper);
  font-size: 1rem;
  padding: 2px 8px;
  opacity: 0.7;
}

.modal-close:hover { opacity: 1; }

.modal-body {
  padding: 1.25rem;
  overflow-y: auto;
  flex: 1;
}

.modal-footer {
  padding: 0.9rem 1.25rem;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  background: var(--cream);
}

.form-group {
  margin-bottom: 1rem;
}

.form-group > label {
  display: block;
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.4rem;
}

.form-group .hint { text-transform: none; letter-spacing: 0; font-size: 0.65rem; }

.form-group input[type="number"],
.form-group textarea {
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1.5px solid var(--border);
  border-radius: 4px;
  font-size: 0.85rem;
  font-family: 'Instrument Sans', sans-serif;
  background: white;
  color: var(--ink);
  outline: none;
  transition: border-color 0.2s;
  /* Allow vertical resize for a long narrative, but cap it so dragging the
     resize handle can't grow the box past the modal's bounds — overflow
     scrolls inside the textarea instead of pushing it outside the
     "Build Protest Package" window. */
  resize: vertical;
  max-height: 45vh;
  overflow-y: auto;
  box-sizing: border-box;
}

.form-group input:focus,
.form-group textarea:focus { border-color: var(--accent); }

.checkbox-group label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.82rem;
  font-family: 'Instrument Sans', sans-serif;
  padding: 4px 0;
  color: var(--ink);
}

.checkbox-group input[type="checkbox"] { width: 14px; height: 14px; accent-color: var(--accent); }

#protest-comp-summary {
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.75rem;
  font-size: 0.78rem;
}

#protest-comp-summary h4 { font-family: 'DM Mono', monospace; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); margin-bottom: 0.5rem; }
#protest-comp-summary .ps-row { display: flex; justify-content: space-between; padding: 2px 0; }
#protest-comp-summary .ps-over { color: var(--accent); font-weight: 700; }

/* ── Detail sections ─────────────────────────────────────────────────────── */
.section-title {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--blue);
  border-bottom: 1px solid var(--blue-light);
  padding-bottom: 3px;
  margin: 10px 0 5px;
}

.section-title-year {
  display: flex;
  align-items: center;
  gap: 6px;
}
.section-title-year span:first-child { flex-shrink: 0; }
.year-select {
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 4px;
  cursor: pointer;
}

.status-row { margin-bottom: 6px; display: flex; gap: 6px; flex-wrap: wrap; }

.badge-protest {
  background: #e8f5e9; color: var(--green); border: 1px solid #a5d6a7;
  border-radius: 12px; padding: 2px 8px; font-size: 11px; font-weight: 600;
}
.badge-noticed {
  background: #fff8e1; color: #f57f17; border: 1px solid #ffe082;
  border-radius: 12px; padding: 2px 8px; font-size: 11px; font-weight: 600;
}
.badge-deadline {
  background: #e3f2fd; color: #1565c0; border: 1px solid #90caf9;
  border-radius: 12px; padding: 2px 8px; font-size: 11px; font-weight: 600;
}
.badge-deadline-urgent {
  background: #fff3e0; color: #e65100; border-color: #ffcc80;
}
.badge-deadline-past {
  background: #fce4ec; color: #b71c1c; border-color: #ef9a9a;
}
.badge-up {
  background: #ffebee; color: #c62828; border-radius: 10px;
  padding: 1px 7px; font-size: 10px; font-weight: 700; margin-left: 6px;
}
.badge-dn {
  background: #e8f5e9; color: var(--green); border-radius: 10px;
  padding: 1px 7px; font-size: 10px; font-weight: 700; margin-left: 6px;
}

.mini-grid { margin-bottom: 4px; }
.mg-row {
  display: flex; justify-content: space-between;
  font-size: 11px; padding: 2px 0; border-bottom: 1px solid #f5f5f5;
}
.mg-row span:first-child { color: var(--muted); }
.mg-row span:last-child  { font-weight: 600; }

.detail-value.mono { font-family: monospace; font-size: 12px; }
.detail-value.small { font-size: 11px; }

.area-list {
  display: flex; flex-wrap: wrap; gap: 4px; margin: 5px 0 8px;
}
.area-chip {
  background: #f0f4ff; border: 1px solid #c5d0f0; border-radius: 4px;
  padding: 2px 6px; font-size: 10px; color: #3a5a9a;
}
.beds-baths-line {
  font-size: 12px; font-weight: 700; color: var(--ink);
  background: var(--cream); border: 1px solid var(--border);
  border-radius: 4px; padding: 4px 8px; margin-bottom: 6px;
  letter-spacing: 0.02em;
}

.nbrhd-stats-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 4px; margin: 5px 0 3px;
}
.ns-stat {
  background: var(--cream); border: 1px solid var(--border);
  border-radius: 4px; padding: 5px 6px; text-align: center;
}
.ns-label {
  font-family: 'DM Mono', monospace; font-size: 0.58rem;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em;
}
.ns-val {
  font-family: 'DM Serif Display', serif; font-size: 0.9rem;
  margin-top: 2px; color: var(--ink);
}
.ns-over .ns-val  { color: var(--accent); }
.ns-under .ns-val { color: var(--accent2); }
.nbrhd-range {
  font-size: 10px; color: var(--muted); margin-bottom: 6px;
  font-family: 'DM Mono', monospace;
}

/* Flood zone badges */
.badge-fz {
  border-radius: 12px; padding: 2px 8px; font-size: 11px; font-weight: 600;
}
.badge-fz-high { background: #ffebee; color: #b71c1c; border: 1px solid #ef9a9a; }
.badge-fz-low  { background: #e8f5e9; color: var(--accent2); border: 1px solid #a5d6a7; }

/* Tax bill panel */
.tax-total-banner {
  font-family: 'DM Serif Display', serif; font-size: 1.5rem;
  color: var(--ink); margin: 4px 0 2px;
}
.tax-total-label {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.68rem; color: var(--muted); font-weight: 400;
}
.tax-header, .tax-row {
  display: grid; grid-template-columns: 1fr 72px 88px 76px;
  font-size: 0.72rem; padding: 3px 0;
  border-bottom: 1px solid var(--border);
}
.tax-header {
  font-family: 'DM Mono', monospace; font-size: 0.58rem;
  color: var(--muted); text-transform: uppercase; margin-top: 4px;
}
.tax-name { font-weight: 500; }
.tax-rate, .tax-taxable { color: var(--muted); font-size: 0.68rem; align-self: center; }
.tax-amt  { font-weight: 700; text-align: right; }

/* Value history table */
.hist-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}
.hist-table th {
  font-family: 'DM Mono', monospace; font-size: 0.6rem;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em;
  text-align: left; padding: 4px 6px; border-bottom: 1px solid var(--border);
}
.hist-table td {
  padding: 5px 6px; border-bottom: 1px solid #f5f5f5;
}
.hist-table .hist-yr {
  font-family: 'DM Serif Display', serif; font-size: 0.95rem;
}

/* Extra features */
.extras-grid { display: flex; flex-wrap: wrap; gap: 5px; margin: 4px 0 8px; }
.extra-item {
  background: #f0f4ff; border: 1px solid #c5d0f0; border-radius: 5px;
  padding: 4px 8px; min-width: 90px;
}
.extra-dscr { font-size: 11px; font-weight: 600; color: #1a3a6b; }
.extra-meta { font-size: 10px; color: var(--muted); }
.extra-val  { font-size: 10px; font-weight: 700; color: var(--accent2); margin-top: 1px; }

/* ── Comparables cards ───────────────────────────────────────────────────── */
.ci-header {
  display: flex; align-items: center; gap: 6px; margin-bottom: 2px;
}
.ci-star  { font-size: 11px; font-weight: 700; color: var(--green); }
.ci-num   { font-size: 11px; font-weight: 700; color: var(--blue); min-width: 24px; }
.ci-val   { font-weight: 700; color: var(--green); font-size: 13px; flex: 1; }
.ci-diff  { font-size: 10px; font-weight: 700; padding: 1px 5px; border-radius: 10px; }
.ci-diff.over  { background: #ffebee; color: #c62828; }
.ci-diff.under { background: #e8f5e9; color: var(--green); }

.ci-chips {
  display: flex; flex-wrap: wrap; gap: 3px; margin: 3px 0;
}
.chip {
  background: var(--gray); border: 1px solid var(--border);
  border-radius: 4px; padding: 1px 5px; font-size: 10px; color: #444;
}

.ci-vals-row {
  display: flex; flex-wrap: wrap; gap: 6px;
  font-size: 10px; color: var(--muted); margin-top: 2px;
}

.stat-bold { font-weight: 700; }

/* Leaflet popup tweaks */
.leaflet-popup-content { font-family: 'Instrument Sans', sans-serif; font-size: 0.82rem; min-width: 160px; }
.popup-addr { font-weight: 600; margin-bottom: 4px; }
.popup-val { font-family: 'DM Serif Display', serif; color: var(--accent2); font-size: 1rem; }
.popup-acct { font-family: 'DM Mono', monospace; color: var(--muted); font-size: 0.68rem; }
.popup-link { display: block; margin-top: 6px; color: var(--accent); cursor: pointer; text-decoration: underline; font-size: 0.75rem; }

/* ── Comparables Table Modal ─────────────────────────────────────────────── */
.ct-stats-bar {
  display: flex;
  align-items: center;
  gap: 0;
  background: #1a3a6b;
  padding: 10px 16px;
  flex-wrap: wrap;
}
.ct-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 4px 18px;
  border-right: 1px solid rgba(255,255,255,0.15);
}
.ct-stat:last-child { border-right: none; }
.ct-stat-divider { width: 1px; height: 32px; background: rgba(255,255,255,0.25); padding: 0; margin: 0 6px; }
.ct-stat-lbl { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase; color: #8fb3e8; }
.ct-stat-val { font-family: 'DM Serif Display', serif; font-size: 15px; color: #fff; margin-top: 2px; }
.ct-stat-verdict .ct-stat-val { font-size: 13px; font-weight: 700; }
.ct-over  .ct-stat-val { color: #ff8a80; }
.ct-under .ct-stat-val { color: #69f0ae; }

#ct-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 14px;
  background: #f5f0e8;
  border-bottom: 1px solid #d4cec2;
  gap: 10px;
  flex-wrap: wrap;
}
.ct-ctrl-left { display: flex; align-items: center; gap: 10px; }
.ct-ctrl-right { display: flex; align-items: center; gap: 8px; }

#ct-filter {
  padding: 5px 10px;
  border: 1.5px solid #d4cec2;
  border-radius: 4px;
  font-size: 12px;
  font-family: 'Instrument Sans', sans-serif;
  width: 200px;
  outline: none;
}
#ct-filter:focus { border-color: #c8401a; }

#ct-sort-label { font-family: 'DM Mono', monospace; font-size: 10px; color: #7a7268; }

.ct-sel-badge {
  background: #1a3a6b;
  color: white;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  display: none;
}

#ct-table-wrap {
  overflow: auto;
  flex: 1;
}

#ct-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  min-width: 900px;
}

.ct-th {
  background: #2c4a7a;
  color: #d8e8ff;
  font-family: 'DM Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 8px 8px;
  text-align: left;
  white-space: nowrap;
  border-right: 1px solid #3a5a8a;
  position: sticky;
  top: 0;
  z-index: 10;
}
.ct-th.ct-num { text-align: right; }
.ct-th-check { width: 32px; text-align: center; }

.ct-th.ct-sortable { cursor: pointer; user-select: none; }
.ct-th.ct-sortable:hover { background: #3a5a8a; }
.ct-sort-icon { font-size: 9px; }

.ct-td {
  padding: 6px 8px;
  border-bottom: 1px solid #ede8dc;
  border-right: 1px solid #f0ece4;
  vertical-align: middle;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}
.ct-td.ct-num { text-align: right; }
.ct-td-check { text-align: center; width: 32px; }
.ct-td-num { text-align: right; color: #999; font-size: 11px; width: 32px; }
.ct-muted { color: #aaa; }

.ct-row { cursor: pointer; transition: background 0.12s; }
.ct-row:hover { background: #f0ebe0 !important; }
.ct-row-even { background: #faf7f2; }
.ct-row-checked { background: #e8f0fb !important; }
.ct-row-checked:hover { background: #dde8f8 !important; }

.ct-row-subject {
  background: #fff3e0;
  font-size: 12px;
  border-left: 3px solid #c8401a;
}
.ct-row-subject .ct-td { border-bottom: 2px solid #c8401a; }
.ct-subject-star { color: #c8401a; font-weight: 700; font-size: 14px; }

.ct-subaddr { font-size: 10px; color: #999; margin-top: 1px; }

.ct-pct-over  { color: #c62828; font-weight: 700; font-size: 11px; }
.ct-pct-under { color: #2e7d32; font-weight: 700; font-size: 11px; }

#ct-table input[type="checkbox"] { width: 13px; height: 13px; accent-color: #1a3a6b; cursor: pointer; }

.hidden { display: none !important; }

/* ── Mobile / narrow viewports ────────────────────────────────────────────── */
.sidebar-handle { display: none; }

@media (max-width: 800px) {
  /* Sidebar becomes a collapsible bottom sheet that floats over the
     full-width map instead of squeezing it into a sliver. */
  #sidebar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    min-width: 0;
    height: 80vh;
    max-height: 80vh;
    border-right: none;
    border-top: 1px solid var(--border);
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -6px 28px rgba(0,0,0,0.22);
    transform: translateY(calc(100% - 56px));
    transition: transform 0.28s ease;
    z-index: 1500;
  }

  #sidebar.sidebar-open {
    transform: translateY(0);
  }

  #sidebar-header {
    cursor: pointer;
    border-radius: 14px 14px 0 0;
    padding: 0 1.1rem;
  }

  /* Mobile-friendliness audits flag any rendered text under 12px — bump
     the smallest labels (map legend, panel/field labels) up to that
     floor. These checks scan the whole DOM, not just what's above the
     fold, so the collapsed sidebar's contents count too. */
  .panel-label { font-size: 12px; }
  .search-field-hint { font-size: 12px; }

  /* The <label for="search-…"> rows and the inputs they activate are real
     tap targets — give both the 48px floor (the bare section-header
     ".panel-label" divs above are no longer <label>s, so they're exempt). */
  .search-field-label {
    min-height: 48px;
    align-items: center;
  }
  .search-type-input {
    min-height: 48px;
  }

  /* iOS Safari auto-zooms the whole page when a focused text input renders
     below 16px — that's the "scale of the window changes" jump users see
     while typing into search/filter/number fields. Floor every text-entry
     control at 16px on mobile so focusing one never triggers that zoom. */
  .search-type-input,
  .form-group input[type="number"],
  .form-group textarea,
  #ct-filter {
    font-size: 16px;
  }

  /* Drawn as a small triangle pointing up (closed = "tap to open"); rotated
     180° to point down once the sheet is open ("tap to close"). */
  .sidebar-handle {
    display: block;
    position: absolute;
    top: 10px;
    left: 50%;
    width: 0;
    height: 0;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
    border-bottom: 8px solid rgba(255,255,255,0.55);
    transform: translateX(-50%);
    transition: transform 0.2s ease;
  }

  #sidebar.sidebar-open .sidebar-handle {
    transform: translateX(-50%) rotate(180deg);
  }

  /* Keep the legend clear of the collapsed sheet's handle bar. The gap
     needs to be generous (not just the 56px bar height) because mobile
     browsers resize the viewport as their address bar shows/hides, and
     vh-based heights don't always settle in perfect sync — a tight
     margin here ends up visually overlapping on real devices. Both the
     title and rows are also bumped to the 12px text-size floor. */
  #map-legend {
    bottom: 180px;
    font-size: 12px;
    padding: 0.5rem 0.65rem;
  }
  .legend-title { font-size: 12px; }

  /* Leaflet's default zoom buttons (26-30px) and attribution links (~14px
     tall) read as undersized tap targets on mobile audits — enlarge both
     to the 48px floor without changing their on-map position. */
  .leaflet-bar a,
  .leaflet-touch .leaflet-bar a {
    width: 48px;
    height: 48px;
    line-height: 48px;
    font-size: 20px;
  }
  .leaflet-control-attribution a {
    display: inline-block;
    padding: 18px 6px;
    line-height: 1;
  }

  .panel { padding: 1rem 1.1rem; }

  /* Once a search collapses the input fields, let the results list grow to
     fill the rest of the open sheet (instead of capping at 260px with its
     own inner scrollbar) so the whole list is visible without scrolling
     past empty space below it. Only while no parcel is selected yet —
     once #detail-panel appears it needs that space instead, so this would
     otherwise squeeze it and overlap its header row with "Edit Search". */
  #sidebar.sidebar-open #search-panel:has(#search-fields-wrap.hidden):has(~ #detail-panel.hidden) {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  #sidebar.sidebar-open #search-panel:has(#search-fields-wrap.hidden):has(~ #detail-panel.hidden) #search-results {
    flex: 1;
    max-height: none;
  }

  /* Once a search result is picked, the search results list collapses
     (see selectParcel in app.js) — let the property details panel take
     over that freed space and fill the rest of the open sheet, scrolling
     internally if its content runs long. */
  #sidebar.sidebar-open #search-panel:has(#search-fields-wrap.hidden) ~ #detail-panel:not(.hidden) {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
  }

  /* ── Touch-friendly tap targets (≥48px, per mobile-friendliness audits) ── */
  button {
    min-height: 48px;
    padding: 0.8rem 1.1rem;
  }

  .btn-small {
    min-height: 48px;
    min-width: 48px;
    padding: 10px 14px;
    font-size: 0.8rem;
  }

  .modal-close {
    min-height: 48px;
    min-width: 48px;
    padding: 10px 16px;
    font-size: 1.15rem;
  }

  .checkbox-group input[type="checkbox"] { width: 19px; height: 19px; }
  .checkbox-group label { min-height: 48px; padding: 14px 0; gap: 10px; }

  #ct-table input[type="checkbox"] { width: 17px; height: 17px; }
  .ct-td-check, .ct-th-check { width: 38px; }

  .search-item, .comp-item { padding: 0.95rem 1rem; }

  /* ── Simplified navigation: one clear column of full-width actions ─────
     instead of squeezed side-by-side buttons that are easy to mis-tap. */
  .btn-row {
    flex-direction: column;
    gap: 8px;
  }
  .btn-row > button {
    flex: none;
    width: 100%;
  }

  /* Comparables table modal: let the filter row wrap instead of overflowing */
  #ct-filter { width: 130px; padding: 9px 10px; }
  .ct-stats-bar { padding: 8px 10px; }
  .ct-stat { padding: 4px 10px; }
}

/* Loading spinner */
@keyframes spin { to { transform: rotate(360deg); } }
.spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  vertical-align: middle;
  margin-right: 6px;
}

/* ── Ko-fi floating support button ──────────────────────────────────────────── */
#kofi-btn {
  position: fixed;
  top: 14px;
  right: 16px;
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px 7px 10px;
  background: #ff5e5b;
  color: #fff;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  border-radius: 20px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.22);
  transition: background 0.15s, transform 0.12s, box-shadow 0.15s;
  white-space: nowrap;
}
#kofi-btn:hover {
  background: #e04a47;
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(0,0,0,0.28);
}
#kofi-btn:active { transform: translateY(0); }
#kofi-btn svg { flex-shrink: 0; }

@media (max-width: 600px) {
  #kofi-btn span { display: none; }
  #kofi-btn { padding: 8px; border-radius: 50%; top: 10px; right: 10px; }
}
