/* ============================================================================
   views.css — layout specific to each page.
   ========================================================================== */

/* ============================ DASHBOARD ================================== */
.hero-card {
  position: relative; overflow: hidden;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--pad-card);
}
.hero-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--hero-accent, var(--primary));
}
.hero-card__eyebrow {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--text-muted);
  margin-bottom: var(--sp-2);
}
.hero-card__eyebrow svg { width: 15px; height: 15px; }
.hero-card__title { font-size: var(--fs-xl); margin-bottom: var(--sp-1); }
.hero-card__meta { color: var(--text-muted); font-size: var(--fs-base); }

.countdown { display: flex; gap: var(--sp-3); margin-top: var(--sp-4); flex-wrap: wrap; }
.countdown__unit {
  min-width: 62px; padding: var(--sp-2) var(--sp-3);
  background: var(--surface-2); border-radius: var(--r-md); text-align: center;
}
.countdown__num {
  display: block; font-size: var(--fs-xl); font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums; line-height: 1.15; letter-spacing: -0.02em;
}
.countdown__label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-subtle); font-weight: var(--fw-semi); }
.countdown--urgent .countdown__num { color: var(--danger); }
.countdown--soon .countdown__num { color: var(--accent); }

.timeline { display: flex; flex-direction: column; }
.timeline__item {
  display: grid; grid-template-columns: 62px 20px 1fr; gap: var(--sp-3);
  padding: var(--sp-3) 0; align-items: start;
}
.timeline__time {
  font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--text-muted);
  font-variant-numeric: tabular-nums; padding-top: 1px;
}
.timeline__rail { position: relative; display: grid; place-items: start center; height: 100%; }
.timeline__rail::before {
  content: ""; position: absolute; top: 14px; bottom: -18px; width: 2px;
  background: var(--border);
}
.timeline__item:last-child .timeline__rail::before { display: none; }
.timeline__node {
  width: 11px; height: 11px; border-radius: 50%; margin-top: 5px;
  background: var(--node-color, var(--primary)); position: relative; z-index: 1;
  box-shadow: 0 0 0 3px var(--surface);
}
.timeline__body { min-width: 0; }
.timeline__body strong { display: block; font-size: var(--fs-base); font-weight: var(--fw-semi); }
.timeline__body span { font-size: var(--fs-sm); color: var(--text-muted); }
.timeline__item.is-now .timeline__node { background: var(--now-line); animation: pulse 2.4s ease-in-out infinite; }
.timeline__item.is-past { opacity: 0.5; }
@keyframes pulse { 0%,100% { box-shadow: 0 0 0 3px var(--surface), 0 0 0 3px color-mix(in srgb, var(--now-line) 40%, transparent); } 50% { box-shadow: 0 0 0 3px var(--surface), 0 0 0 8px color-mix(in srgb, var(--now-line) 0%, transparent); } }

.progress-tile { display: flex; align-items: center; gap: var(--sp-4); }
.progress-tile__text { min-width: 0; }

/* ============================ SCHEDULE =================================== */
.sched-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.sched-toolbar .spacer { flex: 1; }

.week-grid {
  --time-col: 68px;
  --hour-h: 58px;
  display: grid;
  grid-template-columns: var(--time-col) repeat(var(--day-count, 5), minmax(112px, 1fr));
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
  min-width: max-content;
}
.week-scroll { overflow-x: auto; overscroll-behavior-x: contain; padding-bottom: var(--sp-2); }
@media (min-width: 1024px) { .week-grid { min-width: 0; } }

