/* Aluma for educators: one student's page and the read-only student view
   (educators_student.js).

   Loaded after educators.css, whose tokens and shared pieces (.card, .btn,
   .tabs, .stat, .status-chip, .pct-bar, .chip, .set-row, the ec- calendar)
   this builds on. Every class here starts with sp- (the page), sv- (the
   student view) or is a name the spec gives (.student-page, .activity-row,
   .edu-sv), and every colour is an --e-* token or a tint of one: the gate's
   sweeps read every sheet, and an app-wide token name here would trip them.

   Widths: on a phone the header stacks, the two actions share a row with
   More as an icon, the tabs scroll sideways and every card is one column.
   From 960px the Overview has its side column (340px) and the Struggling
   and Mastered cards sit two by two. */

.student-page { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.student-page > .back-btn { margin-bottom: -8px; }

/* ── header ───────────────────────────────────────────────────────────── */
.sp-hero {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "av id"
    "status status"
    "perms perms"
    "actions actions";
  gap: 14px 16px;
  align-items: center;
  min-width: 0;
}
.sp-hero > .avatar { grid-area: av; }
.sp-id { grid-area: id; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sp-name { overflow-wrap: anywhere; }
.sp-meta { color: var(--e-text-2); font-size: 15px; font-weight: 560; line-height: 1.4; overflow-wrap: anywhere; }
/* On a phone each phrase is its own line, so neither breaks in the middle. */
.sp-meta-bit { display: block; }
.sp-meta-sep { display: none; }
.sp-status { grid-area: status; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0; }
.sp-reasons { min-width: 0; color: var(--e-text-2); font-size: 14px; font-weight: 620; overflow-wrap: anywhere; }
.sp-perms-wrap { grid-area: perms; min-width: 0; }
/* What the student allows: a quiet sentence of state, not pills that read
   as filters. What is off gets a lock and the warn ink, and says who sets it. */
.sp-perms { display: flex; flex-direction: column; gap: 3px; }
.sp-perm-line {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  min-width: 0;
  color: var(--e-text-2);
  font-size: 14px;
  font-weight: 580;
  line-height: 1.45;
}
.sp-perm-line > .ico { margin-top: 2px; color: var(--e-icon); }
.sp-perm-line.is-off,
.sp-perm-line.is-off > .ico { color: var(--e-warn-ink); }
.sp-perm-words { min-width: 0; overflow-wrap: anywhere; }
/* Each permission is a word in that sentence. */
.sp-perms .chip {
  display: inline;
  padding: 0;
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  white-space: normal;
}
.sp-perm-line.is-off .chip { font-weight: 680; }

.sp-actions {
  grid-area: actions;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) auto;
  gap: 10px;
  min-width: 0;
}
.sp-actions .btn { min-width: 0; padding-left: 14px; padding-right: 14px; }
.sp-actions .btn-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-wide { display: none; }
.sp-narrow { display: inline; }
/* On a phone More is an icon; its name stays for assistive tech. */
.sp-more-btn { width: 48px; padding: 0; }
/* A 320px phone: Remind on its own row, Student view and More under it,
   so neither label is cut to "Re..." or "Studen...". */
@media (max-width: 359px) {
  .sp-actions { grid-template-columns: minmax(0, 1fr) auto; }
  .sp-actions .sp-remind { grid-column: 1 / -1; }
}
.sp-more-btn .btn-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

@media (min-width: 760px) {
  .sp-hero {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "av id"
      "av status"
      "av perms"
      "av actions";
    gap: 12px 22px;
    align-items: start;
  }
  .sp-hero > .avatar { align-self: start; }
  .sp-actions { display: flex; flex-wrap: wrap; margin-top: 4px; }
  .sp-actions .btn { padding-left: 22px; padding-right: 22px; }
  .sp-wide { display: inline; }
  .sp-narrow { display: none; }
  .sp-meta-bit { display: inline; white-space: nowrap; }
  .sp-meta-sep { display: inline; }
  .sp-more-btn { width: auto; padding: 0 20px; }
  .sp-more-btn .btn-label { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; }
}
@media (min-width: 1100px) {
  .sp-hero {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "av id actions"
      "av status actions"
      "av perms actions";
  }
  .sp-actions { flex-wrap: nowrap; justify-content: flex-end; margin-top: 0; }
}

/* the More menu */
.sp-more { position: relative; display: flex; min-width: 0; }
.sp-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 30;
  width: min(290px, calc(100vw - 32px));
  padding: 8px;
  border-radius: 24px;
  background: var(--e-surface);
  box-shadow: var(--e-shadow-pop);
  animation: e-pop 0.18s var(--e-ease);
}
.sp-menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 46px;
  padding: 10px 14px;
  border: 0;
  border-radius: 16px;
  background: none;
  color: var(--e-text);
  font-size: 15px;
  font-weight: 620;
  text-align: left;
  cursor: pointer;
}
.sp-menu-item > span { min-width: 0; overflow-wrap: anywhere; }
.sp-menu-item .ico { width: 18px; height: 18px; color: var(--e-icon); }
.sp-menu-item:hover,
.sp-menu-item:focus-visible { background: var(--e-surface-3); }
.sp-menu-item.is-danger { color: var(--e-risk-ink); }
.sp-menu-item.is-danger .ico { color: var(--e-risk-ink); }
.sp-menu-item.is-danger:hover { background: var(--e-risk-soft); }

