/* =========================================================================
   Class of 27 — desktop-first visual system.
   Single full-height app frame: the page itself never scrolls, each panel
   owns its own scroll region so the whole tool fits a maximised window.
   ========================================================================= */

:root {
  color-scheme: light dark;

  --font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text',
    'Segoe UI Variable Text', 'Segoe UI', Inter, system-ui, sans-serif;
  --font-num: 'SF Mono', ui-monospace, 'Cascadia Mono', 'Segoe UI Mono', Menlo, monospace;

  --bg: #f5f5f7;
  --surface: #ffffff;
  --surface-2: #fafafc;
  --surface-3: #f1f1f4;
  --ink: #1d1d1f;
  --ink-2: #3f3f43;
  /* Both secondary text tones clear WCAG AA against the light surfaces even
     at the 10.5–12px sizes used throughout this dense desktop UI. */
  --muted: #626267;
  --faint: #6d6d72;
  --hairline: rgba(0, 0, 0, 0.09);
  --hairline-strong: rgba(0, 0, 0, 0.16);

  --accent: #0071e3;
  --accent-soft: rgba(0, 113, 227, 0.1);
  --focus-ring: rgba(0, 113, 227, 0.4);

  --ok-bg: #e8f6ed;
  --ok-ink: #14713b;
  --ok-line: rgba(20, 113, 59, 0.18);
  --err-bg: #fdeceb;
  --err-ink: #bf2c1d;
  --err-line: rgba(191, 44, 29, 0.18);
  --warn-bg: #fff5e4;
  --warn-ink: #8f5606;
  --warn-line: rgba(143, 86, 6, 0.2);
  --both-bg: #f1ecfd;
  --both-ink: #5a3ab0;
  --both-line: rgba(90, 58, 176, 0.18);

  --r-xl: 22px;
  --r-lg: 16px;
  --r-md: 12px;
  --r-sm: 9px;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05), 0 1px 1px rgba(0, 0, 0, 0.03);
  --shadow-md: 0 10px 34px rgba(0, 0, 0, 0.07);

  --gutter: 16px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --surface: #1c1c1e;
    --surface-2: #202022;
    --surface-3: #2c2c2e;
    --ink: #f5f5f7;
    --ink-2: #d8d8dc;
    --muted: #98989d;
    --faint: #939398;
    --hairline: rgba(255, 255, 255, 0.11);
    --hairline-strong: rgba(255, 255, 255, 0.2);

    --accent: #0a84ff;
    --accent-soft: rgba(10, 132, 255, 0.16);
    --focus-ring: rgba(10, 132, 255, 0.5);

    --ok-bg: rgba(48, 209, 88, 0.14);
    --ok-ink: #4cd471;
    --ok-line: rgba(48, 209, 88, 0.28);
    --err-bg: rgba(255, 69, 58, 0.14);
    --err-ink: #ff6961;
    --err-line: rgba(255, 69, 58, 0.28);
    --warn-bg: rgba(255, 159, 10, 0.14);
    --warn-ink: #ffb340;
    --warn-line: rgba(255, 159, 10, 0.28);
    --both-bg: rgba(191, 90, 242, 0.14);
    --both-ink: #d08bf5;
    --both-line: rgba(191, 90, 242, 0.28);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-md: 0 10px 34px rgba(0, 0, 0, 0.45);
  }
}

* {
  box-sizing: border-box;
}

/* [hidden] must beat the display rules on .pill/.chip and friends. */
[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
  overflow: hidden;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 14px;
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button,
input,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
}

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

:focus:not(:focus-visible) {
  outline: none;
}

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

/* Quiet, Apple-ish overlay scrollbars for the internal scroll regions. */
.scroll {
  overflow: hidden auto;
  min-height: 0;
  flex: 1;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline-strong) transparent;
  overscroll-behavior: contain;
}

.scroll::-webkit-scrollbar {
  width: 9px;
}

.scroll::-webkit-scrollbar-track {
  background: transparent;
}

