/* ══ ONE STUDENT — the page behind every roster row ═════════════════════════
   js/11c-student-profile.js, markup in index.html (#screen-student). Numbered
   22 so it lands after 20-coach-roster.css, whose click-through affordances it
   also carries — the roster's own file is left alone.

   SAME REGISTER AS THE ROSTER, one step closer in. The roster is a bulletin:
   triage at display weight over a box score set as agate. This is the piece
   behind one line of it, so it opens with a masthead and a set of figures, then
   runs four panels each introduced by a mono kicker and a serif head — the
   sub-heads of an article, not four identical cards on a grid.

   THE WEIGHT ORDER, again, is the point:

     masthead   who this is, and the four numbers the roster row showed. The
                name is the largest thing on the page.
     the line   the rating over time. Given the stop-press 3px rule, because
                the direction of travel is the news about a student.
     skill /    two columns of reference agate, weakest skill first. Consulted,
     answers    not read.
     notes      what the coach writes. A ruled writing line, in the app's hand.

   NO `overflow-y: auto` ANYWHERE IN THIS FILE. `.screen` is `height: 100%`, so
   any descendant carrying it becomes an inner scroller and the page below the
   fold renders, sits in the DOM, and is invisible to a full-page capture. That
   defect has now cost this project seven screens; see
   tests/test_page_wrapper_scrolling.py.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ══ THE CLICK-THROUGH, on the roster ═══════════════════════════════════════
   Every roster row and every triage entry opens a profile. 20-coach-roster.css
   already moves `.cr-name` to blue on row hover — it looked interactive before
   it was, so this mostly finishes a promise the roster was already making. */

.bs .cr-row.is-openable,
.bs .cr-flag.is-openable { cursor: pointer; }
.bs .cr-flag.is-openable:hover { box-shadow: 3px 3px 0 var(--bs-camel); }
.bs .cr-flag.is-openable:hover .cr-flag-name { color: var(--bs-blue); }

/* The name is a real <button> so the keyboard can reach it — a <tr> cannot hold
   focus. It must be typographically INVISIBLE: the cell around it already sets
   the face, size and weight, and a button resets all three. */
.bs .cr-open {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  margin: 0;
  text-align: left;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.bs .cr-open:focus-visible {
  outline: 2px solid var(--bs-blue);
  outline-offset: 2px;
}
.bs .cr-row:hover .cr-open,
.bs .cr-flag:hover .cr-open { color: var(--bs-blue); }

/* ══ THE PROFILE ════════════════════════════════════════════════════════════ */

.bs .sp {
  --sp-measure: 800px;
  padding-bottom: 12px;
}

/* ── masthead ──
   The sixth private ramp, clamp(29px, 5vw, 46px), and its own 3px underrule.
   Both are .page-head's now (02-chrome.css); the underrule survives as the
   folio's border-top — the same 3px in the same place, under one name.

   The descender finding this block recorded is still live and is why
   .page-title sets line-height 1.06 rather than the 1.0 it would otherwise
   want: Fraunces' descenders clear a 1.0 box, so `y` and `g` in a student's
   name rendered 5px outside the h2's content box. MEASURED at all four widths.
   Do not tighten it back. A student name is the one page title that can be
   arbitrarily long and unbreakable, so it keeps its own wrap rule. */
.bs .sp-name { overflow-wrap: anywhere; }
.bs .sp-dateline {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  margin-top: 9px;
}
.bs .sp-sep { margin: 0 7px; color: var(--bs-rule); }

/* The four figures the roster row was showing, restated at the size the roster
   could not give them. Hairline rules between, box-score fashion — not four
   boxes, which would read as cards and flatten the masthead into a dashboard. */
.bs .sp-figs {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 0;
  margin-top: 18px;
}
.bs .sp-fig {
  padding: 0 22px;
  border-left: 1px solid var(--bs-rule);
  flex: 0 0 auto;
}
.bs .sp-fig:first-child { padding-left: 0; border-left: 0; }
.bs .sp-fig-val {
  font-family: var(--bs-mono);
  font-size: 25px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--bs-ink);
}
.bs .sp-fig-val.is-none { color: var(--bs-ink-3); }
.bs .sp-fig-lbl {
  font-family: var(--bs-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  margin-top: 6px;
}

/* ── a panel ── */
.bs .sp-panel {
  border-top: 1px solid var(--bs-rule);
  margin-top: 34px;
  padding-top: 13px;
  min-width: 0;
}
/* The rating line is the news, so it gets the stop-press rule the triage band
   uses one screen back. */
.bs #sp-panels > .sp-panel:first-child {
  border-top: 3px solid var(--bs-ink);
  margin-top: 30px;
}
.bs .sp-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 14px;
  margin-bottom: 13px;
}
.bs .sp-kicker {
  font-family: var(--bs-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  order: 2;
}
.bs .sp-panel-title {
  font-family: var(--bs-ed);
  font-variation-settings: 'WONK' 1;
  font-weight: 900;
  font-size: 21px;
  line-height: 1.1;
  letter-spacing: -.016em;
  color: var(--bs-ink);
  margin: 0;
  order: 1;
}

.bs .sp-thin,
.bs .sp-foot {
  font-family: var(--bs-ui);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--bs-ink-2);
  border-left: 2px solid var(--bs-rule);
  padding-left: 13px;
  max-width: 58ch;
  margin: 4px 0 0;
}
.bs .sp-foot {
  font-size: 12.5px;
  color: var(--bs-ink-3);
  border-left-color: var(--bs-stock-2);
  margin-top: 14px;
}

