/* ============================================================================
   THE GOLDEN — grader primitives.
   Component names come from design_handoff_the_golden_build/COMPONENTS.md.
   Class names are that component name, kebab-cased, under a `gr-` prefix:
       PrimaryAction → .gr-primary-action        RubricLevel → .gr-rubric-level

   ⚠ NO RAW VALUES. Every colour, size, radius, shadow, duration and easing in
   this file is a var() from grader-tokens.css. The only literals permitted are
   structural zeroes and 100%/1fr-class layout keywords, which are not design
   decisions. `tools/grader-tokens-only.js` enforces this and fails the build.

   ⚠ STATE IS CLASS-DRIVEN, not just pseudo-class driven. /dev/components has to
   render nine states side by side, and :hover/:focus cannot be forced. Every
   state therefore has an `.is-*` class, and the live pseudo-classes delegate to
   the same declarations. Never style a state in one place only.
   ========================================================================= */

/* ══ base ═════════════════════════════════════════════════════════════════ */

.gr-root {
  background: var(--sub);
  color: var(--text);
  font-family: var(--f-u);
  font-size: var(--t-ui-md);
  font-weight: 450;
  -webkit-font-smoothing: antialiased;
}
.gr-root *, .gr-root *::before, .gr-root *::after { box-sizing: border-box; }

/* Depth tiers. NEVER applied to an ancestor of the stage — a filter on an
   ancestor creates a containing block and desaturates the student's work. */
.gr-near { filter: var(--near); }
.gr-mid  { filter: var(--mid); }
.gr-far  { filter: var(--far); }

/* Grain — chrome only. Never over the stage, a photograph or a waveform. */
.gr-grain { position: relative; }
.gr-grain > .gr-grain-layer {
  position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background-image: var(--grain); opacity: var(--grain-opacity);
}

/* ══ the frame mark ═══════════════════════════════════════════════════════
   Four corner brackets. One motif, one meaning: THIS IS THE ACTIVE THING.
   At most one per region; three on screen is the ceiling.
   Arms and inset are passed as custom properties so one class serves every
   size in the token file. */

.gr-fm { position: absolute; inset: var(--fm-i, var(--fm-inset)); pointer-events: none; }
.gr-fm > i {
  position: absolute; width: var(--fm-a, var(--fm-arm-md)); height: var(--fm-a, var(--fm-arm-md));
  border: 0 solid var(--fm-c, var(--fm-color));
}
.gr-fm > i:nth-child(1) { top: 0; left: 0;  border-top-width: var(--fm-stroke); border-left-width: var(--fm-stroke);  border-top-left-radius: var(--fm-radius); }
.gr-fm > i:nth-child(2) { top: 0; right: 0; border-top-width: var(--fm-stroke); border-right-width: var(--fm-stroke); border-top-right-radius: var(--fm-radius); }
.gr-fm > i:nth-child(3) { bottom: 0; left: 0;  border-bottom-width: var(--fm-stroke); border-left-width: var(--fm-stroke);  border-bottom-left-radius: var(--fm-radius); }
.gr-fm > i:nth-child(4) { bottom: 0; right: 0; border-bottom-width: var(--fm-stroke); border-right-width: var(--fm-stroke); border-bottom-right-radius: var(--fm-radius); }

/* ══ PrimaryAction ════════════════════════════════════════════════════════
   The ONLY emissive element on screen. Disabled drops it out of the emissive
   class entirely — no gold anywhere. */

.gr-primary-action {
  position: relative; display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: var(--sp-1); padding: var(--sp-6) var(--sp-8); border: 0; border-radius: var(--r-2xl);
  background: var(--gold); box-shadow: var(--gold-in), var(--contact), var(--bloom);
  color: #1c1710; font-family: var(--f-d); font-weight: 700; font-size: 13.5px;
  cursor: pointer; transition: transform var(--dur-press) var(--ease-standard),
                              box-shadow var(--dur-raise) var(--ease-standard),
                              background var(--dur-raise) var(--ease-standard);
}
.gr-primary-action .gr-sub { font-size: 10.5px; font-weight: 450; color: rgba(26,22,12,.62); font-variant-numeric: tabular-nums; }
/* ⚠ OPEN QUESTION — the keycap's FILL is not specified anywhere. COMPONENTS.md
   names the keycap ("keycap ⌘↵") and the design source discusses keycaps in
   prose, but no file gives it a background. Rendered UNFILLED rather than
   inventing a value, per the handoff's rule. It still reads as a keycap from
   the mono face and the glyph. Awaiting a ruling. */