.scroll::-webkit-scrollbar-thumb {
  background: var(--hairline-strong);
  border: 3px solid transparent;
  border-radius: 99px;
  background-clip: content-box;
}

.scroll::-webkit-scrollbar-thumb:hover {
  background: var(--faint);
  background-clip: content-box;
}

/* ------------------------------- app frame ------------------------------ */

.app {
  height: 100%;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--gutter);
  padding: 16px 20px 20px;
  max-width: 2400px;
  margin: 0 auto;
}

.topbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px;
  padding: 12px 18px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-sm);
}

.brand-block {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.mark {
  display: block;
  flex: none;
  border-radius: 27.5%;
}

.kicker {
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 2px;
}

h1 {
  font-size: 19px;
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.021em;
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.top-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* --------------------------------- buttons ------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hairline-strong);
  border-radius: 980px;
  padding: 7px 15px;
  background: var(--surface);
  color: var(--ink);
  font-size: 13px;
  font-weight: 550;
  letter-spacing: -0.01em;
  text-decoration: none;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.12s ease, opacity 0.18s ease;
}

.btn:hover {
  background: var(--surface-3);
}

.btn:active {
  transform: scale(0.975);
}

.btn-quiet {
  border-color: transparent;
  background: transparent;
  color: var(--muted);
}

.btn-quiet:hover {
  background: var(--surface-3);
  color: var(--ink);
}

.panel-foot a {
  color: var(--accent);
  font-weight: 600;
}

/* --------------------------------- layout ------------------------------- */

.workspace {
  display: grid;
  grid-template-columns: minmax(360px, 420px) minmax(0, 1fr);
  gap: var(--gutter);
  min-height: 0;
}

.rail {
  display: grid;
  grid-template-rows: minmax(360px, 3fr) minmax(200px, 2fr);
  gap: var(--gutter);
  min-height: 0;
}

/* Wide desktops get a true three-column workspace: the rail dissolves and its
   two panels become first-class grid columns. */
@media (min-width: 1680px) {
  .workspace {
    grid-template-columns: 400px 380px minmax(0, 1fr);
  }

  .rail {
    display: contents;
  }
}

@media (min-width: 2100px) {
  .workspace {
    grid-template-columns: 440px 420px minmax(0, 1fr);
  }
}

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

/* In the two-column rail the grid above gives Schedule and Course bank a 3:2
   share. Both still own their scroll region and can shrink on short screens. */
.panel-schedule {
  flex: 0 1 auto;
  min-height: 280px;
}

.panel-bank {
  flex: 1 1 auto;
  min-height: 200px;
}

.panel-head {
  flex: none;
  padding: 15px 18px 13px;
  border-bottom: 1px solid var(--hairline);
  background: var(--surface);
}

.panel-title-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.panel-title {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.015em;
  margin: 0;
}

.panel-hint {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.4;
  margin: 5px 0 0;
}

.panel-aside {
  color: var(--faint);
  font-size: 11.5px;
  white-space: nowrap;
}

.panel-body {
  padding: 14px 18px 18px;
}

.panel-foot {
  flex: none;
  padding: 11px 18px;
  border-top: 1px solid var(--hairline);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.45;
}

/* ---------------------------------- pills ------------------------------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: 980px;
  padding: 4px 10px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  border: 1px solid transparent;
  white-space: nowrap;
}

.pill.neutral {
  color: var(--muted);
  background: var(--surface-3);
  border-color: var(--hairline);
}

.pill.ready {
  color: var(--ok-ink);
  background: var(--ok-bg);
  border-color: var(--ok-line);
}

.status-eligible {
  color: var(--ok-ink);
  background: var(--ok-bg);
  border-color: var(--ok-line);
}

.status-missing {
  color: var(--err-ink);
  background: var(--err-bg);
  border-color: var(--err-line);
}

.status-grade {
  color: var(--warn-ink);
  background: var(--warn-bg);
  border-color: var(--warn-line);
}

.status-both {
  color: var(--both-ink);
  background: var(--both-bg);
  border-color: var(--both-line);
}

.status-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* The schedule always has exactly six admission-countable courses: fixed
   ENG4U plus the five U/M choices. Keep that shared projection visible once,
   instead of repeating it beside every program threshold. */