/* ── tabs ─────────────────────────────────────────────────────────────── */
/* Seven tabs don't fit a phone: the strip scrolls, with a fade at an end
   that has more past it (the script sets has-before and has-after). */
/* 12px under the privacy line: the line belongs to the header, the tabs
   to what follows, and the page's 20px gap would split them evenly. Under
   the strip, 16px to the tab's first card: the gap every filter row in
   Aluma leaves (the roster's toolbar, the plan's week head). */
.sp-tabs-wrap { position: relative; min-width: 0; margin-top: -8px; margin-bottom: -4px; }
.sp-tabs {
  margin-bottom: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.sp-tabs::-webkit-scrollbar { display: none; }
/* Positioned, so the screen-reader words inside a tab scroll with it
   instead of hanging off the page's right edge. */
.sp-tab { position: relative; flex: 1 0 auto; scroll-snap-align: start; }
/* A count is a small pill on the grey track, white until its tab is picked. */
.sp-tab .tab-count {
  min-width: 20px;
  height: 20px;
  margin-left: 0;
  padding: 0 6px;
  background: var(--e-surface);
  color: var(--e-text-2);
  font-size: 11px;
  box-shadow: inset 0 0 0 1px var(--e-border);
}
.sp-tab[aria-selected="true"] .tab-count { background: var(--e-accent-soft); color: var(--e-accent-soft-ink); box-shadow: none; }
.sp-tabs-wrap::before,
.sp-tabs-wrap::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  width: 22px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s var(--e-ease);
}
.sp-tabs-wrap::before {
  left: 0;
  border-radius: var(--e-radius-pill) 0 0 var(--e-radius-pill);
  background: linear-gradient(90deg, var(--e-surface-3), rgba(237, 242, 246, 0));
}
.sp-tabs-wrap::after {
  right: 0;
  border-radius: 0 var(--e-radius-pill) var(--e-radius-pill) 0;
  background: linear-gradient(270deg, var(--e-surface-3), rgba(237, 242, 246, 0));
}
.sp-tabs-wrap.has-before::before,
.sp-tabs-wrap.has-after::after { opacity: 1; }

.sp-panels { min-width: 0; }
.sp-panel { min-width: 0; }

/* ── cards ────────────────────────────────────────────────────────────── */
.sp-card { padding: 20px; min-width: 0; }
@media (min-width: 640px) {
  .sp-card { padding: 24px 26px; }
}
.sp-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 14px;
  margin-bottom: 14px;
}
/* A head that carries a filter (Activity's All / Reminders / Plan /
   Settings) is a filter row, and leaves the same 16px as the others. */
.sp-card-head:has(.sp-act-filter) { margin-bottom: 16px; }
.sp-card-title { font-size: 19px; font-weight: 750; letter-spacing: -0.022em; line-height: 1.25; overflow-wrap: anywhere; }
.sp-card-title:focus { outline: none; }
.sp-empty { color: var(--e-text-2); font-size: 15px; line-height: 1.45; }
.sp-foot { margin-top: 14px; color: var(--e-text-2); font-size: 14px; font-weight: 580; }
.sp-card-note {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: -6px 0 14px;
  color: var(--e-text-2);
  font-size: 13px;
  font-weight: 600;
}
.sp-card-note .ico { flex: none; color: var(--e-accent); }
.sp-stack { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

/* rows of schoolwork */
.sp-rows { display: flex; flex-direction: column; }
.sp-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
}
.sp-row + .sp-row { border-top: 1px solid var(--e-hair); }
.sp-row-main { min-width: 0; }
.sp-row-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  font-size: 15px;
  font-weight: 640;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.sp-row-title > span:last-child { min-width: 0; }
.sp-row-sub { margin-top: 1px; color: var(--e-text-2); font-size: 13px; overflow-wrap: anywhere; }
.sp-row.is-done .sp-row-title { color: var(--e-text-2); }
.sp-row > .due { justify-self: end; }