.week-grid__corner,
.week-grid__dayhead {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-2); border-bottom: 1px solid var(--border);
  padding: var(--sp-2) var(--sp-2);
  text-align: center;
}
.week-grid__corner { z-index: 3; border-right: 1px solid var(--border); }
.week-grid__dayhead strong { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.week-grid__dayhead small { font-size: var(--fs-xs); color: var(--text-subtle); font-variant-numeric: tabular-nums; }
.week-grid__dayhead.is-today { background: var(--primary-soft); }
.week-grid__dayhead.is-today strong { color: var(--primary-soft-fg); }
/* --text-subtle only reaches 4.43:1 on the tinted today cell; the accent
   foreground is both compliant and the more meaningful colour here. */
.week-grid__dayhead.is-today small { color: var(--primary-soft-fg); font-weight: var(--fw-semi); }

.week-grid__times {
  grid-column: 1; grid-row: 2;
  border-right: 1px solid var(--border); background: var(--surface);
}
.week-grid__hour {
  height: var(--hour-h); position: relative;
  font-size: var(--fs-xs); color: var(--text-subtle); font-variant-numeric: tabular-nums;
  padding-right: 6px; text-align: right;
}
/* nowrap is load-bearing, not tidiness. In 12-hour mode "10:00 AM" is wider
   than the time column: it wrapped to two lines, which pushed its centre down
   by a whole line-height while "9:00 AM" stayed on one. The labels then
   disagreed with each other by 9.6px halfway down the grid, and the earlier
   hours read as shifted up against the ones below. The column is sized for
   the widest label the 12-hour format can produce. */
.week-grid__hour span { position: relative; top: -7px; white-space: nowrap; }
/* The first label has no gridline above it to sit on — it marks the top edge
   of the grid, and the -7px nudge pushed it under the sticky day header,
   which paints over it. Top-align just this one so it is fully visible. */
.week-grid__hour:first-child span { top: 0; }

.week-grid__day {
  grid-row: 2; position: relative;
  border-right: 1px solid var(--border);
  background-image: repeating-linear-gradient(to bottom, var(--grid-line) 0 1px, transparent 1px var(--hour-h));
}
.week-grid__day:last-child { border-right: 0; }
.week-grid__day.is-today { background-color: color-mix(in srgb, var(--primary) 4%, transparent); }

.session {
  position: absolute; left: 2px; right: 2px;
  padding: 5px 7px; overflow: hidden;
  border-radius: var(--r-sm);
  border-left: 3px solid var(--s-color, var(--primary));
  background: color-mix(in srgb, var(--s-color, var(--primary)) 14%, var(--surface));
  color: var(--text); text-align: left;
  font-size: var(--fs-xs); line-height: 1.3;
  transition: transform var(--dur-instant) var(--ease-out), filter var(--dur-fast);
  cursor: pointer;
}
.session:hover { filter: brightness(0.97); z-index: 4; }
:root.is-dark .session:hover { filter: brightness(1.15); }
.session:active { transform: scale(0.98); }
.session strong { display: block; font-weight: var(--fw-semi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.session span { color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.session.is-conflict { outline: 2px dashed var(--danger); outline-offset: -2px; }

.now-line {
  position: absolute; left: 0; right: 0; height: 2px;
  background: var(--now-line); z-index: 3; pointer-events: none;
}
.now-line::before {
  content: ""; position: absolute; left: -4px; top: -3px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--now-line);
}

/* Day list (mobile / list mode) */
.day-list { display: flex; flex-direction: column; gap: var(--sp-5); }
.day-block__head {
  display: flex; align-items: baseline; gap: var(--sp-2);
  margin-bottom: var(--sp-2); padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--border);
}
.day-block__head h3 { font-size: var(--fs-base); }
.day-block__head small { color: var(--text-subtle); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.day-block__head .badge-today {
  margin-left: auto; font-size: var(--fs-xs); font-weight: var(--fw-bold);
  color: var(--primary-soft-fg); background: var(--primary-soft);
  padding: 2px 8px; border-radius: var(--r-full);
}

.slot {
  display: grid; grid-template-columns: 66px 1fr auto; gap: var(--sp-3);
  align-items: center; width: 100%; text-align: left;
  padding: var(--sp-3); border-radius: var(--r-md);
  border-left: 3px solid var(--s-color, var(--primary));
  background: var(--surface); border-top: 1px solid var(--border);
  border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
  transition: background var(--dur-fast), transform var(--dur-instant);
  min-height: 56px;
}
.slot + .slot { margin-top: var(--sp-2); }
.slot:hover { background: var(--surface-hover); }
.slot:active { transform: scale(0.995); }
.slot__time { font-size: var(--fs-sm); font-weight: var(--fw-semi); font-variant-numeric: tabular-nums; line-height: 1.3; }
.slot__time small { display: block; font-weight: var(--fw-regular); color: var(--text-subtle); }
.slot__body { min-width: 0; }
.slot__body strong { display: block; font-weight: var(--fw-semi); }
.slot__body span { font-size: var(--fs-sm); color: var(--text-muted); }

/* ============================== EXAMS ==================================== */
.exam-card {
  display: grid; gap: var(--sp-3);
  grid-template-columns: 68px 1fr;
  padding: var(--pad-card);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg);
  border-left: 4px solid var(--e-color, var(--primary));
  transition: border-color var(--dur-fast), background var(--dur-fast);
}
.exam-card:hover { background: var(--surface-hover); }
.exam-card.is-done { opacity: 0.62; }
.exam-card.is-urgent { border-left-color: var(--danger); }

.exam-date {
  display: grid; place-items: center; align-content: center;
  padding: var(--sp-2); border-radius: var(--r-md);
  background: var(--surface-2); text-align: center; height: fit-content;
}
.exam-date__day { font-size: var(--fs-xl); font-weight: var(--fw-bold); line-height: 1; font-variant-numeric: tabular-nums; }
.exam-date__mon { font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em; font-weight: var(--fw-bold); color: var(--text-subtle); margin-top: 3px; }
.exam-date__dow { font-size: var(--fs-xs); color: var(--text-subtle); margin-top: 2px; }

.exam-body { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.exam-body__title { display: flex; align-items: flex-start; gap: var(--sp-2); }
.exam-body__title h3 { font-size: var(--fs-lg); min-width: 0; }
.exam-facts { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); font-size: var(--fs-sm); color: var(--text-muted); }
.exam-facts span { display: inline-flex; align-items: center; gap: 5px; }
.exam-facts svg { width: 14px; height: 14px; flex: none; color: var(--text-subtle); }
.exam-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-1); }

