/* Design tokens. Everything below composes from these - no ad-hoc values, so
   spacing and colour stay consistent as the UI grows. */
:root {
  --bg: #0d1017;
  --surface: #151922;
  --surface-2: #1b202b;
  --surface-3: #222836;
  --line: #262d3b;
  --line-strong: #333c4e;

  --fg: #e8ebf2;
  --fg-dim: #a3adc0;
  --fg-faint: #717d92;

  --accent: #4f9cf9;
  --accent-ink: #06101f;
  --confident: #22c55e;
  --borderline: #f59e0b;
  --danger: #f87171;

  --s1: 4px;  --s2: 8px;   --s3: 12px;
  --s4: 16px; --s5: 24px;  --s6: 32px;

  --r1: 5px; --r2: 7px; --r3: 10px;
  --shadow: 0 8px 28px rgba(0, 0, 0, .45);
  --focus: 0 0 0 2px var(--accent-ink), 0 0 0 4px var(--accent);
  --head-h: 52px;
  --foot-h: 30px;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font: 13px/1.5 ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.muted { color: var(--fg-dim); }
.small, .hint { font-size: 11.5px; }
.hint { color: var(--fg-faint); }
.spacer { flex: 1; }

kbd {
  font: 500 10px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--surface-3); border: 1px solid var(--line-strong);
  border-bottom-width: 2px; border-radius: var(--r1);
  padding: 1px 4px; color: var(--fg-dim);
}

/* ------------------------------------------------------------------ buttons */