/* ── Overview ─────────────────────────────────────────────────────────── */
.sp-overview { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
@media (min-width: 960px) {
  .sp-overview { gap: 24px; }
}
.sp-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; min-width: 0; }
.sp-main,
.sp-side { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
@media (min-width: 960px) {
  .sp-cols { grid-template-columns: minmax(0, 1fr) 340px; gap: 24px; align-items: start; }
  .sp-side .sp-card-title { font-size: 17px; }
  .sp-side .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sp-side .goal-row { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  /* The first row's cards end level: what is due beside the numbers. The
     first card of each column takes the slack, inside itself. */
  .sp-cols-top { align-items: stretch; }
  .sp-cols-top .sp-main > .sp-work,
  .sp-cols-top .sp-side > .sp-stats { flex: 1 1 auto; }
}

/* One column: the first row reads what is due, the numbers, then the
   card that joined it. */
@media (max-width: 959px) {
  .sp-cols-top > .sp-main,
  .sp-cols-top > .sp-side { display: contents; }
  .sp-cols-top .sp-joins { order: 1; }
}

/* Working on now: the list, then today's plan held to the bottom. */
.sp-work { display: flex; flex-direction: column; }
.sp-work-top { margin-bottom: 16px; }
.sp-work .sp-plan-today { margin-top: auto; }
.sp-work-more { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--e-hair); font-size: 14px; }
.sp-work-more.is-quiet { color: var(--e-text-2); font-weight: 560; }

/* today's and tomorrow's sittings, under Working on now */
.sp-plan-today {
  padding: 14px 16px;
  border-radius: 20px;
  background: var(--e-night-soft);
}
.sp-plan-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 10px; }
.sp-mini { color: var(--e-night-ink); font-size: 14px; font-weight: 740; }
.sp-plan-total { color: var(--e-night-ink); font-size: 13px; font-weight: 650; }
.sp-plan-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.sp-plan-item { display: flex; align-items: flex-start; gap: 8px; font-size: 14px; font-weight: 600; line-height: 1.4; }
.sp-plan-item .ico { flex: none; margin-top: 2px; color: var(--e-night-ink); }
.sp-plan-text { min-width: 0; overflow-wrap: anywhere; }
.sp-plan-item.is-done .sp-plan-text { color: var(--e-text-2); text-decoration: line-through; text-decoration-color: rgba(79, 93, 104, 0.5); }
.sp-plan-none { margin-top: 6px; color: var(--e-text-2); font-size: 14px; }
.sp-plan-tomorrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(13, 89, 99, 0.16);
  color: var(--e-text-2);
  font-size: 14px;
  font-weight: 600;
}
.sp-plan-tomorrow > p { min-width: 0; }

/* Next 7 days: the full width, so its seven columns (from 920px) have room. */
.sp-week .ec-foot { margin-top: 14px; }

/* Schoolwork, in groups (the family app's work card) */
.sp-assignments .sp-card-head { margin-bottom: 2px; }
.sp-group + .sp-group { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--e-hair); }
.sp-group-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0 2px; }
.sp-group-title { font-size: 15px; font-weight: 740; letter-spacing: -0.01em; }
.sp-group-end { display: inline-flex; flex: none; align-items: center; gap: 8px; }
.sp-group-note { color: var(--e-risk-ink); font-size: 13px; font-weight: 680; }
.sp-group-count {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 24px;
  padding: 0 8px;
  border-radius: var(--e-radius-pill);
  background: var(--e-surface-3);
  color: var(--e-text-2);
  font-size: 12px;
  font-weight: 720;
  font-variant-numeric: tabular-nums;
}
.sp-group.is-alert .sp-group-title { color: var(--e-risk-ink); }
.sp-group.is-alert .sp-group-count { background: var(--e-risk-soft); color: var(--e-risk-ink); }
.sp-group .sp-empty { padding: 4px 0 10px; font-size: 14px; }
.sp-group-more { padding: 2px 0 10px; font-size: 14px; }

/* Classes and grades: one column, two once there are four or more */
.sp-class-list { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: 28px; }
@media (min-width: 560px) {
  .sp-class-list.is-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.sp-class {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
  padding: 10px 0;
  border-top: 1px solid var(--e-hair);
}
.sp-class-name { min-width: 0; font-size: 15px; font-weight: 620; overflow-wrap: anywhere; }
.sp-grade { display: inline-flex; flex: none; align-items: center; gap: 6px; font-size: 15px; font-weight: 720; font-variant-numeric: tabular-nums; }
.sp-grade.is-none { color: var(--e-text-2); font-size: 13px; font-weight: 600; }
.sp-grade.is-low { color: var(--e-warn-ink); }
.sp-low {
  padding: 1px 8px 2px;
  border-radius: var(--e-radius-pill);
  background: var(--e-warn-soft);
  color: var(--e-warn-ink);
  font-size: 12px;
  font-weight: 720;
}

/* the numbers, with the week's study as their bottom row */
.sp-stats { display: flex; flex-direction: column; padding: 20px 22px; }

/* Study this week: seven bars, today last */
/* Held to the bottom of the card: a stretched row's slack goes above it. */
.sp-stats > :nth-last-child(2) { margin-bottom: 20px; }
.sp-study-days {
  margin-top: auto;
  padding-top: 18px;
  border-top: 1px solid var(--e-hair);
}
.sp-days-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 10px; margin-bottom: 12px; }
.sp-days-best { color: var(--e-text-3); font-size: 13px; font-weight: 560; }
.sp-days {
  display: grid;
  grid-template-columns: repeat(7, minmax(28px, 1fr));
  gap: 8px;
  align-items: end;
}
.sp-day { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.sp-bar-track {
  display: flex;
  align-items: flex-end;
  width: 100%;
  max-width: 30px;
  height: 64px;
  border-radius: 10px;
  background: var(--e-bar-track);
  overflow: hidden;
}
.sp-bar { display: block; width: 100%; border-radius: 10px; background: var(--e-bar-known); }
.sp-bar.is-zero { height: 0; }
.sp-day-letter { color: var(--e-text-2); font-size: 12px; font-weight: 700; }
.sp-day.is-today .sp-day-letter { color: var(--e-accent); }
.sp-day.is-today .sp-bar-track { box-shadow: inset 0 0 0 1.5px rgba(31, 95, 130, 0.32); }

/* topic rows: the side card, Struggling and Mastered */
.sp-weak-list,
.sp-topic-list,
.sp-progress-list { display: flex; flex-direction: column; gap: 14px; }
.sp-topic + .sp-topic,
.sp-progress-row + .sp-progress-row { padding-top: 14px; border-top: 1px solid var(--e-hair); }
.sp-weak-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 10px;
  margin-bottom: 6px;
}
.sp-topic-name { min-width: 0; font-size: 15px; font-weight: 660; overflow-wrap: anywhere; }
.sp-subject-tag { color: var(--e-text-2); font-size: 13px; font-weight: 600; }
.sp-subject-chip { padding: 3px 10px; font-size: 12px; }
/* Add practice: at the row's end, beside the topic and its subject. */
.sp-topic.has-add .sp-weak-head { justify-content: flex-start; align-items: center; }
.sp-topic-add { margin-left: auto; }
.sp-topic-add.btn-sm { min-height: 34px; padding: 0 12px; font-size: 13px; }
.sp-topic-add .ico { width: 15px; height: 15px; }
.sp-topic-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
  margin-top: 7px;
  color: var(--e-text-2);
  font-size: 13px;
  font-weight: 560;
}
.sp-review { padding: 3px 10px; font-size: 12px; }
.sp-meta-part { white-space: nowrap; }

