/* teacher-features.css — components added to the teacher workspace (index.html) AFTER
   the fork, kept out of that page's inline <style> block so they never need de-forking.
   index.html is the last holdout of arch/inline_shared_sprint.md (step 6: replace its 953
   inline lines with the master imports). Anything new belongs here instead, which is also
   the "no new inline styles, not even one attribute" rule (public/CLAUDE.md) with a place
   to land. When step 6 runs, the .review-modal-* rules below join their siblings in
   components.css; the rest stay page-level.

   EVERY selector that shares a class with the inline block is COMPOUND (.btn.x, not .x).
   This file is linked ahead of that block, so an equal-specificity rule would lose the
   cascade and the styling would silently not apply — the failure mode this page has
   already shipped twice. One extra class in the selector removes the ordering dependency. */

/* THE STATE PRIMITIVES, reached by import rather than by a second copy. index.html links only
   teacher-entry.css (which imports entry-shared.css) and this file, so .load-error and
   .load-error-msg were defined nowhere this page could see them — and state.css's own header
   records what that costs: the round 13 repair once shipped seven .load-error banners onto the
   student manager as unstyled text, because the markup was right and nothing defined the class.
   C31 puts six of those banners on THIS page, so the import comes first.
   Safe to import alone: every var() in state.css carries a literal fallback, deliberately, so it
   does not need tokens.css - which this page does not load either. (Ray, 2026-09-16.) */
@import "state.css";

/* .btn-sm for the Retry controls those banners carry. COMPOUND per the rule above, and a reference
   rather than a sixth copy: components.css holds the master, index.html does not load that
   tier, and this value has already been de-forked once across five pages. Same numbers. */
.btn.btn-sm { padding: 4px 10px; font-size: 12px; }

/* Report-modal header actions — the download control sits beside the close button.
   Used by BOTH overlays (CV Review and the generic report modal), which is the point:
   one definition, so the two cannot drift apart the way their markup did. */
.review-modal-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.btn.review-modal-download {
  font-size: 11px;
  padding: 5px 12px;
  white-space: nowrap;
}

/* CV Bank / Job Spec Bank row controls — the small per-row buttons (Review, Intel, Spec,
   Fit). .is-accent carries the accent treatment; --accent-ink is the mode-aware token for
   accent-coloured text on a pale ground (--accent-text is for text ON the accent fill). */
.btn.bank-row-btn {
  font-size: 9px;
  padding: 1px 5px;
}

.btn.bank-row-btn.is-accent {
  color: var(--accent-ink);
  border-color: var(--accent);
}

/* ── The three CV tiles, and the Protagonist report they open ────────────────────────────
   One CV row carries three documents — CV Protagonist, CV Review, CV Intelligence — that are
   paid for separately and fail separately. The row used to show a button per document only
   once its blob had landed, so "never run", "still building" and "failed" were one blank
   space. The tile states are the model's (cvTiles in js/teacher/cvPipeline.js); these rules
   only colour them, and the state modifiers are written as compounds so a stray .is-ready
   elsewhere on the page cannot pick them up. */

.cv-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 4px;
  padding: 0 6px 6px;
}

.cv-tile {
  display: flex;
  flex-direction: column;
  gap: 3px;
  border: 1px solid var(--border-light);
  border-left: 3px solid var(--border);
  border-radius: 4px;
  padding: 5px 7px;
  min-width: 0;
}

.cv-tile.is-ready { border-left-color: var(--accent); }
.cv-tile.is-building { border-left-color: var(--accent); background: var(--accent-glow); }
.cv-tile.is-failed { border-left-color: var(--error); }

.cv-tile-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
}

.cv-tile-title {
  font-size: 11px;
  font-weight: 600;
  min-width: 0;
}

.cv-tile-state {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  flex-shrink: 0;
}

.cv-tile.is-ready .cv-tile-state { color: var(--success-ink); }
.cv-tile.is-failed .cv-tile-state { color: var(--error); }

/* The job spec row: radio, label, Edit and delete. Its documents are tiles below it, as the CV
   row's are. Wrapping keeps the delete button on screen, since the card clips past its edge. */
.spec-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  padding: 4px 6px;
  font-size: 11px;
}

.cv-tile-note {
  font-size: 9.5px;
  line-height: 1.45;
  color: var(--text-muted);
}

.cv-tile-err {
  font-size: 9.5px;
  line-height: 1.45;
  color: var(--error);
}

.cv-tile-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
}

/* The CV Protagonist report. Nothing in this window is smaller than 14px (Ray, 2026-09-28), so
   the shared modal classes it borrows are raised here, under the window's own class, rather
   than in their shared rules, which the other report windows still read. */

.cv-report-modal { font-size: 14px; }

.cv-report-modal .review-modal-title {
  font-size: 18px;
  text-transform: none;
  letter-spacing: 0;
}

.cv-report-modal .review-modal-label,
.cv-report-modal .review-no-review,
.cv-report-modal .load-error,
.cv-report-modal .btn,
.cv-report-modal .btn-sm,
.cv-report-modal .btn.btn-sm,
.cv-report-modal .btn.review-modal-download {
  font-size: 14px;
}