button {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-3); color: var(--fg);
  border: 1px solid var(--line-strong); border-radius: var(--r2);
  padding: 6px 11px; font: inherit; font-weight: 500; cursor: pointer;
  transition: background .12s, border-color .12s, opacity .12s;
  white-space: nowrap;
}
button:hover:not(:disabled) { background: #2a3143; border-color: #3f4a60; }
button:active:not(:disabled) { transform: translateY(.5px); }
button:disabled { opacity: .38; cursor: not-allowed; }
button:focus-visible, input:focus-visible, .tab:focus-visible { outline: none; box-shadow: var(--focus); }

button.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
button.primary:hover:not(:disabled) { background: #6aabfa; border-color: #6aabfa; }
button.primary:disabled { background: var(--surface-3); border-color: var(--line-strong); color: var(--fg); }
button.ghost { background: transparent; border-color: transparent; color: var(--fg-dim); }
button.ghost:hover:not(:disabled) { background: var(--surface-3); color: var(--fg); }
button.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* ------------------------------------------------------------------- header */

header {
  display: flex; align-items: center; gap: var(--s3);
  height: var(--head-h); padding: 0 var(--s4);
  border-bottom: 1px solid var(--line); background: var(--surface);
}
.brand { display: flex; align-items: baseline; gap: var(--s2); }
h1 { font-size: 13.5px; font-weight: 650; margin: 0; letter-spacing: -.1px; }
.brand .hint { letter-spacing: .3px; text-transform: uppercase; font-size: 9.5px; }

.upload span {
  display: inline-flex; align-items: center;
  background: var(--surface-3); border: 1px solid var(--line-strong);
  border-radius: var(--r2); padding: 6px 11px; cursor: pointer; font-weight: 500;
}
.upload span:hover { background: #2a3143; border-color: #3f4a60; }

#docinfo { color: var(--fg-dim); font-size: 11.5px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; max-width: 340px; }

.modes { display: flex; gap: var(--s1); background: var(--surface-2);
  padding: 3px; border-radius: var(--r2); border: 1px solid var(--line); }
.modes button { border-color: transparent; background: transparent; padding: 5px 10px; }
.modes button:hover:not(.on) { background: var(--surface-3); }
/* Undo/redo sit in a modes-style group but are actions, not a mode: nothing here
   is ever `.on`, and a spent stack greys out rather than disappearing so the
   pair does not shift position as you work. */
.modes.history button:disabled { opacity: .35; cursor: default; background: transparent; }

/* -------------------------------------------------------------------- stage */

main { display: flex; height: calc(100% - var(--head-h)); }

#stage { position: relative; flex: 1; overflow: hidden; background: #090c12; min-width: 280px; }
#canvas { position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; }
#canvas.panning { cursor: grab; }

#hint, #busy {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  color: var(--fg-dim); background: rgba(21, 25, 34, .95);
  padding: var(--s3) var(--s4); border: 1px solid var(--line);
  border-radius: var(--r3); pointer-events: none; box-shadow: var(--shadow);
}
#busy { display: flex; align-items: center; gap: var(--s2); }
.spin {
  width: 13px; height: 13px; border-radius: 50%; flex: none;
  border: 2px solid var(--line-strong); border-top-color: var(--accent);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }


#grip { width: 5px; cursor: col-resize; background: var(--line); flex: none; transition: background .12s; }
#grip:hover, #grip.dragging { background: var(--accent); }

/* --------------------------------------------------------------- pages */

/* The page bar sits over the canvas rather than in the header: it belongs to the
   drawing, and it appears and disappears with one. */
#pagestrip {
  position: absolute; top: var(--s2); left: var(--s2); right: var(--s2); z-index: 6;
  display: flex; gap: var(--s1); overflow-x: auto; padding: var(--s1);
  background: rgba(21, 25, 34, .92); border: 1px solid var(--line);
  border-radius: var(--r2); backdrop-filter: blur(3px);
}
.pagechip {
  flex: none; padding: 4px 10px; font-size: 11.5px; font-weight: 600;
  background: transparent; border-color: transparent; color: var(--fg-dim);
}
.pagechip:hover:not(.on) { background: var(--surface-3); color: var(--fg); }
.pagechip.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.pc {
  margin-left: 5px; padding: 0 5px; border-radius: 999px;
  font-size: 10px; font-weight: 700; line-height: 15px;
}
/* under review vs confirmed - the same two meanings the tabs use */
.pc.found { background: var(--borderline); color: #2b1a00; }
.pc.done { background: var(--confident); color: #04220f; }
.pagechip.on .pc { box-shadow: 0 0 0 1px rgba(0, 0, 0, .25); }

/* A page heading inside the review and confirmed lists. Sticky, because the
   whole point is knowing which sheet you are reading while you scroll. */
.pagehead {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; gap: var(--s2);
  margin: var(--s2) 0 var(--s1); padding: 5px var(--s2);
  background: var(--surface-2); border: 1px solid var(--line);
  border-left: 3px solid var(--fg-faint); border-radius: var(--r1);
  cursor: pointer; font-size: 11px;
}
.pagehead:hover { border-left-color: var(--accent); }
.pagehead.here { border-left-color: var(--accent); background: var(--surface-3); }
.pagehead b { color: var(--fg); font-weight: 600; letter-spacing: .02em; }
.pagehead span {
  margin-left: auto; color: var(--fg-faint); font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ page picker */

#picker {
  position: absolute; inset: 0; z-index: 22;
  display: flex; align-items: center; justify-content: center;
  background: rgba(9, 12, 18, .72); backdrop-filter: blur(2px);
}
.picker-card {
  width: min(760px, 92%); max-height: 86%; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r3); box-shadow: var(--shadow); padding: var(--s4);
}
.picker-head { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s3); }
#picker-title { font-weight: 600; font-size: 13.5px; }
.picker-grid {
  flex: 1; min-height: 0; overflow-y: auto;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: var(--s2); padding: var(--s1);
}
/* A page cell is a toggle, so it reads as pressed rather than merely highlighted */
.pcell {
  display: block; padding: var(--s1); border-radius: var(--r2);
  background: var(--surface-2); border: 2px solid var(--line);
  cursor: pointer; text-align: center;
}
.pcell:hover { border-color: var(--line-strong); }
.pcell.on { border-color: var(--accent); background: rgba(79, 156, 249, .12); }
.pcell img {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: contain;
  background: #fff; border-radius: var(--r1);
}
.pcell .pcap { display: block; margin-top: 4px; font-size: 11.5px; font-weight: 600; color: var(--fg-dim); }
.pcell.on .pcap { color: var(--fg); }
.pcell .pmeta { display: block; font-size: 10px; color: var(--fg-faint); }
.picker-foot { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s3); }

/* ------------------------------------------------------------- name dialog */