.gr-primary-action .gr-keycap {
  margin-left: var(--sp-4); padding: 0 var(--sp-2); border-radius: var(--r-xs);
  font-family: var(--f-n); font-size: var(--t-mono-md); opacity: .62;
}
.gr-primary-action:hover, .gr-primary-action.is-hover { filter: brightness(1.02); }
.gr-primary-action:active, .gr-primary-action.is-pressed {
  transform: translateY(1.5px); box-shadow: inset 0 2px 4px rgba(0,0,0,.5);
}
.gr-primary-action.is-saved { background: var(--pass); box-shadow: var(--gold-in), var(--contact); }

/* ══ RubricLevel ══════════════════════════════════════════════════════════
   Rest = INSET, so it reads as machined into the card.
   Selected = RAISED, and the level dot gains its luminosity. */

.gr-rubric-level {
  position: relative; display: flex; align-items: center; gap: var(--sp-5);
  width: 100%; padding: var(--sp-5) var(--sp-6); border: 0; border-radius: var(--r-xl);
  background: var(--ctl); box-shadow: var(--ctl-in);
  color: var(--text3); font-family: var(--f-u); font-size: var(--t-ui-sm); text-align: left;
  cursor: pointer; transition: background var(--dur-base) var(--ease-standard),
                              box-shadow var(--dur-base) var(--ease-standard);
}
.gr-rubric-level .gr-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none; opacity: .55;
  transition: opacity var(--dur-base) var(--ease-standard);
}
.gr-rubric-level[data-level="exceeds"]     .gr-dot { background: var(--pass); }
.gr-rubric-level[data-level="meets"]       .gr-dot { background: var(--k3200); }
.gr-rubric-level[data-level="approaching"] .gr-dot { background: var(--k4300); }
.gr-rubric-level[data-level="beginning"]   .gr-dot { background: var(--fail); }
.gr-rubric-level.is-selected {
  background: var(--ctl-up); box-shadow: var(--edge-hi), var(--edge-un), var(--contact); color: var(--text);
}
.gr-rubric-level.is-selected .gr-dot { opacity: 1; }
.gr-rubric-level[data-level="exceeds"].is-selected     .gr-dot { box-shadow: var(--lum-pass); }
.gr-rubric-level[data-level="meets"].is-selected       .gr-dot { box-shadow: var(--lum-gold); }
.gr-rubric-level[data-level="approaching"].is-selected .gr-dot { box-shadow: var(--lum-gold); }
.gr-rubric-level[data-level="beginning"].is-selected   .gr-dot { box-shadow: var(--lum-fail); }

/* ══ CommentField ═════════════════════════════════════════════════════════ */

.gr-comment-field-wrap { position: relative; }
.gr-comment-field {
  display: block; width: 100%; min-height: 70px; padding: var(--sp-5) var(--sp-6);
  border: 0; border-radius: var(--r-xl); background: #0e1012;
  box-shadow: inset 0 1px 3px rgba(0,0,0,.6), inset 0 0 0 1px #1f2226;
  color: var(--text2); font-family: var(--f-u); font-size: var(--t-ui-sm); resize: vertical;
  transition: box-shadow var(--dur-fast) var(--ease-standard);
}
.gr-comment-field::placeholder { color: var(--dim); }
.gr-comment-field:focus { outline: none; }

/* ══ SuggestedLine ════════════════════════════════════════════════════════ */

.gr-suggested-line {
  position: relative; display: block; width: 100%;
  padding: var(--sp-3) var(--sp-5); border: 0; border-radius: var(--r-md);
  background: var(--ctl); box-shadow: var(--ctl-in);
  color: var(--muted); font-family: var(--f-u); font-size: var(--t-ui-xxs);
  text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer; transition: background var(--dur-fast) var(--ease-standard);
}

