* { margin: 0; padding: 0; box-sizing: border-box; }


body {
  font-family: var(--tau-font-ui);
  background: var(--tau-bg);
  color: var(--tau-ink);
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.hidden { display: none !important; }
/* The nav (a sibling, not a child) takes its own height; each view fills
   whatever's left rather than claiming the full viewport itself. */
.view { flex: 1; min-height: 0; display: flex; flex-direction: column; }

button {
  font: inherit;
  cursor: pointer;
  border: 1px solid var(--tau-line);
  background: var(--tau-surface);
  border-radius: 8px;
  padding: 8px 14px;
  color: var(--tau-ink);
}
button:hover { border-color: var(--tau-forest); }

/* ---------- assignment list ---------- */

.visibility-cue { font-size: 12px; color: var(--tau-ink-soft); padding: 10px 32px 0; }

/* ---------- workspace ---------- */

.ws-body { flex: 1; min-height: 0; display: flex; }

.sidebar {
  width: 290px;
  min-width: 290px;
  /* A step quieter than the chat pane it sits beside — this is structure,
     not content, and should read as considered rather than competing with
     the conversation for attention. */
  background: var(--tau-surface-2);
  border-right: 1px solid var(--tau-line);
  display: flex;
  flex-direction: column;
  padding: 14px;
  gap: 12px;
}

/* Same collapsible pill-into-sage-box pattern as the assignment card's own
   prompt (.acard-disclosure-prompt below) — reused wholesale rather than
   restyled, so the prompt reads as the same object whether it's on the home
   card or here. The sidebar's own flex gap handles spacing, so no extra
   margin. */
.ws-prompt { margin: 0; }

/* ---------- session list ---------- */
/* Claude-Code-in-VS-Code shape: a new-session action pinned above a flat,
   newest-first list of this draft's conversations. Other drafts' status and
   scores live entirely on the home assignment card — this list only ever
   answers "which session, in the draft I'm currently in". */

.new-session-btn {
  width: 100%;
  text-align: left;
  font-weight: 600;
  color: var(--tau-forest);
  border-color: var(--tau-line);
}
.new-session-btn:hover { background: var(--tau-hover-surface); }
.new-session-btn:disabled { opacity: 0.5; cursor: default; }

.session-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; min-height: 0; }
.session-list-empty { color: var(--tau-ink-soft); font-size: 13px; padding: 8px 10px; }