/* Tests coming up, and Test prep */
.sp-test-list { display: flex; flex-direction: column; gap: 14px; }
.sp-test,
.sp-prep { display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 12px; align-items: start; }
.sp-prep + .sp-prep { padding-top: 14px; border-top: 1px solid var(--e-hair); }
.sp-test-ico {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: var(--e-streak-soft);
  color: var(--e-streak-ink);
}
.sp-test-ico .ico { width: 18px; height: 18px; }
.sp-test-name { font-size: 15px; font-weight: 680; overflow-wrap: anywhere; }
.sp-test-sub { margin-top: 1px; color: var(--e-text-2); font-size: 13px; font-weight: 560; overflow-wrap: anywhere; }
.sp-prep-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 3px; }
.sp-prep-line .sp-test-sub { margin-top: 0; }
.sp-prep-out { margin-top: 6px; color: var(--e-text-2); font-size: 13px; font-weight: 600; }
.sp-prep-line > .sp-prep-out { margin-top: 0; }
.sp-band { padding: 4px 11px; font-size: 12px; }
.sp-band.is-strong,
.sp-band.is-solid { background: var(--e-ok-soft); color: var(--e-ok-ink); }
.sp-band.is-building { background: var(--e-warn-soft); color: var(--e-warn-ink); }

