:root {
  --blue: #3373d9;
  --pink: #e65a8c;
  --yellow: #f2c733;
  --brown: #8c5933;
  --green: #40a659;
  --purple: #8c4dbf;

  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #f3f3f6;
  --text: #16161a;
  --muted: #6b6b76;
  --line: #dcdce3;
  --accent: #4b3fa8;
  --on-accent: #ffffff;

  --font: "Nunito", ui-rounded, "SF Pro Rounded", "Varela Round", system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #121216;
    --surface: #1c1c22;
    --surface-2: #26262e;
    --text: #f2f2f6;
    --muted: #a0a0ad;
    --line: #34343e;
    --accent: #9a8ff0;
    --on-accent: #14142a;
  }
}

[data-wedge="blue"]   { --wedge: var(--blue); }
[data-wedge="pink"]   { --wedge: var(--pink); }
[data-wedge="yellow"] { --wedge: var(--yellow); }
[data-wedge="brown"]  { --wedge: var(--brown); }
[data-wedge="green"]  { --wedge: var(--green); }
[data-wedge="purple"] { --wedge: var(--purple); }

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.45;
  padding-bottom: calc(5rem + env(safe-area-inset-bottom));
}

button, select, textarea { font: inherit; color: inherit; }

:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 8px; }

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

.app-header {
  padding: calc(1.1rem + env(safe-area-inset-top)) 16px 0.5rem;
  text-align: center;
}

/* Back to /trivia/, which is the page that explains what this is. */
.app-back {
  display: inline-block;
  margin-top: 0.2rem;
  color: var(--muted);
  font-size: 0.85rem;
}

.app-header h1 {
  margin: 0;
  font-size: 1.65rem;
  font-weight: 900;
  letter-spacing: 0.2px;
}

/* ---------- play: the card ---------- */

.view { max-width: 520px; margin: 0 auto; padding: 0 24px; }

.card {
  list-style: none;
  margin: clamp(16px, 8vh, 72px) 0 0;
  padding: 0;
}

.row {
  display: flex;
  align-items: center;
  gap: 18px;
  width: 100%;
  padding: 10px 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.row:disabled { opacity: 0.4; cursor: default; }
.row:not(:disabled):active .oval { transform: scale(0.94); }

/* A real oval: an ellipse, not a pill. */
.oval {
  flex: none;
  width: 68px;
  height: 40px;
  border-radius: 50%;
  background: var(--wedge, var(--line));
  transition: transform 0.08s ease-out;
}

.oval.small { width: 44px; height: 26px; }

.name { font-size: 1.35rem; font-weight: 700; }

.status { min-height: 1.5rem; margin: 1.25rem 0 0.5rem; text-align: center; color: var(--muted); }

#retry { display: block; margin: 0 auto; }

/* ---------- categories tab ---------- */

h2 { font-size: 1.1rem; font-weight: 800; margin: 1.75rem 0 0.25rem; }

.hint { margin: 0 0 0.75rem; color: var(--muted); font-size: 0.9rem; }

.slots { display: grid; gap: 10px; }

.slot {
  display: grid;
  grid-template-columns: 44px 5.5rem 1fr;
  align-items: center;
  gap: 12px;
}

.slot label { font-weight: 700; }

select, textarea {
  width: 100%;
  padding: 10px 12px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 12px;
}

textarea { resize: vertical; }

.category-list { list-style: none; margin: 0; padding: 0; }

.category-list li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}

.cat-name { font-weight: 700; }
.muted { color: var(--muted); font-size: 0.9rem; }

/* ---------- tab bar ---------- */

.tabbar {
  position: fixed;
  inset: auto 0 0 0;
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}

.tab {
  flex: 1;
  padding: 16px 8px;
  background: none;
  border: 0;
  border-top: 3px solid transparent;
  font-weight: 800;
  color: var(--muted);
  cursor: pointer;
}

.tab[aria-current="page"] { color: var(--accent); border-top-color: var(--accent); }

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

.btn {
  padding: 13px 18px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 14px;
  font-weight: 800;
  cursor: pointer;
}

.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

.link { background: none; border: 0; padding: 6px 4px; color: var(--accent); font-weight: 800; cursor: pointer; }

/* A quiet action. Reveal is what somebody reaches for on nearly every card and
   flagging is what they reach for almost never, so the two should not carry the
   same weight: this one shrinks to a line of small text and only darkens when
   it is pointed at. It keeps a real focus ring, because being unobtrusive is
   not the same as being hard to reach from a keyboard. */
.btn-quiet {
  justify-self: center;
  margin-top: 2px;
  padding: 4px 10px;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--muted);
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
}
.btn-quiet:hover { color: var(--text); }
.btn-quiet:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- dialogs ---------- */

dialog {
  width: min(92vw, 520px);
  max-height: 90dvh;
  padding: 20px;
  background: var(--surface);
  color: var(--text);
  border: 0;
  border-radius: 22px;
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.35);
}

dialog::backdrop { background: rgb(0 0 0 / 0.5); }

#question-dialog { border-top: 10px solid var(--wedge, var(--accent)); }

.dialog-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }

.chip {
  padding: 4px 12px;
  background: var(--wedge, var(--accent));
  color: #fff;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 800;
}

