:root {
  --bg: #16130f;
  --panel: #221d17;
  --line: #3a3128;
  --text: #e8dcc8;
  --muted: #a8977c;
  --accent: #d4a24c;
  --error: #e07a5f;
}

* { box-sizing: border-box; }

/* .overlay sets display, which would otherwise win over the hidden attribute */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.4 system-ui, sans-serif;
}

header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
}

h1 { margin: 0; font-size: 20px; color: var(--accent); }
.brand { display: inline-flex; align-items: center; gap: 10px; flex: none; }
.brand img { display: block; flex: none; }
#status, #results-head { color: var(--muted); }
#status { min-width: 0; overflow-wrap: anywhere; }
#logout { margin-left: auto; flex: none; }

@media (max-width: 560px) {
  #status { order: 1; flex-basis: 100%; }
}

/* The page is exactly the window's height: the search bar across the top, then the player,
   its picture centred in what the column leaves, and right of it the results, which scroll in
   their own box so the player stays where it is. */
body { display: flex; flex-direction: column; height: 100dvh; }
header { flex: none; }

main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(340px, 36%);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "search search" "player found";
  gap: 12px 16px;
  padding: 12px 16px 16px;
  flex: 1;
  min-height: 0;
}

#search { grid-area: search; min-width: 0; }
#player { grid-area: player; }
#found { grid-area: found; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
#results-head { flex: none; margin: 0 0 6px; }
#results-box { flex: 1; min-height: 120px; overflow: auto; }

/* the bar, one panel of two rows: the picker and the chosen search's fields (one form shows
   at a time) over their hint line; then, under a divider, the Version Filter with its
   checkboxes beside it when open */
#search {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 8px 10px;
}
#search-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
#search-bar form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 0 8px; }
#search-bar form label { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
/* one line, so no hint changes the bar's height (and so the picture's); the whole text is
   its title */
#search-note { margin: 4px 2px 0; min-height: 1.4em; white-space: nowrap; overflow: hidden;
               text-overflow: ellipsis; }
#version-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
}
#versions { flex: 1 1 auto; min-width: 0; }

@media (max-width: 900px) {
  /* one column: the page scrolls as a whole again; the results come before the player, still
     in their box */
  body { height: auto; }
  main {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    grid-template-areas: "search" "found" "player";
  }
  #results-box { flex: none; max-height: 60vh; }
  #search-note { white-space: normal; }
  /* scrolled to (startPlay does), the player is exactly the window's height */
  #player { height: calc(100dvh - 32px); }
}

input, button, select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 4px 6px;
  font: inherit;
}

input[type=number] { width: 80px; }
#name { width: 320px; max-width: 100%; }
#pos { width: 160px; font-variant-numeric: tabular-nums; }
#creature-name { width: 240px; max-width: 100%; }
#item { width: 280px; max-width: 100%; }
#spell { max-width: 100%; }
input:invalid { border-color: var(--error); }
button { cursor: pointer; }
button:hover:not(:disabled) { border-color: var(--accent); }
button:disabled, select:disabled { opacity: 0.5; cursor: default; }

#version-list { display: flex; flex-wrap: wrap; gap: 4px 12px; }
#version-list label.unplayable { color: var(--muted); }

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 4px 6px; border-bottom: 1px solid var(--line); }
th { color: var(--muted); font-weight: normal; }
tbody tr { cursor: pointer; }
tbody tr:hover { background: var(--panel); }
tbody tr.unplayable { cursor: default; color: var(--muted); }
/* the recording playing (markPlaying), kept while the pointer is elsewhere; the accent bar
   is the first cell's, as a box-shadow on a row is unreliable with collapsed borders */
tbody tr.playing { background: var(--panel); }
tbody tr.playing td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
tbody tr.playing td.name { color: var(--accent); }
td.name { word-break: break-all; }
td.windows button { padding: 0 4px; margin: 0 2px 2px 0; }
#results.stale { opacity: 0.5; }

#pager { display: flex; gap: 8px; margin-top: 8px; }

/* The player column: the client, whose own bar has the playback controls, takes the space
   the error line leaves, so the whole picture stays in view (setupCanvas fits it to #screen). */
#player {
  min-width: 0;
  min-height: 0;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
/* a load or map-scale failure, one line above the client */
#player-error { flex: none; margin: 0 0 6px; }
#screen {
  position: relative;
  flex: 1 1 0;                  /* its size is the column's, never the picture's, */
  min-height: 0;                /* so the picture cannot push the column's height */
  overflow: auto;               /* only below the picture's minimum (camfind.js) */
  display: flex;
}
/* centred; margin rather than align/justify, so a picture under the minimum starts at the
   top-left and scrolls instead of being cut */
#canvas-scroll { margin: auto; }
/* Clip the untransformed layout box (the Client size) to the displayed footprint. The border
   is the footprint's, off the canvas, so its logical drawing size and pointer origin agree. */
#canvas-footprint { overflow: hidden; border: 1px solid var(--line); box-sizing: content-box; }

#canvas {
  display: block;
  background: #000;
  transform-origin: top left;
  touch-action: none;
}

#canvas:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* the loading screens: over the whole page until the index is ready, and over the
   player while a recording loads */
.overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(22, 19, 15, 0.92);
  z-index: 10;
}

.overlay.page { position: fixed; z-index: 20; }

.overlay .box {
  width: min(460px, 100%);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 16px;
}

.overlay .box h1 { margin-bottom: 10px; }
.overlay p { margin: 0 0 10px; }
.overlay p:last-child { margin-bottom: 0; }
.overlay progress { width: 100%; margin: 0 0 10px; accent-color: var(--accent); }
.note { color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }
.error { color: var(--error); }

/* the login page (login.html): the index screen's box, with a form in it */
#login { display: flex; flex-direction: column; gap: 4px; }
#login label { color: var(--muted); margin-top: 6px; }
#login button { margin-top: 12px; align-self: flex-start; }
#login-error { margin: 10px 0 0; }
#login .note { margin: 10px 0 0; }

/* the reference list: a section heading, then a restoration per <details> with its
   readings, each a time button (greyed, without one, when camfind cannot play it) */
#references h3 { margin: 12px 0 2px; }
#references details { margin: 2px 0; }
#references summary { cursor: pointer; overflow-wrap: anywhere; }
#references ul { margin: 2px 0 6px; padding-left: 20px; list-style: none; }
#references li { margin: 1px 0; overflow-wrap: anywhere; }
#references li button { padding: 0 4px; margin-right: 4px; }
#references li.unplayable { color: var(--muted); }
#references li.playing { color: var(--accent); }   /* a reading of the recording playing */
#references.stale { opacity: 0.5; }