/* ── the rating line ──
   A uniformly scaled viewBox (`height: auto`, no preserveAspectRatio override)
   so nothing distorts, and NO text inside the drawing — the labels are HTML
   agate below it and stay 9px at 320 instead of scaling down with the plot. */
.bs .sp-spark {
  max-width: var(--sp-measure);
  border-bottom: 1px solid var(--bs-ink);
}
.bs .sp-spark-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
.bs .sp-spark-area { fill: var(--bs-stock-2); }
.bs .sp-spark-line {
  fill: none;
  stroke: var(--bs-ink);
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.bs .sp-spark-dot { fill: var(--bs-pen); }

.bs .sp-spark-scale {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 30px;
  max-width: var(--sp-measure);
  margin-top: 10px;
}
.bs .sp-scale-item { display: flex; align-items: baseline; gap: 7px; }
.bs .sp-scale-val {
  font-family: var(--bs-mono);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--bs-ink);
}
.bs .sp-scale-lbl {
  font-family: var(--bs-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}
.bs .sp-spark-note {
  font-family: var(--bs-hand);
  font-size: 20px;
  line-height: 1.2;
  color: var(--bs-ink-3);
  margin: 12px 0 0;
  transform: rotate(-.8deg);
  transform-origin: left center;
}

/* ── the two reference panels ──
   `minmax(0, 1fr)`, not `1fr`: a grid track's default `min-width: auto` is its
   content's min-content width, so a long unbroken skill label would push the
   column — and the page — wider than the viewport rather than wrapping. */
.bs .sp-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0 44px;
}
/* NOT two equal columns. MEASURED at 1440: even halves made the page TALLER
   than the single-column layout at 1024 (pair 2058px against 1712px), because
   the answers column carries prose and a 490px measure wraps every stem onto a
   third line while the skills column — agate and a bar — sat half empty. The
   skills side gives up the width it was not using. */
@media (min-width: 1040px) {
  .bs .sp-pair { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); }
}

/* ── per-skill accuracy ── */
.bs .sp-skills,
.bs .sp-answers,
.bs .sp-notes {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bs .sp-skill {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "name fig"
    "bar  bar";
  align-items: baseline;
  gap: 6px 16px;
  padding: 11px 0 12px;
  border-bottom: 1px solid var(--bs-rule);
}
.bs .sp-skill-name {
  grid-area: name;
  font-family: var(--bs-ui);
  font-size: 14.5px;
  font-weight: 700;
  color: var(--bs-ink);
  overflow-wrap: anywhere;
}
/* Not colour alone: a thin skill also carries the word, and its bar is hatched
   rather than solid. */
.bs .sp-stamp {
  display: inline-block;
  margin-left: 9px;
  font-family: var(--bs-mono);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  border: 1.5px dashed currentColor;
  padding: 2px 6px 1px;
  vertical-align: 2px;
}
.bs .sp-skill-fig {
  grid-area: fig;
  display: flex;
  align-items: baseline;
  gap: 9px;
  white-space: nowrap;
}
.bs .sp-skill-pct {
  font-family: var(--bs-mono);
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--bs-ink);
}
.bs .sp-skill.is-thin .sp-skill-pct { color: var(--bs-ink-3); }
/* Deliberately NOT uppercased, unlike every other agate label in this file:
   the content is "14/18 · 26s" and `text-transform: uppercase` rendered the
   unit as "26S", which reads as part of a code rather than as seconds. */
.bs .sp-skill-n {
  font-family: var(--bs-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .12em;
  color: var(--bs-ink-3);
  font-variant-numeric: tabular-nums;
}
.bs .sp-bar {
  grid-area: bar;
  height: 6px;
  background: var(--bs-stock-2);
  overflow: hidden;
}
.bs .sp-bar-fill {
  height: 100%;
  background: var(--bs-ink);
}
.bs .sp-skill.is-thin .sp-bar-fill {
  background: repeating-linear-gradient(
    -45deg, var(--bs-ink-3) 0 2px, transparent 2px 5px);
}

/* ── recent answers ── */
.bs .sp-answer {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "mark stem"
    "mark meta";
  gap: 3px 12px;
  padding: 11px 0 12px;
  border-bottom: 1px solid var(--bs-rule);
}
/* Right and wrong differ by GLYPH and by fill, not by hue alone. */
.bs .sp-answer-mark {
  grid-area: mark;
  align-self: start;
  width: 21px;
  height: 21px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--bs-mono);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  border: 1.5px solid currentColor;
}
.bs .sp-answer[data-ok="yes"] .sp-answer-mark {
  background: var(--bs-ok);
  border-color: var(--bs-ok);
  color: var(--bs-sheet);
}
.bs .sp-answer[data-ok="no"] .sp-answer-mark {
  color: var(--bs-pen);
  border-style: dashed;
}
.bs .sp-answer-stem {
  grid-area: stem;
  font-family: var(--bs-ui);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--bs-ink);
  overflow-wrap: anywhere;
}
/* The SKILL is uppercased agate; the seconds and the rating delta are not, for
   the same reason as .sp-skill-n above. */