.projected-average-wrap {
  flex: none;
  padding: 12px 18px 0;
  background: var(--surface);
}

.projected-average-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* Tall enough for the gauge below to clear its own ring. "100.0%" is five
     tabular figures, so the inner disc has to stay wider than the number. */
  min-height: 92px;
  padding: 9px 11px 9px 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  background: linear-gradient(135deg, var(--accent-soft), var(--surface) 72%);
}

.projected-average-copy {
  min-width: 0;
}

.projected-average-copy h3 {
  margin: 0 0 5px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.065em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.projected-average-copy p {
  margin: 0;
  max-width: 245px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}

.projected-average-gauge {
  --gauge-color: var(--accent);
  position: relative;
  flex: 0 0 74px;
  width: 74px;
  height: 74px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: conic-gradient(
    from -90deg,
    var(--gauge-color) 0 var(--gauge-progress),
    var(--surface-3) var(--gauge-progress) 100%
  );
  color: var(--ink);
}

.projected-average-gauge::before {
  content: '';
  position: absolute;
  inset: 7px;
  border-radius: inherit;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--hairline);
}

.projected-average-gauge span {
  position: relative;
  z-index: 1;
  font-family: var(--font-num);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.055em;
  font-variant-numeric: tabular-nums;
}

.projected-average-gauge.is-empty {
  --gauge-color: var(--faint);
  color: var(--muted);
}

/* ------------------------------ section heads --------------------------- */

.section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 9px;
}

.section-heading h3 {
  margin: 0;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--muted);
}

.section-heading span {
  color: var(--faint);
  font-size: 11px;
}

.section + .section {
  margin-top: 18px;
}

/* -------------------------------- courses ------------------------------- */

.fixed-card,
.slot-card {
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  padding: 11px 12px;
}

.fixed-card + .fixed-card,
.slot-card + .slot-card {
  margin-top: 8px;
}

.slot-card {
  background: var(--surface);
  transition: border-color 0.16s ease, background 0.16s ease, box-shadow 0.16s ease, opacity 0.16s ease;
}

.slot-card.is-drag-over {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.slot-card.is-empty {
  padding: 0;
  border: 0;
  background: transparent;
}

.slot-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 62px;
  color: var(--faint);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  font-size: 12.5px;
}

.course-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 90px 26px;
  gap: 10px;
  align-items: center;
}

.fixed-card .course-row {
  grid-template-columns: minmax(0, 1fr) 90px;
}