#namer {
  position: absolute; inset: 0; z-index: 20;
  display: flex; align-items: center; justify-content: center;
  background: rgba(9, 12, 18, .62); backdrop-filter: blur(2px);
}
.namer-card {
  width: 340px; background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r3); box-shadow: var(--shadow); padding: var(--s4);
}
.namer-head { display: flex; gap: var(--s3); align-items: center; margin-bottom: var(--s3); }
.namer-head img {
  width: 76px; height: 52px; object-fit: contain; flex: none;
  background: #fff; border-radius: var(--r1); border: 1px solid var(--line-strong);
}
#namer-title { font-weight: 600; font-size: 13.5px; }
.namer-known { display: flex; flex-wrap: wrap; gap: var(--s1); margin-bottom: var(--s3); }
.namer-known:empty { display: none; }
.namer-chip {
  background: var(--surface-2); border: 1px solid var(--line-strong);
  border-radius: 999px; padding: 5px 11px; font-size: 12px;
}
.namer-chip.preferred { border-color: var(--accent); background: rgba(79, 156, 249, .12); }
.namer-chip .hint { margin-left: 5px; }
.namer-new { margin-bottom: var(--s3); }
.field-label { color: var(--fg-dim); font-size: 11px; font-weight: 500;
  margin: var(--s3) 0 var(--s1); letter-spacing: .2px; }

/* --------------------------------------------------------- colour picker */

.swatches { display: flex; flex-wrap: wrap; gap: var(--s1); }
.swatch-btn {
  width: 26px; height: 26px; padding: 0; border-radius: var(--r2);
  border: 2px solid transparent; box-shadow: 0 0 0 1px var(--line-strong) inset;
}
.swatch-btn:hover:not(:disabled) { transform: scale(1.08); }
.swatch-btn.chosen { border-color: var(--fg); box-shadow: 0 0 0 2px var(--bg) inset; }
.swatch-btn.taken { opacity: .3; }
.swatch-btn.taken::after { content: ''; }
/* Every colour spoken for: they unlock, so they must stop looking unavailable.
   Full strength, carrying how many symbols already wear it - a fact about the
   drawing, not a reason you cannot pick it.

   The count sits on its own dark disc rather than directly on the swatch. The
   palette is ten vivid colours spanning red to blue at L* 41-60, so no single
   ink colour reads on all of them; a fixed disc does. */
.swatch-btn.reused { position: relative; }
.swatch-btn.reused::after {
  content: attr(data-count);
  position: absolute; inset: 0; margin: auto;
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--bg); color: var(--fg);
  font-size: 10px; font-weight: 700; line-height: 15px;
  text-align: center; letter-spacing: 0;
}
.swatches.small .swatch-btn { width: 18px; height: 18px; border-width: 2px; }

/* -------------------------------------------------------------- symbols */

.symcard {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s2); border-radius: var(--r2);
  border: 1px solid var(--line); border-left: 3px solid var(--row);
  margin-bottom: var(--s2); background: var(--surface-2);
}
.symcard img {
  width: 64px; height: 44px; object-fit: contain; flex: none;
  background: #fff; border-radius: var(--r1); cursor: pointer;
}
.symcard img.blank { background: var(--surface-3); cursor: default; }
.symcard .symmain { flex: 1; min-width: 0; }
.symcard .symname { font-weight: 600; font-size: 13px; }
.symcard .swatches { margin-top: var(--s1); }
.symcard > button { padding: 3px 8px; flex: none; }
.namer-foot { display: flex; align-items: center; gap: var(--s2); }

/* -------------------------------------------------------------------- panel */

#panel {
  width: 400px; flex: none; background: var(--surface);
  display: flex; flex-direction: column; overflow: hidden;
  border-left: 1px solid var(--line);
}

