/* ================================================================
   INSTRUCTOR-REVIEW.CSS — the instructor feedback mode's page:
   the two-door chooser, the question browser, and the graph pane.
   Markup in index.html #page-instructor-review; logic in
   instructor-review.js. The topbar badge stays in account-menu.css
   (it is topbar chrome, not this page).
   ================================================================ */

.ir-container { max-width: 1100px; }

/* ── the reading measure ─────────────────────────────────────────────
   985px, centred — the SAME measure "Why this app exists" sets on its
   own container (styles/how-it-works.css). Seth, 2026-08-27: reviewing
   a question is reading, and it was being done at the width of a
   dashboard. Everything prose-shaped rides this measure.

   NOT the graph view, which is why the measure lives on these three
   children and not on `.ir-container` above them: #ir-graph escapes the
   container entirely (`position: fixed`, full-bleed under the topbar —
   see the graph pane block below), and an inspector wants every pixel
   for the same reason prose does not. */
.ir-head,
#ir-chooser,
#ir-questions {
  margin-left: auto;
  margin-right: auto;
  max-width: 985px;
}

.ir-head {
  align-items: baseline;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  margin-bottom: 18px;
}
.ir-head h1 { margin: 0; }
.ir-head .subtitle { flex: 1 1 auto; margin: 0; }

/* ── chooser: two doors, same posture as the welcome fork ────────── */
.ir-chooser {
  display: flex;
  gap: 20px;
  margin-top: 24px;
}
.ir-door {
  background: var(--panel, transparent);
  border: 1px solid var(--border);
  border-radius: 18px;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  font: inherit;
  gap: 10px;
  padding: 32px 26px;
  text-align: left;
  transition: border-color 120ms ease, transform 120ms ease;
}
.ir-door:hover,
.ir-door:focus-visible {
  border-color: var(--accent, currentColor);
  transform: translateY(-2px);
}
.ir-door-title { font-size: 1.25rem; font-weight: 600; }
.ir-door-note { font-size: 0.95rem; line-height: 1.45; opacity: 0.7; }

/* ── shared bits ─────────────────────────────────────────────────── */
.ir-hint { font-size: 0.9rem; opacity: 0.65; }
.ir-pill {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: inherit;
  cursor: pointer;
  font: inherit;
  font-size: 0.88rem;
  padding: 5px 13px;
}
.ir-pill:hover { border-color: var(--accent, currentColor); }
.ir-pill--on { border-color: var(--accent, currentColor); font-weight: 600; }
.ir-topics,
.ir-subtopics { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.ir-subtopics:empty { margin: 0; }

.ir-flag--on { border-color: var(--accent, currentColor); font-weight: 600; }

/* ── question cards ──────────────────────────────────────────────── */
.ir-q {
  background: var(--panel, transparent);
  border: 1px solid var(--border);
  border-radius: 14px;
  margin: 0 0 14px;
  padding: 16px 18px;
}
.ir-q-head {
  display: flex;
  flex-wrap: wrap;
  font-size: 0.85rem;
  gap: 12px;
  margin-bottom: 8px;
  opacity: 0.75;
}
.ir-q-id { font-weight: 600; }
/* Reading size, a step down from the 20px the explainer pages set: the
   question is the prose on this card, but a card also carries a header,
   three code disclosures and a flag row, and 20px made those read as
   footnotes to it. */
.ir-q-text {
  font-size: 18px;
  line-height: 1.7;
  margin-bottom: 10px;
  white-space: pre-wrap;
}
.ir-q-details { margin: 6px 0; }
.ir-q-details > summary { cursor: pointer; font-size: 0.88rem; opacity: 0.75; }
.ir-q-details > pre {
  background: var(--bg, rgba(0, 0, 0, 0.25));
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.85rem;
  margin: 6px 0 0;
  overflow-x: auto;
  padding: 10px 12px;
  white-space: pre;
}
.ir-q-flags {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 8px;
}
.ir-q-status,
.ir-form-status { font-size: 0.85rem; opacity: 0.8; }
/* The note is where the review actually is — "what's wrong with this
   problem" is a paragraph, not a label. So: opens at four lines instead
   of one, grows itself from there (autogrow.js), and sits on a prose
   measure rather than the full width of the card.

   `resize: none` + `overflow-y: hidden` are the two halves of "the box
   is always exactly as tall as the text". The drag handle is gone
   because a self-sizing box can only be dragged wrong, and the
   scrollbar is gone because the height is measured to make it
   unnecessary — if autogrow ever failed, hiding it would hide text, so
   that pairing is deliberate and load-bearing, not decoration. */
.ir-q-note {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-sizing: border-box;
  color: inherit;
  display: block;
  font: inherit;
  font-size: 17px;
  line-height: 1.6;
  /* ~4 lines: an empty note that already looks like somewhere to write
     a paragraph. autogrow never sets a height below this — min-height
     wins over the height it assigns. */
  min-height: 132px;
  max-width: 68ch;
  overflow-y: hidden;
  padding: 10px 12px;
  resize: none;
  width: 100%;
}

/* ── graph pane: FULL-BLEED, hosting the real lesson map ──────────
   Seth, 2026-08-27: the graph door should "cover the whole screen, or not
   the whole screen, still leaving like the top bar".

   So #ir-graph leaves the page's 1100px container and pins itself under the
   topbar. It has to be `position: fixed` rather than a tall block, because
   what lands inside it is `.kg-container.kg2` — a Cytoscape canvas that sizes
   itself from its box — and a box that ends at the fold is a map that ends at
   the fold. `--dd-topbar-h` is the one source for the bar's height
   (styles/layout.css); the inset reads it rather than repeating 44px.

   z-index 40 sits UNDER the topbar (50) and the nav drawer (110/120) on
   purpose: this covers the page, not the app's chrome. */
#ir-graph:not(.hidden) {
  background: var(--bg);
  inset: var(--dd-topbar-h) 0 0 0;
  position: fixed;
  z-index: 40;
}
body.ir-kg-open { overflow: hidden; }