/* ══ QueueRow ═════════════════════════════════════════════════════════════
   Active = raised + frame mark. NEVER an outline. */

.gr-queue-row {
  position: relative; display: flex; align-items: center; gap: var(--sp-5);
  width: 100%; padding: var(--sp-4) var(--sp-5); border: 0; border-radius: var(--r-lg);
  background: transparent; box-shadow: none; color: var(--text3);
  font-family: var(--f-u); font-size: var(--t-ui-xs); text-align: left;
  cursor: pointer; transition: background var(--dur-base) var(--ease-standard),
                              box-shadow var(--dur-base) var(--ease-standard);
}
.gr-queue-row .gr-row-name { flex: 1; font-family: var(--f-d); font-size: var(--t-display-xs); letter-spacing: var(--t-display-xs-ls); }
.gr-queue-row .gr-row-score { font-family: var(--f-n); font-size: var(--t-mono-lg); letter-spacing: var(--t-mono-lg-ls); color: var(--k9000); font-variant-numeric: tabular-nums; }
.gr-queue-row.is-active {
  background: var(--panel-hi); box-shadow: var(--edge), var(--edge-un), var(--contact); color: var(--text);
}

/* ══ TierSegment / TierControl ════════════════════════════════════════════ */

.gr-tier-control { display: inline-flex; gap: var(--sp-1); padding: var(--sp-1); border-radius: var(--r-2xl); background: var(--ctl); box-shadow: var(--ctl-in); }
.gr-tier-segment {
  position: relative; min-width: 66px; padding: var(--sp-3) var(--sp-6);
  border: 0; border-radius: var(--r-lg); background: transparent; box-shadow: none;
  color: var(--muted); font-family: var(--f-u); font-size: var(--t-ui-xs);
  cursor: pointer; transition: background var(--dur-quick) var(--ease-standard),
                              box-shadow var(--dur-quick) var(--ease-standard),
                              color var(--dur-quick) var(--ease-standard);
}
.gr-tier-segment .gr-seg-sub { display: block; font-family: var(--f-n); font-size: var(--t-mono-xs); letter-spacing: var(--t-mono-xs-ls); color: var(--k12000); }
.gr-tier-segment.is-active {
  background: var(--ctl-up); box-shadow: var(--edge-hi), var(--contact); color: var(--k3200);
}

/* ══ SHARED STATE MATRIX ══════════════════════════════════════════════════
   Nine states, identical treatment on every component. Declared once here so
   the six matrix components cannot drift apart.
   `.gr-s` marks a component as participating. */

/* Hover — face lifts ~2%. NO geometry change, no shadow change, no movement. */
.gr-s:hover:not(.is-disabled), .gr-s.is-hover:not(.is-disabled) { filter: brightness(1.02); }

/* Focus — frame mark + 1px warm inner ring. Identical everywhere, never
   replaced by a browser outline, never suppressed. */
.gr-s:focus-visible, .gr-s.is-focus {
  outline: none; box-shadow: inset 0 0 0 1px var(--k3200-line), var(--ctl-in);
}
.gr-comment-field:focus-visible, .gr-comment-field.is-focus {
  box-shadow: inset 0 1px 3px rgba(0,0,0,.6), inset 0 0 0 1px var(--k3200-line);
}

/* Active — the operative element in its region. One per region. */
.gr-s.is-active { background: var(--ctl-up); box-shadow: var(--edge-hi), var(--edge-un), var(--contact); color: var(--text); }

/* ⚠ PrimaryAction is EMISSIVE IN EVERY STATE BUT ONE. The shared active and
   selected rules above swap the face to control material, which silently
   un-golds the only emissive element on screen — caught rendering the matrix,
   where the `active` cell came out grey. COMPONENTS.md is explicit that
   DISABLED is the single state that "drops it out of the emissive class
   entirely — no gold anywhere". Everything else keeps the gold. */
