:root {
  --bg: #14161a;
  --panel: #1e2127;
  --line: #2e333c;
  --text: #e8eaed;
  --muted: #99a0ab;
  --yes-solid: #2f9e5e;
  --no-solid: #d0483c;
  --maybe-solid: #8a6d3b;
  --accent: #6fa8ff;
}

* { box-sizing: border-box; }

/* The whole app is viewport-bound: the PAGE never scrolls, only the two panels
   that can overflow (the field list and, on mobile, nothing else). 100dvh rather
   than 100vh so a mobile browser's collapsing toolbar cannot push the verdict
   buttons off-screen — the one thing that must always be reachable. */
html, body { height: 100%; }
body {
  margin: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* ── top bar ───────────────────────────────────────────────── */
.bar {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 14px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  font-size: 13px;
}
.bar__title { font-weight: 600; }
.bar__progress { color: var(--muted); }
.bar__spacer { flex: 1; }
.bar__sync { color: var(--muted); font-size: 12px; }
.bar__sync[data-state="pending"] { color: #d8a657; }
.bar__sync[data-state="error"] { color: var(--no-solid); }
.bar__who { color: var(--muted); }

/* ── page frame ────────────────────────────────────────────── */
main {
  flex: 1 1 auto;
  /* Both axes again. main is itself a flex item of body, so without min-width:0
     the video's intrinsic width propagates all the way up here and body's
     overflow:hidden silently CLIPS the result — no scrollbar, just a missing
     third verdict button. Every flex/grid item on the path from <body> to the
     <video> needs this. */
  min-height: 0; min-width: 0;
  display: flex; flex-direction: column; gap: 12px;
  padding: 12px 16px;
  max-width: 1500px; width: 100%; margin: 0 auto;
}

/* ── controls (top) ────────────────────────────────────────── */
.verdict { flex: 0 0 auto; }

.nav { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.nav button {
  padding: 7px 14px; background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px; font-size: 14px; cursor: pointer;
}
.nav button:hover:not(:disabled) { border-color: var(--muted); }
.nav button:disabled { opacity: .4; cursor: default; }
.nav__skip { margin-left: auto; }

.counter { color: var(--muted); font-size: 13px; margin-left: 6px; }
.counter b { color: var(--text); font-size: 15px; }

.verdict__buttons { display: flex; gap: 10px; }
.v {
  /* min-width:0 is load-bearing: a flex item defaults to min-width:auto, so
     "Not accurate" would refuse to shrink below its text and push the row wider
     than a phone screen. */
  flex: 1; min-width: 0; padding: 13px 10px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px;
  font-size: 15px; font-weight: 600; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 9px;
}
.v:hover { border-color: var(--muted); }
.v kbd {
  font: inherit; font-size: 11px; font-weight: 500;
  padding: 1px 6px; border-radius: 3px;
  border: 1px solid var(--line); color: var(--muted);
}
.v[aria-pressed="true"] { color: #fff; border-color: transparent; }
.v--yes[aria-pressed="true"]   { background: var(--yes-solid); }
.v--no[aria-pressed="true"]    { background: var(--no-solid); }
.v--maybe[aria-pressed="true"] { background: var(--maybe-solid); }
.v[aria-pressed="true"] kbd { border-color: rgba(255,255,255,.35); color: rgba(255,255,255,.8); }

#note {
  width: 100%; margin-top: 10px; padding: 8px 11px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: 6px;
  font: inherit; font-size: 14px; resize: none;
}

/* ── two-column body ───────────────────────────────────────── */
.grid {
  flex: 1 1 auto;
  min-height: 0; min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  /* Explicit, and NOT the implicit `auto`: an auto row sizes to its content, so
     once a video reported its real height the row grew past the viewport and the
     map was clipped with no way to scroll to it. */
  grid-template-rows: minmax(0, 1fr);
  gap: 16px;
}

.media {
  /* Both axes: a grid item defaults to min-width/min-height:auto, which floors at
     the content's intrinsic size. A 1080-wide video would then refuse to shrink
     and push the whole page wider than a phone screen. */
  min-height: 0; min-width: 0;
  background: #000;
  border: 1px solid var(--line); border-radius: 8px;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.media video, .media img {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto;
  display: block; object-fit: contain;
}
.media__fail { color: var(--muted); padding: 30px; text-align: center; font-size: 14px; }

.info {
  min-height: 0; min-width: 0;
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line); border-radius: 8px;
  padding: 14px;
}
.info__head { flex: 0 0 auto; display: flex; justify-content: flex-end; margin-bottom: 10px; }
.pill {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  padding: 3px 8px; border-radius: 20px; border: 1px solid var(--line); color: var(--muted);
}
.pill--none { border-color: #6b5730; color: #d8a657; }

/* The only scrollable region on desktop: reasoning can run long, and it may not
   push the map or the buttons off-screen. */
.fields {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  margin: 0 0 12px;
  /* minmax(0,1fr), not 1fr — a bare 1fr floors at max-content and lets a long
     reasoning string widen the page instead of wrapping. */
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 14px; align-content: start;
}
.fields dt {
  color: var(--muted); font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;
  white-space: nowrap; padding-top: 2px;
}
.fields dd { margin: 0; overflow-wrap: anywhere; font-size: 14.5px; }
.fields dd.is-empty { color: #5d6470; font-style: italic; }
.fields dd.is-long { font-size: 13.5px; color: #c6cbd3; }
.fields .filename { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }

.info { overflow: hidden; }   /* nothing escapes the panel; .fields is the scroller */

.map {
  flex: 0 0 auto;
  border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: var(--bg);
}
.map__tabs {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; border-bottom: 1px solid var(--line);
}
.map__tab {
  padding: 3px 10px; font-size: 12px; cursor: pointer;
  background: transparent; color: var(--muted);
  border: 1px solid transparent; border-radius: 20px;
}
.map__tab:hover:not(:disabled) { color: var(--text); }
.map__tab[aria-pressed="true"] { background: var(--bg); color: var(--text); border-color: var(--line); }
.map__tab:disabled { opacity: .35; cursor: default; }
.map__hint { margin-left: auto; font-size: 11px; color: #d8a657; }

.map iframe { display: block; width: 100%; height: 230px; border: 0; }
.map__none { padding: 24px; text-align: center; color: var(--muted); font-size: 14px; }
.map__link { padding: 7px 11px; font-size: 13px; border-top: 1px solid var(--line); }
.map__link a { color: var(--accent); text-decoration: none; }

/* Shorter screens: give the map less and the fields more. */
@media (max-height: 800px) {
  .map iframe { height: 165px; }
  #note { margin-top: 8px; }
}

/* ── mobile: media + geo + the three verdicts, one screen ──── */
@media (max-width: 768px) {
  /* No note field and no map on purpose. The map iframe is also skipped in JS,
     so a phone on mobile data never fetches Google Maps at all. */
  #note, .map { display: none; }

  main { padding: 10px; gap: 10px; }
  .bar { padding: 7px 10px; font-size: 12px; }
  .bar__title, .bar__who { display: none; }

  .nav { margin-bottom: 8px; gap: 6px; }
  .nav button { padding: 6px 11px; font-size: 13px; }
  /* Dropped on phones: judging already auto-advances to the next unreviewed clip,
     so this button is redundant, and keeping it made the nav row's min-content
     wider than the viewport — which pushed every other row out with it. */
  .nav__skip { display: none; }
  .counter { margin-left: auto; }

  .verdict__buttons { gap: 7px; }
  .v { padding: 15px 4px; font-size: 14px; }
  .v kbd { display: none; }          /* no physical keyboard to hint at */

  .grid {
    /* minmax(0,1fr), not a bare 1fr — a bare 1fr floors at min-content and the
       video's intrinsic width widens the page past the viewport. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 10px;
  }
  .info { padding: 11px; }
  .info__head { margin-bottom: 8px; }
  .fields { margin-bottom: 0; gap: 5px 10px; }
  .fields dd { font-size: 14px; }
}

/* Landscape phones are too short to stack: go back to side-by-side. */
@media (max-width: 768px) and (orientation: landscape) {
  .grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: 1fr; }
  .v { padding: 10px 4px; }
}