.ir-kg {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
}

/* The instructor's own strip. Everything a learner gets — Fit, the
   Mastery/Lessons switch, the lesson pane — arrives inside the hosted graph;
   only flagging belongs to this file. */
.ir-kg-bar {
  align-items: center;
  border-bottom: 1px solid var(--border);
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  gap: 10px 12px;
  padding: 8px 14px;
}
.ir-kg-hint { flex: 1 1 240px; min-width: 0; }
/* Reads as a target, not a label: it names the concept it will file against. */
#ir-flag-concept:disabled { cursor: default; opacity: 0.45; }

.ir-kg-frame {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  position: relative;
}
/* Qualified by #page-instructor-review for SPECIFICITY, not scope — the same
   trick styles/why-map.css documents for its own host. The Knowledge Graph's
   `.kg-container` becomes a descendant of `.ir-container` the moment it is
   moved in, and would otherwise keep that container's 1100px measure and
   render the map into a slice of the screen. */
#page-instructor-review .ir-kg-frame.is-hosting-kg > .kg-container {
  inset: 0;
  margin: 0;
  max-width: none;
  overflow: auto;
  padding: 0;
  position: absolute;
  width: auto;
}
.ir-graph-status {
  left: 50%;
  opacity: 0.7;
  position: absolute;
  text-align: center;
  top: 50%;
  transform: translate(-50%, -50%);
}

/* ── the ✛ handle ─────────────────────────────────────────────────
   Cytoscape draws to a canvas, so there is no DOM per node to hang this off:
   instructor-graph-edit.js positions it from the node's rendered box and
   re-places it on pan, zoom and drags. It lives in `.kg2-graph`, the overlay
   layer the Fit control and the legend already sit in, so it inherits that
   stacking context.

   z-index 4: OVER the canvas, UNDER `.kg2-controls` and `.kg2-legend` (both 5
   in styles/how-it-works.css). Those are the graph's own furniture, one half
   of it clickable — a handle that landed on the Fit button or the
   Mastery/Lessons switch and swallowed the press would break the map for the
   sake of an instructor affordance. Overlap is rare (top-right and
   bottom-left corners); when it happens the fixed control wins. The dock
   (z-index 20) is above both, and a node under it is hidden anyway.

   `translate(-50%, -115%)` hangs it just clear of the node's TOP edge, which
   is the edge Seth asked for and — under dagre's rankDir BT — the side the
   things a concept unlocks are drawn on. */
.ir-handle {
  align-items: center;
  background: #3ddc84;
  border: none;
  border-radius: 999px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
  color: #10331f;
  cursor: crosshair;
  display: flex;
  font-size: 15px;
  font-weight: 700;
  height: 26px;
  justify-content: center;
  line-height: 1;
  padding: 0;
  position: absolute;
  touch-action: none;   /* the drag is ours; a phone must not pan the page with it */
  transform: translate(-50%, -115%);
  width: 26px;
  z-index: 4;
}
.ir-handle:hover { filter: brightness(1.12); }

/* The rubber band during a ✛ drag. Never a hit target — a pointer test
   against it would shadow the bubble the instructor is aiming at. */
.ir-band {
  height: 100%;
  left: 0;
  pointer-events: none;
  position: absolute;
  top: 0;
  width: 100%;
  z-index: 3;
}

