:root {
  --bg: #f8fafc;
  --bg-elev: #fff;
  --fg: #0f172a;
  --muted: #64748b;
  --border: #e2e8f0;
  --accent: #2563eb;
  --accent-fg: #fff;
  --chip-bg: #e2e8f0;
  --chip-on-bg: #2563eb;
  --chip-on-fg: #fff;
  --toast-bg: #0f172a;
  --toast-fg: #f8fafc;
  --tap: 44px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f172a;
    --bg-elev: #1e293b;
    --fg: #f8fafc;
    --muted: #94a3b8;
    --border: #334155;
    --chip-bg: #334155;
    --toast-bg: #f8fafc;
    --toast-fg: #0f172a;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
  line-height: 1.4;
  padding-bottom: env(safe-area-inset-bottom);
}

.topbar {
  padding: 12px 16px 8px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 5;
}
.topbar h1 { margin: 0; font-size: 1.25rem; }
.topbar-title { display: flex; align-items: center; gap: 10px; }
.topbar-logo { width: 32px; height: 32px; flex-shrink: 0; }
.hint { margin: 4px 0 0; color: var(--muted); font-size: 0.875rem; }
.needs-chips { margin-top: 8px; gap: 6px; }
.needs-chips .chip {
  font-size: 0.8125rem;
  min-height: 32px;
  padding: 4px 10px;
}

.filters {
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  padding: 0;
}
.filters > summary {
  list-style: none;
  cursor: pointer;
  padding: 12px 16px;
  font-weight: 600;
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: var(--tap);
}
.filters > summary::-webkit-details-marker { display: none; }
.filters > summary::after {
  content: "▼";
  font-size: 0.75rem;
  color: var(--muted);
  transition: transform 0.15s;
}
.filters[open] > summary::after { transform: rotate(180deg); }
.filter-summary {
  font-weight: 400;
  color: var(--muted);
  font-size: 0.875rem;
  margin-left: 8px;
  flex: 1;
  text-align: right;
}

.filter-group {
  padding: 8px 16px 12px;
  border-top: 1px solid var(--border);
}
.filter-group h2 {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin: 8px 0;
}
.hint-inline {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  margin-left: 6px;
}
.text-input {
  appearance: none;
  width: 100%;
  background: var(--bg-elev);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font: inherit;
  min-height: var(--tap);
}
.text-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
}
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.chip {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--chip-bg);
  color: var(--fg);
  padding: 0 14px;
  height: var(--tap);
  min-width: var(--tap);
  border-radius: calc(var(--tap) / 2);
  font: inherit;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.chip[aria-pressed="true"] {
  background: var(--chip-on-bg);
  color: var(--chip-on-fg);
  border-color: var(--chip-on-bg);
}
.chip .swatch {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.2);
  display: inline-block;
}

.clear-btn {
  appearance: none;
  margin: 0 16px 16px;
  padding: 10px 16px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  border-radius: 8px;
  font: inherit;
  cursor: pointer;
  min-height: var(--tap);
}

main { padding: 12px 12px 24px; }
.count {
  color: var(--muted);
  font-size: 0.875rem;
  margin: 4px 4px 12px;
}
.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}
.tile {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 8px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
  min-height: 140px;
  font: inherit;
  color: inherit;
}
.tile:active { transform: scale(0.98); }
/* Shared checkerboard for any element that contains a flag image. Solid
   white flags (Nepal, Japan, Vatican, etc.) would otherwise blend into a
   white page background and look like they have no border or extent. The
   main grid's .tile img and the detail dialog's .detail img also pick
   this up via their own selectors below — kept duplicated there to avoid
   needing JS changes for the legacy tile rendering paths. */