.tabs { display: flex; flex: none; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.tab {
  flex: 1; border: none; border-radius: 0; background: none; color: var(--fg-faint);
  padding: 10px 6px; font-weight: 600; font-size: 12px;
  border-bottom: 2px solid transparent; justify-content: center;
}
.tab:hover:not(.on) { background: var(--surface-3); color: var(--fg-dim); }
.tab.on { color: var(--fg); border-bottom-color: var(--accent); background: var(--surface); }
.badge {
  min-width: 18px; padding: 0 5px; border-radius: 999px; background: var(--surface-3);
  color: var(--fg-dim); font-size: 10.5px; font-weight: 600; line-height: 16px;
}
.tab.on .badge { background: var(--accent); color: var(--accent-ink); }
.badge:empty { display: none; }
.badge.flash { animation: flash .8s ease-out 2; }
@keyframes flash { 50% { background: var(--confident); color: var(--accent-ink); } }

.pane { display: none; flex-direction: column; min-height: 0; flex: 1; }
.pane.on { display: flex; }
.pane-head { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); flex: none; }
.pane-head p { margin: 0; }
.pane-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--s2); }
.pane-foot {
  flex: none; display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--s4); border-top: 1px solid var(--line); background: var(--surface-2);
}

.pane-body::-webkit-scrollbar { width: 10px; }
.pane-body::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 99px; border: 3px solid var(--surface); }
.pane-body::-webkit-scrollbar-thumb:hover { background: var(--line-strong); }

.empty { color: var(--fg-faint); font-size: 12px; text-align: center; padding: var(--s6) var(--s4); margin: 0; }
.empty b { display: block; color: var(--fg-dim); font-weight: 600; margin-bottom: var(--s1); }

/* ------------------------------------------------------------------- inputs */

.field { display: block; }
.field span { display: block; color: var(--fg-dim); font-size: 11px; font-weight: 500;
  margin-bottom: var(--s1); letter-spacing: .2px; }
.field input {
  width: 100%; padding: 7px 10px; border-radius: var(--r2);
  border: 1px solid var(--line-strong); background: var(--bg); color: var(--fg); font: inherit;
}
.field input::placeholder { color: var(--fg-faint); }
.field input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus); }

.slider { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s3); }
.slider label { color: var(--fg-dim); font-size: 11px; font-weight: 500; flex: none; }
.slider input[type=range] { flex: 1; accent-color: var(--accent); }
output { font-variant-numeric: tabular-nums; color: var(--fg-dim); font-size: 11.5px; min-width: 28px; text-align: right; }

#searchinfo { margin-top: var(--s2); color: var(--fg-dim); font-size: 11.5px; }

.chips { display: flex; flex-wrap: wrap; gap: var(--s1); }
.chips:empty { display: none; }
.chip {
  display: inline-flex; align-items: center;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px 10px; font-size: 11.5px; color: var(--fg-dim);
}
.chip b { color: var(--fg); font-weight: 600; margin-left: 4px; }
.chip button { border: none; background: none; padding: 0 0 0 5px; color: var(--fg-faint); }
.chip button:hover { color: var(--danger); background: none; }

