/* ============================================================
   REQUESTS — the board

   Ported from the approved mockup. The mockup's own token block is gone (juq.css
   already defines the same values) and three class names are scoped, because
   juq.css already owns them and a literal copy would have silently inherited the
   wrong styling:

     .card  -> .rq-card    juq.css .card is the homepage card
     .chip  -> .rq-chip    juq.css .chip is the navbar live chip
     .seg   -> .u-seg      promoted to system.css; five of them across two pages

   `.dot` and `.eyebrow` are NOT scoped: those are the shared ones, and the
   mockup was drawing the site's own component.
   ============================================================ */

.rq-page { padding-bottom: var(--s-11); }

/* ---------- the tabs ----------
   Games and movies are separate boards, not a filter, so the control that
   switches them is the biggest thing on the page after the title. */
.rq-tabs { display: flex; margin: var(--s-7) 0 var(--s-6); border: var(--bw) solid var(--ink); border-radius: var(--radius); overflow: hidden; }
.rq-tabs button {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: var(--s-3);
  font-family: var(--f-display); font-size: var(--t-h3); font-weight: 700;
  padding: var(--s-5) var(--s-6); cursor: pointer;
  background: var(--surface); color: var(--muted);
  border: 0; border-right: var(--bw) solid var(--ink);
}
.rq-tabs button:last-child { border-right: 0; }
.rq-tabs button[aria-selected="true"] { background: var(--accent); color: var(--accent-ink); }

/* ---------- ask + allowance ---------- */
.rq-ask { display: grid; grid-template-columns: 1fr auto; gap: var(--s-5); margin-bottom: var(--s-5); }
.rq-field { position: relative; display: flex; align-items: center; border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface); padding: 0 var(--s-5); }
.rq-field svg { width: 16px; height: 16px; color: var(--muted); flex: none; }
.rq-field input { flex: 1; background: transparent; border: 0; outline: 0; color: var(--ink); font-family: var(--f-display); font-size: var(--t-md); padding: var(--s-5); }
.rq-field input::placeholder { color: var(--muted); }

/* Both budgets, side by side. There are two and showing only one made the other
   invisible until you hit the wall. Stated as a fraction, because a bare "4"
   invites "out of how many". */
.rq-allow { display: flex; border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface); }
.rq-allow > div { display: flex; align-items: baseline; gap: var(--s-3); padding: var(--s-4) var(--s-6); border-right: var(--bw) solid var(--line-strong); }
.rq-allow > div:last-child { border-right: 0; }
.rq-allow .val { font-family: var(--f-mono); font-size: var(--t-h3); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; }
.rq-allow .val em { font-style: normal; color: var(--accent); }
.rq-allow .val .of { color: var(--muted); }

.rq-controls { display: flex; gap: var(--s-5); flex-wrap: wrap; justify-content: space-between; margin-bottom: var(--s-6); }
.rq-arrow { font-size: var(--t-mono); }

/* ---------- the search dropdown ----------
   The box does two jobs and used to admit to neither: it live-filters the board
   AND looks up new titles to add. One list, two labelled sections, with what is
   already on the board FIRST - because "is this already requested" is the
   question you actually have, and answering it kills the duplicate at source. */
.rq-drop { position: absolute; top: calc(100% + var(--s-2)); left: 0; right: 0; z-index: 20; max-height: 340px; overflow-y: auto; border: var(--bw) solid var(--ink); border-radius: var(--radius); background: var(--surface); }
.rq-drop-h { position: sticky; top: 0; background: var(--surface-2); border-bottom: var(--bw) solid var(--line); padding: var(--s-3) var(--s-5); }
.rq-sr { display: flex; align-items: center; gap: var(--s-4); width: 100%; text-align: left; padding: var(--s-4) var(--s-5); cursor: pointer; background: transparent; border: 0; border-bottom: 1px solid var(--line); color: inherit; font: inherit; }
.rq-sr:last-child { border-bottom: 0; }
.rq-sr:hover, .rq-sr.hl { background: var(--accent-soft); }
.rq-sr-art { width: 34px; height: 46px; flex: none; border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background-size: cover; background-position: center; }
.rq-sr-i { flex: 1; min-width: 0; }
.rq-sr-t { font-size: var(--t-body); font-weight: 700; line-height: 1.2; }
.rq-sr-s { font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); }
.rq-sr-tag { font-family: var(--f-mono); font-size: var(--t-micro); letter-spacing: 0.1em; text-transform: uppercase; padding: 2px var(--s-2); border-radius: var(--radius); border: var(--bw) solid var(--line-strong); color: var(--muted); white-space: nowrap; }
.rq-sr-tag.add { border-color: var(--accent); color: var(--accent); }
.rq-drop-msg { padding: var(--s-5); color: var(--muted); font-family: var(--f-mono); font-size: var(--t-mono); }
.rq-clear { flex: none; background: transparent; border: 0; color: var(--muted); font-size: var(--t-h3); line-height: 1; cursor: pointer; padding: 0 var(--s-2); }
.rq-clear:hover { color: var(--accent); }

/* ---------- the board ---------- */
.rq-grid { display: grid; gap: var(--s-6); grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); padding-bottom: var(--s-11); }
.rq-card { display: flex; flex-direction: column; border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface); overflow: hidden; cursor: pointer; text-align: left; padding: 0; color: inherit; font: inherit; }
.rq-card:hover { border-color: var(--accent); }
.rq-card.dim .rq-shot { opacity: 0.55; }

/* Box art is 285x380 from Twitch, so the well is 3:4. */
.rq-shot { position: relative; aspect-ratio: 3 / 4; background: var(--surface-2); border-bottom: var(--bw) solid var(--line-strong); overflow: hidden; }
.rq-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rq-art { position: absolute; inset: 0; display: grid; place-items: center; padding: var(--s-5); text-align: center; }
.rq-art span { font-weight: 800; font-size: var(--t-lg); letter-spacing: -0.02em; line-height: 1.15; opacity: 0.82; }

/* The done badge carries the DATE, because "he played this" and "he played this
   in March 2024" are different facts, and the second is the one people ask. */
.rq-badge { position: absolute; left: var(--s-3); right: var(--s-3); bottom: var(--s-3); display: flex; align-items: center; gap: var(--s-2); font-family: var(--f-mono); font-size: var(--t-micro); letter-spacing: 0.08em; text-transform: uppercase; padding: var(--s-2) var(--s-3); border-radius: var(--radius); border: var(--bw) solid var(--ink); background: var(--surface); }
.rq-badge.done { background: var(--ok); color: #06210f; border-color: var(--ok); }
.rq-badge.scam { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.rq-badge .when { margin-left: auto; opacity: 0.85; letter-spacing: 0; }
/* Play count only appears once sessions are organised into named runs, the same
   rule JuqTube groups by. An unorganised game shows nothing, not a wrong number. */
.rq-plays { position: absolute; top: var(--s-3); right: var(--s-3); display: flex; align-items: center; gap: var(--s-1); font-family: var(--f-mono); font-size: var(--t-micro); font-weight: 700; padding: var(--s-1) var(--s-2); border-radius: var(--radius); border: var(--bw) solid var(--ink); background: var(--surface); color: var(--ink); }

.rq-body { padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-3); flex: 1; }
/* One line. Grid rows size to their tallest card, so one long title used to
   inflate every card in its row. */
.rq-t { font-size: var(--t-body); font-weight: 700; line-height: 1.25; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rq-by { font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); }
.rq-foot { margin-top: auto; display: flex; align-items: center; gap: var(--s-3); }
.rq-vote { display: flex; align-items: center; gap: var(--s-2); font-family: var(--f-mono); font-size: var(--t-mono); font-weight: 700; padding: var(--s-2) var(--s-4); cursor: pointer; border: var(--bw) solid var(--ink); border-radius: var(--radius); background: var(--surface-2); color: var(--ink); }
.rq-vote:hover { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.rq-vote.voted { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.rq-vote.back { border-style: dashed; }
.rq-score { margin-left: auto; display: flex; gap: var(--s-4); font-family: var(--f-mono); font-size: var(--t-mono); font-variant-numeric: tabular-nums; }
.rq-cell { text-align: right; line-height: 1.2; }
.rq-who { font-size: var(--t-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); display: block; }

/* ---------- the entry ---------- */
/* 85 is the site's modal layer, above .fx (80). It was 40 - which is below
   .fx and below the page chrome - so the entry opened UNDERNEATH everything
   and only the flying clone (60) was ever visible. It read as the popup
   animating open and then vanishing, when it had never been on top at all. */
/* ANCHORED TO THE TOP, NOT CENTRED, and that is about the flight rather than
   taste. The details load after the panel opens, so a centred box grows
   downward AND upward as they arrive - which moves the poster after the cover
   has already flown to where it used to be. It read as the animation sliding
   into place and then snapping upward.

   Top-anchored, the poster is at a fixed offset from the top of the viewport
   from the first frame, so nothing that loads later can move it. At
   max-height 86vh a tall entry fills the screen anyway, so the two only differ
   for short ones. */
.rq-lb { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.72); display: grid; justify-items: center; align-items: start; padding: 7vh var(--s-7) var(--s-7); z-index: 85; overflow-y: auto; }
.rq-lb[hidden] { display: none; }
.rq-lb-box { width: min(760px, 100%); border: var(--bw) solid var(--ink); border-radius: var(--radius); background: var(--surface); }
.rq-lb-head { display: flex; gap: var(--s-6); padding: var(--s-7); border-bottom: var(--bw) solid var(--line); }
.rq-lb-art { width: 128px; flex: none; aspect-ratio: 3/4; border: var(--bw) solid var(--line-strong); border-radius: var(--radius); display: grid; place-items: center; padding: var(--s-4); text-align: center; background-size: cover; background-position: center; }
.rq-lb-art span { font-weight: 800; font-size: var(--t-sm); opacity: 0.82; }
.rq-lb-h { flex: 1; min-width: 0; }
.rq-lb-h h2 { margin: 0 0 var(--s-3); font-size: var(--t-h2); letter-spacing: -0.02em; line-height: 1.15; }
.rq-lb-close { align-self: flex-start; background: transparent; border: 0; color: var(--muted); font-size: var(--t-h2); line-height: 1; cursor: pointer; padding: 0 var(--s-2); }
.rq-lb-close:hover { color: var(--accent); }
.rq-sec { padding: var(--s-7); border-bottom: var(--bw) solid var(--line); }
.rq-sec:last-child { border-bottom: 0; }
.rq-sec > .u-lbl { display: block; margin-bottom: var(--s-4); }
.rq-why { border-left: var(--bw) solid var(--accent); padding-left: var(--s-5); color: var(--muted); font-size: var(--t-sm); }

.rq-series { margin-bottom: var(--s-6); }
.rq-series:last-child { margin-bottom: 0; }
.rq-series-h { display: flex; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-3); }
.rq-series-h b { font-size: var(--t-md); }
.rq-ep { display: flex; align-items: center; gap: var(--s-4); padding: var(--s-4); border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface-2); font-family: var(--f-mono); font-size: var(--t-mono); margin-bottom: var(--s-2); color: inherit; text-decoration: none; }
/* It goes somewhere, so it has to look like it does. */
.rq-ep:hover { border-color: var(--accent); }
/* Pushed right by the Watch label's margin, so every duration in the list
   lines up on the same edge instead of floating after whatever the title left. */
.rq-ep .go { flex: none; margin-left: auto; font-size: var(--t-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); opacity: 0; transition: opacity 0.15s ease; }
.rq-ep:hover .go { opacity: 1; color: var(--accent); }
@media (hover: none) { .rq-ep .go { opacity: 1; } }
.rq-ep .num { color: var(--accent); font-weight: 700; }
.rq-ep .nm { color: var(--ink); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Who is in THIS episode, sitting against the end of the title so the two read
   as one line. The header above pools every guest across the whole series and
   so cannot say which episode is which. */
.rq-ep .ep-with { flex: none; color: var(--accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 44%; }
.rq-ep .dur { flex: none; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 44px; text-align: right; }
@media (max-width: 560px) { .rq-ep .ep-with { display: none; } }

/* ---------- rating ----------
   Scores are stored to a tenth, so whole-number buttons threw away precision
   the backend already keeps. Range 0.1 to 10, matching the clamp server-side. */
.rq-rt-out { display: flex; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-5); }
/* Display type, so it scales with the viewport rather than pinning to a step:
   44px is oversized on a phone. */
.rq-rt-out b { font-family: var(--f-mono); font-size: clamp(32px, 7vw, 44px); font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; }
.rq-rt-out .of { font-family: var(--f-mono); font-size: var(--t-md); color: var(--muted); }
.rq-rt-out .hint { margin-left: auto; align-self: center; }
/* Ticks at the whole numbers, so the scale you are estimating against is drawn
   rather than remembered. */
.rq-track { position: relative; height: 46px; border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface-2); cursor: pointer; touch-action: none; overflow: hidden; }
.rq-fill { position: absolute; inset: 0 auto 0 0; background: var(--accent-soft); border-right: var(--bw) solid var(--accent); pointer-events: none; }
.rq-ticks { position: absolute; inset: 0; pointer-events: none; }
.rq-ticks i { position: absolute; top: 0; bottom: 60%; width: 1px; background: var(--line-strong); }
.rq-ticks span { position: absolute; bottom: 3px; transform: translateX(-50%); font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); }
.rq-track:focus-visible { outline: var(--bw) solid var(--accent); outline-offset: 2px; }
/* Touch only. A tenth is about 1% of the track width, which a fingertip cannot
   land on, so after a touch drag sets the whole number the tenths appear as
   targets big enough to hit. Never shown to a mouse or a keyboard, where the
   track is already exact. */