.label {
  display: block;
  margin: 0 0 4px;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.q-text { margin: 0 0 16px; font-size: 1.4rem; font-weight: 700; line-height: 1.3; }

#q-answer-block hr { border: 0; border-top: 1px solid var(--line); margin: 4px 0 14px; }
.a-text { margin: 0 0 6px; font-size: 1.25rem; font-weight: 800; color: var(--accent); }
.a-text:focus { outline: none; }
.citation { margin: 0 0 8px; color: var(--muted); font-size: 0.85rem; }

.dialog-actions { display: grid; gap: 10px; margin-top: 18px; }
.row-actions { grid-template-columns: 1fr 1fr; }

#flag-title { margin: 0 0 12px; font-size: 1.2rem; }

fieldset { border: 0; margin: 0 0 14px; padding: 0; }
.choice { display: flex; align-items: center; gap: 10px; padding: 8px 0; font-weight: 600; }
.choice input { width: 1.2rem; height: 1.2rem; accent-color: var(--accent); }

/* ---------- assigning categories to wedges ---------- */

/* Every category tile is the same size wherever it sits: on a wedge or in the available
   list. Size lives on .tile, so the two only differ in what they lay out inside. */
.tile {
  display: grid;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 10px 14px;
  text-align: left;
  background: var(--surface-2);
  border: 2px solid transparent;
  border-radius: 14px;
  cursor: pointer;
}

.slot { display: block; }

/* swatch, color name, then the category */
.drop { grid-template-columns: 44px 5.5rem 1fr; border-color: var(--line); border-style: dashed; }

.drop.filled {
  background: color-mix(in srgb, var(--wedge) 12%, var(--surface));
  border-style: solid;
  border-color: color-mix(in srgb, var(--wedge) 45%, var(--line));
}

/* category, then its question count */
.cat-chip { grid-template-columns: 1fr auto; border-color: var(--line); cursor: grab; }

.category-list { display: grid; gap: 10px; }
.category-list li { display: block; padding: 0; border-bottom: 0; }
.empty-note { padding: 10px 2px; }

/* Picked up and waiting for a destination. */
.tile.picked {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent);
}

/* While a drag is in flight, every place the tile could land gets a faint outline, so the
   choices are visible before the pointer reaches one. The available list only joins in when
   the tile came off a wedge, since dropping an unassigned category there does nothing. */
body.dragging .tile:not(.is-dragging) { outline: 2px dashed color-mix(in srgb, var(--accent) 35%, transparent); outline-offset: 2px; }
body.dragging.from-wedge #category-list { outline: 2px dashed color-mix(in srgb, var(--accent) 35%, transparent); outline-offset: 6px; border-radius: 16px; }

/* The one under the pointer, which is the tile that would actually receive the drop. The
   selector needs two classes to outrank .drop.filled, which otherwise wins on specificity
   and leaves an occupied wedge looking untouched. */
.tile.drop-over,
body.dragging .tile.drop-over {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
  border-style: solid;
  background: color-mix(in srgb, var(--accent) 18%, var(--surface));
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* A filled wedge under the pointer is about to give up its category, so say so. */
.tile.drop-over.filled .cat-name { text-decoration: line-through; opacity: 0.65; }

/* Must outrank the faint advertise rule above, which carries an id plus two classes. */
#category-list.drop-over,
body.dragging.from-wedge #category-list.drop-over {
  outline: 3px solid var(--accent);
  outline-offset: 6px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.is-dragging { opacity: 0.4; }

/* The tile that follows the pointer. Its width is set inline from the tile it came from,
   so it keeps that size rather than shrinking to its text. */
.drag-ghost {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  min-height: 56px;
  /* Floats a row above the pointer rather than centered on it, so the tile being targeted
     stays visible underneath; the ghost is the same width as a tile and would cover it. */
  margin: -78px 0 0 -40px;
  padding: 10px 14px;
  font-weight: 700;
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  color: var(--text);
  border: 2px solid var(--accent);
  border-radius: 14px;
  box-shadow: 0 10px 28px rgb(0 0 0 / 0.3);
  pointer-events: none;
}

/* While dragging, stop the gesture turning into a text selection or a page scroll. */
body.dragging { user-select: none; touch-action: none; }
body.dragging .cat-chip { cursor: grabbing; }

@media (prefers-reduced-motion: no-preference) {
  .tile { transition: border-color 120ms, background-color 120ms, box-shadow 120ms; }
}

/* Narrow screens: drop the color word so the category keeps the room it needs. */
@media (max-width: 30rem) {
  .drop { grid-template-columns: 44px 1fr; }
  .slot-color { display: none; }
}

/* ---------- page entry ---------- */

/* The document starts transparent and fades up once this stylesheet has applied,
   so a late stylesheet or a swapping webfont never shows as a flash of unstyled
   text. Same half second the main site uses, so every page on the domain enters
   the same way, and it is skipped for anyone who has asked for less motion.

   Deliberately no animation-fill-mode: forwards. The last keyframe is opacity 1,
   which is the resting value anyway, so forwards changes nothing when the
   animation runs. When it does not run it is the whole difference between a page
   that is simply there and a page pinned at opacity 0 with nothing on it, which
   is where an extension that pauses animations would leave it. */
body {
  animation: fadeIn 0.5s ease-in;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  body { animation: none; }
}