/* the Reminders box */
.sp-rem-left { color: var(--e-text-2); font-size: 14px; font-weight: 600; }
.sp-rem-num {
  margin-right: 2px;
  color: var(--e-text);
  font-size: 26px;
  font-weight: 780;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.sp-rem-none { margin-top: 6px; color: var(--e-text-2); font-size: 14px; }
.sp-rem-item { margin-top: 12px; padding: 10px 12px; border-radius: 16px; background: var(--e-surface-2); box-shadow: inset 0 0 0 1px var(--e-hair); }
.sp-rem-item.is-next { background: var(--e-night-soft); box-shadow: none; }
.sp-rem-meta { color: var(--e-text-2); font-size: 13px; font-weight: 600; }
.sp-rem-label { margin-right: 2px; color: var(--e-text); font-weight: 720; }
.sp-rem-item.is-next .sp-rem-label { color: var(--e-night-ink); }
.sp-rem-text { margin-top: 2px; color: var(--e-text); font-size: 14px; font-weight: 600; line-height: 1.4; overflow-wrap: anywhere; }
.sp-rem-btn { margin-top: 14px; }
.sp-reminders-box .perm-note { margin-top: 14px; }

/* What the student allows */
.sp-allow-list { display: flex; flex-direction: column; }
.sp-permissions .set-row { padding: 12px 0; gap: 12px; }
.sp-allow.is-off .set-ico { background: var(--e-surface-3); color: var(--e-text-2); }
.sp-onoff {
  flex: none;
  padding: 3px 11px 4px;
  border-radius: var(--e-radius-pill);
  font-size: 12px;
  font-weight: 720;
}
.sp-onoff.is-on { background: var(--e-ok-soft); color: var(--e-ok-ink); }
.sp-onoff.is-off { background: var(--e-surface-3); color: var(--e-text-2); }
.sp-permissions .sp-foot { margin-top: 10px; font-size: 13px; }

/* ── Struggling ───────────────────────────────────────────────────────── */
/* A count beside a card's title. */
.sp-head-count {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 24px;
  padding: 0 8px;
  border-radius: var(--e-radius-pill);
  background: var(--e-surface-3);
  color: var(--e-text-2);
  font-size: 12px;
  font-weight: 720;
  font-variant-numeric: tabular-nums;
}
.sp-head-count.is-risk { background: var(--e-risk-soft); color: var(--e-risk-ink); }

/* Start here: what to work on next, the numbers beside it, the two ways
   to act. The first step is the one to start with: it alone is tinted. */
.sp-next .sp-card-head { margin-bottom: 4px; }
.sp-next-sub { margin-bottom: 16px; color: var(--e-text-2); font-size: 14px; font-weight: 580; overflow-wrap: anywhere; }
.sp-next-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; min-width: 0; }
.sp-steps-wrap { min-width: 0; }
.sp-steps { display: flex; flex-direction: column; gap: 8px; }
.sp-step {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 12px 16px 12px 12px;
  border-radius: 20px;
  background: var(--e-surface-2);
  box-shadow: inset 0 0 0 1px var(--e-hair);
}
.sp-step:first-child { background: var(--e-accent-soft); box-shadow: none; }
.sp-step-num {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--e-surface);
  color: var(--e-accent);
  font-size: 15px;
  font-weight: 760;
  font-variant-numeric: tabular-nums;
  box-shadow: inset 0 0 0 1.5px rgba(31, 95, 130, 0.22);
}
.sp-step:first-child .sp-step-num { background: var(--e-accent); color: #fff; box-shadow: none; }
.sp-step-body { min-width: 0; }
.sp-step-title { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; overflow-wrap: anywhere; }
.sp-step-why { margin-top: 2px; color: var(--e-text-2); font-size: 13px; font-weight: 580; line-height: 1.4; overflow-wrap: anywhere; }
.sp-step-end { justify-self: end; min-width: 0; }
.sp-step-pct {
  color: var(--e-risk-ink);
  font-size: 20px;
  font-weight: 780;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.sp-steps-more { margin-top: 8px; padding-left: 12px; color: var(--e-text-2); font-size: 13px; font-weight: 600; }
@media (max-width: 479px) {
  .sp-step { grid-template-columns: 28px minmax(0, 1fr); gap: 4px 10px; padding: 12px; }
  .sp-step-num { width: 28px; height: 28px; font-size: 14px; }
  .sp-step-end { grid-column: 2; justify-self: start; }
  .sp-step-pct { font-size: 16px; }
}

/* the three numbers: a row under the steps on a phone, a column beside
   them from 760px */
.sp-focus { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; min-width: 0; }
.sp-focus .sp-tile {
  padding: 12px 14px;
  border-radius: 18px;
  background: var(--e-surface-2);
  box-shadow: inset 0 0 0 1px var(--e-hair);
}
.sp-focus .stat-value { font-size: 26px; }
.sp-focus .sp-tile.is-warn { background: var(--e-warn-soft); box-shadow: none; }
.sp-focus .sp-tile.is-risk { background: var(--e-risk-soft); box-shadow: none; }
.sp-tile.is-warn .stat-label,
.sp-tile.is-warn .stat-label .ico,
.sp-tile.is-warn .stat-value { color: var(--e-warn-ink); }
.sp-tile.is-risk .stat-label,
.sp-tile.is-risk .stat-label .ico,
.sp-tile.is-risk .stat-sub { color: var(--e-risk-ink); }
@media (max-width: 479px) {
  .sp-focus .sp-tile { padding: 10px 10px 9px; border-radius: 16px; }
  .sp-focus .stat-label { align-items: flex-start; font-size: 12px; line-height: 1.3; }
  .sp-focus .stat-label .ico { display: none; }
  .sp-focus .stat-value { font-size: 22px; }
}
@media (min-width: 760px) {
  .sp-next-body { grid-template-columns: minmax(0, 1fr) 220px; gap: 20px; align-items: start; }
  .sp-focus { grid-template-columns: minmax(0, 1fr); }
  .sp-focus .sp-tile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "label value" "sub value";
    align-items: center;
    gap: 0 10px;
  }
  .sp-focus .stat-label { grid-area: label; }
  .sp-focus .stat-value { grid-area: value; font-size: 24px; }
  .sp-focus .stat-sub { grid-area: sub; }
}

.sp-next-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--e-hair);
}
.sp-next-hint {
  display: flex;
  flex: 1 1 220px;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--e-text-2);
  font-size: 14px;
  font-weight: 580;
}
.sp-next-hint .ico { color: var(--e-warn-ink); }
@media (max-width: 479px) {
  .sp-next-acts .btn { flex: 1 1 auto; }
}