.course-title {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.012em;
  margin: 0 0 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.course-meta {
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.grade-field {
  display: flex;
  align-items: stretch;
  gap: 4px;
  min-width: 0;
}

.grade-label {
  flex: 1;
  min-width: 0;
  display: block;
}

.stepper {
  display: flex;
  flex-direction: column;
  flex: none;
  width: 20px;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  overflow: hidden;
}

.step {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted);
  transition: background 0.12s ease, color 0.12s ease;
  touch-action: none;
}

.step + .step {
  border-top: 1px solid var(--hairline);
}

.step svg {
  display: block;
  width: 9px;
  height: 5.5px;
}

.step:hover {
  background: var(--accent-soft);
  color: var(--accent);
}

.step:active {
  background: var(--accent);
  color: #fff;
}

.grade-input {
  width: 100%;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  text-align: right;
  background: var(--surface);
  font-family: var(--font-num);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
  -moz-appearance: textfield;
}

.grade-input::-webkit-outer-spin-button,
.grade-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.grade-input:hover {
  border-color: var(--faint);
}

.grade-input:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.grade-input.is-empty {
  border-color: var(--warn-line);
  background: var(--warn-bg);
}

.icon-button {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  color: var(--faint);
  background: transparent;
  font-size: 15px;
  line-height: 1;
  transition: background 0.16s ease, color 0.16s ease;
}

.icon-button:hover {
  color: var(--err-ink);
  background: var(--err-bg);
}

.badge-line {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
}

.tag {
  border-radius: 980px;
  padding: 2.5px 8px;
  background: var(--surface-3);
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.005em;
}

.tag.good {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.tag.muted {
  background: var(--surface-3);
  color: var(--faint);
}

/* ------------------------------ course bank ----------------------------- */

.search-wrap {
  position: relative;
  margin-bottom: 12px;
}

.search-input {
  width: 100%;
  border: 1px solid var(--hairline-strong);
  border-radius: 980px;
  padding: 7px 14px 7px 32px;
  background: var(--surface-2);
  font-size: 13px;
  transition: border-color 0.16s ease, box-shadow 0.16s ease, background 0.16s ease;
}

.search-input::placeholder {
  color: var(--faint);
}

.search-input:focus {
  border-color: var(--accent);
  background: var(--surface);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--faint);
  font-size: 12px;
  pointer-events: none;
}

.bank-group + .bank-group {
  margin-top: 14px;
}

.bank-group-label {
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 7px;
}

.course-bank {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 7px;
}

.course-card {
  position: relative;
  display: block;
  width: 100%;
  padding: 9px 10px;
  text-align: left;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface-2);
  transition: transform 0.14s ease, border-color 0.14s ease, box-shadow 0.14s ease, background 0.14s ease;
}

.course-card[draggable='true'] {
  cursor: grab;
}

.course-card:hover {
  border-color: var(--hairline-strong);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}

.course-card.is-selected {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.course-card.is-selected::after {
  content: '✓';
  position: absolute;
  top: 7px;
  right: 9px;
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
}

.course-card .course-title {
  font-size: 12.5px;
  padding-right: 14px;
}

.course-card .course-meta {
  font-size: 10.5px;
}

.bank-empty {
  padding: 22px 10px;
  text-align: center;
  color: var(--faint);
  font-size: 12.5px;
}

/* --------------------------------- toast -------------------------------- */

.inline-note {
  margin-top: 10px;
  padding: 8px 11px;
  border-radius: var(--r-md);
  background: var(--warn-bg);
  border: 1px solid var(--warn-line);
  color: var(--warn-ink);
  font-size: 12px;
  font-weight: 550;
}

/* -------------------------------- filters ------------------------------- */

.filter-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 12px;
}

/* First control in the results header and the widest, because a subject name is
   what the reader arrives knowing. It takes the leftover row width so the school
   chips and the eligibility segmented control keep their natural size. */
.search-programs {
  flex: 1 1 260px;
  min-width: 220px;
  max-width: 420px;
}

.school-filter {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

.school-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 11px 4px 5px;
  border: 1px solid var(--hairline);
  border-radius: 980px;
  background: var(--surface-2);
  font-size: 12px;
  font-weight: 550;
  letter-spacing: -0.008em;
  color: var(--ink-2);
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}

.school-chip .mark {
  border-radius: 27.5%;
}

.school-chip:hover {
  border-color: var(--hairline-strong);
  background: var(--surface);
}

.school-chip.is-active {
  border-color: transparent;
  background: var(--ink);
  color: var(--surface);
}

.school-chip.all {
  padding-left: 11px;
}

.school-chip .chip-count {
  color: var(--faint);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
}

.school-chip.is-active .chip-count {
  color: rgba(255, 255, 255, 0.65);
}

@media (prefers-color-scheme: dark) {
  .school-chip.is-active .chip-count {
    color: rgba(0, 0, 0, 0.55);
  }
}

.segmented {
  display: inline-flex;
  padding: 2px;
  border-radius: 980px;
  background: var(--surface-3);
  border: 1px solid var(--hairline);
}

.segmented button {
  border: 0;
  border-radius: 980px;
  padding: 4px 13px;
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  font-weight: 550;
  transition: background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
}

.segmented button.is-active {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}