.conv-item {
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 14px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.conv-item:hover { background: var(--tau-hover-surface); }
.conv-item.active { background: var(--tau-surface-2); color: var(--tau-forest); }
.conv-item.locked::after { content: ' 🔒'; font-size: 11px; }

.sidebar-footer { display: flex; flex-direction: column; gap: 8px; }
.submit-btn {
  background: var(--tau-forest); color: var(--tau-on-forest); border-color: var(--tau-forest);
  border-radius: var(--tau-r-pill); padding: 10px 18px;
  box-shadow: 0 3px 8px -3px color-mix(in oklab, var(--tau-forest) 45%, transparent);
}
.submit-btn:hover { background: var(--tau-forest-lift); border-color: var(--tau-forest-lift); }

/* ---------- chat ---------- */

/* Floats beside the tinted sidebar rather than sitting flush against it —
   same "structure stays quiet, content gets elevation" split as the
   dashboard's tinted rail next to its shadow-lifted cards. Rounded only on
   the free edges (right/top/bottom); the sidebar-facing edge stays square,
   since that seam is the docking line, not a corner. */
.chat {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  margin: 8px 8px 8px 0;
  border-radius: 0 var(--tau-r-xl) var(--tau-r-xl) 0;
  overflow: hidden;
  background: var(--tau-surface);
  box-shadow: var(--tau-shadow);
}

.chat-header {
  padding: 12px 24px;
  background: var(--tau-surface);
  border-bottom: 1px solid var(--tau-line);
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 600;
  font-size: 14px;
}
#btnRename { border: none; background: none; color: var(--tau-ink-soft); padding: 2px 6px; }

/* ---------- coaching-mode banner ---------- */

/* Pedagogy, not a fault. It sits inside the chat rather than the sidebar because
   it governs the next reply the student reads — and it is neutral surface with a
   forest rule, because a tinted banner reads as a warning about a broken tool. */
.mode-banner {
  display: flex;
  align-items: center;
  gap: var(--tau-s3);
  padding: 10px var(--tau-s5);
  background: var(--tau-surface-2);
  color: var(--tau-ink-soft);
  border-bottom: 1px solid var(--tau-line);
  box-shadow: inset 3px 0 0 var(--tau-forest);
  font-size: var(--tau-text-sm);
  line-height: var(--tau-leading-snug);
}
.mode-banner strong { color: var(--tau-ink); font-weight: 600; }
.mode-banner .mode-why {
  margin-left: auto;
  flex-shrink: 0;
  border: none;
  background: none;
  padding: 0 var(--tau-s1);
  font-size: var(--tau-text-xs);
  color: var(--tau-ink-soft);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.mode-banner .mode-why:hover { color: var(--tau-forest); }

.messages { flex: 1; overflow-y: auto; padding: 24px; display: flex; flex-direction: column; gap: 16px; }

.empty-state { margin: auto; text-align: center; color: var(--tau-ink-soft); max-width: 420px; }
.empty-state .empty-sub { font-size: 13px; margin-top: 8px; }

/* ---------- turns ---------- */

/* The turn shell itself is in components.css — the report and the teacher's
   transcript replay the same object. What stays here is chat-only: the edit
   affordance and the interrupted-response note, neither of which exists on a
   surface you can only read. */

.msg .stopped-note { display: block; font-size: 11px; color: var(--tau-ink-soft); margin-top: 6px; font-style: italic; }

/* ---------- coach is thinking ---------- */

/* A multi-second model call makes this unavoidable. It is a peer of the turns,
   not an overlay, so the thread does not jump when the first token lands. */
.thinking {
  display: flex;
  align-items: center;
  gap: var(--tau-s2);
  color: var(--tau-ink-faint);
  font-size: 13.5px;
  padding-left: 2px;
}
/* A breathing orb, not three static dots — this is the one moment the
   product is visibly an AI reasoning in real time, and a row of grey dots is
   indistinguishable from any loading spinner on the web. Sage-to-forest, the
   same two brand colours already in the token set doing one more job, not a
   new colour invented for this. */
.thinking-orb {
  width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0;
  background: radial-gradient(circle at 32% 30%, var(--tau-origin-together-bg), var(--tau-forest) 75%);
  animation: tau-breathe 2.1s ease-in-out infinite;
}
@keyframes tau-breathe {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 color-mix(in oklab, var(--tau-forest) 28%, transparent); }
  50% { transform: scale(1.12); box-shadow: 0 0 0 6px color-mix(in oklab, var(--tau-forest) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .thinking-orb { animation: none; } }

.msg-edit-btn {
  position: absolute;
  left: calc(var(--tau-target) * -1);
  top: 50%;
  transform: translateY(-50%);
  width: var(--tau-target);
  height: var(--tau-target);
  display: none;
  place-items: center;
  border: none;
  background: none;
  color: var(--tau-ink-soft);
  font-size: var(--tau-text-md);
  padding: 0;
}
/* Shown on focus as well as hover — hover-only would put this control out of
   reach of a keyboard, and off a touch screen entirely. */
.turn-student:hover .msg-edit-btn,
.msg-edit-btn:focus-visible { display: grid; }

/* ---------- composer ---------- */

.composer {
  padding: 12px 24px 16px;
  background: var(--tau-surface);
  border-top: 1px solid var(--tau-line);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.composer-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.composer-row .spacer { flex: 1; }
.composer-hint { font-size: var(--tau-text-xs); color: var(--tau-ink-faint); }

.edit-banner {
  width: 100%;
  font-size: 12px;
  color: var(--tau-forest);
  background: var(--tau-surface-2);
  border-radius: 6px;
  padding: 4px 10px;
}
.edit-banner button { border: none; background: none; color: var(--tau-ink-soft); font-size: 12px; padding: 0 4px; }

.stop-btn { color: var(--tau-attention); border-color: var(--tau-attention); }

#input {
  width: 100%;
  font: inherit;
  font-size: var(--tau-text-md);
  border: 1px solid transparent;
  border-radius: var(--tau-r-lg);
  padding: 11px 13px;
  resize: none;
  max-height: 160px;
  background: var(--tau-surface-2);
  color: var(--tau-ink);
  transition: box-shadow var(--tau-dur-medium) var(--tau-ease-decelerate), background var(--tau-dur-short) var(--tau-ease-standard);
}
#input:hover { background: var(--tau-surface); box-shadow: var(--tau-shadow); }
#input:focus { outline: none; background: var(--tau-surface); box-shadow: var(--tau-shadow); border-color: var(--tau-forest); }

/* Persistent header (not a note buried at the bottom) so a student who follows
   a locked past-draft conversation is reoriented the instant they land, and
   always has one click back to their live draft. */
.reading-banner {
  padding: 10px 24px;
  background: var(--tau-auditor-bg);
  border-bottom: 1px solid var(--tau-line);
  font-size: 13px;
  color: var(--tau-ink);
  display: flex;
  align-items: center;
  gap: 14px;
}
.reading-banner-return {
  background: none; border: 1px solid var(--tau-auditor); color: var(--tau-auditor);
  padding: 4px 10px; font-size: 12px; border-radius: 7px;
}
.reading-banner-return:hover { background: var(--tau-auditor-bg); border-color: var(--tau-auditor); }

/* ---------- report ---------- */

.report { padding: 32px; max-width: 860px; margin: 0 auto; width: 100%; overflow-y: auto; display: flex; flex-direction: column; gap: 20px; }

.report-pending { text-align: center; color: var(--tau-ink-soft); padding: 80px 0; }
.report-pending .spinner {
  width: 28px; height: 28px; margin: 0 auto 16px;
  border: 3px solid var(--tau-line); border-top-color: var(--tau-forest);
  border-radius: 50%; animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.samr-hero {
  background: var(--tau-surface); border: 1px solid var(--tau-line); border-radius: 14px;
  padding: 24px; text-align: center;
}
.samr-hero .samr-level { font-size: 26px; font-weight: 700; }
.samr-hero .samr-total { color: var(--tau-ink-soft); font-size: 14px; margin-top: 4px; }

.tau-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; }
.tau-card {
  background: var(--tau-surface); border: 1px solid var(--tau-line); border-radius: 12px; padding: 16px;
}
.tau-card .tau-name { font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--tau-ink-soft); }
.tau-card .tau-score { font-size: 28px; font-weight: 700; margin: 4px 0; }
.tau-card .tau-desc { font-size: 12px; color: var(--tau-ink-soft); line-height: 1.45; }
.tau-bar { height: 6px; background: var(--tau-meter-track); border-radius: 3px; margin: 8px 0; overflow: hidden; }
.tau-bar > div { height: 100%; background: var(--tau-forest); border-radius: 3px; }

.report-panel { background: var(--tau-surface); border: 1px solid var(--tau-line); border-radius: 12px; padding: 20px; }
.report-panel h3 { font-size: 15px; margin-bottom: 12px; }

.strength { border-left: 3px solid var(--tau-forest); padding: 6px 14px; margin-bottom: 12px; }
.strength .quote { font-style: italic; }
.strength .note { font-size: 13px; color: var(--tau-ink-soft); margin-top: 4px; }
.growth-move { padding: 8px 14px; background: var(--tau-surface-2); border-radius: 8px; margin-bottom: 8px; font-size: 14px; }
.bridge { font-size: 14px; color: var(--tau-ink-soft); margin-top: 12px; line-height: 1.5; }

/* The provenance bar, origin chips and legend live in components.css — the
   report renders the same three, and had built its own set. */
.concept-item { display: flex; gap: 10px; font-size: 13px; padding: 6px 0; border-bottom: 1px solid var(--tau-line); align-items: baseline; }
.concept-phrase { color: var(--tau-ink-soft); font-style: italic; }

/* ---------- submit modal ---------- */
/* Chrome + layout come from components.css's .scrim/.confirm/.confirm-lg —
   this is only the essay textarea's own styling. */
#essayText { font: inherit; border: 1px solid var(--tau-line); border-radius: var(--tau-r-md); padding: 10px 14px; resize: vertical; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.upload-drop {
  display: flex; align-items: center; justify-content: center;
  min-height: 96px; padding: 16px; text-align: center;
  border: 1px dashed var(--tau-line); border-radius: var(--tau-r-md);
  background: var(--tau-surface-2); color: var(--tau-ink-soft);
  font-size: var(--tau-text-md); cursor: pointer;
  transition: background var(--tau-dur-short) var(--tau-ease-standard),
              border-color var(--tau-dur-short) var(--tau-ease-standard);
}
.upload-drop:hover, .upload-drop.drag-over { background: var(--tau-surface); border-color: var(--tau-forest); }
.upload-drop.has-file { text-align: left; color: var(--tau-ink); }

.upload-error { font-size: var(--tau-text-sm); color: var(--tau-attention); }
.upload-switch { margin-top: 2px; }
#draftUpload, #draftPaste { display: flex; flex-direction: column; gap: 10px; }

/* ---------- login ---------- */

.login-body { overflow: hidden; background: var(--tau-surface-2); }

/* One continuous ground-wash page, not two adjacent panels — the card is
   what signals "raised," so the two halves don't need their own fill or a
   seam between them. Stacks on narrow viewports. */
.login-shell {
  display: flex;
  width: 100%;
  height: 100%;
}
.login-hero {
  flex: 1 1 50%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--tau-s4);
  padding: var(--tau-s9);
}
.login-hero-logo { height: 64px; width: auto; }
.login-hero-title {
  font-size: clamp(28px, 4vw, 44px);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.1;
}
.login-hero-tagline {
  font-size: clamp(15px, 1.6vw, 19px);
  color: var(--tau-ink-soft);
  max-width: 42ch;
  text-wrap: balance;
}
.login-hero-sub {
  font-size: clamp(13px, 1.2vw, 15px);
  color: var(--tau-ink-faint);
  max-width: 44ch;
  margin-top: calc(var(--tau-s2) * -1);
  text-wrap: balance;
}
.login-panel {
  flex: 1 1 50%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow-y: auto;
  padding: var(--tau-s6);
}
.login-card {
  width: 100%;
  max-width: 420px;
  gap: 14px;
}
.login-card h1 { font-size: 20px; }
.login-sub { font-size: 14px; color: var(--tau-ink-soft); margin-top: -8px; }

@media (max-width: 760px) {
  .login-shell { flex-direction: column; overflow-y: auto; }
  .login-hero {
    flex: 0 0 auto;
    padding: var(--tau-s7) var(--tau-s6);
    gap: var(--tau-s3);
  }
  .login-hero-logo { height: 44px; }
  .login-hero-title { font-size: 26px; }
  .login-hero-tagline { font-size: 14px; max-width: none; }
  .login-hero-sub { font-size: 13px; max-width: none; }
  .login-panel { flex: 1 1 auto; max-width: none; }
}

.google-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: flex-start;
  padding: 11px 14px;
  font-size: 14px;
  text-align: left;
}
.google-btn:disabled { opacity: var(--tau-disabled); cursor: not-allowed; }
.google-btn:disabled:hover { border-color: var(--tau-line); }
.google-mark {
  font-weight: 700;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--tau-surface-2);
  flex-shrink: 0;
}
.soon {
  margin-left: auto;
  white-space: nowrap;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tau-ink-soft);
}

.login-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--tau-ink-soft);
}
.login-divider::before,
.login-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--tau-line);
}

#loginForm { display: flex; flex-direction: column; gap: 6px; }
#loginForm label { font-size: 13px; color: var(--tau-ink-soft); margin-top: 6px; }
#loginForm input {
  font: inherit;
  border: 1px solid var(--tau-line);
  border-radius: 8px;
  padding: 9px 12px;
  background: var(--tau-surface);
  color: var(--tau-ink);
}
#loginForm input:focus { outline: 2px solid var(--tau-surface-2); border-color: var(--tau-forest); }

.login-error {
  background: var(--tau-attention-bg);
  border: 1px solid var(--tau-attention);
  color: var(--tau-attention);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
  margin-top: 10px;
}
.login-submit {
  margin-top: 12px;
  background: var(--tau-forest);
  border-color: var(--tau-forest);
  color: var(--tau-on-forest);
  padding: 10px 14px;
  font-weight: 600;
}
.login-submit:hover { background: var(--tau-forest-lift); border-color: var(--tau-forest-lift); }
.login-submit:disabled { opacity: var(--tau-disabled); cursor: default; }

.test-accounts { font-size: 13px; color: var(--tau-ink-soft); border-top: 1px solid var(--tau-line); padding-top: 12px; }
.test-accounts summary { cursor: pointer; }
.test-hint { margin: 10px 0 8px; }
.test-hint code { background: var(--tau-surface-2); padding: 1px 6px; border-radius: 5px; }
.test-accounts ul { list-style: none; display: flex; flex-direction: column; gap: 4px; }
.test-accounts li { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.test-account {
  padding: 3px 8px;
  font-size: 12px;
  border-radius: 6px;
  color: var(--tau-forest);
}
.test-note { font-size: 11px; }

/* ---------- dashboard shell ---------- */

.dash { display: flex; flex: 1; overflow: hidden; }

/* Fixed ground: identity and standing. Scrolls independently of the content.
   No border — separation from the content pane is tonal (surface-2 against
   the page's --tau-bg), not a hairline. Depth belongs to elevated surfaces
   like the assignment cards; this is flat structure, so it stays flat. */
.dash-rail {
  width: 292px;
  min-width: 292px;
  background: var(--tau-surface-2);
  overflow-y: auto;
  padding: 20px 18px 36px;
  display: flex;
  flex-direction: column;
}
.dash-main { flex: 1; overflow-y: auto; padding: 26px 32px 72px; background: #FFFFFF; }
:root[data-theme="dark"] .dash-main { background: var(--tau-bg); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .dash-main { background: var(--tau-bg); }
}
.dash-main > .chunk { max-width: 880px; }

.rail-identity { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
.rail-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--tau-surface-3); color: var(--tau-forest);
  display: grid; place-items: center;
  font-size: 14px; font-weight: 700; flex-shrink: 0;
}
.rail-who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rail-name { font-size: 14px; font-weight: 600; }
.rail-sub { font-size: 12px; color: var(--tau-ink-soft); }

.rail-nav {
  padding-top: 16px; margin-top: 16px; border-top: 1px solid var(--tau-line);
  display: flex; flex-direction: column; gap: 2px;
}
.rail-nav-row {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; padding: 7px 8px; border: none; border-radius: var(--tau-r-sm);
  background: none; text-align: left; cursor: pointer;
  transition: background var(--tau-dur-short) var(--tau-ease-standard);
}
.rail-nav-row:hover, .rail-nav-row:focus-visible { background: var(--tau-surface-3); }
.rail-nav-title { font-size: 13px; font-weight: 600; }
.rail-nav-due { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }

/* Pinned to the bottom of the rail via margin-top: auto — whatever room
   .rail-nav doesn't use, this claims, so guidance reads as the rail's
   settled-at-the-bottom conclusion rather than just more stacked content. */
.rail-progress { padding-top: 16px; margin-top: auto; border-top: 1px solid var(--tau-line); }
.rail-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--tau-ink-soft); margin-bottom: 12px;
}
.rail-block + .rail-block { margin-top: 26px; }
.rail-empty { font-size: 13px; color: var(--tau-ink-soft); line-height: 1.55; }

.meters { display: flex; flex-direction: column; gap: 18px; }
.meter-name { font-size: 12px; color: var(--tau-ink-soft); margin-bottom: 5px; display: block; }
/* Same slot the old ▲/▼ delta line and the bar underneath it used to fill —
   a sentence carries more than either did on its own, so it replaces both
   rather than sitting alongside them. */
.meter-guidance { font-size: 12.5px; color: var(--tau-ink-soft); line-height: 1.5; }

/* ---------- content chunks ---------- */

.chunk { margin-bottom: 38px; }
.chunk-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.chunk-head h2 { font-size: 17px; letter-spacing: -0.01em; }
.chunk-count { font-size: 12px; color: var(--tau-ink-soft); }
.chunk-note { font-size: 13px; color: var(--tau-ink-soft); margin-bottom: 14px; }
.chunk-head + #currentList { margin-top: 14px; }
.home-empty { color: var(--tau-ink-soft); font-size: 14px; }

/* ---------- current assignment card ---------- */

/* Chrome (background/border/radius/padding) comes from components.css's
   .card + .card-lg — this card's own values were an exact, independently-
   arrived-at match for .card-lg, so it composes rather than redeclares.
   Urgency reuses .card-edge-caution/.card-edge-attention for the same
   reason: a recoloured card would make an ordinary deadline look like an
   error state, and that edge rule already exists once in components.css. */