.exam-group__head {
  display: flex; align-items: center; gap: var(--sp-3);
  margin: var(--sp-6) 0 var(--sp-3);
}
.exam-group__head:first-child { margin-top: 0; }
.exam-group__head h2 { font-size: var(--fs-base); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: var(--fw-bold); }
.exam-group__head hr { flex: 1; height: 1px; background: var(--border); border: 0; }

/* ============================== TASKS ==================================== */
.task-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--sp-3);
  align-items: center;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
  transition: background var(--dur-fast);
  min-height: 56px;
}
.task-row:last-child { border-bottom: 0; }
.task-row:hover { background: var(--surface-hover); }
.task-row.is-done .task-row__title { text-decoration: line-through; color: var(--text-subtle); }

.task-check {
  width: 22px; height: 22px; border-radius: var(--r-sm);
  border: 2px solid var(--border-strong); background: var(--surface);
  display: grid; place-items: center; flex: none;
  transition: background var(--dur-fast), border-color var(--dur-fast), transform var(--dur-instant) var(--ease-spring);
}
.task-check svg { width: 14px; height: 14px; stroke-width: 3; opacity: 0; transform: scale(0.5); transition: opacity var(--dur-fast), transform var(--dur-fast) var(--ease-spring); color: var(--primary-fg); }
.task-check:hover { border-color: var(--primary); }
.task-check[aria-pressed="true"] { background: var(--primary); border-color: var(--primary); }
.task-check[aria-pressed="true"] svg { opacity: 1; transform: none; }
/* Hit area ≥44px without changing visual bounds */
.task-check::after { content: ""; position: absolute; inset: -11px; }
.task-check { position: relative; }

.task-row__body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.task-row__title { font-weight: var(--fw-medium); overflow-wrap: anywhere; }
.task-row__meta { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.task-row__actions { display: flex; gap: 2px; opacity: 0; transition: opacity var(--dur-fast); }
.task-row:hover .task-row__actions,
.task-row:focus-within .task-row__actions { opacity: 1; }
@media (hover: none) { .task-row__actions { opacity: 1; } }

.quick-add { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.quick-add .input { flex: 1; }

.filter-bar {
  display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center;
  margin-bottom: var(--sp-4);
}
.filter-bar .spacer { flex: 1; }

/* ============================== GRADES =================================== */
.gpa-hero { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-6); }
.gpa-hero__ring { flex: none; position: relative; display: grid; place-items: center; }
.gpa-hero__ring output {
  position: absolute; display: grid; place-items: center; text-align: center;
  font-size: var(--fs-2xl); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em; line-height: 1;
}
.gpa-hero__ring output small { display: block; font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--text-subtle); letter-spacing: 0; margin-top: 3px; }

.course-grade {
  display: grid; gap: var(--sp-2); min-width: 0;
  padding: var(--sp-4) 0; border-bottom: 1px solid var(--border);
}
/* Grid and flex items default to min-width:auto, which refuses to shrink
   below their content — the classic cause of horizontal scroll on phones.
   Everything that holds variable-length text opts out explicitly. */
.course-grade > * { min-width: 0; max-width: 100%; }
.course-grade:last-child { border-bottom: 0; }
.course-grade__top { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; flex-wrap: wrap; }
.course-grade__top strong { flex: 1 1 40%; min-width: 0; }
.course-grade__pct { font-variant-numeric: tabular-nums; font-weight: var(--fw-bold); font-size: var(--fs-lg); }
.course-grade__letter {
  min-width: 40px; text-align: center; padding: 2px var(--sp-2);
  border-radius: var(--r-sm); font-weight: var(--fw-bold); font-size: var(--fs-sm);
  background: var(--surface-2);
}

.bars { display: flex; align-items: stretch; gap: var(--sp-2); height: 148px; padding-top: var(--sp-3); }
/* Three rows: value, a flexible track, label. The bar's height percentage is
   resolved against the track alone, so 81% and 90% render exactly 9% apart —
   a bar chart that misstates its own values is worse than no chart. */
.bars__col { flex: 1 1 0; min-width: 0; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 5px; }
.bars__value { font-size: var(--fs-xs); font-weight: var(--fw-semi); text-align: center; font-variant-numeric: tabular-nums; }
.bars__track { display: flex; align-items: flex-end; justify-content: center; min-height: 0; }
.bars__bar { width: 100%; max-width: 46px; border-radius: var(--r-xs) var(--r-xs) 0 0; background: var(--bar-color, var(--primary)); transition: height var(--dur-slow) var(--ease-out); min-height: 3px; }
.bars__label { font-size: var(--fs-xs); color: var(--text-subtle); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; text-align: center; }

/* ============================= COURSES =================================== */
.course-card { display: flex; flex-direction: column; gap: var(--sp-3); border-top: 3px solid var(--c-color, var(--primary)); }
.course-card__head { display: flex; align-items: flex-start; gap: var(--sp-3); }
.course-card__head h3 { font-size: var(--fs-lg); flex: 1; min-width: 0; }
.course-card__code { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-subtle); letter-spacing: 0.02em; }
.course-card__stats { display: flex; gap: var(--sp-4); font-size: var(--fs-sm); color: var(--text-muted); flex-wrap: wrap; }
.course-card__stats span { display: inline-flex; align-items: center; gap: 5px; }
.course-card__stats svg { width: 14px; height: 14px; color: var(--text-subtle); }

/* ============================= SETTINGS ================================== */
.setting-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4) 0; border-bottom: 1px solid var(--border);
}
.setting-row:last-child { border-bottom: 0; }
.setting-row__text { flex: 1 1 220px; min-width: 0; }
.setting-row__text strong { display: block; font-weight: var(--fw-semi); }
.setting-row__text span { font-size: var(--fs-sm); color: var(--text-muted); }
.setting-row__control { flex: 0 0 auto; }

.danger-zone { border-color: var(--danger); }
.danger-zone .card__head h2 { color: var(--danger); }

.kbd-list { display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.kbd-list div { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); font-size: var(--fs-sm); }
.kbd-list kbd {
  font-family: var(--font-sans); font-size: var(--fs-xs); font-weight: var(--fw-semi);
  padding: 2px 7px; border: 1px solid var(--border); border-bottom-width: 2px;
  border-radius: var(--r-xs); background: var(--surface-2); white-space: nowrap;
}

/* ============================================================================
   Block kinds — a class, a paid shift and planned study time must be
   distinguishable at a glance, without relying on colour alone.
   ========================================================================== */
/* Paid work reads as texture, not damage. The hatch was 12% of a slate block
   sitting on a slate fill, which came out as grey-on-grey and looked like a
   disabled or broken cell next to the coloured class blocks. Work blocks are
   amber now (which is what blockColorVar always intended, and what the Work
   hours page uses), and the stripe is finer and lighter so it reads as a
   surface rather than a defect. */
.session--work, .slot--work { background-image: repeating-linear-gradient(
    135deg, transparent 0 7px, color-mix(in srgb, var(--s-color) 18%, transparent) 7px 11px); }
.session--study, .slot--study { border-left-style: dashed; }
.session--study { background: color-mix(in srgb, var(--s-color, var(--primary)) 8%, var(--surface)); }

.kind-tag {
  font-size: 10px; font-weight: var(--fw-bold); text-transform: uppercase;
  letter-spacing: 0.05em; opacity: 0.75;
}

/* ============================================================================
   Day view — one column, hours down the side, and a line that tracks the
   current time so you can see where you stand at a glance.
   ========================================================================== */
.day-view {
  --time-col: 62px;
  --hour-h: 76px;
  position: relative;
  display: grid;
  grid-template-columns: var(--time-col) 1fr;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.day-view__head {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-bottom: 0;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  position: sticky; top: var(--topbar-h); z-index: 3;
}
.day-view__head + .day-view { border-radius: 0 0 var(--r-lg) var(--r-lg); border-top: 0; }
.day-view__head h2 { font-size: var(--fs-base); }
.day-view__head .spacer { flex: 1; }

.day-view__times { border-right: 1px solid var(--border); }
.day-view__hour {
  height: var(--hour-h); position: relative;
  font-size: var(--fs-xs); color: var(--text-subtle);
  font-variant-numeric: tabular-nums; text-align: right;
  padding-right: 8px;
}
.day-view__hour span { position: relative; top: -8px; white-space: nowrap; }

.day-view__track {
  position: relative;
  background-image: repeating-linear-gradient(
    to bottom, var(--grid-line) 0 1px, transparent 1px var(--hour-h));
}

.day-block {
  position: absolute; left: 8px; right: 8px;
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px; overflow: hidden;
  border-radius: var(--r-sm);
  border-left: 4px solid var(--s-color, var(--primary));
  background: color-mix(in srgb, var(--s-color, var(--primary)) 13%, var(--surface));
  text-align: left; color: var(--text);
  transition: filter var(--dur-fast), transform var(--dur-instant);
  cursor: pointer;
}
.day-block:hover { filter: brightness(0.97); }
:root.is-dark .day-block:hover { filter: brightness(1.15); }
.day-block:active { transform: scale(0.995); }
.day-block strong { font-size: var(--fs-base); font-weight: var(--fw-semi); line-height: 1.25; }
.day-block span { font-size: var(--fs-xs); color: var(--text-muted); }
.day-block--work { background-image: repeating-linear-gradient(
    135deg, transparent 0 7px, color-mix(in srgb, var(--s-color) 10%, transparent) 7px 14px); }
.day-block--study { border-left-style: dashed; }
.day-block.is-past { opacity: 0.45; }
.day-block.is-now { box-shadow: 0 0 0 2px var(--now-line); }

/* The moving line */
.day-now {
  position: absolute; left: 0; right: 0; height: 0;
  z-index: 5; pointer-events: none;
  border-top: 2px solid var(--now-line);
}
.day-now__dot {
  position: absolute; left: -5px; top: -5px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--now-line);
}
.day-now__label {
  position: absolute; right: 6px; top: -10px;
  padding: 1px 7px; border-radius: var(--r-full);
  background: var(--now-line); color: #fff;
  font-size: 10px; font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.day-now__time {
  position: absolute; left: 0; top: -9px;
  transform: translateX(calc(-1 * var(--time-col)));
  width: var(--time-col); text-align: right; padding-right: 8px;
  font-size: var(--fs-xs); font-weight: var(--fw-bold);
  color: var(--now-line); font-variant-numeric: tabular-nums;
}

.day-status {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-4);
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface);
}
.day-status__now {
  font-weight: var(--fw-semi);
}
.day-status__bar {
  flex: 1 1 140px; min-width: 120px; height: 6px;
  border-radius: var(--r-full); background: var(--surface-2); overflow: hidden;
}
.day-status__fill { height: 100%; background: var(--now-line); border-radius: inherit; }

/* Load summary */
.load-bar { display: flex; height: 10px; border-radius: var(--r-full); overflow: hidden; background: var(--surface-2); }
.load-bar__seg { height: 100%; }
.load-legend { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-2); font-size: var(--fs-xs); color: var(--text-muted); }
.load-legend span { display: inline-flex; align-items: center; gap: 5px; }

/* ============================================================================
   Account screens — sign in, sign up, recovery.
   ========================================================================== */
.auth-shell {
  display: grid; place-items: center;
  min-height: calc(100dvh - var(--topbar-h) - var(--sp-12));
  padding: var(--sp-4) 0 var(--sp-12);
}
.auth-card {
  width: min(420px, 100%);
  display: flex; flex-direction: column; gap: var(--sp-4);
  padding: var(--sp-6);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-md);
}
.auth-card h1 { font-size: var(--fs-xl); }
.auth-card__brand {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-base); font-weight: var(--fw-bold);
  margin-bottom: var(--sp-1);
}
.auth-card__brand .brand__mark { width: 34px; height: 34px; }
.auth-card__foot {
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
}

/* ============================================================================
   Admin console
   ========================================================================== */