.note {
  margin-top: var(--s3); padding: var(--s2) var(--s3); border-radius: var(--r2);
  background: rgba(245, 158, 11, .1); border: 1px solid rgba(245, 158, 11, .35);
  color: #f5cf8e; font-size: 11.5px; display: flex; align-items: center; gap: var(--s2);
}
.note span { flex: 1; }
.note button { padding: 3px 9px; font-size: 11px; flex: none; }
.note.clipped { background: rgba(248, 113, 113, .1); border-color: rgba(248, 113, 113, .35); color: #f3b0b0; }

/* -------------------------------------------------------------------- cards */

.card {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s2); border: 1px solid transparent; border-radius: var(--r2); cursor: pointer;
}
.card:hover { background: var(--surface-2); border-color: var(--line); }
.card.active { background: var(--surface-2); border-color: var(--accent); }
.card img {
  width: 76px; height: 50px; object-fit: contain; flex: none;
  background: #fff; border-radius: var(--r1);
}
.card .meta { min-width: 0; flex: 1; }
.card input[type=checkbox] { flex: none; width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
.card .tier { font-weight: 600; }
.card .tier.seed { color: var(--accent); }
.card .tier.confident { color: var(--confident); }
.card .tier.borderline { color: var(--borderline); }
/* a maybe the user vouched for: in the review list on their say-so, not the
   engine's, so it reads as its own thing rather than borrowing "confident" */
.card .tier.accepted { color: var(--accent); }
.card .also { flex: none; opacity: 0; padding: 3px 8px; font-size: 11px; transition: opacity .12s; }
.card:hover .also, .card.active .also { opacity: 1; }

.tagin {
  width: 100%; background: transparent; border: 1px solid transparent;
  border-radius: var(--r1); color: var(--fg); font: inherit; padding: 2px 5px;
}
.tagin::placeholder { color: var(--fg-faint); }
.tagin:hover { border-color: var(--line-strong); }
.tagin:focus { outline: none; border-color: var(--accent); background: var(--bg); }
/* A tag Detect proposed rather than one you typed. Marked, not hidden: it is
   here to be checked, and on a drawing whose lettering had to be recognised
   rather than read it is the only cue that a character might be wrong. The mark
   goes the moment you edit the field. */
.tagin.suggested { border-bottom: 1px dashed var(--accent); border-radius: 0; }

/* A tag admitted only because it is the closest lettering to the symbol - the
 * position is trustworthy, the characters are not. It reuses the same amber the
 * Maybes tab uses for borderline matches, so "look at this one" means the same
 * thing everywhere in the app. */
.tagin.suggested.doubtful { border-bottom-color: var(--borderline); border-bottom-width: 2px; }

.swatch {
  display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin-right: 5px; flex: none; box-shadow: 0 0 0 1px rgba(255, 255, 255, .22);
}

/* --------------------------------------------------------------------- list */

.krow {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2); border-radius: var(--r2);
  border: 1px solid transparent; border-left: 3px solid var(--row, transparent);
}
.krow:hover { background: var(--surface-2); border-color: var(--line); border-left-color: var(--row); }
.krow img {
  width: 54px; height: 36px; object-fit: contain; flex: none;
  background: #fff; border-radius: var(--r1); cursor: pointer;
}
.krow .kmain { flex: 1; min-width: 0; }
.krow .kname { color: var(--fg-dim); font-size: 10.5px; display: flex; align-items: center; gap: 5px; }
.krow button { padding: 3px 7px; font-size: 11px; flex: none; }
/* the row whose box is selected on the drawing */
.krow.picked { background: var(--surface-2); border-color: var(--accent); }
.krow.flash { animation: rowflash 1.5s ease-out; }
@keyframes rowflash { 0%, 40% { background: rgba(79, 156, 249, .2); } }

.pill {
  font-size: 9px; font-weight: 700; letter-spacing: .5px; padding: 1px 5px;
  border-radius: var(--r1); background: var(--surface-3); color: var(--fg-dim);
}
.pill.manual { background: rgba(79, 156, 249, .18); color: #9fc7fb; }
.pill.waiting {
  background: rgba(245, 158, 11, .18); color: #f5cf8e;
  border: none; padding: 1px 6px; cursor: pointer;
}
.pill.waiting:hover { background: rgba(245, 158, 11, .3); }
.card .pill.manual { margin-right: 5px; }

/* --------------------------------------------------------------- status bar */

#statusbar {
  height: var(--foot-h); flex: none; display: flex; align-items: center; gap: var(--s3);
  padding: 0 var(--s4); border-top: 1px solid var(--line);
  background: var(--surface-2); color: var(--fg-faint); font-size: 11px;
}
#statusbar .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-faint); }
#statusbar .dot.live { background: var(--confident); }
/* what the selected box can be done with; brighter than the rest of the bar
   because it appears in response to an action and then goes away again */
#statusbar #st-pick { color: var(--fg); }
#statusbar #st-pick::before { content: '·'; margin-right: var(--s3); color: var(--fg-faint); }

/* ------------------------------------------------------------------- toasts */

#toasts {
  position: fixed; bottom: var(--s4); left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: var(--s2); z-index: 40; pointer-events: none;
}
.toast {
  background: var(--surface); border: 1px solid var(--line-strong); border-left: 3px solid var(--accent);
  border-radius: var(--r2); padding: var(--s2) var(--s3); box-shadow: var(--shadow);
  font-size: 12px; display: flex; align-items: center; gap: var(--s2);
  animation: rise .18s ease-out;
}
.toast.warn { border-left-color: var(--borderline); }
.toast.bad { border-left-color: var(--danger); }
.toast button { pointer-events: auto; padding: 2px 8px; font-size: 11px; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }
