/* ============================================================================
   grader-shell.css — the frame that NEVER CHANGES between item types.
   Names from COMPONENTS.md §1. Tokens only; tools/grader-tokens-only.js guards.

   THE INVARIANT THIS FILE EXISTS TO HOLD: the nav, the rail, the score panel
   and the footer are identical for a photograph, a video and a question set.
   Only the centre column changes. If a pane ever needs to move something out
   here, the pane is wrong.
   ========================================================================= */

/* ── GraderShell ──────────────────────────────────────────────────────────── */
.gr-shell {
  position: relative; display: flex; flex-direction: column;
  height: 100%; min-height: 0; border-radius: var(--r-5xl); overflow: hidden;
  background: var(--sub);
  box-shadow: var(--edge), inset 0 0 0 1px #1c1e21, var(--contact), 0 34px 76px -30px rgba(0,0,0,.85);
}

/* ── GraderNav — FAR depth tier ───────────────────────────────────────────── */
.gr-nav {
  display: flex; align-items: center; gap: var(--sp-7);
  height: 58px; padding: 0 var(--sp-8); flex: none;
  background: linear-gradient(var(--lit), #111315, #0b0d0e);
  box-shadow: var(--edge), inset 0 -1px 0 rgba(0,0,0,.6);
  filter: var(--far);
}
.gr-nav-title { font-family: var(--f-d); font-weight: 700; font-size: var(--t-display-md); letter-spacing: var(--t-display-md-ls); color: var(--text); }
.gr-nav-meta  { font-family: var(--f-n); font-size: var(--t-mono-sm); letter-spacing: var(--t-mono-sm-ls); color: var(--k9000); }
.gr-nav-spacer { flex: 1; }
.gr-queue-back, .gr-type-glyph {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5); border: 0; border-radius: var(--r-lg);
  background: var(--ctl); box-shadow: var(--ctl-in);
  color: var(--text3); font-family: var(--f-u); font-size: var(--t-ui-xs); cursor: pointer; position: relative;
}
.gr-type-glyph { font-family: var(--f-n); font-size: var(--t-mono-md); letter-spacing: var(--t-mono-md-ls); color: var(--k7500); cursor: default; }

/* ── GraderGrid ───────────────────────────────────────────────────────────── */
.gr-grid { display: grid; grid-template-columns: 204px 1fr 320px; flex: 1; min-height: 0; }

/* ── QueueRail — MID depth tier ───────────────────────────────────────────── */
.gr-rail {
  position: relative; display: flex; flex-direction: column; min-height: 0;
  background: var(--panel-lo); box-shadow: inset -1px 0 0 rgba(0,0,0,.55);
  filter: var(--mid);
}
.gr-rail-head { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-6) var(--sp-6) var(--sp-4); }
.gr-rail-list { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--sp-4) var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-1); }
.gr-queue-filter {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5); border-radius: var(--r-lg);
  font-family: var(--f-d); font-weight: 600; font-size: var(--t-display-sm); color: var(--text2);
}
.gr-queue-progress { padding: var(--sp-5) var(--sp-6) var(--sp-4); }
.gr-progress-count { font-family: var(--f-d); font-weight: 700; font-size: var(--t-display-xl); letter-spacing: var(--t-display-xl-ls); color: var(--text); font-variant-numeric: tabular-nums; }
.gr-progress-unit  { font-family: var(--f-n); font-size: var(--t-mono-sm); letter-spacing: var(--t-mono-sm-ls); color: var(--k9000); }
.gr-pips { display: flex; gap: var(--sp-1); padding: var(--sp-1); border-radius: var(--r-xs); background: #0d0e10; box-shadow: inset 0 1px 2px rgba(0,0,0,.6); margin-top: var(--sp-4); }
.gr-pip { flex: 1; height: 3px; border-radius: 1px; background: #2b2e33; }
.gr-pip.is-done    { background: var(--pass);  box-shadow: var(--lum-pass); }
.gr-pip.is-current { background: var(--k3200); box-shadow: var(--lum-gold); }
.gr-rail.is-crew .gr-pip { height: 4px; }
.gr-pace { font-family: var(--f-n); font-size: var(--t-mono-sm); letter-spacing: var(--t-mono-sm-ls); color: var(--k9000); padding: 0 var(--sp-6) var(--sp-5); }

/* ── StageColumn — NO grain, NO filter, NO gradient, NO cool cast ─────────── */
.gr-stagecol {
  position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0;
  background: var(--n-surround); padding: var(--sp-4) var(--sp-10) var(--sp-7);
}
.gr-stagecol-body { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
/* ⚠ The Stage primitive carries NO intrinsic size — it is padding plus an
   absolutely-positioned frame, so on its own it collapses to 22×22 (the
   padding). /dev/components hid this by giving it a sized box; the shell did
   not, and the centre column rendered empty. The stage IS the centre column,
   so it fills it. */
.gr-stagecol-body > .gr-stage { width: 100%; height: 100%; }

/* ── ScorePanel — NEAR tier ───────────────────────────────────────────────── */
.gr-panel {
  position: relative; display: flex; flex-direction: column; min-height: 0;
  background: var(--panel); box-shadow: inset 1px 0 0 rgba(255,255,255,.03);
}
.gr-panel-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: var(--sp-7) var(--sp-8) var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-7); }
.gr-panel-footer {
  flex: none; display: flex; align-items: center; gap: var(--sp-5);
  padding: var(--sp-6) var(--sp-8) var(--sp-7);
  background: linear-gradient(var(--lit), #121416, #0d0f10);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.035);
}
.gr-panel-footer .gr-primary-action { flex: 1; }

/* ── tier disclosure — the mechanism that holds the control budget ────────── */
/* Anything above the current tier is REMOVED from the DOM, not hidden. A
   hidden control still counts against the budget the moment someone tabs to
   it, and countControls() would be lying. */
.gr-tier-only { display: contents; }

/* ── save state — unmistakable, and never a spinner ───────────────────────── */
.gr-savestate {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  font-family: var(--f-n); font-size: var(--t-mono-sm); letter-spacing: var(--t-mono-sm-ls);
}
.gr-savestate[data-state="saved"]    { color: var(--pass-dim); }
.gr-savestate[data-state="saving"]   { color: var(--k9000); }
.gr-savestate[data-state="unsaved"]  { color: var(--k4300); }
.gr-savestate[data-state="failed"]   { color: var(--fail); }
.gr-savestate .gr-status-dot { width: 7px; height: 7px; }

/* ── shortcut overlay ─────────────────────────────────────────────────────── */
.gr-shortcuts {
  position: absolute; inset: 0; z-index: 10; display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.62);
}
.gr-shortcuts-card {
  min-width: 420px; padding: var(--sp-9); border-radius: var(--r-4xl);
  background: var(--panel-hi); box-shadow: var(--edge), var(--edge-un), var(--float);
}
.gr-shortcuts-card h3 { font-family: var(--f-d); font-weight: 700; font-size: var(--t-display-lg); letter-spacing: var(--t-display-lg-ls); color: var(--text); margin: 0 0 var(--sp-6); }
.gr-sc-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-9); padding: var(--sp-3) 0; }
.gr-sc-row span { font-size: var(--t-ui-xs); color: var(--text3); }
.gr-sc-keys { display: flex; gap: var(--sp-2); }
.gr-sc-key {
  min-width: 20px; padding: var(--sp-1) var(--sp-3); border-radius: var(--r-xs); text-align: center;
  background: var(--ctl); box-shadow: var(--ctl-in);
  font-family: var(--f-n); font-size: var(--t-mono-md); letter-spacing: var(--t-mono-md-ls); color: var(--k5600);
}

/* ── laptop 1280 ──────────────────────────────────────────────────────────── */
@media (max-width: 1400px) {
  .gr-grid { grid-template-columns: 176px 1fr 292px; }
  .gr-nav  { height: 54px; padding: 0 var(--sp-7); gap: var(--sp-6); }
  .gr-stagecol { padding: var(--sp-3) var(--sp-9) var(--sp-6); }
  .gr-tier-segment { min-width: 58px; }
  .gr-tier-segment .gr-seg-sub { display: none; }
}

/* ── TraversalFlip ──────────────────────────────────────────────────────────
   Sits in the rail head beside the filter. Present only on panes that have
   items to traverse — see the note at its render site. */
.gr-traversal-flip {
  margin-left: auto; padding: var(--sp-1) var(--sp-4); border: 0; border-radius: var(--r-sm);
  background: var(--ctl); box-shadow: var(--ctl-in);
  color: var(--k3200); font-family: var(--f-n); font-size: var(--t-mono-sm);
  letter-spacing: var(--t-mono-sm-ls); cursor: pointer; position: relative;
}

/* ── a queue row that names a QUESTION, not a person ───────────────────────
   A student row is one short name and stays one line. An item row carries the
   question itself, because "Q3" identifies nothing when four questions in the
   set open the same way — so it is allowed to wrap to three lines and the row
   grows with it. */
.gr-rail-list .gr-queue-row .gr-queue-name,
.gr-rail-list .gr-queue-row .gr-row-name {
  white-space: normal; overflow: visible; text-overflow: clip;
  line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* The number under the instrument. It is the score about to be written, so it
   is read at a glance and never competes with the stage for attention. */
.gr-score-note {
  margin-top: var(--sp-2);
  text-align: center;
  font-family: var(--f-u);
  font-size: var(--t-mono-xs);
  letter-spacing: var(--t-mono-xs-ls);
  text-transform: uppercase;
  color: var(--muted);
}
/* Partly marked is a REFUSAL at save, so it is warned about here, in the one
   place a teacher is already looking before they press it. */
.gr-score-note.is-partial { color: var(--fail); }

/* The breath between a criterion's name and its levels. Was an inline style. */
.gr-rubric-gap { height: var(--sp-5); }

/* An assignment with no rubric. Stated, never faked. */
.gr-rubric-none {
  font-family: var(--f-u); font-size: var(--t-ui-sm);
  color: var(--muted); padding: var(--sp-5) 0;
}

/* The way back out of the end-of-section screen. */
.gr-fin-back { display: flex; justify-content: center; padding: var(--sp-6) 0 var(--sp-8); }

/* ══ SITTING IN THE APP, NOT ON TOP OF IT ═══════════════════════════════════
   The grader used to render as a floating dark card — full radius, a 34/76px
   drop shadow — inside a light page it shared nothing else with. It now wears
   the platform's own page chrome (.page-head-row / .page-h1 / .page-sub, the
   same markup the gradebook returns) and fills the content column.

   ⚠ THE STAGE STAYS DARK ON PURPOSE. Everything around the work is native and
   light; the panel the photograph or video actually sits in is not, because
   judging exposure against a white surround skews how you read it. That is why
   every serious photo tool does the same. */
.gr-page { display: flex; flex-direction: column; gap: var(--sp-5); min-height: 0; }
.gr-page .page-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-5); }
.gr-page-actions { display: flex; gap: var(--sp-3); }
.gr-page-btn {
  font-family: var(--f-u); font-size: var(--t-ui-sm); cursor: pointer;
  padding: var(--sp-3) var(--sp-5); border-radius: var(--r-sm);
  background: transparent; color: var(--muted); border: 1px solid var(--edge-un);
}
.gr-page-btn:hover { color: var(--text); border-color: var(--edge); }

/* Fill the column instead of floating in it. */
.gr-page .gr-shell {
  border-radius: var(--r-md);
  box-shadow: var(--edge), inset 0 0 0 1px #1c1e21, var(--contact);
  height: auto; min-height: 62vh;
}

/* ══ TYPE A SCORE ═══════════════════════════════════════════════════════════
   The override. It sits under the instrument because that is where the number
   it replaces already is — a teacher who disagrees with the rubric total looks
   there first. Marks are kept when this is used, so the student still gets the
   per-criterion feedback; this changes the grade, not the record of why. */
.gr-typed {
  margin-top: var(--sp-4); display: flex; align-items: center;
  justify-content: space-between; gap: var(--sp-4);
}
.gr-typed-lab {
  font-family: var(--f-u); font-size: var(--t-mono-xs); letter-spacing: var(--t-mono-xs-ls);
  text-transform: uppercase; color: var(--muted);
}
.gr-typed-wrap { display: flex; align-items: baseline; gap: var(--sp-2); }
.gr-typed-score {
  width: 4.5rem; text-align: right;
  font-family: var(--f-n); font-size: var(--t-display-xs); letter-spacing: var(--t-display-xs-ls);
  color: var(--text); background: var(--panel-lo);
  border: 1px solid var(--edge-un); border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
}
.gr-typed-score:focus { outline: none; border-color: var(--gold); color: var(--lit); }
.gr-typed-score::placeholder { color: var(--faint); }
/* The spinners are noise on a score field and steal the arrow keys. */
.gr-typed-score::-webkit-outer-spin-button,
.gr-typed-score::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.gr-typed-score { -moz-appearance: textfield; appearance: textfield; }
.gr-typed-of {
  font-family: var(--f-n); font-size: var(--t-mono-sm); letter-spacing: var(--t-mono-sm-ls);
  color: var(--muted);
}