/* -------------------------------- results ------------------------------- */

/* The results column is the widest thing on screen at 2560x1440, so the school
   cards flow into columns rather than one tall stack. Grid (not CSS columns)
   is deliberate: expanding a program must not reshuffle cards between columns.
   `align-items: start` keeps each card at its natural height. */
/* Independent columns, not a shared grid. Grid rows take the height of their
   tallest cell, so expanding one field card stretched the row and left dead
   space beside it in the other column. Each column now flows on its own.
   Which card lands in which column is decided in JS at render time, so
   expanding a card cannot reshuffle cards between columns. */
.results-columns {
  display: grid;
  grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr));
  align-items: start;
  gap: 12px;
}

.results-col {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.field-group {
  min-width: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}

.field-group > summary,
.program-card > summary,
.offer-card > summary {
  list-style: none;
  cursor: pointer;
  transition: background 0.16s ease;
}

.field-group > summary::-webkit-details-marker,
.program-card > summary::-webkit-details-marker,
.offer-card > summary::-webkit-details-marker {
  display: none;
}

.field-group > summary:hover,
.program-card > summary:hover,
.offer-card > summary:hover {
  background: var(--surface-2);
}

.group-summary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 12px 15px;
}

.chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  flex: none;
  color: var(--faint);
  font-size: 11px;
  transition: transform 0.18s ease;
}

.field-group[open] > summary .chevron,
.program-card[open] > summary .chevron,
.offer-card[open] > summary .chevron {
  transform: rotate(90deg);
}

.group-title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -0.017em;
  min-width: 0;
}

.group-title span.text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.group-subtitle {
  color: var(--muted);
  font-size: 11.5px;
  margin-top: 2px;
}

.group-counts {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* On a wide results column the programs flow into columns instead of one tall
   stack, which roughly halves the scroll height at 2560x1440. `align-items:
   start` keeps a card that the user expanded from stretching its neighbour. */
.program-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(500px, 1fr));
  align-items: start;
  gap: 7px;
  padding: 8px;
  background: var(--bg);
  border-top: 1px solid var(--hairline);
}

@media (prefers-color-scheme: dark) {
  .program-list {
    background: rgba(0, 0, 0, 0.28);
  }
}

.program-card {
  min-width: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
}

.program-summary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 11px;
  align-items: center;
  padding: 10px 13px;
}

.program-title {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.014em;
  margin-bottom: 2px;
}

.program-degree {
  color: var(--muted);
  font-size: 11.5px;
}

/* One chip per school offering this program. The squircle carries the school's
   brand colour; the chip wash carries that school's eligibility outcome, so
   brand identity and status never compete for the same channel. */
.offer-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 5px;
}

.offer-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2.5px 9px 2.5px 3px;
  border-radius: 980px;
  border: 1px solid transparent;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
}

.offer-chip .mark {
  border-radius: 27.5%;
}

.program-body {
  border-top: 1px solid var(--hairline);
  padding: 11px;
  background: var(--surface-2);
  display: grid;
  gap: 9px;
}

.offer-card {
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
}

.offer-head {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
}

.offer-card[open] > .offer-head {
  border-bottom: 1px solid var(--hairline);
}

.offer-body {
  padding: 11px 12px 12px;
}

.offer-school {
  font-size: 13px;
  font-weight: 650;
  letter-spacing: -0.015em;
}

.offer-meta {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
  margin-top: 2px;
}

.top-six {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
  margin-bottom: 11px;
}

.top-six-title {
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}

.top-six-list {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.course-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 980px;
  background: var(--surface-3);
  font-size: 11.5px;
  font-weight: 550;
}

.course-chip .g {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  font-size: 11px;
}

.average-summary {
  text-align: right;
  padding-left: 14px;
  border-left: 1px solid var(--hairline);
  min-width: 122px;
}

.required-average {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  background: var(--surface-3);
}