.flag-bg {
  background-color: var(--bg-elev);
  background-image:
    linear-gradient(45deg, var(--border) 25%, transparent 25%),
    linear-gradient(-45deg, var(--border) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--border) 75%),
    linear-gradient(-45deg, transparent 75%, var(--border) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.tile img {
  width: 100%;
  height: 90px;
  object-fit: contain;
  background-color: var(--bg-elev);
  background-image:
    linear-gradient(45deg, var(--border) 25%, transparent 25%),
    linear-gradient(-45deg, var(--border) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--border) 75%),
    linear-gradient(-45deg, transparent 75%, var(--border) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
  border-radius: 4px;
}
.tile-name {
  font-size: 0.875rem;
  line-height: 1.2;
  word-break: break-word;
}
.tile-count {
  font-size: 0.6875rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-top: -2px;
}
.tile-warn {
  position: relative;
  border-color: #f59e0b;
}
.tile-withheld {
  position: relative;
  border-color: #64748b;
}
.badge-warn {
  position: absolute;
  top: 4px;
  right: 4px;
  background: #f59e0b;
  color: #1f2937;
  font-size: 0.625rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  pointer-events: none;
}
.badge-withheld {
  position: absolute;
  top: 4px;
  right: 4px;
  background: #64748b;
  color: #f8fafc;
  font-size: 0.625rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  pointer-events: none;
}

dialog.detail {
  border: none;
  border-radius: 16px;
  background: var(--bg-elev);
  color: var(--fg);
  padding: 20px;
  max-width: min(92vw, 480px);
  width: 92vw;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
}
dialog.detail::backdrop { background: rgba(0, 0, 0, 0.5); }
.detail img {
  width: 100%;
  max-height: 220px;
  object-fit: contain;
  background-color: var(--bg-elev);
  background-image:
    linear-gradient(45deg, var(--border) 25%, transparent 25%),
    linear-gradient(-45deg, var(--border) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--border) 75%),
    linear-gradient(-45deg, transparent 75%, var(--border) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
  border-radius: 6px;
}
.detail h2 { margin: 12px 0 8px; font-size: 1.125rem; }
.detail .tags {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.875rem;
  margin: 0 0 6px;
  white-space: pre;
  overflow-x: auto;
}
.detail-description {
  margin: 0 0 12px;
  font-size: 0.875rem;
  color: var(--fg);
  line-height: 1.45;
}
.detail-source {
  margin: 0 0 12px;
  font-size: 0.75rem;
  color: var(--muted);
}
/* Icon-button row at the bottom of the detail dialog. Reuses the
   .fix-actions-inner flex container + .icon-btn styling defined for the
   review/suggestions pages so the visual vocabulary is consistent. */
.detail-links {
  margin: 0 0 12px;
}
.detail-close {
  position: absolute;
  top: 8px;
  right: 12px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.75rem;
  cursor: pointer;
  line-height: 1;
}
.copy-btn {
  width: 100%;
  appearance: none;
  background: var(--accent);
  color: var(--accent-fg);
  border: none;
  padding: 14px;
  border-radius: 10px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  min-height: var(--tap);
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom) + 24px);
  transform: translateX(-50%) translateY(20px);
  background: var(--toast-bg);
  color: var(--toast-fg);
  padding: 10px 16px;
  border-radius: 999px;
  font-size: 0.875rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
  z-index: 50;
  max-width: 90vw;
  text-align: center;
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.review-main {
  padding: 16px;
  max-width: 960px;
  margin: 0 auto;
}
.suggestions-section {
  margin-bottom: 16px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 16px;
}
.suggestions-section:last-child { margin-bottom: 0; }
.suggestions-section[open] { padding-bottom: 16px; }
.suggestions-h2 {
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  padding: 4px 0;
  margin: 0;
  /* Hint the disclosure with a chevron that rotates on open. The default
     triangle marker varies by browser and doesn't theme well. */
}
.suggestions-h2::-webkit-details-marker { display: none; }
.suggestions-h2::before {
  content: "›";
  display: inline-block;
  width: 1em;
  margin-right: 4px;
  color: var(--muted);
  font-weight: 400;
  transition: transform 120ms ease;
}
.suggestions-section[open] > .suggestions-h2::before {
  transform: rotate(90deg);
}
.suggestions-h2 .muted {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.875rem;
}
.suggestions-blurb {
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.45;
  margin: 12px 0;
}
.suggestions-blurb code {
  background: var(--bg);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.8125rem;
}
/* The table inside a details is the only place .review-table appears in
   isolation; the section's existing border handles the frame now, so drop
   the duplicate from the table itself when nested here. */