/* Nothing to work on: one calm line instead of three empty cards. */
.sp-clear { display: flex; align-items: flex-start; gap: 14px; padding: 14px 16px; border-radius: 20px; background: var(--e-ok-soft); }
.sp-clear-ico {
  display: grid;
  flex: none;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 14px;
  background: var(--e-surface);
  color: var(--e-ok-ink);
}
.sp-clear-title { padding-top: 1px; color: var(--e-ok-ink); font-size: 16px; font-weight: 720; }
.sp-clear-sub { margin-top: 2px; color: var(--e-text); font-size: 14px; line-height: 1.45; overflow-wrap: anywhere; }
/* Nothing here, yet not on track: no all-clear green, the status's icon
   in its tone, and the ways to act under it. */
.sp-clear.is-quiet { background: var(--e-surface-2); box-shadow: inset 0 0 0 1px var(--e-hair); }
.sp-clear.is-quiet .sp-clear-title { color: var(--e-text); }
.sp-clear.is-quiet .sp-clear-ico { color: var(--e-warn-ink); }
.sp-clear.is-quiet.is-risk .sp-clear-ico { color: var(--e-risk-ink); }

.sp-grid-2 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; min-width: 0; }
@media (min-width: 960px) {
  .sp-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
}
/* Weak topics with late work under them, beside the missed questions. On
   a phone the columns dissolve into one list in reading order. */
.sp-struggle-grid { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.sp-struggle-col { display: contents; }
.sp-struggle-grid .sp-weak-card { order: 1; }
.sp-struggle-grid .sp-missed { order: 2; }
.sp-struggle-grid .sp-overdue { order: 3; }
@media (min-width: 960px) {
  .sp-struggle-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: stretch; }
  .sp-struggle-col { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
  /* The last card of the shorter column takes the slack, so both end level. */
  .sp-struggle-col > :last-child { flex: 1 1 auto; }
}
.sp-topic-missed { color: var(--e-risk-ink); font-weight: 640; }
/* Weak topics holds the slack when its column is the shorter one: the
   list at the top, the "nothing late" line at the foot. */
.sp-weak-card { display: flex; flex-direction: column; }
.sp-weak-foot {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: auto;
  padding-top: 18px;
  color: var(--e-ok-ink);
  font-size: 14px;
  font-weight: 620;
}
.sp-weak-card > .sp-topic-list { margin-bottom: 4px; }

/* Questions missed */
.sp-miss-list { display: flex; flex-direction: column; }
.sp-miss { display: flex; flex-direction: column; gap: 10px; padding: 16px 0; }
.sp-miss:first-child { padding-top: 0; }
.sp-miss + .sp-miss { border-top: 1px solid var(--e-hair); }
.sp-q { font-size: 15px; font-weight: 640; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
/* What they picked beside the answer, one box with a thin line between
   (stacked on a phone). */
.sp-answers {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  overflow: hidden;
  border-radius: 16px;
  background: var(--e-surface);
  box-shadow: 0 0 0 1px var(--e-hair);
}
@media (min-width: 560px) {
  .sp-answers.is-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.sp-pick {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  padding: 8px 12px 9px;
  font-size: 14px;
  font-weight: 620;
  line-height: 1.4;
}
.sp-pick.is-picked { background: var(--e-risk-soft); color: var(--e-risk-ink); }
.sp-pick.is-answer { background: var(--e-ok-soft); color: var(--e-ok-ink); }
.sp-pick-label { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 740; letter-spacing: 0.01em; }
.sp-pick-label .ico { width: 13px; height: 13px; }
.sp-pick-text { min-width: 0; color: var(--e-text); overflow-wrap: anywhere; }
.sp-miss-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; }
.sp-miss-topics .chip { white-space: normal; overflow-wrap: anywhere; }
.sp-when { color: var(--e-text-3); font-size: 13px; font-weight: 560; }
.sp-missed .sp-group-more { padding-top: 12px; border-top: 1px solid var(--e-hair); }

/* ── Mastered ─────────────────────────────────────────────────────────── */
.sp-counts-line { margin-bottom: 16px; color: var(--e-text-2); font-size: 15px; font-weight: 620; }
.sp-subject-group + .sp-subject-group { margin-top: 18px; }
/* Small caps in the quiet ink: violet stays for the checks. Caps by
   font-variant, so the words read the same to anything reading the text. */
.sp-subject { margin-bottom: 2px; color: var(--e-text-2); font-size: 15px; font-weight: 720; font-variant-caps: all-small-caps; letter-spacing: 0.05em; }
.sp-known-list { display: flex; flex-direction: column; }
.sp-known {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 10px;
  padding: 8px 0;
}
.sp-known + .sp-known { border-top: 1px solid var(--e-hair); }
.sp-known-ico {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--e-violet-soft);
  color: var(--e-violet-ink);
}
.sp-known-topic { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; font-size: 15px; font-weight: 620; overflow-wrap: anywhere; }
.sp-known-topic > span:first-child { min-width: 0; }
.sp-known-seen { color: var(--e-text-3); font-size: 13px; font-weight: 560; white-space: nowrap; }
@media (max-width: 479px) {
  .sp-known { grid-template-columns: 24px minmax(0, 1fr); }
  .sp-known-seen { grid-column: 2; }
}

/* ── Activity ─────────────────────────────────────────────────────────── */
/* The log, and the week in numbers beside it from 960px. */
.sp-act-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; min-width: 0; }
@media (min-width: 960px) {
  .sp-act-cols { grid-template-columns: minmax(0, 1fr) 300px; gap: 24px; }
  .sp-act-summary .sp-card-title { font-size: 17px; }
}
/* All, Reminders, Plan, Settings: the tab strip's look, small. */
.sp-act-filter { display: flex; flex-wrap: wrap; gap: 2px; padding: 4px; border-radius: var(--e-radius-pill); background: var(--e-surface-3); }
.sp-filter {
  min-height: 34px;
  padding: 0 13px;
  border: 0;
  border-radius: var(--e-radius-pill);
  background: none;
  color: var(--e-text-2);
  font-size: 13px;
  font-weight: 650;
  cursor: pointer;
  transition: background-color 0.18s var(--e-ease), color 0.18s var(--e-ease);
}
.sp-filter:hover { color: var(--e-text); }
.sp-filter[aria-pressed="true"] {
  background: var(--e-surface);
  color: var(--e-text);
  box-shadow: 0 0 0 1px rgba(18, 28, 36, 0.04), 0 2px 6px rgba(18, 28, 36, 0.10);
}
@media (pointer: coarse) {
  .sp-filter { min-height: 40px; }
}
.sp-act-day + .sp-act-day { margin-top: 8px; }
/* The day stays in sight while its rows scroll by, under the top bar. */
.sp-act-day-title {
  position: sticky;
  top: 66px;
  z-index: 1;
  padding: 8px 0 4px;
  background: var(--e-surface);
  color: var(--e-text-2);
  font-size: 13px;
  font-weight: 720;
}
.sp-activity-list { display: flex; flex-direction: column; }
.activity-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  padding: 12px 0;
}
.activity-row + .activity-row { border-top: 1px solid var(--e-hair); }
.sp-act-ico {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: var(--e-accent-soft);
  color: var(--e-accent);
}
.sp-act-ico .ico { width: 18px; height: 18px; }
.activity-row[data-kind="plan"] .sp-act-ico { background: var(--e-night-soft); color: var(--e-night-ink); }
.activity-row[data-kind="notify"] .sp-act-ico,
.activity-row[data-kind="perms"] .sp-act-ico { background: var(--e-violet-soft); color: var(--e-violet-ink); }
.activity-row[data-kind="reminder_cancelled"] .sp-act-ico,
.activity-row[data-kind="left"] .sp-act-ico { background: var(--e-surface-3); color: var(--e-text-2); }
.sp-act-text { padding-top: 1px; font-size: 15px; font-weight: 600; line-height: 1.45; overflow-wrap: anywhere; }
.sp-act-when { margin-top: 1px; color: var(--e-text-3); font-size: 13px; font-weight: 560; }
.sp-activity-more { padding-top: 12px; }
.sp-activity .sp-act-note { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--e-hair); }