.required-average-number {
  font-family: var(--font-num);
  font-size: 27px;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.required-average-label {
  font-size: 9.5px;
  font-weight: 650;
  letter-spacing: 0.025em;
  text-transform: uppercase;
  white-space: nowrap;
}

.required-average.is-met {
  color: var(--ok-ink);
  background: var(--ok-bg);
  border-color: var(--ok-line);
}

.required-average.is-below {
  color: var(--warn-ink);
  background: var(--warn-bg);
  border-color: var(--warn-line);
}

.required-average.is-pending {
  color: var(--muted);
}

.criteria-list {
  display: grid;
  gap: 6px;
}

.criterion {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: 9px;
  align-items: start;
  padding: 9px 11px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
}

.criterion-icon {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  margin-top: 1px;
}

.criterion.pass .criterion-icon {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.criterion.fail .criterion-icon {
  background: var(--err-bg);
  color: var(--err-ink);
}

/* An outstanding portfolio, audition or supplementary form is a task, not a
   shortfall. It reads amber rather than red so the eye can separate "go and do
   this" from "you are short a course". */
.criterion.action {
  border-color: var(--warn-line);
  background: var(--warn-bg);
}

.criterion.action .criterion-icon {
  background: var(--warn-ink);
  color: var(--warn-bg);
}

.criterion-tag {
  display: inline-block;
  margin-right: 5px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--warn-ink);
  color: var(--warn-bg);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: 1px;
}

.outstanding {
  margin-bottom: 11px;
  padding: 9px 11px;
  border: 1px solid var(--warn-line);
  border-radius: var(--r-sm);
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: 11.5px;
  line-height: 1.45;
}

.outstanding-lead {
  font-weight: 600;
}

.outstanding.is-only-blocker .outstanding-lead {
  font-weight: 700;
}

.outstanding-list {
  margin: 4px 0 0;
  padding-left: 16px;
}

.outstanding-list li {
  margin-top: 2px;
}

.criterion-label {
  font-weight: 550;
  font-size: 12.5px;
  line-height: 1.35;
  margin-bottom: 2px;
}

.criterion-detail {
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.4;
}

.umbrella-note {
  margin-bottom: 11px;
  padding: 8px 11px;
  border-radius: var(--r-sm);
  background: var(--accent-soft);
  color: var(--ink-2);
  font-size: 11.5px;
  line-height: 1.45;
}

.reference-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 9px;
}

.reference {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border: 1px solid var(--hairline);
  border-radius: 980px;
  background: var(--surface);
  color: var(--accent);
  font-size: 11px;
  font-weight: 550;
  text-decoration: none;
  transition: border-color 0.16s ease, background 0.16s ease;
}

.reference:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.program-note,
.source-note {
  margin-top: 9px;
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.45;
}

.program-note strong,
.source-note strong {
  color: var(--ink-2);
  font-weight: 600;
}

.source-note a {
  color: var(--accent);
  text-decoration: none;
}

.source-note a:hover {
  text-decoration: underline;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 64px 32px;
  text-align: center;
  color: var(--muted);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}

.empty-state strong {
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.015em;
}

.empty-state p {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  max-width: 380px;
}

/* ----------------------- stacked desktop compaction -------------------- */

/* Below the three-column breakpoint, Schedule and Course bank share the
   left rail. Give Schedule a deliberate 3:2 share and compact its fixed
   chrome so its course list remains a real working viewport rather than a
   sliver between the gauge and footer. */