.cv-report-modal .review-section-heading {
  font-size: 14px;
  letter-spacing: 0.04em;
}

/* Its header line: the point count, the flags that tell the teacher the document has moved on
   since the run, and the teacher-view toggle. */
.cv-report-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  font-size: 14px;
  color: var(--text-muted);
  padding-bottom: 12px;
}

.cv-report-flag {
  font-size: 14px;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--accent-glow);
  border-radius: 3px;
  padding: 2px 8px;
}

.cv-teacher-toggle {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--text-main);
  cursor: pointer;
}

.cv-opening-para {
  font-size: 15px;
  line-height: 1.65;
  color: var(--text-main);
  margin: 0 0 10px;
}

/* One numbered point: the number in its own column, then the CV's words, what is wrong, the
   change, and why it matters. */
.cv-point {
  display: flex;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-light);
}

.cv-point:last-child { border-bottom: none; }

.cv-point-num {
  flex: 0 0 2em;
  font-size: 15px;
  font-weight: 700;
  color: var(--accent-ink);
  text-align: right;
}

.cv-point-body {
  flex: 1;
  min-width: 0;
}

.cv-finding-obs {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--text-main);
}

/* The CV's own words, so the reader can find the line without opening the file. */
.cv-finding-quote {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-muted);
  border-left: 2px solid var(--border);
  padding-left: 8px;
  margin: 0 0 6px 2px;
  white-space: pre-wrap;
}

.cv-finding-fix {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-main);
  margin-top: 4px;
}

.cv-finding-importance {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-muted);
  margin-top: 4px;
}

.cv-teacher-view {
  border-top: 2px solid var(--border);
  padding-top: 18px;
}

.cv-factor {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  padding: 4px 0;
  border-bottom: 1px solid var(--border-light);
  font-size: 14px;
}

.cv-factor-title {
  flex: 0 0 11em;
  color: var(--text-main);
}

.cv-factor-word {
  flex-shrink: 0;
  font-weight: 700;
}

.cv-factor-word.is-fix { color: var(--error); }
.cv-factor-word.is-work { color: var(--text-main); }
.cv-factor-word.is-good { color: var(--accent-ink); }

.cv-factor-detail {
  font-size: 14px;
  color: var(--text-muted);
}

.cv-assessment-summary {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-main);
  margin: 8px 0 0;
}

.cv-job { padding: 6px 0; }
.cv-job + .cv-job { border-top: 1px solid var(--border-light); }

.cv-job-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-main);
}

.cv-job-coverage {
  font-size: 14px;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.cv-job-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  padding: 3px 0;
  font-size: 14px;
}

.cv-job-word {
  flex: 0 0 8.5em;
  font-weight: 700;
  color: var(--text-muted);
}

.cv-job-word.is-fix { color: var(--error); }
.cv-job-word.is-work { color: var(--text-main); }
.cv-job-word.is-good { color: var(--accent-ink); }

.cv-job-text {
  flex: 1 1 16em;
  min-width: 0;
  color: var(--text-main);
  overflow-wrap: anywhere;
}

.cv-elsewhere {
  padding: 6px 0;
  border-bottom: 1px solid var(--border-light);
}

.cv-elsewhere-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 14px;
  color: var(--text-main);
}

.cv-elsewhere-state {
  font-size: 14px;
  font-weight: 700;
  color: var(--text-muted);
  flex-shrink: 0;
}

.cv-elsewhere-src {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-muted);
  margin-top: 2px;
}

/* ── Homework history + awaiting-review line (student card, Students drawer) ──────────
   A homework row used to read "B2 . 12/08/2025" and nothing else, so the teacher could not
   tell which handout it came from; source_title is derived server-side from the questions'
   lesson (db/homework.py _homework_source). The alert block above it exists because a
   completion only changed a status word inside a closed dropdown. */

.hw-hist-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 0;
  border-bottom: 1px solid var(--border-light);
  font-size: 11px;
  flex-wrap: wrap;
}

.hw-hist-main { min-width: 0; flex: 1; }

.hw-hist-title {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hw-hist-meta {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-top: 1px;
}

.hw-hist-status { color: var(--text-muted); }
/* --success-ink, not --success: the fill colour on a pale ground measures 2.2:1, well under
   AA, and this is 10px uppercase. The ink token is the mode-aware pair for exactly this, the
   way --accent-ink is, and the same row on /student-manager already uses it
   (students-features.css .hist-status-done). Measured 2026-08-31: 6.26:1 light, 9.53:1 dark. */
.hw-hist-status.is-done { color: var(--success-ink); font-weight: 600; }

/* Marks a completed row nobody has opened yet, so the list itself reads the same way the
   alert above it does once the teacher goes looking. */
.hw-hist-new {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--accent);
  color: var(--accent-text);
}

.hw-hist-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }

.btn.hw-hist-btn {
  font-size: 10px;
  padding: 1px 6px;
}

.hw-review-alert {
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 6px 8px;
  margin-bottom: 6px;
}

.hw-review-alert-head {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  color: var(--accent-ink);
  margin-bottom: 4px;
}

.hw-review-alert-count {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .04em;
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--accent);
  color: var(--accent-text);
}

.hw-review-alert-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  padding: 2px 0;
}

.hw-review-alert-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hw-review-alert-date {
  font-size: 10px;
  color: var(--text-muted);
  flex-shrink: 0;
}

/* ── BEL case study: the rail controls and the brief on the Course Map ──────────────────────
   The rail block stacks the plan-mode, scope and story selects; the brief block renders the
   plan-level case (company, sector, opening, cast) above the Course Map rows, where the rows
   themselves cannot carry it — it is one JSON object on the plan, not a section of handout. */

.case-rail {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
}

.case-rail-note,
.case-rail-err {
  font-size: 11px;
  line-height: 1.5;
}

.case-rail-note {
  color: var(--text-muted);
}

.case-rail-err {
  color: var(--error);
}

.case-brief {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  padding: 12px 14px;
  margin-bottom: 16px;
  background: var(--canvas-bg);
}

.case-brief-kicker {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin-bottom: 6px;
}

.case-brief-company {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-main);
}

.case-brief-sector {
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 8px;
}

.case-brief-prose {
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-main);
  margin-bottom: 8px;
}

.case-brief-cast {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.case-brief-person {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 99px;
  border: 1px solid var(--border);
  color: var(--text-muted);
}

/* Account-email banner — the strip under the teacher toolbar, and the control that the
   free-tier 403 in routes/deps.py tells an unverified teacher to use. The student pages get
   theirs from css/learner-features.css, which index.html does not load, so this is restated
   rather than reached for.
   Teal rather than a warning amber: one scheme on every page, and this page's token set has no
   warning-pale ground to sit on. */
.teacher-email-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  background: var(--accent-glow);
  color: var(--accent-ink);
  font-size: 12px;
}

.teacher-email-banner-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  flex: 1;
  min-width: 260px;
}

.teacher-email-banner-msg {
  flex: 1;
  min-width: 200px;
  line-height: 1.5;
}

.teacher-email-banner-input {
  flex: 0 1 240px;
  min-width: 160px;
  padding: 5px 9px;
  font-size: 12px;
  font-family: inherit;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--canvas-bg);
  color: var(--text-main);
}

/* Compound on .btn for the reason stated at the top of this file: linked ahead of the inline
   block, an equal-specificity rule would lose and the sizing would silently not apply. */
.btn.teacher-email-banner-btn {
  font-size: 11px;
  padding: 4px 12px;
}

.teacher-email-banner-note { color: var(--success-ink); }

.teacher-email-banner-err { color: var(--error); }

.teacher-email-banner-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  color: inherit;
  padding: 2px 6px;
  margin-left: auto;
}

.teacher-email-banner-close:hover { color: var(--text-main); }

/* Track-card parts, the same values the six older cards carry inline. The OPIc card is the
   first written under the no-new-inline-styles rule, so the parts get names here; the older
   cards migrate when index.html's step 6 runs. .field-note is the muted one-line hint under
   a picker, same values as the inline <small> the other track panels use. */
.track-card-tag {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.07em;
  color: var(--accent);
  background: var(--accent-glow);
  padding: 2px 8px;
  border-radius: 4px;
  align-self: flex-start;
}

.track-card-name {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 4px;
}

.track-card-badge {
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  opacity: 0.8;
  border: 1px solid currentColor;
  padding: 0 4px;
  border-radius: 3px;
  margin-left: 4px;
}

.track-card-desc {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.6;
}

.field-note {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.5;
}

.field-stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ── Narrow and touch widths: the section rail, the document actions, the toolbar ──────────
   verify_debt Session 2 measured these at 390px on 2026-09-24. The rail row never wrapped,
   so .rail-name (flex: 1; min-width: 0) got whatever the badge, the level select and the
   handles left, which was 0px; the arrows were glyph-sized (10x9px); and both the document
   action row and the toolbar were single nowrap rows. Compound selectors per the rule above. */
.rail-list .rail-row { flex-wrap: wrap; row-gap: 4px; }
.rail-row .rail-name { min-width: 72px; }

/* 24px is the WCAG 2.2 minimum target. Stacked, the pair is 48px tall, so desktop keeps the
   small glyphs rather than doubling every row's height. */
@media (pointer: coarse) {
  .rail-move .rail-move-btn { min-width: 32px; min-height: 24px; font-size: 12px; }
}

.doc-header .doc-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  min-width: 0;
}
.document-canvas .doc-header { flex-wrap: wrap; gap: 8px; }

/* Each toolbar button keeps its accessible name from the label text, so the label is hidden
   visually rather than removed. */
@media (max-width: 480px) {
  .toolbar .icon-btn .btn-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .toolbar .icon-btn { padding: 4px 6px; }
}