.gr-primary-action.is-active, .gr-primary-action.is-selected {
  background: var(--gold); box-shadow: var(--gold-in), var(--contact), var(--bloom); color: #1c1710;
}
.gr-primary-action.is-focus { box-shadow: var(--gold-in), var(--contact), var(--bloom), inset 0 0 0 1px var(--k3200-line); }
.gr-primary-action.is-error { box-shadow: var(--gold-in), var(--contact), inset 0 0 0 1px var(--fail-line); }
.gr-primary-action.is-loading { box-shadow: var(--gold-in), var(--contact); }

/* Pressed — goes DOWN into the panel. */
.gr-s:active:not(.is-disabled), .gr-s.is-pressed {
  transform: translateY(1.5px); box-shadow: inset 0 2px 4px rgba(0,0,0,.5);
}

/* Selected — raised like active but WITHOUT the mark: it holds a value, but it
   is not where the keys are going. */
.gr-s.is-selected { background: var(--ctl-up); box-shadow: var(--edge-hi), var(--edge-un), var(--contact); color: var(--text); }

/* Disabled — drops to substrate. It stops being an object. */
.gr-s.is-disabled {
  background: linear-gradient(var(--lit), #1a1c1f, #161719) !important;
  box-shadow: none !important; color: #4d5157 !important;
  cursor: default; pointer-events: none; transform: none !important;
}
.gr-s.is-disabled .gr-dot { background: #4d5157 !important; box-shadow: none !important; opacity: 1; }
.gr-s.is-disabled .gr-sub, .gr-s.is-disabled .gr-keycap { color: #4d5157; background: transparent; }

/* Loading — face desaturates and a determinate hairline runs the bottom edge.
   NO SPINNER ANYWHERE IN THE PRODUCT. */
.gr-s.is-loading { filter: saturate(.88); }
.gr-s.is-loading::after {
  content: ''; position: absolute; left: 0; bottom: 0; height: 1.5px; width: 42%;
  border-bottom-left-radius: inherit; background: var(--k3200);
}

/* Error — a ring and a dot. Never a red fill behind text, never a red border
   on a whole panel. */
.gr-s.is-error { box-shadow: inset 0 0 0 1px var(--fail-line), var(--ctl-in); }
.gr-s.is-error::before {
  content: ''; position: absolute; top: 50%; right: var(--sp-5); transform: translateY(-50%);
  width: 7px; height: 7px; border-radius: 50%; background: var(--fail); box-shadow: var(--lum-fail);
}

/* ══ supporting primitives ════════════════════════════════════════════════ */

/* StatusDot — 7px. Circle when graded/current, 2px-radius square otherwise. */
.gr-status-dot { width: 7px; height: 7px; border-radius: var(--fm-radius); flex: none; }
.gr-status-dot.is-round { border-radius: 50%; }
.gr-status-dot[data-status="graded"]   { background: var(--pass);  box-shadow: var(--lum-pass); border-radius: 50%; }
.gr-status-dot[data-status="current"]  { background: var(--k3200); box-shadow: var(--lum-gold); border-radius: 50%; }
.gr-status-dot[data-status="flagged"]  { background: var(--k4300); box-shadow: var(--lum-gold); }
.gr-status-dot[data-status="waiting"]  { background: #2b2e33; }
.gr-status-dot[data-status="late"]     { background: var(--k4300); }
.gr-status-dot[data-status="missing"]  { background: var(--fail);  box-shadow: var(--lum-fail); }
.gr-status-dot[data-status="excused"]  { background: var(--k12000); }
.gr-status-dot[data-status="returned"] { background: var(--pass-dim); }
.gr-status-dot[data-status="overridden"] { background: var(--k2700); }

/* AvatarTile — 22px. Crew = a 2×2 tile grid. That grid is the ONLY difference
   between a crew row and a student row. */
.gr-avatar-tile {
  width: 22px; height: 22px; border-radius: var(--r-md); flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--ctl); box-shadow: var(--ctl-in);
  font-family: var(--f-n); font-size: 8.5px; color: var(--k7500);
}
.gr-avatar-tile.is-crew { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-1); padding: var(--sp-2); }
.gr-avatar-tile.is-crew > i { border-radius: 1.5px; background: var(--k12000); }

/* RoleSlot — D director, C camera, A audio, E editor, T talent. */
.gr-role-slot {
  width: 11px; height: 11px; border-radius: 3px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: #141618; box-shadow: inset 0 1px 1px rgba(0,0,0,.55);
  font-family: var(--f-n); font-size: 6.8px; color: var(--k9000);
}
.gr-role-slot.is-active { background: var(--ctl-up); box-shadow: var(--edge); color: var(--k3200); }

/* ExceptionMark — one glyph, never a second line of tag text, or crew rows
   grow taller than student rows. */
.gr-exception-mark { width: 6px; height: 6px; border-radius: 1px; background: transparent; box-shadow: inset 0 0 0 1.5px var(--k4300); flex: none; }

/* ScoreInstrument — NOT a donut. A recessed rail with a needle. */
.gr-score-instrument { position: relative; height: 38px; border-radius: var(--r-md); background: #0c0e0f; box-shadow: inset 0 2px 4px rgba(0,0,0,.8), inset 0 -1px 0 rgba(255,255,255,.025); }
.gr-score-instrument .gr-tick { position: absolute; bottom: 12px; width: 1px; background: #33373d; height: 6px; }
.gr-score-instrument .gr-tick.is-major { height: 11px; background: #4a4f56; }
.gr-score-instrument .gr-tick-label { position: absolute; bottom: 1px; transform: translateX(-50%); font-family: var(--f-n); font-size: 7.5px; color: var(--k12000); }
.gr-score-instrument .gr-needle {
  position: absolute; bottom: 9px; width: 3px; height: 20px; border-radius: 1px; margin-left: -1.5px;
  background: var(--gold); box-shadow: var(--gold-in), 0 1px 3px rgba(0,0,0,.6), var(--bloom);
  transition: left .34s var(--ease-settle);
}
.gr-score-instrument .gr-ghost { position: absolute; bottom: 11px; width: 2px; height: 16px; border-radius: 1px; margin-left: -1px; background: var(--k2700); opacity: .85; }

/* CriterionCard */
.gr-criterion-card { position: relative; padding: var(--sp-7) var(--sp-7) var(--sp-6); border-radius: var(--r-3xl); background: var(--panel-hi); box-shadow: var(--edge), var(--edge-un), var(--contact); }
.gr-criterion-name { font-family: var(--f-d); font-weight: 700; font-size: var(--t-display-lg); letter-spacing: var(--t-display-lg-ls); color: var(--text); }

/* MarkedSummary — the collapsed row of already-marked criteria. */
.gr-marked-summary { display: flex; align-items: center; gap: var(--sp-5); padding: var(--sp-4) var(--sp-6); border-radius: var(--r-xl); background: var(--ctl); box-shadow: var(--ctl-in), inset 0 0 0 1px var(--pass-line); color: var(--text3); font-size: var(--t-ui-xs); }

/* SkipButton */
.gr-skip-button { padding: var(--sp-5) var(--sp-7); border: 0; border-radius: var(--r-xl); background: var(--ctl); box-shadow: var(--ctl-in); color: var(--text3); font-family: var(--f-u); font-size: var(--t-ui-sm); cursor: pointer; position: relative; }

/* Stage — true neutral. NO grain, NO filter, NO gradient, NO cool cast. */
.gr-stage { position: relative; padding: var(--sp-6); background: var(--n-surround); }
.gr-stage-frame { position: absolute; inset: var(--sp-6); border-radius: var(--r-2xl); background: var(--n-stage); border: 1px solid var(--n-edge); }
.gr-stage-meta { font-family: var(--f-n); font-size: var(--t-mono-sm); letter-spacing: var(--t-mono-sm-ls); color: var(--n-faint); font-variant-numeric: tabular-nums; }

/* Mustang rule — 3px × 12px section rules ONLY, never a fill. */
.gr-mustang-rule { width: 12px; height: 3px; background: var(--mustang); border-radius: 1px; flex: none; }