.admin-stats { display: grid; gap: var(--gap-grid); grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

.role-pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: var(--r-full);
  font-size: var(--fs-xs); font-weight: var(--fw-bold);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.role-pill--admin        { background: var(--danger-soft);  color: var(--danger); }
.role-pill--cohort_admin { background: var(--info-soft);    color: var(--info); }
.role-pill--student      { background: var(--surface-2);    color: var(--text-muted); }

.plan-pill { font-size: var(--fs-xs); font-weight: var(--fw-semi); padding: 2px 8px; border-radius: var(--r-full); }
.plan-pill--active   { background: var(--success-soft); color: var(--success); }
.plan-pill--trial    { background: var(--info-soft);    color: var(--info); }
.plan-pill--past_due { background: var(--warn-soft);    color: var(--warn); }
.plan-pill--canceled,
.plan-pill--free     { background: var(--surface-2);    color: var(--text-muted); }

/* ============================================================================
   Sync indicator
   ========================================================================== */
.sync-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: var(--r-full);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  background: var(--surface-2); color: var(--text-muted);
  white-space: nowrap;
}
.sync-pill svg { width: 13px; height: 13px; }
.sync-pill--syncing  { color: var(--info); }
.sync-pill--syncing svg { animation: spin 1s linear infinite; }
.sync-pill--offline,
.sync-pill--expired  { background: var(--warn-soft);   color: var(--warn); }
.sync-pill--error,
.sync-pill--conflict { background: var(--danger-soft); color: var(--danger); }
.sync-pill--idle     { background: var(--success-soft); color: var(--success); }

.account-row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) 0;
}
.avatar {
  display: grid; place-items: center; flex: none;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--primary); color: var(--primary-fg);
  font-weight: var(--fw-bold); font-size: var(--fs-base);
}

/* ------------------------------------------------------------------- work */

.work-hero__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-3);
}
.work-hero__head h2 { font-size: var(--fs-lg); }
.work-hero__figure {
  display: flex; align-items: baseline; gap: var(--sp-2); margin-bottom: var(--sp-2);
}
.work-hero__used { font-size: var(--fs-2xl); line-height: 1; letter-spacing: -0.02em; }
.work-hero__remaining { margin-top: var(--sp-2); font-size: var(--fs-sm); }
.work-small { font-size: var(--fs-sm); }

/* The meter reads as a fuel gauge: the fill is the week, the track is the cap.
   An over-limit week paints past the track's end so it cannot be mistaken for
   a full-but-legal one. */
.work-meter__bar {
  position: relative; height: 10px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border); overflow: hidden;
}
.work-meter__fill { height: 100%; background: var(--success); transition: width .3s ease; }
.work-meter__bar.is-warn .work-meter__fill { background: var(--warn); }
.work-meter__bar.is-danger .work-meter__fill { background: var(--danger); }
.work-meter__over {
  position: absolute; inset-block: 0; right: 0;
  background: repeating-linear-gradient(45deg,
    var(--danger) 0 4px, color-mix(in srgb, var(--danger) 55%, transparent) 4px 8px);
}
.work-meter__scale {
  display: flex; justify-content: space-between;
  font-size: var(--fs-xs); color: var(--text-subtle); margin-top: 4px;
}

.work-list { list-style: none; margin: var(--sp-3) 0 0; padding: 0; }
.work-row {
  display: grid; grid-template-columns: minmax(0, 8.5rem) 1fr auto auto;
  gap: var(--sp-2); align-items: center;
  padding: var(--sp-2) 0; border-top: 1px solid var(--border);
}
.work-row__when { display: flex; flex-direction: column; font-size: var(--fs-sm); }
.work-row__what { display: flex; flex-wrap: wrap; gap: var(--sp-1); align-items: center; min-width: 0; font-size: var(--fs-sm); }
.work-row__hours { font-weight: var(--fw-semi); }

@media (max-width: 640px) {
  .work-row { grid-template-columns: 1fr auto auto; }
}

.work-weeks { list-style: none; margin: 0; padding: 0; }
.work-weeks__row {
  display: grid; grid-template-columns: 1fr auto auto; gap: var(--sp-3);
  align-items: center; padding: var(--sp-2) 0; border-top: 1px solid var(--border);
}
.work-weeks__row:first-child { border-top: 0; }
.work-weeks__row > div { display: flex; flex-direction: column; }
.work-weeks__row.is-breach strong { color: var(--danger); }

.work-note {
  display: flex; gap: var(--sp-2); align-items: flex-start;
  margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--border);
  font-size: var(--fs-sm); color: var(--text-subtle);
}
.work-note svg { flex: none; margin-top: 2px; }

.work-setup p { margin-bottom: var(--sp-2); }
.work-setup .btn { margin-top: var(--sp-2); }