.rq-fine { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.24s ease, margin 0.24s ease; margin-top: 0; }
.rq-fine.show { grid-template-rows: 1fr; margin-top: var(--s-5); }
.rq-fine > div { overflow: hidden; min-height: 0; }
.rq-fine-lbl { font-family: var(--f-mono); font-size: var(--t-micro); letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin: 0 0 var(--s-2); }
.rq-fine-row { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.rq-fine-row button { min-width: 44px; height: 44px; cursor: pointer; border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface-2); color: var(--ink); font-family: var(--f-mono); font-size: var(--t-mono); font-weight: 700; }
.rq-fine-row button.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ============================================================
   THE ENTRY, IN FULL

   Loaded after the panel opens, from IGDB for games and TMDB for movies. None
   of it is stored on our side, which is why none of it is on the board
   document - the board answers "what is on the board", this answers "what IS
   this".

   THREE TREATMENTS, NOT ONE, carried over from v1's modal because the reasoning
   is sound: a wall of identical pills is unreadable, so the kinds of fact are
   drawn differently.

     Facts    objective, about the title itself - year, runtime, genre, the
              outside world's score. Small and muted; you scan them.
     Status   ONE pill: what the BOARD knows. Requested, played, scammed.
              Loud, because it is the only one that changes.
     Ratings  their own block once done, with real numbers. Tenzin versus chat
              is the interesting part and it earns the space.
   ============================================================ */

.rq-facts { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.rq-chip {
  font-family: var(--f-mono); font-size: var(--t-micro); letter-spacing: 0.04em;
  padding: var(--s-1) var(--s-3); border-radius: var(--radius);
  border: var(--bw) solid var(--line-strong); color: var(--muted); white-space: nowrap;
}
.rq-chip.dim { opacity: 0.7; }

/* The one loud pill. It is the only thing here that can change. */
.rq-status { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; margin-top: var(--s-4); }
.rq-pill {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--f-mono); font-size: var(--t-label); letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700;
  padding: var(--s-2) var(--s-4); border-radius: var(--radius); border: var(--bw) solid currentColor;
}
.rq-pill.open { color: var(--accent); }
.rq-pill.done { color: var(--ok); }
.rq-pill.scam { color: var(--accent); background: var(--accent-soft); }

.rq-overview { color: var(--muted); font-size: var(--t-md); line-height: 1.65; margin: 0; }
.rq-overview.dim { font-style: italic; opacity: 0.75; }

/* Where to watch / Plays on. Provider chips carry their logo, because a row of
   brand marks is recognised faster than a row of names. */
/* One row per way of getting it. "Included on Peacock" and "rentable on
   YouTube" answer different questions, so they are not mixed together. */
.rq-watch-row { display: flex; align-items: baseline; gap: var(--s-5); margin-bottom: var(--s-4); flex-wrap: wrap; }
.rq-watch-row:last-of-type { margin-bottom: 0; }
.rq-watch-how { flex: none; min-width: 96px; font-family: var(--f-mono); font-size: var(--t-label); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.rq-provs { display: flex; flex-wrap: wrap; gap: var(--s-3); flex: 1; }
.rq-prov {
  display: inline-flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-4); border-radius: var(--radius);
  border: var(--bw) solid var(--line-strong); background: var(--surface-2);
  color: var(--ink); text-decoration: none; font-size: var(--t-sm); font-weight: 700;
}
.rq-prov:hover { border-color: var(--accent); color: var(--accent); }
.rq-prov img { width: 22px; height: 22px; border-radius: var(--radius); display: block; }
.rq-src { color: var(--muted); font-family: var(--f-mono); font-size: var(--t-micro); margin-top: var(--s-4); }

/* The footer: where it came from, and the two things you can do with it. */
.rq-foot-bar { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; }
.rq-foot-bar .rq-by { flex: 1; min-width: 0; }
.rq-btn {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font-family: var(--f-mono); font-size: var(--t-mono); font-weight: 700;
  padding: var(--s-3) var(--s-5); cursor: pointer;
  border: var(--bw) solid var(--line-strong); border-radius: var(--radius);
  background: var(--surface-2); color: var(--ink); text-decoration: none;
}
.rq-btn:hover { border-color: var(--accent); color: var(--accent); }