/* ── the inspector ────────────────────────────────────────────────
   RIGHT-hand side, per Seth ("it should show the information about it on the
   right, and you should be able to have the options on the right sidebar").

   It OVERLAYS the hosted graph's lesson pane rather than taking a third
   column. The pane is the reason tapping a bubble is worth doing, and the map
   is the thing being reviewed — a permanent third column would have made the
   network the narrowest panel on the screen. An edge has no lesson behind it,
   so for the selection that needs this room the pane underneath has nothing
   to say anyway; closing the inspector hands it straight back.

   `:not(.hidden)` because `.hidden { display: none }` (components.css) has the
   same specificity as a bare `.ir-insp`, and which one won would then depend
   on stylesheet order. */
.ir-insp:not(.hidden) { display: flex; }
.ir-insp {
  backdrop-filter: blur(6px);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  border-left: 1px solid var(--border-strong);
  bottom: 0;
  flex-direction: column;
  position: absolute;
  right: 0;
  top: 0;
  width: min(360px, 42%);
  /* Above the learner-model dock (z-index 20 in styles/how-it-works.css),
     which is opaque and would otherwise cut this panel off at its top edge. */
  z-index: 30;
}
.ir-insp-head {
  align-items: center;
  border-bottom: 1px solid var(--border);
  display: flex;
  flex: 0 0 auto;
  font-size: 0.85rem;
  justify-content: space-between;
  letter-spacing: 0.04em;
  opacity: 0.75;
  padding: 9px 12px;
  text-transform: uppercase;
}
.ir-insp-x {
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 2px 4px;
}
.ir-insp-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  overflow-y: auto;
  padding: 14px;
}
.ir-insp-title { font-size: 1.05rem; font-weight: 600; line-height: 1.35; }
.ir-arrow { opacity: 0.6; }
.ir-insp-label {
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  margin-top: 4px;
  opacity: 0.6;
  text-transform: uppercase;
}
.ir-warn { color: #ffb454; }

/* Direction: three states of one fact, so they read as one control rather
   than three buttons that happen to be adjacent. */
.ir-dirs { display: flex; flex-direction: column; gap: 6px; }
.ir-dir {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: inherit;
  cursor: pointer;
  font: inherit;
  font-size: 0.9rem;
  padding: 7px 10px;
  text-align: left;
}
.ir-dir:hover { border-color: var(--accent, currentColor); }
.ir-dir--on { border-color: #3ddc84; font-weight: 600; }

.ir-insp-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.ir-danger { border-color: color-mix(in srgb, #e3212c 55%, var(--border)); }
.ir-danger:hover { border-color: #e3212c; }
.ir-tags { display: flex; flex-direction: column; gap: 6px; }

#ir-new-name {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-sizing: border-box;
  color: inherit;
  font: inherit;
  padding: 8px 10px;
  width: 100%;
}

/* The ledger. Every proposal is undoable from here and not only from the
   element it was made on — a deleted edge has no arrow left to click. */
.ir-ledger { display: flex; flex-direction: column; gap: 5px; list-style: none; margin: 0; padding: 0; }
.ir-ledger li {
  align-items: flex-start;
  background: color-mix(in srgb, var(--bg) 60%, transparent);
  border: 1px solid var(--border);
  border-radius: 8px;
  display: flex;
  font-size: 0.88rem;
  gap: 8px;
  justify-content: space-between;
  line-height: 1.35;
  padding: 7px 9px;
}
/* Sent, not gone: the proposal is still drawn on the map, so the row stays —
   struck through, and out of the Send button's count. */
.ir-ledger li.is-sent { opacity: 0.55; }
.ir-ledger li.is-sent span { text-decoration: line-through; }
.ir-undo {
  background: transparent;
  border: none;
  color: inherit;
  cursor: pointer;
  font: inherit;
  opacity: 0.55;
  padding: 0 2px;
}
.ir-undo:hover { opacity: 1; }
.ir-count {
  background: #3ddc84;
  border-radius: 999px;
  color: #10331f;
  font-weight: 700;
  padding: 1px 7px;
}
.ir-insp-status { font-size: 0.85rem; opacity: 0.85; }

/* Same behaviour as the question note, smaller numbers: this one lives in a
   360px panel, so its measure is the panel and there is no room to open at
   four lines. It still grows as you type (autogrow.js). */
#ir-insp-note {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-sizing: border-box;
  color: inherit;
  font: inherit;
  font-size: 15px;
  line-height: 1.55;
  min-height: 84px;
  overflow-y: hidden;
  padding: 9px 11px;
  resize: none;
}

@media (max-width: 800px) {
  .ir-chooser { flex-direction: column; }
  /* Narrow, the inspector stops being a sidebar over a map that has no room
     to spare and takes the bottom of the screen instead. */
  .ir-insp {
    border-left: none;
    border-top: 1px solid var(--border-strong);
    height: 58%;
    top: auto;
    width: 100%;
  }
}