.work-alert { border-color: var(--danger); }
.work-alert h3 { display: flex; align-items: center; gap: var(--sp-2); color: var(--danger); }
.work-alert ul { margin: var(--sp-2) 0 0; padding-left: 1.1rem; font-size: var(--fs-sm); }

/* ------------------------------------------------------------- coursework */

.cw-filters { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.cw-filters .dot { margin-right: 5px; }
.cw-small { font-size: var(--fs-sm); }
.cw-ok { color: var(--success); font-weight: var(--fw-semi); }
.cw-done { text-decoration: line-through; color: var(--text-subtle); }

.cw-progress { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.cw-progress__bar {
  flex: 1; height: 8px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border); overflow: hidden;
}
.cw-progress__fill { height: 100%; background: var(--primary); transition: width .3s ease; }

.cw-week { margin-bottom: var(--sp-4); }
.cw-week__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-3);
}
.cw-week__head h3 { font-size: var(--fs-base); }
.cw-week__stats { display: flex; align-items: center; gap: var(--sp-2); flex: none; }
/* The current week is the one being worked; give it the accent rail so it is
   findable after scrolling past a term of history. */
.cw-week.is-current { border-color: var(--primary); box-shadow: inset 3px 0 0 var(--primary); }
.cw-week.is-past { opacity: 0.75; }
/* …unless there is unfinished work in it, in which case it is the most
   important card on the page and must not fade away. */
.cw-week.is-behind { opacity: 1; border-color: var(--warn); }

.cw-collapse > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3);
}
.cw-collapse > summary::-webkit-details-marker { display: none; }
.cw-collapse[open] > summary { margin-bottom: var(--sp-3); }

.cw-group + .cw-group { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--border); }
.cw-group h4 {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-subtle); font-weight: var(--fw-semi); margin-bottom: var(--sp-2);
}

.cw-reading { min-height: 38px; align-items: center; padding: 2px 0; }
.cw-reading .checkbox__text small { display: flex; align-items: center; gap: 5px; color: var(--text-subtle); }

.cw-deadline {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) 0; border-top: 1px solid var(--border);
}
.cw-group h4 + .cw-deadline { border-top: 0; }
.cw-deadline__body {
  flex: 1; min-width: 0; text-align: left; background: none; border: 0; padding: 0;
  cursor: pointer; color: inherit; font: inherit;
}
.cw-deadline__body > span { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.cw-deadline__body small { display: flex; align-items: center; gap: 5px; color: var(--text-subtle); font-size: var(--fs-xs); }
.cw-deadline__body:hover > span { text-decoration: underline; }
.cw-deadline.is-overdue .cw-deadline__body small { color: var(--danger); }

.cw-tag {
  flex: none; font-size: 10px; font-weight: var(--fw-bold);
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 3px 7px; border-radius: var(--r-xs);
}
.cw-tag--exam { background: var(--danger-soft); color: var(--danger); }
.cw-tag--task { background: var(--info-soft); color: var(--info); }

.cw-behind { border-color: var(--warn); margin-bottom: var(--sp-4); }
.cw-behind h3 { display: flex; align-items: center; gap: var(--sp-2); color: var(--warn); font-size: var(--fs-base); }
.cw-behind > p { margin: var(--sp-2) 0 var(--sp-3); color: var(--text-muted); }
.cw-heavy { color: var(--warn); font-weight: var(--fw-semi); }

/* ------------------------------------------------------------- attendance */

.att-small { font-size: var(--fs-sm); }
.att-card { margin-bottom: var(--sp-4); }
.att-card__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-3);
}
.att-card__head h3 { font-size: var(--fs-base); }
.att-count { text-align: right; flex: none; }
.att-count strong { display: block; font-size: var(--fs-lg); line-height: 1.1; }

/* A rail per permitted absence, filled as they are used. Four pips with one
   filled says "three left" faster than the fraction does. */