@media (max-width: 1679px) {
  .panel-head {
    padding: 11px 14px 10px;
  }

  .panel-body {
    padding: 11px 14px 14px;
  }

  .panel-foot {
    padding: 8px 14px;
    font-size: 10.5px;
    line-height: 1.35;
  }

  .panel-schedule .panel-hint {
    margin-top: 3px;
    font-size: 11px;
    line-height: 1.3;
  }

  .panel-schedule .status-strip {
    margin-top: 6px;
  }

  .projected-average-wrap {
    padding: 7px 14px 0;
  }

  .projected-average-panel {
    min-height: 68px;
    padding: 6px 8px 6px 12px;
  }

  .projected-average-copy h3 {
    margin-bottom: 3px;
    font-size: 10.5px;
  }

  .projected-average-copy p {
    font-size: 10.5px;
  }

  .projected-average-gauge {
    flex-basis: 56px;
    width: 56px;
    height: 56px;
  }

  .projected-average-gauge::before {
    inset: 6px;
  }

  .projected-average-gauge span {
    font-size: 15px;
  }

  .panel-schedule .section + .section {
    margin-top: 14px;
  }

  .panel-schedule .fixed-card,
  .panel-schedule .slot-card:not(.is-empty) {
    padding: 9px 10px;
  }

  .filter-bar {
    gap: 8px;
    margin-top: 8px;
  }

  .search-programs {
    margin-bottom: 0;
  }
}

/* A split-screen or small laptop still stays desktop-first: two columns are
   retained, but the rail yields width to Results and program grids are allowed
   to shrink instead of being clipped by their former 500px minimum. */
@media (max-width: 1100px) {
  .workspace {
    grid-template-columns: minmax(300px, 38%) minmax(0, 1fr);
    gap: 12px;
  }

  .program-list {
    grid-template-columns: minmax(0, 1fr);
  }

  .panel-results .panel-title-row {
    align-items: flex-start;
    flex-direction: column;
    gap: 7px;
  }

  .school-filter,
  .legend {
    gap: 4px;
  }

  .school-chip {
    gap: 5px;
    padding-right: 8px;
    font-size: 11px;
  }

  .segmented button {
    padding-left: 10px;
    padding-right: 10px;
  }
}

/* At 720px tall and below there is not room for both panels' full explanatory
   chrome. The complete hint remains in the accessibility tree, while its
   visual copy is clamped; the redundant persistence footer yields its space
   to the actual schedule controls. */
@media (max-width: 1679px) and (max-height: 720px) {
  .app {
    gap: 12px;
    padding: 10px 14px 14px;
  }

  .topbar {
    padding: 8px 14px;
  }

  .workspace,
  .rail {
    gap: 12px;
  }

  .rail {
    grid-template-rows: minmax(240px, 3fr) minmax(170px, 2fr);
  }

  .panel-schedule {
    min-height: 240px;
  }

  .panel-bank {
    min-height: 170px;
  }

  .panel-schedule .panel-hint {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
  }

  .panel-schedule .panel-foot {
    display: none;
  }

  .panel-schedule .projected-average-panel {
    min-height: 60px;
  }

  .panel-schedule .projected-average-gauge {
    flex-basis: 50px;
    width: 50px;
    height: 50px;
  }
}

/* --------------------------------- print -------------------------------- */

@media print {
  :root {
    --bg: #fff;
    --surface: #fff;
    --surface-2: #fff;
    --surface-3: #fff;
  }

  html,
  body {
    height: auto;
    overflow: visible;
    background: #fff;
  }

  .app {
    display: block;
    height: auto;
    max-width: none;
    padding: 0;
  }

  .topbar {
    border: 0;
    box-shadow: none;
    padding: 0 0 12px;
    border-bottom: 1px solid #ccc;
    border-radius: 0;
  }

  .top-actions,
  .panel-bank,
  .filter-bar,
  .legend,
  .icon-button,
  .stepper {
    display: none !important;
  }

  .workspace {
    display: block;
  }

  .rail {
    display: block;
  }

  .program-list {
    grid-template-columns: 1fr;
  }

  .results-columns {
    display: block;
  }

  .panel {
    border: 0;
    box-shadow: none;
    border-radius: 0;
    overflow: visible;
    margin-top: 18px;
  }

  .scroll {
    overflow: visible !important;
  }

  .panel-head {
    padding-left: 0;
    padding-right: 0;
  }

  .panel-body {
    padding-left: 0;
    padding-right: 0;
  }

  .program-card,
  .field-group,
  .offer-card,
  .criterion {
    break-inside: avoid;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}