.suggestions-section .review-table {
  border: none;
  background: transparent;
  border-radius: 0;
}
/* Sub-bucket headings inside the colors section. */
.colors-subhead {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--fg);
  margin: 20px 0 8px;
  text-transform: none;
  letter-spacing: 0;
}
.colors-subblurb {
  color: var(--muted);
  font-size: 0.8125rem;
  line-height: 1.4;
  margin: 4px 0 8px;
}
.colors-subgroup { margin-top: 8px; }
.colors-subgroup > summary { cursor: pointer; list-style: none; }
.colors-subgroup > summary::-webkit-details-marker { display: none; }
.colors-subgroup > summary::before {
  content: "›";
  display: inline-block;
  width: 1em;
  margin-right: 4px;
  color: var(--muted);
  font-weight: 400;
  transition: transform 120ms ease;
}
.colors-subgroup[open] > summary::before { transform: rotate(90deg); }
/* Color swatch chips inside table cells. */
.color-swatch-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0 6px 2px 0;
  font-size: 0.8125rem;
  white-space: nowrap;
  vertical-align: middle;
}
.color-swatch-dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid var(--border);
}
.review-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
.review-table th,
.review-table td {
  text-align: left;
  padding: 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  font-size: 0.875rem;
}
.review-table th {
  background: var(--bg);
  color: var(--muted);
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.review-table tr:last-child td { border-bottom: none; }
.review-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.review-table a { color: var(--accent); text-decoration: none; }
.review-table a:hover { text-decoration: underline; }
.review-table .muted { color: var(--muted); font-size: 0.8125rem; }
.reason-tag {
  display: inline-block;
  background: #fde68a;
  color: #78350f;
  font-size: 0.625rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 999px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.suggested-cell {
  display: flex;
  align-items: center;
  gap: 12px;
}
.review-thumb {
  width: 56px;
  height: 38px;
  object-fit: contain;
  background-color: var(--bg-elev);
  background-image:
    linear-gradient(45deg, var(--border) 25%, transparent 25%),
    linear-gradient(-45deg, var(--border) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--border) 75%),
    linear-gradient(-45deg, transparent 75%, var(--border) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
  border-radius: 4px;
  flex-shrink: 0;
}
/* Compact icon-only action buttons used in the colors mismatch row where
   two fix paths need to fit side-by-side. Tooltip via the link's title.
   Keep the <td> as a normal table-cell (so the base rule's vertical-align:
   middle keeps the buttons on the row's baseline) and put the flex layout
   on an inner wrapper div. Setting display: flex on the <td> itself works
   visually but takes the cell out of table layout and misaligns it. */
.fix-actions {
  width: 1%;
  white-space: nowrap;
}
.fix-actions-inner {
  display: inline-flex;
  gap: 6px;
  align-items: center;
}
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--bg);
  color: var(--accent) !important;
  border: 1px solid var(--border);
  text-decoration: none !important;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
  flex-shrink: 0;
}
.icon-btn:hover {
  background: var(--accent);
  color: var(--accent-fg) !important;
  border-color: var(--accent);
}

@media (max-width: 720px) {
  .review-table thead { display: none; }
  .review-table tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    padding: 12px;
  }
  .review-table td {
    border-bottom: none;
    padding: 4px 0;
  }
  .review-table td:nth-child(3) { text-align: left; }
  .review-table td:nth-child(4) { grid-column: 1 / -1; margin-top: 8px; }
  .review-table tr { border-bottom: 1px solid var(--border); }

  /* Colors-mismatch rows have 5 cells (Flag, Wikidata, Ours, OSM uses, Fix).
     Give them a layout where the swatches and fix actions span the full row
     instead of being squeezed into half-width cells where they tear apart. */
  #colors-mismatch-rows tr {
    grid-template-columns: 1fr auto;
  }
  #colors-mismatch-rows td:nth-child(1) { /* Flag */ }
  #colors-mismatch-rows td:nth-child(2) { grid-column: 1 / -1; }  /* WD swatches */
  #colors-mismatch-rows td:nth-child(3) { grid-column: 1 / -1; }  /* our swatches */
  #colors-mismatch-rows td:nth-child(4) { /* OSM uses, sits beside Flag */
    grid-column: 2;
    grid-row: 1;
    text-align: right;
    align-self: center;
  }
  #colors-mismatch-rows td:nth-child(5) {
    grid-column: 1 / -1;
    margin-top: 4px;
  }
}