/* the week in numbers */
.sp-sum-list { display: flex; flex-direction: column; }
.sp-sum { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 9px 0; }
.sp-sum + .sp-sum { border-top: 1px solid var(--e-hair); }
.sp-sum-ico {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 12px;
  background: var(--e-accent-soft);
  color: var(--e-accent);
}
.sp-sum-ico .ico { width: 17px; height: 17px; }
.sp-sum-label { min-width: 0; font-size: 14px; font-weight: 620; overflow-wrap: anywhere; }
.sp-sum-num { font-size: 20px; font-weight: 760; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.sp-sum.is-zero .sp-sum-ico { background: var(--e-surface-3); color: var(--e-icon); }
.sp-sum.is-zero .sp-sum-label,
.sp-sum.is-zero .sp-sum-num { color: var(--e-text-3); }
.sp-act-summary .sp-foot { margin-top: 10px; padding-top: 12px; border-top: 1px solid var(--e-hair); font-size: 13px; }

/* An actions tab that didn't load (a partial deploy). */
.sp-missing .sp-card-title { margin-bottom: 8px; }

/* ── the student view ─────────────────────────────────────────────────── */
/* The student's skin (.edu-sv in educators.css) recolours the accent; this
   is the layout. The banner stays under the top bar while the page scrolls. */
.edu-sv { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.sv-banner {
  position: sticky;
  top: 74px;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 9px 9px 11px;
  border-radius: 22px;
  background: var(--e-accent-soft);
  color: var(--e-accent-soft-ink);
  box-shadow: var(--e-shadow-sm);
}
/* Whose view: their avatar, with the swap mark on its corner. */
.sv-banner-who { position: relative; flex: none; }
.sv-banner-who .avatar { width: 40px; height: 40px; font-size: 16px; }
.sv-banner-swap {
  position: absolute;
  right: -5px;
  bottom: -5px;
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: var(--e-accent);
  color: #fff;
  box-shadow: 0 0 0 2px var(--e-accent-soft);
}
.sv-banner-swap .ico { width: 12px; height: 12px; }
.sv-banner-words { flex: 1 1 auto; min-width: 0; }
.sv-banner-text { font-size: 15px; font-weight: 720; line-height: 1.3; overflow-wrap: anywhere; }
.sv-nowrap { white-space: nowrap; }
.sv-banner-sub { margin-top: 1px; color: var(--e-accent-soft-ink); font-size: 13px; font-weight: 600; }
.sv-banner .btn { flex: none; }
/* On a phone the way back is "Back", so the banner stays one row. */
.sv-back .sp-wide { display: inline; }
.sv-back .sp-narrow { display: none; }
@media (max-width: 559px) {
  .sv-back .sp-wide { display: none; }
  .sv-back .sp-narrow { display: inline; }
  .sv-banner .btn { padding: 0 14px; }
}
.sv-sections { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.sv-card { padding: 20px; min-width: 0; }
@media (min-width: 640px) {
  .sv-card { padding: 24px 26px; }
}
.sv-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 14px; margin-bottom: 16px; }
.sv-title { font-size: 21px; font-weight: 760; letter-spacing: -0.025em; line-height: 1.25; }
.sv-sub { color: var(--e-text-2); font-size: 14px; font-weight: 600; }

/* Today: streak, study and goal, then the four lists */
.sv-strip { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.sv-tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 14px 16px;
  border-radius: 20px;
  background: var(--e-surface-2);
  box-shadow: inset 0 0 0 1px var(--e-hair);
}
.sv-tile.is-goal { grid-column: 1 / -1; }
.sv-tile.is-kept { background: var(--e-streak-soft); box-shadow: none; }
@media (min-width: 640px) {
  .sv-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .sv-tile.is-goal { grid-column: auto; }
}
.sv-tile-value { font-size: 24px; font-weight: 780; letter-spacing: -0.03em; line-height: 1.15; font-variant-numeric: tabular-nums; }
.sv-tile-value.is-quiet { color: var(--e-text-2); font-size: 16px; font-weight: 650; letter-spacing: 0; }
.sv-goal-title { font-size: 15px; font-weight: 700; overflow-wrap: anywhere; }
.sv-lists { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px 32px; margin-top: 22px; }
@media (min-width: 760px) {
  .sv-lists { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.sv-list { min-width: 0; }
.sv-list-title { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; font-size: 15px; font-weight: 740; }
.sv-count {
  display: inline-grid;
  place-items: center;
  min-width: 24px;
  height: 22px;
  padding: 0 7px;
  border-radius: var(--e-radius-pill);
  background: var(--e-surface-3);
  color: var(--e-text-2);
  font-size: 12px;
  font-weight: 720;
  font-variant-numeric: tabular-nums;
}
.sv-list.is-risk .sv-list-title { color: var(--e-risk-ink); }
.sv-list.is-risk .sv-count { background: var(--e-risk-soft); color: var(--e-risk-ink); }
.sv-rows { display: flex; flex-direction: column; }
.sv-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 9px 0; }
.sv-row + .sv-row { border-top: 1px solid var(--e-hair); }
.sv-row-title { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 15px; font-weight: 620; line-height: 1.35; overflow-wrap: anywhere; }
.sv-row-title > span:last-child { min-width: 0; }
.sv-row-sub { margin-top: 1px; color: var(--e-text-2); font-size: 13px; overflow-wrap: anywhere; }
.sv-plan { grid-template-columns: 20px minmax(0, 1fr); align-items: start; }
.sv-plan-ico { margin-top: 2px; color: var(--e-night-ink); }
.sv-plan.is-done .sv-row-title { color: var(--e-text-2); text-decoration: line-through; text-decoration-color: rgba(79, 93, 104, 0.5); }
.sv-empty { padding: 4px 0; color: var(--e-text-2); font-size: 14px; }
.sv-foot,
.sv-more { margin-top: 6px; color: var(--e-text-2); font-size: 13px; font-weight: 650; }

/* Calendar: this week, then next */
.sv-week + .sv-week { margin-top: 20px; }
.sv-week-label { margin-bottom: 8px; color: var(--e-text-2); font-size: 13px; font-weight: 720; }

/* Mastery: Verified, Learning, Needs work */
.sv-mastery-groups { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px 32px; }
@media (min-width: 960px) {
  .sv-mastery-groups { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.sv-group { min-width: 0; }
.sv-topics { display: flex; flex-direction: column; gap: 12px; margin-top: 6px; }
/* Verified: a check, not a full bar. */
.sv-topic.is-verified { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.sv-check {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--e-accent-soft);
  color: var(--e-accent);
}
.sv-topic-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 10px; margin-bottom: 5px; }
.sv-topic-name { min-width: 0; font-size: 14px; font-weight: 640; overflow-wrap: anywhere; }
.sv-topic-subject { color: var(--e-text-2); font-size: 12px; font-weight: 600; }

/* ── less motion, touch ───────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .sp-menu { animation: none; }
  .sp-filter { transition: none; }
  .sp-tabs { scroll-behavior: auto; }
  .sp-tabs-wrap::before,
  .sp-tabs-wrap::after { transition: none; }
}
@media (pointer: coarse) {
  .sp-menu-item { min-height: 48px; }
  .sp-topic-add.btn-sm,
  .sp-filter { min-height: 44px; }
}