.att-pips { display: flex; gap: 5px; margin-bottom: var(--sp-3); }
.att-pip {
  flex: 1; height: 6px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.att-pip.is-used { background: var(--danger); border-color: var(--danger); }

.att-headline { font-weight: var(--fw-semi); margin-bottom: 2px; }
.att-danger  { color: var(--danger); }
.att-warn    { color: var(--warn); }
.att-success { color: var(--success); }
.att-info    { color: var(--text-muted); }
.att-card--danger  { border-color: var(--danger); }
.att-card--warn    { border-color: var(--warn); }

.att-note {
  display: flex; gap: var(--sp-2); align-items: flex-start;
  margin-top: var(--sp-3); padding: var(--sp-2) var(--sp-3);
  background: var(--surface-2); border-radius: var(--r-sm);
  font-size: var(--fs-sm); color: var(--text-muted);
}
.att-note svg { flex: none; margin-top: 2px; }

.att-history { margin-top: var(--sp-3); }
.att-history > summary { cursor: pointer; font-size: var(--fs-sm); color: var(--text-muted); }
.att-list { list-style: none; margin: var(--sp-2) 0 0; padding: 0; }
.att-row {
  display: grid; grid-template-columns: auto auto 1fr auto;
  gap: var(--sp-2); align-items: center;
  padding: var(--sp-2) 0; border-top: 1px solid var(--border);
}
.att-card .btn--sm { margin-top: var(--sp-3); }

.att-alert { border-color: var(--danger); margin-bottom: var(--sp-4); }
.att-alert h2 { display: flex; align-items: center; gap: var(--sp-2); color: var(--danger); font-size: var(--fs-base); }
.att-alert ul { margin: var(--sp-2) 0 0; padding-left: 1.1rem; font-size: var(--fs-sm); }

/* ---------------------------------------------------------------- work pay */

.pay-card { margin-bottom: var(--sp-4); }
.pay-card__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3); margin-bottom: var(--sp-2);
}
.pay-card__head h2 { font-size: var(--fs-lg); }
.pay-card__figure { display: flex; align-items: baseline; gap: var(--sp-2); }
.pay-total {
  font-size: var(--fs-2xl); line-height: 1; letter-spacing: -0.02em;
  color: var(--success);
}
.pay-line {
  display: flex; align-items: center; gap: var(--sp-2);
  margin-top: var(--sp-2); font-size: var(--fs-sm);
  color: var(--success); font-weight: var(--fw-semi);
}
.pay-line svg { flex: none; }
.pay-week { color: var(--success); font-weight: var(--fw-semi); }
/* The pay column only exists when a rate is set, so the row template has to
   change with it rather than leaving an empty gap. */
.work-weeks.has-pay .work-weeks__row { grid-template-columns: 1fr auto auto auto; }

.pay-projection {
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 4px;
}
.pay-projection__row {
  display: flex; justify-content: space-between; gap: var(--sp-3);
  font-size: var(--fs-sm); color: var(--text-muted);
}
.pay-projection__row.is-total {
  padding-top: 6px; margin-top: 2px; border-top: 1px dashed var(--border);
  color: var(--text); font-weight: var(--fw-semi);
}

.pay-jobs { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--border); }
.pay-jobs h3 {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-subtle); font-weight: var(--fw-semi); margin-bottom: var(--sp-2);
}
.pay-jobs ul { list-style: none; margin: 0; padding: 0; }
.pay-job {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3); padding: var(--sp-2) 0; border-top: 1px solid var(--border);
}
.pay-jobs li:first-child { border-top: 0; }
.pay-job__name { display: flex; flex-direction: column; min-width: 0; }
.pay-job__name strong { font-size: var(--fs-sm); }
.pay-job__money { text-align: right; flex: none; display: flex; flex-direction: column; }
.pay-job__money strong { color: var(--success); }
.pay-card--empty { border-style: dashed; }
.pay-card--empty p { margin: var(--sp-2) 0 var(--sp-3); }

/* --------------------------------------------------- device copy compare */

.copy-grid { display: grid; gap: var(--sp-3); grid-template-columns: 1fr 1fr; }
@media (max-width: 560px) { .copy-grid { grid-template-columns: 1fr; } }
.copy-side {
  padding: var(--sp-3); border: 1px solid var(--border);
  border-radius: var(--r-md); background: var(--surface-2);
}
.copy-side strong { font-size: var(--fs-sm); }

/* ------------------------------------------------------- coursework modes */

.cw-toolbar {
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap; margin-bottom: var(--sp-3);
}
.cw-toolbar .spacer { flex: 1; }
.cw-modes { flex: none; }

.cw-group + .cw-group { margin-top: var(--sp-5); }
.cw-group__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-3); font-size: var(--fs-sm); font-weight: var(--fw-semi);
  padding-bottom: var(--sp-2); margin-bottom: var(--sp-2);
  border-bottom: 1px solid var(--border);
}
.cw-group__head small { color: var(--text-subtle); font-variant-numeric: tabular-nums; }
.cw-deadlines .cw-deadline { padding: var(--sp-2) 0; }