.page-footer {
  padding: 24px 16px 48px;
  text-align: center;
  color: var(--muted);
  font-size: 0.875rem;
}
.page-footer a { color: var(--accent); text-decoration: none; }
.page-footer a:hover { text-decoration: underline; }

/* ---- curator page ---- */
/* Curator-only: the topbar (queue counter + needing-attention chips) is
   queue-management UI, not classification UI. Let it scroll out of view so
   the flag image and form take all the visible space while curating. */
body.curate .topbar { position: relative; }

.curate-main {
  padding: 12px 16px 96px;
  max-width: 720px;
  margin: 0 auto;
}
.curate-flag {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 16px;
  /* Pin the flag image so it stays visible while the curator scrolls through
     the form fields below. Sticky inside .curate-main, anchored to the top of
     the viewport once .topbar scrolls away. */
  position: sticky;
  top: 0;
  z-index: 4;
}
.curate-flag img {
  display: block;
  width: 100%;
  max-height: 180px;
  object-fit: contain;
  background-color: var(--bg-elev);
  background-image:
    linear-gradient(45deg, var(--border) 25%, transparent 25%),
    linear-gradient(-45deg, var(--border) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--border) 75%),
    linear-gradient(-45deg, transparent 75%, var(--border) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
  border-radius: 6px;
}
.curate-meta { margin-top: 12px; }
.curate-meta h2 { margin: 0 0 4px; font-size: 1.125rem; }
.meta-line { color: var(--muted); font-size: 0.875rem; margin: 0; }
.meta-line a { color: var(--accent); }
.description-input {
  min-height: calc(var(--tap) * 2);
  resize: vertical;
  line-height: 1.4;
}

.curate-actions {
  display: flex;
  gap: 10px;
  margin-top: 16px;
}
.action-primary,
.action-secondary {
  flex: 1;
  appearance: none;
  font: inherit;
  font-weight: 600;
  padding: 14px;
  min-height: var(--tap);
  border-radius: 10px;
  cursor: pointer;
}
.action-primary {
  background: var(--accent);
  color: var(--accent-fg);
  border: none;
}
.action-primary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.action-secondary {
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--border);
}
.action-secondary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.curate-filter-bar {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
  color: var(--muted);
}

.curate-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--bg-elev);
  border-top: 1px solid var(--border);
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 10px;
  z-index: 10;
}
.curate-footer > span:first-child {
  flex: 1;
  color: var(--muted);
  font-size: 0.875rem;
}
.curate-footer .action-primary,
.curate-footer .action-secondary {
  flex: 0 1 auto;
  padding: 10px 14px;
}

/* Shared review-page primitives (review-colors, review-icons). Mirrors
   the .row-chip/.review-row idiom used inline on those pages but keeps
   the small bits (badges, action buttons) here so both pages stay
   visually in sync. */
.review-badge {
  display: inline-block;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid var(--accent);
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.review-badge.zero {
  border-color: var(--border);
  color: var(--muted);
  background: transparent;
}
.row-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}
.review-btn {
  appearance: none;
  font: inherit;
  font-size: 0.8125rem;
  padding: 4px 12px;
  height: 30px;
  border-radius: 15px;
  border: 1px solid var(--accent);
  background: var(--bg-elev);
  color: var(--accent);
  cursor: pointer;
}
.review-btn:hover {
  background: color-mix(in srgb, var(--accent) 8%, var(--bg-elev));
}
/* Already reviewed by this browser: filled-in style so the user sees
   their vote, and the label hints that another click undoes it. */
.review-btn.reviewed {
  background: var(--accent);
  color: var(--accent-fg);
}
.review-btn.reviewed:hover {
  background: color-mix(in srgb, var(--accent) 85%, transparent);
}