.bs .sp-answer-meta {
  grid-area: meta;
  font-family: var(--bs-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .14em;
  color: var(--bs-ink-3);
  font-variant-numeric: tabular-nums;
}
.bs .sp-answer-dom { text-transform: uppercase; }

/* ── notes ── */
.bs .sp-panel-notes { max-width: var(--sp-measure); }
.bs .sp-note-form { margin-bottom: 8px; }
.bs .sp-note-lbl {
  display: block;
  font-family: var(--bs-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  margin-bottom: 4px;
}
/* A ruled writing line, like the roster's search and the answer field — not a
   boxed control. */
.bs .sp-note-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--bs-ink);
  border-radius: 0;
  padding: 4px 2px 6px;
  font-family: var(--bs-ui);
  font-size: 15px;
  line-height: 1.5;
  color: var(--bs-ink);
  resize: vertical;
}
.bs .sp-note-input::placeholder { color: var(--bs-ink-3); }
.bs .sp-note-input:focus { outline: none; border-bottom-color: var(--bs-blue); }
.bs .sp-note-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  margin-top: 10px;
}
.bs .sp-note-send {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink);
  background: transparent;
  border: 1.5px solid var(--bs-ink);
  border-radius: 0;
  padding: 6px 13px 5px;
  cursor: pointer;
}
.bs .sp-note-send:hover { background: var(--bs-ink); color: var(--bs-sheet); }
.bs .sp-note-send:focus-visible { outline: 2px solid var(--bs-blue); outline-offset: 2px; }
.bs .sp-note-send[disabled] { cursor: progress; opacity: .55; }
.bs .sp-note-say {
  font-family: var(--bs-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}
.bs .sp-note-say.is-bad { color: var(--bs-pen); }

.bs .sp-note {
  border-left: 2px solid var(--bs-camel);
  padding: 2px 0 2px 14px;
  margin-top: 17px;
}
.bs .sp-note-body {
  font-family: var(--bs-ui);
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--bs-ink);
  max-width: 62ch;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.bs .sp-note-by {
  font-family: var(--bs-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  margin-top: 5px;
}
.bs .sp-note-who { color: var(--bs-ink-2); }

/* ── load failure ──
   Never a silent empty page: on this screen that would read as "this student
   has done nothing", which is a different and much worse claim. */
.bs .sp-fail {
  font-family: var(--bs-ui);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--bs-ink-2);
  border-left: 2px solid var(--bs-pen);
  padding-left: 13px;
  margin-top: 26px;
  max-width: 58ch;
}
.bs .sp-retry {
  display: inline-block;
  margin-top: 9px;
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink);
  background: transparent;
  border: 1.5px solid var(--bs-ink);
  border-radius: 0;
  padding: 6px 12px 5px;
  cursor: pointer;
}
.bs .sp-retry:hover { background: var(--bs-ink); color: var(--bs-sheet); }

/* ── narrow ── */
@media (max-width: 620px) {
  .bs .sp-fig { padding: 0 15px; }
  .bs .sp-fig-val { font-size: 21px; }
  .bs .sp-panel-title { font-size: 19px; }
  .bs .sp-spark-scale { gap: 8px 20px; }
}


/* ── Panel 1: Skill Breakdown ── */
.bs .sp-domain-head {
  font-family: var(--bs-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bs-ink);
  margin: 20px 0 8px;
  border-bottom: 2px solid var(--bs-ink);
  padding-bottom: 4px;
}
.bs .sp-raw-skills {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bs .sp-raw-skill {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--bs-rule);
}
.bs .sp-rs-name {
  font-family: var(--bs-ui);
  font-size: 14.5px;
  font-weight: 700;
  color: var(--bs-ink);
  margin-right: auto;
}
.bs .sp-rs-figs {
  display: flex;
  gap: 12px;
  margin: 0 16px;
  font-family: var(--bs-mono);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}
.bs .sp-rs-rating-box {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 80px;
  justify-content: flex-end;
}
.bs .sp-rs-rating {
  font-family: var(--bs-mono);
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--bs-ink);
}
/* Visual secondary for rd */
.bs .sp-rs-rd {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 600;
  color: var(--bs-ink-3);
  font-variant-numeric: tabular-nums;
}


/* ── Panel 2: Verticals ── */
.bs .sp-vert-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 10px;
}
.bs .sp-vert-lbl {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--bs-mono);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink);
  cursor: pointer;
}
.bs .sp-vert-cb {
  margin: 0;
  cursor: pointer;
}