.acard { margin-bottom: 14px; transition: outline-color var(--tau-dur-short) var(--tau-ease-standard); outline: var(--tau-focus-ring); outline-color: transparent; outline-offset: var(--tau-focus-gap); }
.acard-jumped { outline-color: var(--tau-forest); }

.acard-due { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; }
.acard-due-calm { color: var(--tau-ink-soft); }
.acard-due-soon { color: var(--tau-caution); }
.acard-due-late { color: var(--tau-attention); }
.acard-class { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--tau-ink-soft); }
.acard-sep { color: var(--tau-line-strong); font-size: 11px; }
.acard-title-row { display: flex; align-items: center; justify-content: space-between; gap: var(--tau-s3); margin-top: 5px; }
.acard-title { font-size: 20px; letter-spacing: -0.015em; }
.acard-rubric-btn { flex-shrink: 0; }

/* ---------- draft rows (home card) ---------- */

/* One row per draft slot, always in budget order — the single place a
   student reads "where does draft 2 stand," independent of whatever the
   assignment as a whole is doing. The workspace sidebar only ever shows the
   current draft's sessions, so this is also the only cross-draft view. */
.draft-rows {
  display: flex; flex-direction: column; gap: 8px;
  margin: 15px 0;
}
.draft-row {
  display: flex; flex-direction: column; gap: 10px; padding: 13px 15px;
  font-size: 13px;
  border: 1px solid var(--tau-line);
  border-radius: var(--tau-r-md);
}
/* Line 1 — identity: which draft, and when it's due. */
.draft-row-id { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.draft-row-num { font-weight: 600; }
.draft-row-sep { color: var(--tau-line-strong); }
.draft-row-final-badge {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--tau-ink-soft); border: 1px solid var(--tau-line); border-radius: var(--tau-r-pill);
  padding: 2px 8px; margin-left: 2px;
}
.draft-row-due { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }

/* Line 3 — functionality: a button (current draft), a report link
   (submitted), or just the detail text explaining why there's nothing to do
   (locked, still analyzing). */
.draft-row-body { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.draft-row-detail { color: var(--tau-ink-soft); }
/* Explicitly inert, not just quieter: no bold num, no colored status word,
   reduced opacity on the whole row — has to read as "can't touch this yet"
   at a glance, not as a same-weight row that happens to be gray. */
.draft-row-locked { opacity: 0.55; border-style: dashed; }
.draft-row-locked .draft-row-num { font-weight: 400; color: var(--tau-ink-faint); }

/* draft-row-in-progress/-not-started only ever apply to the current cycle's
   row (see draftRowStatus) — the ledger's "you are here" row, anchored so a
   student scanning down from the button lands on it without re-reading every
   row's label. Sized up (padding, gap) beyond the other rows too — it's the
   one row a returning student actually needs to act on, so it gets to be the
   biggest thing in the ledger, not the same size as an inert past row. */
.draft-row-in-progress, .draft-row-not-started {
  padding: 18px 16px; gap: 14px; border-radius: var(--tau-r-lg);
  background: var(--tau-surface-2);
  border-color: transparent;
}

/* Status vocabulary shared with the workspace's draft sections — one color
   per state so the same word always reads the same way everywhere. */
.status-submitted { color: var(--tau-ink-soft); }
.status-not-started { color: var(--tau-ink-soft); font-style: italic; }
.status-in-progress { color: var(--tau-forest); font-weight: 600; }
.status-locked { color: var(--tau-ink-faint); }

/* A teacher note on a submitted draft is never guaranteed and never the
   point of the row — it's a quiet flag, not a block, so it can't crowd out
   the row's one real action (View report). The note itself only ever reads
   in the report, same place the flag's icon (✉) already means "teacher
   note" on the past-assignment chips. */
.draft-row-note-flag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; font-weight: 600; color: var(--tau-auditor);
}
.draft-row-note-flag .tau-icon { width: 13px; height: 13px; }

/* Lives inside the current draft's row now, not a card-level footer — sized
   down slightly (13px vs 14px) since it's one element among several in a
   row rather than the card's sole point of action. */
.acard-btn, .draft-row-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--tau-forest); border-color: var(--tau-forest); color: var(--tau-on-forest);
  font-weight: 600; border-radius: var(--tau-r-pill);
  box-shadow: 0 3px 8px -3px color-mix(in oklab, var(--tau-forest) 45%, transparent);
  transition: background var(--tau-dur-short) var(--tau-ease-standard), border-color var(--tau-dur-short) var(--tau-ease-standard), transform var(--tau-dur-short) var(--tau-ease-standard);
}
.acard-btn { font-size: 14px; padding: 11px 20px; }
.draft-row-btn { font-size: 13px; padding: 9px 16px; }
.draft-row-action-detail { color: var(--tau-ink-soft); font-size: 13px; }
.acard-btn:hover, .draft-row-btn:hover { background: var(--tau-forest-lift); border-color: var(--tau-forest-lift); }
.acard-btn:active, .draft-row-btn:active { transform: scale(0.97); }

/* .acard-disclosure* moved to components.css section 3c — report.html
   needed the same disclosure component and doesn't load style.css. */

/* ---------- past assignment card ---------- */

/* Chrome comes from components.css's .card — this card's own radius/padding
   (12px, 15/18px) were organic drift from an independent implementation, not
   an intentional size; they're within a couple of px of .card's own values,
   so this composes onto .card exactly rather than keeping a third value. */
.pcard { margin-bottom: 10px; }
.pcard-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.pcard-head h3 { font-size: 15px; flex: 1; min-width: 200px; }
.pcard-outcome { display: flex; align-items: baseline; gap: 9px; }
.pcard-score { font-size: 19px; font-weight: 700; }
.pcard-denom { font-size: 12px; color: var(--tau-ink-soft); margin-left: -6px; }
.pcard-band { font-size: 12px; font-weight: 600; padding-left: 8px; border-left-width: 3px; border-left-style: solid; }
.pcard-meta { font-size: 12px; color: var(--tau-ink-soft); margin: 3px 0 11px; }

/* ---------- draft chips ---------- */

.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.draft-chip {
  display: flex; align-items: baseline; gap: 7px;
  padding: 6px 11px; border-radius: 9px;
  border: 1px solid var(--tau-line); background: var(--tau-surface); font-size: 13px;
}
.draft-chip .chip-cycle { color: var(--tau-ink-soft); font-size: 12px; }
.draft-chip .chip-score { font-weight: 700; font-variant-numeric: tabular-nums; }
.draft-chip .chip-denom { font-weight: 400; font-size: 11px; color: var(--tau-ink-soft); }
.draft-chip .chip-samr { font-size: 12px; color: var(--tau-ink-soft); }
.draft-chip .chip-note { color: var(--tau-auditor); display: inline-flex; }
.draft-chip .chip-note .tau-icon { width: 13px; height: 13px; }
button.draft-chip { cursor: pointer; transition: border-color var(--tau-dur-short) var(--tau-ease-standard); }
button.draft-chip:hover { border-color: var(--tau-forest); }
.draft-chip-pending { color: var(--tau-ink-soft); }
.draft-chip-pending .chip-score { font-weight: 400; font-size: 12px; }

/* The .samr-* colour mapping itself lives in components.css, next to
   .band-1..4 (same ramp, applied as a border accent) — this is just the
   width/padding this particular chip needs from it. */
.draft-chip[class*='samr-'] { border-left-width: 5px; padding-left: 10px; }

@media (max-width: 900px) {
  .dash { flex-direction: column; overflow-y: auto; }
  .dash-rail { width: 100%; min-width: 0; border-right: none; border-bottom: 1px solid var(--tau-line); overflow: visible; padding-bottom: 24px; }
  .dash-main { overflow: visible; padding: 24px 20px 60px; }
  /* Collapsed, the rail is a band: the three blocks run side by side so the
     meters keep a sane width instead of stretching the full page. */
  .rail-progress { display: flex; flex-wrap: wrap; gap: 30px 40px; align-items: flex-start; }
  .rail-block { flex: 1 1 240px; max-width: 340px; }
  .rail-block + .rail-block { margin-top: 0; }
}

