/* Graduate Admissions — global styles */

/* University of Toronto brand palette (brand.utoronto.ca):
   U of T Blue #1E3765 (primary), Campaign Blue #007FA3, Cool Gray #D0D1C9. */
:root {
  --border: #d9d9e3; --muted: #6b6b76;
  --accent: #1E3765;         /* U of T Blue — primary (buttons, nav, headings) */
  --accent-2: #007FA3;       /* U of T Campaign Blue — secondary accent */
  --secondary-blue: #007894; /* Links — distinct from the dark navy body text */
  --bg: #f7f7fa;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: #1c1c22;
  background: var(--bg);
}

/* Base link colour — Secondary Blue, distinct from the dark navy body text.
   Sidebar nav links and .btn override this at higher specificity. */
a { color: var(--secondary-blue); }

/* ----- Layout with sidebar ----- */
.layout { display: flex; align-items: stretch; min-height: 100vh; }

/* The sidebar carries the U of T Blue brand colour; its content is light. */
.sidebar {
  width: 250px; flex: none; background: var(--accent); border-right: none;
  padding: 20px 16px; display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
/* Scale the logo down to fit the sidebar width. */
.sidebar-logo { display: block; width: 100%; max-width: 180px; height: auto; margin: 0 8px 16px; }
.sidebar .brand { font-weight: 600; font-size: 1.05rem; margin-bottom: 12px; padding: 0 8px; color: #fff; }

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; }
.sidebar-nav a {
  color: rgba(255, 255, 255, 0.82); font-size: 0.95rem; text-decoration: none;
  padding: 8px 12px; border-radius: 6px; border-left: 3px solid transparent;
}
.sidebar-nav a:hover { color: #fff; background: rgba(255, 255, 255, 0.10); }
.sidebar-nav a.active {
  color: #fff; background: rgba(255, 255, 255, 0.14); border-left-color: var(--accent-2); font-weight: 500;
}
/* Marks admin-only pages in the sidebar. */
/* Section headings inside the sidebar nav (e.g. "Admin"). */
.nav-heading {
  display: block; margin: 10px 8px 4px; font-size: 0.7rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255, 255, 255, 0.55);
}
.sidebar-nav a + .nav-heading { margin-top: 14px; }
.nav-badge {
  display: inline-block; padding: 1px 7px; border-radius: 999px; margin-left: 4px;
  background: #fff; color: var(--accent); font-size: 0.7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em; vertical-align: 1px;
}

.sidebar-user {
  margin-top: auto; padding-top: 16px; border-top: 1px solid rgba(255, 255, 255, 0.22);
  display: flex; flex-direction: column; gap: 10px; font-size: 0.9rem; color: rgba(255, 255, 255, 0.78);
}
.sidebar-username { padding: 0 8px; }

.cycle-select {
  display: flex; flex-direction: column; gap: 4px; margin: 0 0 20px; padding: 0 8px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
}
.cycle-select label { font-size: 0.78rem; color: rgba(255, 255, 255, 0.72); text-transform: uppercase; letter-spacing: 0.03em; }
.cycle-select select { padding: 6px 8px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.85rem; background: #fff; width: 100%; }


.content { flex: 1; min-width: 0; }
main { margin: 24px 0; padding: 0 24px; }

/* ----- Top bar: minimal — bell, username, log out (right-aligned) ----- */
.topbar {
  display: flex; align-items: center; justify-content: flex-end; height: 44px;
  padding: 0 24px; background: #fff; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 20;
}
.topbar-right { display: flex; align-items: center; gap: 16px; }
/* Username dropdown (mirrors the bell menu, narrower). */
.user-menu { position: relative; }
.user-menu-button {
  background: none; border: none; cursor: pointer; font: inherit;
  font-size: 0.9rem; color: var(--muted); padding: 4px 2px;
}
.user-menu-button:hover, .user-menu-button[aria-expanded="true"] { color: var(--text); }
.user-menu-caret { font-size: 0.7rem; }
.user-menu-panel {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 180px;
  background: #fff; border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); z-index: 30; padding: 4px 0;
}
.user-menu-panel[hidden] { display: none; }
.user-menu-panel a {
  display: block; padding: 8px 14px; font-size: 0.9rem;
  color: var(--text); text-decoration: none; white-space: nowrap;
}
.user-menu-panel a:hover { background: #f2f4f8; }
/* The logout form renders like the menu's links: full-width button, same
   padding/hover, with a divider above. */
.user-menu-panel .logout-form { display: block; margin: 4px 0 0; padding: 4px 0 0; border-top: 1px solid var(--border); }
.user-menu-panel .logout-form button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  cursor: pointer; font: inherit; font-size: 0.9rem; color: var(--text);
  padding: 8px 14px;
}
.user-menu-panel .logout-form button:hover { background: #f2f4f8; }
/* Impersonation: while acting as someone else the topbar itself tints amber
   and carries the notice + stop control on its left; the picker (below) is
   how admins start it. */
.topbar--impersonating {
  background: #fdf2dc; border-bottom: 2px solid #e8c377;
  justify-content: space-between;
}
.topbar-impersonation {
  display: flex; align-items: center; gap: 12px;
  color: #7a5200; font-size: 0.9rem; min-width: 0;
}
.impersonate-picker { position: relative; }
.impersonate-menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 40;
  width: 280px; background: #fff; border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18); padding: 8px;
}
.impersonate-list { list-style: none; margin: 8px 0 0; padding: 0; max-height: 260px; overflow-y: auto; }
.impersonate-option {
  display: block; width: 100%; text-align: left; padding: 6px 8px;
  border: 0; background: none; font: inherit; font-size: 0.88rem;
  border-radius: 6px; cursor: pointer;
}
.impersonate-option:hover, .impersonate-option:focus-visible { background: #f0f4fa; }
.inline-form { display: inline; }
/* Links that should read as text (e.g. the rec detail subtitle's nominator):
   no underline, still coloured/clickable. */
.plain-link a { text-decoration: none; }
.plain-link a:hover, .plain-link a:focus { text-decoration: underline; }
/* Release modal: per-recommendation deadline override rows; unrelease
   modal: the deletion summary list. */
.release-rec-deadlines { margin: 10px 0; font-size: 0.88rem; }
.release-rec-note { margin: 6px 0 2px; }
/* Two aligned columns — the group name (wrapping, never pushing wider) and a
   fixed-width picker — so every row lines up and stays inside the modal. */
.release-rec-list {
  display: grid; grid-template-columns: minmax(0, 1fr) 170px;
  gap: 6px 12px; align-items: center; margin-top: 6px;
  /* Bulk releases can list dozens of recommendations — cap the list and
     scroll inside it (the padding keeps rows clear of the scrollbar). */
  max-height: 260px; overflow-y: auto; padding-right: 6px;
}

.release-rec-row { display: contents; }
.release-rec-name { overflow-wrap: anywhere; }
.release-rec-row .form-control { width: 100%; box-sizing: border-box; margin: 0; }
/* The unrelease deletion summary can list dozens of rows — cap it and
   scroll inside (padding keeps rows clear of the scrollbar). */
.unrelease-summary {
  margin: 8px 0 14px; padding-left: 18px; font-size: 0.88rem;
  max-height: 260px; overflow-y: auto; padding-right: 6px;
}

/* Intents & Offers: the grouped two-row header (Intent (Primary)/(Co) over
   their five subcolumns). */
#intents-offers-table thead .col-group,
#all-groups-table thead .col-group,
#planning-table thead .col-group,
#award-assignments-table thead .col-group { text-align: center; border-left: 1px solid var(--border); }
/* Uniform, compact offer sub-columns (always the last 8 columns) on the
   group tables: narrow fixed width, centred numbers. */
#all-groups-table thead tr[data-freeze-skip] th,
#planning-table thead tr:nth-child(2) th,
#all-groups-table tbody td:nth-last-child(-n+8):not(.empty),
#planning-table tbody td:nth-last-child(-n+8):not(.empty) {
  width: 96px; min-width: 84px; text-align: left; box-sizing: border-box;
  white-space: nowrap;
}
#intents-offers-table thead tr:last-child th { border-top: 1px solid var(--border); }
/* The date columns sort by a numeric epoch data-order, which DataTables
   right-aligns as numbers — keep them reading left like the rest. */
#intents-offers-table th.col-intent-sent, #intents-offers-table td.col-intent-sent,
#intents-offers-table th.col-intent-deadline, #intents-offers-table td.col-intent-deadline { text-align: left; }
.notification-count { color: var(--muted); white-space: nowrap; }
/* Grouped notifications: the summary row is a native <details> toggle whose
   children render as ordinary notification rows behind an indent rail. */
.notification-group > summary { cursor: pointer; list-style: none; position: relative; padding-right: 22px; }
.notification-group > summary::after {
  content: "\25B8"; position: absolute; right: 6px; top: 50%;
  transform: translateY(-50%); color: var(--muted); transition: transform 0.12s;
}
.notification-group[open] > summary::after { transform: translateY(-50%) rotate(90deg); }
/* Icon action buttons (Recommendations table): magnifier/pencil/trash in a
   narrow leading column, so the actions never need horizontal scrolling. */
.row-actions-icons { white-space: nowrap; }
.row-actions-icons .icon-btn { margin-right: 4px; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 6px; padding: 0;
  border: 1px solid var(--border); background: #fff; color: var(--secondary-blue);
  cursor: pointer; vertical-align: middle; text-decoration: none;
}
a.icon-btn:hover, a.icon-btn:focus { text-decoration: none; }
.icon-btn:hover:not(:disabled), .icon-btn:focus-visible {
  color: #fff; background: var(--accent-2); border-color: var(--accent-2);
}
.icon-btn:disabled { opacity: 0.4; cursor: default; }
.icon-btn.icon-danger { color: #b13030; }
.icon-btn.icon-danger:hover:not(:disabled), .icon-btn.icon-danger:focus-visible {
  color: #fff; background: #b13030; border-color: #b13030;
}

/* Auto-decision rule rows (settings modal): a compact inline sentence of
   selects, with the move/remove controls pushed to the row's right edge. */
.auto-rules { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.auto-rule-row {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  font-size: 0.82rem; padding: 3px 6px; border-radius: 6px; background: #f7f7fa;
}
.auto-rule-row select.form-control { width: auto; padding: 2px 22px 2px 6px; font-size: 0.82rem; }
.auto-rule-controls { margin-left: auto; display: inline-flex; gap: 8px; align-items: center; white-space: nowrap; }
.auto-rule-controls .link-btn { font-size: 0.85rem; }
/* The rule-option toggles under the rules list, and breathing room between
   the last one and what follows (the modal's action buttons). */
.auto-opt-row { margin-top: 6px; }
.auto-reset-row { margin-bottom: 14px; }
.notification-group-items {
  list-style: none; margin: 6px 0 0; padding: 0 0 0 14px;
  border-left: 2px solid var(--border);
  display: flex; flex-direction: column; gap: 6px;
}
/* Comment threads: replies chain under their root behind a rail, and the
   per-thread reply form lines up with them. */
.comment-replies {
  list-style: none; margin: 8px 0 0; padding: 0 0 0 12px;
  border-left: 2px solid var(--border);
  display: flex; flex-direction: column; gap: 10px;
}
.comment-reply-form { margin: 8px 0 0 12px; }
.bell { position: relative; }
.bell-button {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: 0; border-radius: 50%; background: none;
  color: var(--muted); cursor: pointer;
}
.bell-button:hover, .bell-button[aria-expanded="true"] { background: #f0f0f5; color: var(--accent); }
.bell-badge {
  position: absolute; top: 2px; right: 0; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px; background: #b13030; color: #fff; font-size: 0.68rem; font-weight: 600;
  line-height: 16px; text-align: center;
}
.bell-menu {
  position: absolute; right: 0; top: calc(100% + 6px); width: 340px; background: #fff;
  border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  z-index: 30;
}
.bell-menu[hidden] { display: none; }
.bell-menu-head {
  display: flex; align-items: center; justify-content: space-between; padding: 10px 12px;
  border-bottom: 1px solid var(--border); font-weight: 600; font-size: 0.9rem;
}
.bell-menu-head form { margin: 0; }
.bell-list { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow-y: auto; }
.bell-item { border-bottom: 1px solid var(--border); }
.bell-item.empty { padding: 12px; color: var(--muted); font-size: 0.88rem; }
.bell-item form { margin: 0; }
.bell-item-open, .notification-open {
  display: flex; flex-direction: column; gap: 2px; width: 100%; padding: 8px 12px;
  border: 0; background: none; text-align: left; font: inherit; color: inherit; cursor: pointer;
}
.bell-item-open:hover, .notification-open:hover { background: #f7f7fa; }
/* Grouped rows render as links (to the notifications page) — no inline-link
   underline; the flex/color styling above already covers anchors. */
a.bell-item-open, a.bell-item-open:hover, a.bell-item-open:focus { text-decoration: none; }
.bell-item.is-unread .notification-message, .notification.is-unread .notification-message { font-weight: 600; }
/* A read child inside a still-unread grouped summary un-bolds: its own row's
   read state wins over the ancestor summary's. */
.notification-group-items .notification:not(.is-unread) .notification-message { font-weight: 400; }
.bell-item.is-unread { border-left: 3px solid var(--accent-2); }
.notification-message { font-size: 0.88rem; }
.notification-meta { font-size: 0.75rem; color: var(--muted); }
.bell-menu-foot {
  display: block; padding: 8px 12px; text-align: center; font-size: 0.85rem;
  color: var(--secondary-blue); text-decoration: none;
}
.bell-menu-foot:hover { text-decoration: underline; }
/* Notifications page */
.notification-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: 8px; background: #fff; }
.notification { border-bottom: 1px solid var(--border); }
.notification:last-child { border-bottom: none; }
.notification.is-unread { border-left: 3px solid var(--accent-2); }
.notification.empty { padding: 16px; color: var(--muted); }
.notification form { margin: 0; }
.notification-open { padding: 10px 14px; }
.notification-kind { display: inline-block; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); }

.cycle-warning {
  background: #fff4d6; border: 1px solid #e6c34d; color: #6b5300;
  padding: 12px 16px; border-radius: 8px; margin-bottom: 18px; font-size: 0.92rem;
}

/* Inline field warning (e.g. a restricted group on the recommendation form). */
.field-warning {
  background: #fff4d6; border: 1px solid #e6c34d; color: #6b5300;
  padding: 8px 11px; border-radius: 6px; font-size: 0.85rem;
}

/* ----- Buttons ----- */
.btn {
  display: inline-block; padding: 8px 14px; border-radius: 6px; border: 1px solid var(--accent);
  background: var(--accent); color: #fff; text-decoration: none; font-size: 0.9rem;
  cursor: pointer; font-family: inherit;
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn:hover { opacity: 0.9; }
/* .btn sets display:inline-block, which overrides the UA [hidden] rule — restore
   it so the `hidden` attribute actually hides a button. */
.btn[hidden] { display: none; }
.btn-secondary { background: #fff; color: var(--accent); }
.btn-danger { background: #fff; color: #b3261e; border-color: #b3261e; }
.btn-small { padding: 4px 10px; font-size: 0.8rem; }
.section-actions { margin: 0 0 12px; }
/* A compact inline "add a row" form (e.g. legal-status mappings on Cycles). */
.inline-add-form { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 16px; }
.inline-add-form input, .inline-add-form select {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.9rem; font-family: inherit;
}

/* ----- Messages ----- */
.messages { list-style: none; margin: 0 0 18px; padding: 0; }
.messages li {
  padding: 10px 14px; border-radius: 6px; font-size: 0.9rem;
  background: #e3f6e8; color: #1e7a3c; border: 1px solid #bfe6cb;
}
.messages li.error { background: #fbe4e4; color: #b13030; border-color: #f0c4c4; }

/* ----- Generic form card ----- */
.form-card {
  max-width: 480px; background: #fff; border: 1px solid var(--border);
  border-radius: 10px; padding: 24px 24px 28px;
}
.form-card--wide { max-width: 760px; }
.form-card--xwide { max-width: 1000px; }
.form-card h1 { font-size: 1.3rem; margin: 0 0 18px; }
/* Section heading — brand-coloured and clearly separated so sections stand out. */
.form-card .form-subhead {
  font-size: 1.05rem; color: var(--accent); font-weight: 600;
  margin: 30px 0 14px; padding-bottom: 6px; border-bottom: 2px solid var(--accent);
}
/* Subordinate heading within a section (e.g. financial-review subsections). */
.form-card .form-subhead--sub {
  font-size: 0.95rem; color: var(--muted); font-weight: 600;
  margin-top: 22px; border-bottom: 1px solid var(--border);
}
.form-card table { margin-bottom: 18px; }
/* Let a wide table scroll horizontally rather than overflow the form card. */
/* Program column sorts by a numeric rank, which DataTables right-aligns as a
   numeric column; keep it left-aligned. The #id scope outranks DataTables. */
/* Applicant numbers are all-digit, so DataTables detects the column as numeric
   and right-aligns it; keep it left-aligned. The #id scope outranks DataTables. */
#committee-review-table th.col-status, #committee-review-table td.col-status,
#committee-review-table th.col-round, #committee-review-table td.col-round,
#committee-review-table th.col-reviewers, #committee-review-table td.col-reviewers,
#committee-review-table th.col-score, #committee-review-table td.col-score { text-align: left; }
/* Recs column: the count pill, centred. While its tooltip is open the cell is
   lifted above the (sticky, z-index 2) frozen header cells so a first-row tip
   isn't hidden behind the header. */
/* Settings: the account rows mirror the edit-cycle page's cycle table. */
.account-table th { width: 180px; white-space: nowrap; text-align: left; }
.account-table .form-control { max-width: 420px; }

/* Email preferences: the per-type frequency grid; radios centred under
   their frequency column. */
.email-preferences-table td { text-align: center; }
.email-preferences-table th[scope="row"] { text-align: left; font-weight: 500; }

/* Nominators: one pill per nominating group; wraps within the frozen width.
   Left-aligned (the numeric data-order would right-align it as a number
   column otherwise). */
#committee-review-table th.col-nominators, #committee-review-table td.col-nominators { text-align: left !important; }
#committee-review-table td.col-nominators { white-space: normal; }
.nominator-pill {
  display: inline-block; margin: 1px 2px 1px 0; padding: 1px 8px;
  border-radius: 10px; font-size: 12px;
  background: #eef1f6; color: #3b4252; border: 1px solid #d6dbe4;
}
/* Reviewer pills keep wrapping (overriding .table-scroll's nowrap) so the table
   overflows/scrolls only when the other columns genuinely exceed the width. */
.table-scroll #committee-review-table td.col-reviewers { white-space: normal; }
/* Reviewer pills are clickable — they open the assign-reviewers modal (same as
   the pencil) when the row's reviewers are editable. */
/* A reviewer pill only opens the assign modal when its row still has the
   assign button (editable rows); locked rows keep the default cursor. */
#committee-review-table td.col-reviewers:has([data-assign]) .review-pill { cursor: pointer; }
/* The Reviewers filter cell holds the reviewer + score dropdowns side by side
   (committee-lead table), each taking half the column width. */
/* Two controls side by side inside one filter cell (an inner wrapper, so the
   <th> stays a table cell and matches the row height). */
.filter-cell-split { display: flex; gap: 4px; align-items: center; }
.filter-cell-split select { flex: 1 1 0; min-width: 0; }
.filter-cell-split .filter-multi { flex: 1 1 0; min-width: 0; }
/* Edit-awards modal, single selection: eligibility badge beside the award name. */
.award-eligibility { margin-left: 6px; font-weight: normal; }
/* Committee Members + Awards overview tables (top of the Committee Review page),
   laid out side by side (they stack on narrow screens). */
.cr-top-sections { display: flex; flex-wrap: wrap; gap: 32px; align-items: flex-start; }
/* Flex items don't margin-collapse with main's margins (a plain .section
   does), so zero both: the top stays level with other pages, and the gap to
   the next section is exactly that section's own 28px top margin — the same
   rhythm as adjacent sections elsewhere (e.g. the admin Applicants page). */
.cr-top-sections > .section { margin-top: 0; margin-bottom: 0; }
/* Section heading with an action beside it (e.g. "Add committee member"),
   hovering above a single full-width rule. The rule moves onto .section-head so
   the button can sit in the header row above it; the h2's own border is removed
   (the higher-specificity selector beats .section h2 later in the file). */
.section-head {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  min-height: 34px; /* match the button-driven height so action-less headers align */
  border-bottom: 2px solid var(--border); padding-bottom: 6px; margin-bottom: 10px;
}
.section .section-head h1, .section .section-head h2 { margin: 0; padding: 0; border-bottom: 0; }
.committee-members-table { width: auto; min-width: 340px; margin-bottom: 0; }
.committee-members-table .col-count { text-align: right; white-space: nowrap; }
/* Row-select checkbox column (Committee Review, All Groups): narrow and centred.
   The filter-row cell beneath it stays empty. */
th.col-select, td.col-select { text-align: center; width: 1% !important; white-space: nowrap; padding-left: 8px !important; padding-right: 8px !important; }
th.col-select input, td.col-select input { margin: 0; vertical-align: middle; }
/* The editable Decision pill: the cell pill is a plain button that rings on
   hover/focus to signal it opens the inline outcome picker. */
.decision-trigger { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; }
.decision-trigger:hover .badge, .decision-trigger:focus-visible .badge {
  box-shadow: 0 0 0 2px var(--accent-2);
}
/* Every inline-editable pill carries a pencil (as on the Reviewers column)
   so editability is visible at rest: outline normally, filled + accent on
   the trigger's hover/focus. */
.decision-trigger .pill-edit-icon {
  display: inline-block; margin-left: 4px; line-height: 0;
  vertical-align: middle; color: var(--secondary-blue);
}
.decision-trigger:hover .pill-edit-icon,
.decision-trigger:focus-visible .pill-edit-icon { color: var(--accent); }
.pill-edit-icon .icon-fill { display: none; }
.decision-trigger:hover .pill-edit-icon .icon-outline,
.decision-trigger:focus-visible .pill-edit-icon .icon-outline { display: none; }
.decision-trigger:hover .pill-edit-icon .icon-fill,
.decision-trigger:focus-visible .pill-edit-icon .icon-fill { display: inline; }
/* Member Score column: rounded-square score pills matching the Reviewer
   panel's .score-option buttons (radius + squarish proportions), for both
   the displayed pill and the editor's choices. */
#committee-review-table td.col-score .review-pill {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 26px; padding: 0 6px;
  border-radius: 6px; font-weight: 600;
}
/* Member Score editor: the score choices sit on one horizontal line. */
.score-editor .decision-options { flex-wrap: nowrap; }
.score-editor .decision-option { cursor: pointer; }
/* Width-frozen cells clip overflow, and an open inline editor can need more
   room than its frozen column: let it spill out of the cell as a small
   overlay (white backing so it reads above the neighbouring cells). */
table.dt-fixed-cols td:has(.decision-editor:not([hidden])) { overflow: visible; position: relative; z-index: 6; }
table.dt-fixed-cols .decision-editor:not([hidden]) .decision-options {
  display: inline-flex; width: max-content; max-width: 70vw;
  background: #fff; padding: 3px 6px; margin: -3px -6px;
  border-radius: 8px; box-shadow: 0 1px 8px rgba(0, 0, 0, 0.25);
}

/* Inline outcome picker: the outcomes as clickable coloured pills, shown in the
   cell in place of the current pill while editing. */
.decision-options { display: flex; flex-wrap: wrap; gap: 6px; }
.decision-option {
  position: relative; cursor: pointer; font: inherit; font-size: 0.78rem;
  padding: 2px 10px; border: 2px solid transparent;
}
.decision-option:hover { opacity: 0.85; }
/* Current outcome (inline pill editor) or the checked radio (bulk "Set as…"). */
.decision-option.is-current, .decision-option:has(input:checked) { border-color: var(--accent); }
/* The radio backing a bulk "Set as…" pill is visually hidden; the label is the pill. */
.decision-option input[type="radio"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
/* Roomier, spaced pills inside the "Set as…" modal. */
.modal .decision-options { margin-bottom: 22px; }
.modal .decision-option { font-size: 0.85rem; padding: 5px 14px; }
/* The bulk-edit users modal: one compact row per role, the role label on the
   left of its Keep/Grant/Remove pills (label + pills alternate in the markup,
   so a two-column grid pairs them up). */
#users-bulk-edit-modal .modal-body {
  display: grid; grid-template-columns: max-content 1fr;
  column-gap: 16px; row-gap: 8px; align-items: center;
}
#users-bulk-edit-modal .form-label { margin-bottom: 0; }
#users-bulk-edit-modal .decision-options { margin-bottom: 0; flex-wrap: nowrap; }
#users-bulk-edit-modal .decision-option { padding: 3px 12px; }
/* The Reviewers-column edit control is a plain link-coloured icon (no button
   chrome); it darkens to the accent colour on hover/focus. */
.assign-edit-btn {
  border: 0; background: none; padding: 2px; cursor: pointer;
  line-height: 0; vertical-align: middle; color: var(--secondary-blue);
}
.assign-edit-btn:hover, .assign-edit-btn:focus-visible { color: var(--accent); }
.assign-edit-btn svg { vertical-align: middle; pointer-events: none; }
/* Outline pencil at rest, filled pencil on hover/focus. */
.assign-edit-btn .icon-fill { display: none; }
.assign-edit-btn:hover .icon-outline, .assign-edit-btn:focus-visible .icon-outline { display: none; }
.assign-edit-btn:hover .icon-fill, .assign-edit-btn:focus-visible .icon-fill { display: inline; }
/* Bulk-actions toolbar above the Committee Review table. */
.bulk-actions { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.bulk-actions .bulk-count { color: var(--muted); font-size: 0.85rem; margin-right: 4px; }
/* Transient confirmation toast for inline AJAX table edits (no page reload). */
.cr-toast {
  position: fixed; left: 50%; bottom: 24px;
  transform: translateX(-50%) translateY(12px);
  background: var(--accent); color: #fff; padding: 10px 18px; border-radius: 8px;
  font-size: 0.9rem; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  opacity: 0; pointer-events: none; z-index: 1000;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.cr-toast.is-visible { opacity: 1; transform: translateX(-50%) translateY(0); }
.cr-toast.cr-toast-error { background: #b3261e; }
/* Pipe separator splitting the bulk-action buttons into visual groups (reviewer
   actions | decision actions). */
.bulk-divider { align-self: center; width: 1px; height: 22px; background: var(--muted); margin: 0 4px; }
/* An indented sub-option under a check-row (e.g. the auto-assign modal). */
.check-row.check-subrow { margin-left: 24px; }

/* Auto-assignment review page: editable reviewer pills + sticky totals box. */
/* Two-column layout: the editable table (left) beside a sticky per-reviewer
   totals box (right) that stays in view while the table scrolls. Stacks on
   narrow screens. */
.autoassign-layout { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.autoassign-main { flex: 1 1 520px; min-width: 0; }
.autoassign-side {
  flex: 0 1 340px; align-self: flex-start; position: sticky; top: 60px;
}
.autoassign-side .form-card { max-width: none; margin: 0; padding: 18px 20px 22px; }
.autoassign-side h2.form-subhead { margin-top: 0; }
.assign-balance-table { width: 100%; margin-bottom: 0; }
.assign-balance-table th, .assign-balance-table td { padding: 6px 6px; font-size: 0.85rem; }
.assign-balance-table .col-count { text-align: right; width: 40px; white-space: nowrap; }
.assign-balance-table .col-other { color: var(--muted); }
.assign-balance-table .col-total { font-weight: 600; }
.assign-balance-note { color: var(--muted); font-size: 0.78rem; margin: 8px 0 0; line-height: 1.4; }
/* Fixed layout so the Applicant column keeps a steady width as the Reviewers
   cell changes; Reviewers takes the (large) remaining space. */
#autoassign-table { table-layout: fixed; width: 100%; }
#autoassign-table th, #autoassign-table td { white-space: normal; vertical-align: top; }
#autoassign-table th:nth-child(1), #autoassign-table td:nth-child(1) { width: 300px; }
/* Applicant mini-card on the auto-assign review page: name + muted number,
   meta pills, then a labelled nominator list. */
.aa-applicant { display: flex; flex-direction: column; gap: 6px; }
.aa-name { font-weight: 600; }
.aa-number { font-weight: 400; color: var(--muted); font-size: 0.85rem; }
.aa-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.aa-noms { padding-top: 6px; }
.aa-noms-label {
  display: block; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 2px;
}
/* Consolidated Applicant cells: the name links to the detail page with the
   applicant number as a muted subtitle beneath it. */
.app-number { font-size: 0.78rem; color: var(--muted); line-height: 1.3; }
/* Legal-status and program pills, coloured for at-a-glance scanning. The
   program hues match the analytics palette (U of T accents). */
.badge.legal-dom { background: #e4eefb; color: #1E3765; }
.badge.legal-intl { background: #f9e3ef; color: #AB1368; }
.badge.prog-msc { background: #dff2f7; color: #00637f; }
.badge.prog-phd { background: #f0e4f3; color: #6D247A; }
/* A magenta-violet neighbour of the PhD purple: clearly kin, clearly not it. */
.badge.prog-dephd { background: #fae6f5; color: #A5308F; }
/* The viewer's own recommendations on the applicant page: a "Yours" chip and
   a soft row tint so they stand out at a glance. */
.badge.mine { background: #f4f8fd; color: #1E3765; }
#applicant-recommendations-table tr.is-mine > td { background: #dfe9f8; }
/* A program mismatch stays amber even on the viewer's own (blue) rows. */
#applicant-recommendations-table tr.is-mine > td.cell-mismatch { background: #fdf2dc; }
/* Nominators as soft chips, echoing the reviewer pills across the app. */
.aa-nom-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.aa-nom-chip {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  background: #eef3f8; color: #1E3765; border: 1px solid #d7e2ee;
  font-size: 0.8rem; white-space: nowrap;
}
.autoassign-cell .assign-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.assign-pill {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 10px;
  border-radius: 999px; background: #e0f0fb; color: #1b5e8a; font-size: 0.82rem;
  white-space: nowrap;
}
.assign-pill.is-conflict { background: #fdf2dc; color: #9a6a00; }
.assign-pill.is-completed { background: #e3f6e8; color: #1e7a3c; }
.assign-remove {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  font-size: 1.05rem; line-height: 1; padding: 0 4px; opacity: 0.7;
}
.assign-remove:hover { opacity: 1; }
.autoassign-cell .assign-add { max-width: 220px; }
.pill-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.pill-legend-label { color: var(--muted); font-size: 0.85rem; }
.legend-swatch { padding: 2px 10px; cursor: default; }
.legend-note { color: var(--muted); font-size: 0.85rem; margin: 0 0 16px; }
/* "new" / "existing" tag inside a reviewer pill — a subtle chip that reads on
   any pill colour. */
.assign-flag {
  font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.03em;
  font-weight: 600; padding: 1px 5px; border-radius: 4px;
  background: rgba(0, 0, 0, 0.10);
}
/* A check-row with a trailing info tooltip: keeps the checkbox+label identical
   to a plain check-row, with the tooltip alongside it. */
.check-row-with-tip { display: flex; align-items: center; gap: 8px; }
/* "Unassign from…" modal recap of the selected applicants — matches the
   modal-list typography, with the heading kept close to the list. */
#unassign-from-recap { gap: 4px; }
#unassign-from-recap .subtitle { margin: 0; }
.recap-list {
  margin: 0; padding-left: 20px;
  font-size: 0.9rem; line-height: 1.5;
  max-height: 220px; overflow-y: auto;
}
.recap-list li { margin-bottom: 4px; }
/* Scrollable region inside a modal (e.g. the bulk-remove users recap table):
   capped height with its own scrollbar; the table header stays visible. */
.modal-scroll { max-height: 260px; overflow-y: auto; }
.modal-scroll table { margin: 0; }
.modal-scroll thead th { position: sticky; top: 0; background: #fff; z-index: 1; }
/* Keep every filter dropdown/input left-aligned, even in numeric-sorted columns
   (Status, Reviewers) that DataTables would otherwise right-align. */
/* Filter rows everywhere: controls sit left regardless of the column's
   detected data type, with tighter padding than data cells so the row
   stays slim. */
/* !important: DataTables' own type-alignment selectors (thead > tr >
   th.dt-type-*) tie on specificity and its stylesheet loads later. */
thead .filter-row th,
table.dataTable thead tr.filter-row th { text-align: left !important; padding-top: 4px; padding-bottom: 4px; }
#applicants-table th.col-number, #applicants-table td.col-number,
#committee-review-table th.col-number, #committee-review-table td.col-number { text-align: left; }
#audit-logs-table th.col-when, #audit-logs-table td.col-when { text-align: left; }
#committee-review-table th.col-avg-score, #committee-review-table td.col-avg-score { text-align: left; }
#committee-review-table th.col-comments, #committee-review-table td.col-comments { text-align: left; }
#committee-review-table th.col-decision-submitted, #committee-review-table td.col-decision-submitted,
#committee-review-table th.col-decision-released, #committee-review-table td.col-decision-released { text-align: left; white-space: nowrap; }
#award-assignment-nominations-table th.col-noms, #award-assignment-nominations-table td.col-noms,
#award-assignment-nominations-table th.col-avg, #award-assignment-nominations-table td.col-avg { text-align: left !important; }
#applicants-table th.col-program, #applicants-table td.col-program,
#committee-review-table th.col-program, #committee-review-table td.col-program { text-align: left !important; }
#applicants-table th.col-recs, #applicants-table td.col-recs { text-align: left; }
#applicants-table td.col-recs:has(.rec-count:hover),
#applicants-table td.col-recs:has(.rec-count:focus) { position: relative; z-index: 5; }
#applicants-table tbody tr:first-child .rec-count .tip-text { bottom: auto; top: calc(100% + 6px); }
#award-nominations-table th.col-rank, #award-nominations-table td.col-rank { text-align: left; }
/* The changelog "When" column holds Y-m-d H:i values that DataTables detects as
   dates and right-aligns; keep it left-aligned. The extra .dataTable class
   outranks DataTables' type-based alignment rule. */
table.changelog-table.dataTable th:first-child,
table.changelog-table.dataTable td:first-child { text-align: left; }
/* Award Assignments: keep the numeric Avg Score column left-aligned too. */
#award-assignment-nominations-table.dataTable th.col-avg,
#award-assignment-nominations-table.dataTable td.col-avg { text-align: left; }

/* DataTables "entries per page" (length) and "Search" controls. The CDN stylesheet
   loads after this file, so these need high specificity / !important to win. */
/* Match the site's font family and size. */
.dt-container .dt-length,
.dt-container .dt-search,
.dt-container .dt-length label,
.dt-container .dt-search label,
.dt-container select.dt-input,
.dt-container input.dt-input {
  font-family: inherit !important;
  font-size: 0.92rem !important;
}
/* "Showing X to Y of Z entries" uses the site's subtitle styling. */
.dt-container .dt-info {
  color: var(--muted) !important; font-size: 0.9rem !important; font-family: inherit !important;
}
/* A magnifying-glass icon inside the search input (the "Search:" label is
   removed and shown as placeholder text instead — see _datatables_scripts.html). */
.dt-container .dt-search input[type="search"] {
  padding-left: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%236b6b76' viewBox='0 0 16 16'%3E%3Cpath d='M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 9px center;
  background-size: 15px;
}
/* Tables without a toolbar keep DataTables' default — length menu on the left,
   search on the right.

   Committee Review has the bulk-actions toolbar on the left of the row (via the
   layout option), so its length menu + search are grouped in the right-hand
   (topEnd) cell, spaced with a pipe divider between them. */
.dt-container .dt-layout-row:has(.bulk-actions) .dt-layout-end {
  display: flex; align-items: center; gap: 16px; margin-left: auto;
}
.dt-container .dt-layout-row:has(.bulk-actions) .dt-search {
  border-left: 1px solid var(--border);
  padding-left: 16px;
}
.dt-container .dt-layout-row .bulk-actions { margin-bottom: 0; }

.table-scroll { overflow-x: auto; margin-bottom: 18px; }
/* With DataTables, _datatables_scripts.html re-nests things so the control
   rows sit outside the scroller and only the table is inside a .table-scroll
   (inside the layout cell); that inner wrapper needs no bottom margin. */
.dt-container .table-scroll { margin-bottom: 0; }
/* The recommendations table may outgrow its container; it scrolls inside
   .table-scroll like the other wide datatables (the DataTables re-nesting
   keeps its control rows outside the scroller). */
#recommendations-table { max-width: none; }
.table-scroll table { margin-bottom: 0; }
.table-scroll th, .table-scroll td { white-space: nowrap; }
/* All-groups admin table: let the long column titles wrap so columns stay
   narrow (overrides the .table-scroll nowrap for the header row only). */
#all-groups-table thead th { white-space: normal; max-width: 110px; vertical-align: bottom; }
/* The filter-row holds dropdown/search controls that are wider than the 110px
   title cap above, so they overflowed their cells. Give the filtered columns
   (Status, Name, Type, GAP Form, Rec. Override, Financial/Office Review —
   columns 2–9, after the select checkbox) a minimum width and lift the cap; the table scrolls horizontally (.table-scroll)
   when the total exceeds the page. The controls fill their cell. */
#all-groups-table th:nth-child(2), #all-groups-table th:nth-child(3),
#all-groups-table th:nth-child(4), #all-groups-table th:nth-child(6),
#all-groups-table th:nth-child(7), #all-groups-table th:nth-child(8),
#all-groups-table th:nth-child(9) { min-width: 150px; max-width: none; }
/* Column 1 is the row-select checkbox: no title to wrap, no min-width. */
#all-groups-table th.col-select { min-width: 0; max-width: none; }
/* Frozen leading columns (dt_freeze.js sets the classes + left offsets):
   sticky to the left edge with an opaque background so scrolled cells pass
   beneath, and a shadow on the last one to mark the edge. Header cells stack
   above body cells. */
table.dataTable .is-frozen { position: sticky; z-index: 1; background: #fff; }
/* DataTables sets header cells to position: relative (for its sort icons)
   with a more specific selector; without !important the frozen header cells
   would be shifted by their left offset instead of pinned. */
table.dataTable thead > tr > th.is-frozen { position: sticky !important; z-index: 2; background: #f0f0f5; }
table.dataTable tbody tr:hover .is-frozen { background: #eaf1fb; }
table.dataTable .is-frozen-last { box-shadow: 4px 0 6px -4px rgba(0, 0, 0, 0.18); }
#all-groups-table .filter-row select,
#all-groups-table .filter-row input[type="search"] { width: 100%; box-sizing: border-box; }
/* Quota columns (the last five of both group tables) hold only a few digits —
   keep them narrow with wrapping multi-line headers. Use max-width (not a fixed
   width) so the header text still fits instead of overflowing. Headers stay
   left-aligned; the digit cells are centred. */
#planning-table th:nth-last-child(-n+5),
#planning-table td:nth-last-child(-n+5):not(.empty),
#all-groups-table th:nth-last-child(-n+5),
#all-groups-table td:nth-last-child(-n+5):not(.empty) {
  max-width: 60px; white-space: normal;
}
#planning-table td:nth-last-child(-n+5):not(.empty),
#all-groups-table td:nth-last-child(-n+5):not(.empty) {
  text-align: center;
}
.cell-center { text-align: center; }

/* GAP detail: the Details table and the Financial Review quota table side by
   side (wrap on narrow screens). */
.detail-columns { display: flex; gap: 40px; flex-wrap: wrap; align-items: flex-start; }
/* Highlights a Recommended Program cell that differs from the applicant's
   Program of Application. */
.cell-mismatch { background: #fdf2dc; color: #9a6a00; }
.form-card .field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 20px; }
/* display:flex above overrides the UA [hidden] rule — restore it for fields
   shown conditionally (e.g. the change-of-program confirmation). */
.form-card .field[hidden] { display: none; }
/* A subtitle inside a question field sits between the label and input; drop its
   default bottom margin so only the field's 6px gap separates it from the input. */
.form-card .field > .subtitle { margin: 0; }
/* Two form fields side by side (e.g. a count beside its funding amount); each
   fills half the row. Stacks on narrow screens. */
/* Edit GAP page: the main form card beside the Financial Review (quota) card. */
.gap-edit-layout { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.gap-edit-layout > .form-card--xwide { flex: 1 1 auto; }
/* The Financial Review + Graduate Office Review cards stack in a right-hand
   column that stays in view (sticky) while the taller left card scrolls. */
.gap-edit-side {
  flex: 1 1 auto; align-self: flex-start; position: sticky; top: 60px;
  display: flex; flex-direction: column; gap: 24px;
}
.gap-edit-side > .form-card { flex: 1 1 auto; }
/* Drop the heading's default 30px top margin (from .form-card .form-subhead) so
   the card title sits against the card's top padding — same treatment as the
   collapsible "Graduate Admissions Planning Form" header on the GAP detail page.
   h2.form-subhead (0,2,1) outranks .form-card .form-subhead (0,2,0). */
.gap-edit-side > .form-card > h2.form-subhead { margin-top: 0; }
/* Collapsible financial-review answers: the summary is the section heading with
   a chevron that flips open/closed. Drop the heading's default top margin so it
   sits snug against the card's top padding. */
.fr-summary summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; gap: 10px;
}
/* Outrank `.form-card .form-subhead` (same 0,2,0) so the heading's 30px top
   margin is actually removed and it sits against the card's top padding. */
.fr-summary summary.form-subhead { margin-top: 0; }
.fr-summary summary::-webkit-details-marker { display: none; }
/* Right-aligned chevron, matching the side-panel cards: points down when open,
   left when closed. */
.fr-summary summary::after {
  content: ""; margin-left: auto; display: inline-block; width: 8px; height: 8px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  color: var(--muted); transform: rotate(45deg); transition: transform 0.15s;
  margin-bottom: 3px; flex: none;
}
.fr-summary details:not([open]) > summary::after { transform: rotate(-45deg); margin-bottom: -2px; }
/* When collapsed, drop the heading's bottom border/padding so it reads as one
   balanced line (form-subhead has no top padding, so kill the 6px bottom too). */
.fr-summary details:not([open]) > summary { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
/* On the group page the preview spans the whole main column, spaced from the
   details table above it. */
.fr-summary--full { max-width: none; margin-top: 16px; box-sizing: border-box; }
/* Award nomination workspace: a check/rationale item, and the ranking list. */
.nom-item { margin: 0 0 14px; display: flex; flex-direction: column; gap: 6px; }
.rank-list { list-style: none; margin: 0 0 4px; padding: 0; }
.rank-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 12px; border: 1px solid var(--border); border-radius: 6px; margin-bottom: 6px;
  background: #fff;
}
.rank-row .rank-name::before { content: counter(rank) ". "; }
.rank-list { counter-reset: rank; }
.rank-row { counter-increment: rank; }
.rank-moves { display: flex; gap: 6px; white-space: nowrap; }
.field-pair { display: flex; gap: 20px; }
.field-pair > .field { flex: 1; min-width: 0; }
@media (max-width: 620px) { .field-pair { flex-direction: column; gap: 0; } }
.help { font-size: 0.8rem; color: var(--muted); margin: 0; }
.markdown-preview {
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 6px;
  background: #fafafa; min-height: 2.5rem; font-size: 0.95rem;
}
.markdown-preview > :first-child { margin-top: 0; }
.markdown-preview > :last-child { margin-bottom: 0; }
/* Side-by-side Markdown editor + live preview (Current Cycle description). */
.md-side-by-side { display: flex; gap: 20px; align-items: stretch; margin-bottom: 16px; }
.md-side-by-side[hidden] { display: none; }
.md-side-by-side > .field { display: flex; flex-direction: column; gap: 6px; }
.md-side-by-side textarea { width: 100%; min-height: 200px; flex: 1; box-sizing: border-box; }
.md-side-by-side .markdown-preview { flex: 1; overflow: auto; }
.md-side-by-side .form-label { font-weight: 600; font-size: 0.9rem; }
/* Per-student support costs grid on the cycle form: inputs fill their cells. */
.cost-table td input { width: 100%; }
.cost-table td, .cost-table th { min-width: 110px; }
/* Rendered Markdown shown inline (e.g. the cycle description on Home). */
.markdown-body { margin: 0 0 16px; }
.markdown-body > :first-child { margin-top: 0; }
.markdown-body > :last-child { margin-bottom: 0; }
/* Collapsible cycle-description preview (cycle detail Overview tab): a form
   card matching the GAP "answers" preview (`.fr-summary`), spaced from the table
   above. The larger caret below makes the toggle more prominent. */
.cycle-desc-card { margin-top: 28px; }
/* Cycle analytics dashboard (Site Configuration). One shared card language
   (.stat-card / .chart-card): same surface, border, radius and accent top
   border; a single 16px gap/rhythm throughout the section. */
/* Cap the grids so cards don't stretch absurdly wide on large screens. */
.stat-cards, .analytics-charts { display: grid; gap: 16px; max-width: 1100px; }
.stat-cards { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin: 16px 0; }
.analytics-charts { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); margin: 0 0 16px; }
.stat-card, .chart-card {
  border: 1px solid var(--border); border-radius: 8px; background: #fafafa;
  border-top: 3px solid var(--accent-2); padding: 12px 16px 14px;
}
.stat-card { display: flex; flex-direction: column; gap: 2px; }
.stat-card .stat-value { font-size: 1.35rem; font-weight: 600; color: var(--accent); font-variant-numeric: tabular-nums; }
.stat-card .stat-label { font-size: 0.82rem; color: var(--muted); }
.stat-card .stat-note { font-size: 0.75rem; color: var(--muted); }
.chart-title {
  margin: 0 0 12px; font-size: 0.92rem; font-weight: 600; color: var(--accent);
  padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.donut-wrap { display: flex; align-items: center; gap: 16px; }
/* The legend must be allowed to shrink inside the card (min-width: 0), and a
   row may wrap its count onto a second line rather than overflow. */
.donut-wrap .chart-legend { flex: 1 1 auto; min-width: 0; }
.donut { width: 116px; height: 116px; flex: none; }
.donut-ring { stroke: #ececf1; stroke-width: 5; }
.donut-seg {
  stroke-width: 5; cursor: pointer;
  transition: stroke-width 0.12s ease, stroke-dasharray 0.55s ease, stroke-dashoffset 0.55s ease;
}
.donut-seg.is-hot { stroke-width: 7; }
.donut-total { font-size: 9px; font-weight: 600; fill: var(--accent); text-anchor: middle; }
.donut-caption { font-size: 3.4px; fill: var(--muted); text-anchor: middle; }
.chart-legend li { border-radius: 5px; padding: 1px 5px; }
.chart-legend li.is-hot { background: #ececf1; }
.analytics-tooltip {
  position: fixed; z-index: 60; pointer-events: none;
  display: flex; align-items: center; gap: 6px;
  background: #1c1c22; color: #fff; font-size: 0.8rem;
  padding: 5px 9px; border-radius: 6px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}
.analytics-tooltip[hidden] { display: none; }
/* Pipeline funnel: one row per stage, bars scale to the Applicants stage. */
.funnel { max-width: 720px; margin: 16px 0; display: flex; flex-direction: column; gap: 7px; }
.funnel-row { display: flex; align-items: center; gap: 12px; }
.funnel-label { flex: 0 0 110px; font-size: 0.85rem; }
.funnel-count { flex: 0 0 48px; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--accent); font-size: 0.9rem; }
.funnel-track { flex: 1 1 auto; height: 16px; border-radius: 4px; background: #ececf1; overflow: hidden; }
.funnel-bar { height: 100%; border-radius: 4px; transition: width 0.55s ease, filter 0.12s ease; cursor: pointer; }
.funnel-bar:hover { filter: brightness(1.2); }
.funnel-gaps { list-style: none; margin: 6px 0 0 170px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 18px; }
.funnel-gap { font-size: 0.82rem; color: var(--secondary-blue); text-decoration: none; }
.funnel-gap:hover { text-decoration: underline; }
.funnel-gap b { font-variant-numeric: tabular-nums; }
/* Cycle Comparison: vertical column charts, one column per selected cycle. */
.compare-picker { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 12px 0 16px; }
.compare-check { display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; cursor: pointer; }
.colchart { display: flex; align-items: stretch; gap: 12px; height: 150px; }
.col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.col[hidden] { display: none; }
.col-value { font-size: 0.8rem; font-weight: 600; color: var(--accent); font-variant-numeric: tabular-nums; }
.col-track { flex: 1 1 auto; width: 100%; max-width: 46px; display: flex; align-items: flex-end; border-radius: 4px; background: #f1f1f5; }
.col-bar {
  width: 100%; border-radius: 4px 4px 0 0; background: var(--accent-2); min-height: 2px;
  transition: height 0.55s ease, filter 0.12s ease; cursor: pointer;
}
.col-bar:hover { filter: brightness(1.2); }
.col.is-current .col-bar { background: var(--accent); }
/* Stacked applicant columns: domestic + international segments (top-down),
   heights as shares of the column's own total. */
.col-bar--stacked { display: flex; flex-direction: column-reverse; background: transparent; overflow: hidden; }
.col-bar--stacked .col-seg { width: 100%; transition: height 0.55s ease, filter 0.12s ease; cursor: pointer; }
.col-bar--stacked .col-seg:hover { filter: brightness(1.2); }
/* Horizontal legend (under stacked comparison charts). The extra class in the
   selector outranks the vertical .chart-legend default regardless of order,
   and labels keep their natural width instead of flexing full-row. */
.chart-legend.chart-legend--row { flex-direction: row; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; }
.chart-legend.chart-legend--row .legend-label { flex: 0 1 auto; }
.col-label { font-size: 0.75rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.col.is-current .col-label { font-weight: 600; color: inherit; }
/* "Other" card rows. */
.context-rows { display: flex; flex-direction: column; gap: 7px; margin: 0; padding: 0; list-style: none; }
.in-progress-pill {
  display: inline-block; padding: 0 7px; border-radius: 999px; font-size: 0.68rem;
  background: #fdf2dc; color: #9a6a00; vertical-align: 1px;
}
.context-rows li { display: flex; align-items: baseline; gap: 8px; font-size: 0.85rem; min-width: 0; }
.context-rows .legend-count { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Round filter pills above the cards. */
.round-pills { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.round-pills .pills-label { font-size: 0.85rem; color: var(--muted); }
.round-pills .pill {
  display: inline-block; padding: 3px 12px; border-radius: 999px; font-size: 0.82rem;
  border: 1px solid var(--border); background: #fff; color: inherit; text-decoration: none;
}
.round-pills .pill:hover { border-color: var(--accent-2); }
.round-pills .pill.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.chart-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; font-size: 0.85rem; }
.chart-legend li { display: flex; align-items: center; gap: 7px; min-width: 0; }
/* Labels shrink with an ellipsis (full text in the title) so every row stays
   on one line; the count keeps its place on the right. */
.legend-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-legend .legend-count { margin-left: auto; color: var(--muted); font-variant-numeric: tabular-nums; padding-left: 12px; white-space: nowrap; }
.swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; display: inline-block; }
.chart-note { font-size: 0.8rem; color: var(--muted); margin: -4px 0 12px; }
.stack-counts { white-space: nowrap; }
.stack-count { display: inline-flex; align-items: center; gap: 4px; margin-right: 10px; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
/* Award description cell: clamp to a few lines; JS reveals a Show more toggle. */
.desc-clip {
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden;
}
.desc-clip.expanded {
  display: block; -webkit-line-clamp: unset; line-clamp: unset; overflow: visible;
}
/* Recommendation notes (applicant detail table) use the same clamp; the cell
   must wrap (the scroll wrapper defaults cells to nowrap) and stay readable. */
#applicant-recommendations-table td.col-notes { white-space: normal; min-width: 240px; max-width: 380px; }
#applicant-recommendations-table td.col-notes .desc-toggle { margin-top: 2px; }
.desc-clip > :first-child { margin-top: 0; }
.desc-clip > :last-child { margin-bottom: 0; }
.desc-toggle {
  display: inline-block; margin-top: 4px; padding: 0;
  background: none; border: none; color: var(--secondary-blue);
  font-size: 0.85rem; cursor: pointer;
}
.desc-toggle:hover { text-decoration: underline; }
/* display:inline-block above overrides the UA [hidden] rule — restore it, or
   every toggle shows regardless of the JS overflow check. */
.desc-toggle[hidden] { display: none; }
/* Form field labels are the questions — keep them full-size and high-contrast
   (not muted/small), which is hard to read for some users. */
.form-card label { font-size: 0.95rem; color: #1c1c22; font-weight: 500; }
.form-card .optional { text-transform: none; font-style: italic; font-weight: 400; color: var(--muted); }
/* Red everywhere a required field is marked — forms and modals alike. */
.required-marker { color: #d32f2f; margin-left: -3px; }
.form-card input, .form-card select {
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.95rem;
}
/* Read-only (auto-calculated) inputs: greyed out with a "no-edit" cursor so
   users see the value is computed, not entered. */
.form-card input[readonly] {
  background: #f0f0f4; color: var(--muted); cursor: not-allowed;
}
/* Read-only value shown on a detail page in place of a form input (same look
   as a read-only input, indented like the form's inputs). */
.form-card .field > .readonly-value {
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 6px;
  background: #f0f0f4; color: var(--muted); font-size: 0.95rem;
  margin-left: 6px; white-space: pre-wrap;
}
/* Indent responses slightly from their question labels so the two read as a
   pair. width:auto lets the flex column stretch the input to fill the remaining
   space (accounting for the margin) instead of overflowing. Checkboxes are on
   their own row (.field--check), so they keep their layout. */
.form-card .field > input:not([type="checkbox"]),
.form-card .field > select,
.form-card .field > textarea {
  margin-left: 6px; width: auto;
}
/* Checkbox field: checkbox and its label sit on one row, label to the right. */
.form-card .field--check { flex-direction: row; align-items: center; gap: 8px; }
.form-card .field--check input[type="checkbox"] {
  width: 16px; height: 16px; padding: 0; margin: 0; border-radius: 4px;
  accent-color: var(--accent); cursor: pointer; flex: none;
}
.form-card .field--check label { margin: 0; cursor: pointer; }
/* Toggle-switch styling for checkboxes marked .switch (overrides the plain
   checkbox sizing above). */
input[type="checkbox"].switch,
.form-card .field--check input[type="checkbox"].switch {
  appearance: none; -webkit-appearance: none;
  position: relative; width: 40px; height: 22px; flex: none;
  padding: 0; margin: 0; border: none; border-radius: 22px;
  background: var(--border); cursor: pointer; transition: background 0.2s;
}
input[type="checkbox"].switch::before {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%; background: #fff;
  transition: transform 0.2s;
}
input[type="checkbox"].switch:checked,
.form-card .field--check input[type="checkbox"].switch:checked { background: var(--accent-2); }
input[type="checkbox"].switch:checked::before,
.form-card .field--check input[type="checkbox"].switch:checked::before { transform: translateX(18px); }
input[type="checkbox"].switch:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.form-actions { display: flex; gap: 10px; align-items: center; margin-top: 6px; }

/* ----- Tooltips ----- */
/* Intent-to-supervise cards (recommendation detail): one card per
   supervisor, side by side for co-supervision. */
.intent-cards { display: flex; flex-wrap: wrap; gap: 16px; }
.intent-card {
  flex: 0 1 340px; min-width: 260px; padding: 14px 16px 10px;
  border: 1px solid var(--border); border-radius: 8px; background: #fafafa;
  border-top: 3px solid var(--accent-2);
}
/* Borderless label/value rows inside the card — lighter than a table. */
.intent-rows { display: flex; flex-direction: column; gap: 10px; }
.intent-row { display: flex; flex-direction: column; gap: 3px; }
.intent-label {
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted);
}
.intent-value { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; }
.intent-card { padding-bottom: 16px; }

/* Info tooltips: a small circle with an italic-serif "i". */
.tooltip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%; position: relative;
  background: #ececf1; color: var(--muted); font-size: 0.7rem; font-weight: 600;
  font-style: italic; font-family: Georgia, serif;
  cursor: help; vertical-align: 1px;
  /* Inside a <th> (uppercased) the "i" trigger and its tip text must keep
     their own case and tracking. */
  text-transform: none; letter-spacing: normal;
}
/* Tip content: plain text via data-tip (::after), or rich HTML via a nested
   .tip-text element (e.g. to bold part of the message). */
.tooltip[data-tip]::after, .tooltip .tip-text {
  position: absolute; left: 0; bottom: calc(100% + 6px);
  width: 230px; background: #1c1c22; color: #fff; padding: 8px 10px;
  border-radius: 6px; font-size: 0.78rem; font-weight: 400; line-height: 1.35;
  font-style: normal; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  text-align: left; text-transform: none; white-space: normal;
  opacity: 0; pointer-events: none; transition: opacity 0.12s; z-index: 10;
}
.tooltip[data-tip]::after { content: attr(data-tip); }
.tooltip:hover::after, .tooltip:focus::after,
.tooltip:hover .tip-text, .tooltip:focus .tip-text { opacity: 1; }
/* Wrapper variant: wraps arbitrary content (e.g. a disabled button, which
   can't receive hover itself) instead of rendering the "?" badge. */
.tooltip.tooltip--wrap {
  width: auto; height: auto; background: none; border-radius: 0;
  color: inherit; font-size: inherit; font-weight: inherit; cursor: default;
  font-style: normal; font-family: inherit;
  vertical-align: baseline;
}
/* Compact bubble for short tips (e.g. a full timestamp over a date cell):
   size to the text instead of the 230px paragraph box. */
.tooltip.tooltip--compact[data-tip]::after { width: max-content; max-width: 230px; white-space: nowrap; }
.tooltip.tooltip--compact .tip-text { width: max-content; max-width: 260px; white-space: normal; }
.tip-text .tip-list { margin: 4px 0 0; padding-left: 16px; }
/* Recs column: the count is plain text; the "?" beside it (a standard round
   tooltip) lists the recommending groups. */
.rec-cell { white-space: nowrap; font-variant-numeric: tabular-nums; }
.rec-count .tip-list { margin: 4px 0 0; padding-left: 18px; }
.rec-cell .tooltip { vertical-align: 1px; }
.rec-count .tip-list li { margin: 1px 0; }

/* ----- Bootstrap-style form control + dropdown (add-user autocomplete) -----
   Component styles matching Bootstrap 5 so the field/menu look like Bootstrap
   without pulling the whole framework in (which would collide with the app's
   own .modal / .btn classes). */
.form-label { display: block; margin-bottom: 0.5rem; font-size: 0.95rem; color: #1c1c22; font-weight: 400; }
/* Bulleted list within a form field (e.g. the GAP group-commitment points). */
.commit-list { margin: 4px 0 0; padding-left: 20px; font-size: 0.95rem; color: #1c1c22; line-height: 1.45; }
.commit-list li { margin-bottom: 6px; }
.commit-list li:last-child { margin-bottom: 0; }
/* display:block below overrides the UA [hidden] rule — restore it so a
   form-control with the hidden attribute (e.g. a hidden rationale box) stays
   hidden. */
.form-control[hidden] { display: none; }
.form-control {
  display: block; width: 100%; padding: 0.375rem 0.75rem;
  font-family: inherit; font-size: 1rem; line-height: 1.5; color: #212529;
  background-color: #fff; border: 1px solid #ced4da; border-radius: 0.375rem;
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.form-control:focus {
  border-color: #86b7fe; outline: 0;
  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}
.dropdown { position: relative; }
.dropdown-menu {
  position: absolute; top: 100%; left: 0; z-index: 1000; width: 100%;
  display: none; max-height: 240px; overflow-y: auto;
  margin-top: 0.125rem; padding: 0.5rem 0; list-style: none;
  font-size: 1rem; color: #212529; text-align: left; background-color: #fff;
  border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 0.375rem;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}
.dropdown-menu.show { display: block; }
.dropdown-item {
  display: block; width: 100%; padding: 0.375rem 1rem; clear: both;
  font-family: inherit; font-size: 0.95rem; font-weight: 400; color: #212529;
  text-align: left; white-space: nowrap; background: transparent; border: 0;
  cursor: pointer;
}
.dropdown-item:hover, .dropdown-item:focus { background-color: #e9ecef; }
.text-muted { color: #6c757d; }
.small { font-size: 0.85em; }

/* ----- Modal dialogs ----- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 100; background: rgba(20, 20, 30, 0.45);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.modal-overlay[hidden] { display: none; }
.modal {
  background: #fff; border-radius: 10px; padding: 22px 24px 24px;
  width: 100%; max-width: 420px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}
.modal--wide { max-width: 620px; }
/* Modal forms adopt the app's non-modal form styling — a brand-coloured,
   underlined heading and app-flavoured inputs/labels — instead of the
   Bootstrap-ish defaults, so modals and full-page forms read the same. */
.modal h2 {
  font-size: 1.2rem; color: var(--accent); font-weight: 600;
  margin: 0 0 16px; padding-bottom: 8px; border-bottom: 2px solid var(--accent);
}
/* A subtitle directly under the heading sits closer to it than the border gap. */
.modal h2 + .subtitle { margin-top: -6px; }
/* Subordinate heading within a modal (e.g. the add-user "Roles" group). */
.modal h3 {
  font-size: 0.95rem; color: var(--muted); font-weight: 600;
  margin: 22px 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
.modal .form-label { font-weight: 500; color: #1c1c22; margin-bottom: 6px; }
.modal .optional { text-transform: none; font-style: italic; font-weight: 400; color: var(--muted); }
/* Inputs match the app's form inputs: softer border, brand focus ring, and the
   same padding/size (overrides the Bootstrap-flavoured .form-control above). */
.modal .form-control {
  padding: 9px 11px; font-size: 0.95rem; line-height: 1.4; color: #1c1c22;
  border: 1px solid var(--border); border-radius: 6px;
  /* Indent the response slightly from its label, matching the non-modal forms.
     .modal-field is a block (not a flex column), so shrink the width to keep the
     input from overflowing its 6px offset. */
  margin-left: 6px; width: calc(100% - 6px);
}
.modal .form-control:focus {
  border-color: var(--accent-2); box-shadow: 0 0 0 3px rgba(0, 127, 163, 0.18);
}
/* Autocomplete wraps its input in .dropdown and anchors the menu to it; indent
   the wrapper so the input and its dropdown menu shift together as a unit. */
.modal .dropdown { margin-left: 6px; }
.modal .dropdown .form-control { margin-left: 0; width: 100%; }
.modal .detail-table { margin-bottom: 4px; }
.modal .detail-table th { width: 110px; }
#view-user-memberships { margin-bottom: 20px; }
.modal .subtitle { margin: 0 0 16px; }
/* Field list in the import modals — one column per line for readability. */
.modal-list {
  margin: 0 0 16px; padding-left: 20px;
  color: var(--muted); font-size: 0.9rem; line-height: 1.5;
}
.modal-list li { margin-bottom: 4px; }
.modal-body { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
.modal-actions { display: flex; gap: 10px; margin-top: 14px; }
.check-row {
  display: flex; align-items: center; gap: 8px; font-size: 0.92rem; cursor: pointer;
}
.check-row input[type="checkbox"] { width: 16px; height: 16px; flex: none; accent-color: var(--accent); }
/* A toggle-switch checkbox inside a .check-row keeps the switch dimensions
   (this outranks the 16px sizing above; the rest comes from the .switch rules). */
.check-row input[type="checkbox"].switch { width: 40px; height: 22px; flex: none; }
/* Emphasised consent checkbox (e.g. the GAP group commitment) — a bordered
   callout so it stands out from the surrounding fields. */
.consent-box {
  margin-top: 6px; padding: 12px 14px; border: 2px solid var(--accent);
  border-radius: 8px; background: #f2f5fb; font-weight: 500;
}

/* Action-button cells: tighter vertical padding so rows with buttons stay
   close to the height of rows without them. The td must keep rendering as a
   real table cell (no display: flex) or it won't stretch to the row height
   and its borders break beside multi-line cells — so the buttons lay out
   inline with margins instead of flex gap. */
.row-actions {
  white-space: nowrap; vertical-align: middle;
  padding-top: 5px !important; padding-bottom: 5px !important;
}
.row-actions > .btn, .row-actions > form { display: inline-flex; align-items: center; vertical-align: middle; }
.row-actions > form { margin: 0; }
.row-actions > * + * { margin-left: 6px; }
.modal-field { margin-bottom: 16px; }
.new-user-note {
  background: #eaf3f6; color: var(--accent); border: 1px solid #cfe4ec;
  border-radius: 6px; padding: 8px 11px; margin: 0 0 14px; font-size: 0.85rem;
}

/* Import preview rows. */
.import-row.import-skip td { background: #fbe4e4; color: #b13030; }
.import-row.import-noop { color: var(--muted); }
/* Per-cell highlight for a value the reviewer must choose: amber while
   unresolved, green once a valid value is selected (toggled by JS). The Change
   column reflects the row's overall state. */
.import-cell-needs { background: #fdf2dc; }
.import-cell-needs.is-resolved { background: #e3f6e8; }
.change-resolved { color: #1e7a3c; font-weight: 500; }
.import-note { font-size: 0.8rem; color: var(--muted); margin-top: 2px; }
.import-row.import-skip .import-note { color: #b13030; }

/* ----- Tabbed views ----- */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; }
.tabs .tab {
  background: none; border: none; cursor: pointer; font-family: inherit;
  font-size: 0.95rem; color: var(--muted); padding: 8px 14px;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs .tab:hover { color: var(--accent); }
.tabs .tab.active { color: #1c1c22; border-bottom-color: var(--accent); font-weight: 500; }
.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* ----- Step progress bar ----- */
.progress-steps { display: flex; list-style: none; margin: 0 0 18px; padding: 0; }
.progress-step {
  flex: 1; text-align: center; position: relative; font-size: 0.78rem; color: var(--muted);
  line-height: 1.2;
}
/* connector line running back to the previous marker (centred on the marker) */
.progress-step::before {
  content: ""; position: absolute; top: 10px; left: -50%; width: 100%; height: 2px;
  background: #e2e2ea; z-index: 0;
}
.progress-step:first-child::before { display: none; }
.progress-marker {
  position: relative; z-index: 1; display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin: 0 auto 4px; border-radius: 50%;
  background: #e2e2ea; border: 2px solid #e2e2ea; color: var(--muted); font-size: 0.72rem;
}
.progress-label { display: block; padding: 0 4px; }
/* reached steps colour the connector into them */
.progress-step.is-done::before,
.progress-step.is-current::before,
.progress-step.is-rejected::before { background: var(--accent); }
.progress-step.is-done .progress-marker { background: var(--accent); border-color: var(--accent); color: #fff; }
.progress-step.is-current .progress-marker { background: #fff; border-color: var(--accent); color: var(--accent); }
.progress-step.is-current .progress-label { color: var(--accent); font-weight: 600; }
.progress-step.is-rejected::before { background: #b3261e; }
.progress-step.is-rejected .progress-marker { background: #b3261e; border-color: #b3261e; color: #fff; }
.progress-step.is-rejected .progress-label { color: #b3261e; font-weight: 600; }

/* ----- Applicant info panel (recommendation form) ----- */
.applicant-info {
  margin-top: 8px; padding: 10px 14px; background: #f0f0f5;
  border: 1px solid var(--border); border-radius: 6px; font-size: 0.9rem;
}
/* Standalone preview (e.g. atop the edit-recommendation form) needs bottom
   spacing before the form fields. */
.applicant-info--preview { margin-bottom: 20px; }
.applicant-info dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; }
.applicant-info dt { color: var(--muted); }
.applicant-info dd { margin: 0; }

/* ----- Applicants table (home) ----- */
h1 { font-size: 1.4rem; margin: 0 0 4px; }
.subtitle { color: var(--muted); margin: 0 0 20px; font-size: 0.9rem; }
/* Lists inside a subtitle inherit its muted colour/size; tidy the spacing so
   they read as part of the subtitle rather than a default browser list. */
.subtitle ol, .subtitle ul { margin: 4px 0 0; padding-left: 20px; line-height: 1.45; }
.subtitle li { margin-bottom: 6px; }
.subtitle li:last-child { margin-bottom: 0; }

/* No overflow:hidden here — popovers (e.g. .tooltip) must escape the table.
   The rounded corners come from radii on the corner cells instead. */
table {
  width: 100%; border-collapse: separate; border-spacing: 0; background: #fff;
  border: 1px solid var(--border); border-radius: 8px;
}
/* Small tables (key-value details, short lists) that shouldn't stretch to the
   full container width. */
table.table--auto { width: auto; }
table > :first-child > tr:first-child > :first-child { border-top-left-radius: 7px; }
table > :first-child > tr:first-child > :last-child { border-top-right-radius: 7px; }
table > :last-child > tr:last-child > :first-child { border-bottom-left-radius: 7px; }
table > :last-child > tr:last-child > :last-child { border-bottom-right-radius: 7px; }
th, td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border); font-size: 0.92rem; }
th { background: #f0f0f5; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: #fafaff; }
/* Clearly highlight the row under the cursor on DataTables-enhanced tables
   (the faint default above is hard to see on these dense tables). */
table.dataTable tbody tr:hover { background: #eaf1fb; }
td a { color: var(--secondary-blue); text-decoration: none; }
td a:hover { text-decoration: underline; }

.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 0.78rem; }
/* display:inline-block above overrides the UA [hidden] rule — restore it
   (e.g. the Edit-awards modal hides its Keep pill for single selections). */
.badge[hidden] { display: none; }
/* A badge that is a link (e.g. the Intent to Supervise count pill): keep the
   pill colours, underline on hover to signal it's clickable. */
a.badge { text-decoration: none; }
a.badge:hover, a.badge:focus-visible { text-decoration: underline; }
.badge.admit, .badge.admit_msc, .badge.admit_phd, .badge.admit_dephd { background: #e3f6e8; color: #1e7a3c; }
.badge.hold { background: #fdf2dc; color: #9a6a00; }
.badge.reject { background: #fbe4e4; color: #b13030; }
.badge.none { background: #ececf1; color: var(--muted); }
/* Quota buckets, each visually distinct (adjustment cards). */
.badge.qa-bucket-dom { background: #e2ecfb; color: #2456a8; }
.badge.qa-bucket-intl { background: #ece4f7; color: #6a3fa0; }
.badge.qa-bucket-com { background: #ddf2ef; color: #1d7a6b; }
.badge.yes { background: #e3f6e8; color: #1e7a3c; }
.badge.no { background: #fbe4e4; color: #b13030; }
/* Source pill in a merged changelog (group page): Group vs GAP form entries. */
.badge.changelog-kind { font-size: 0.72rem; margin-right: 4px; vertical-align: 1px; white-space: nowrap; }
.badge.kind-group { background: #e4eefb; color: #1E3765; }
.badge.kind-gap { background: #e0f0fb; color: #1b5e8a; }
/* Badge rendered as a link (e.g. the GAP-status badges in the Groups tables). */
a.badge { text-decoration: none; cursor: pointer; }
a.badge:hover { opacity: 0.85; }

/* Committee-review workflow status badges (derived ReviewStatus), coloured by
   progression: grey (unassigned) -> amber (in review) -> blue (review complete)
   -> green (decision recorded) -> solid green (decision released). */
.status-badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 0.78rem; white-space: nowrap; }
.status-badge.status-unassigned { background: #ececf1; color: var(--muted); }
.status-badge.status-in_review { background: #fdf2dc; color: #9a6a00; }
.status-badge.status-review_complete { background: #e0f0fb; color: #1b5e8a; }
.status-badge.status-decision_recorded { background: #f2fbf4; color: #4a9b62; }
/* Auto-recorded tentative decisions: same green family, dashed ring to read
   as "machine-made, awaiting the lead's confirmation". */
.status-badge.status-decision_recorded_auto { background: #f2fbf4; color: #4a9b62; box-shadow: inset 0 0 0 1px #7cc79a; }
.status-badge.status-decision_submitted { background: #e3f6e8; color: #1e7a3c; }
.status-badge.status-decision_released { background: #1e7a3c; color: #fff; }
/* Committee-member per-applicant statuses (their simplified Committee Review
   table): amber (missing) -> green (submitted); grey dashed = locked. */
.status-badge.status-missing { background: #fdf2dc; color: #9a6a00; }
.status-badge.status-submitted { background: #e3f6e8; color: #1e7a3c; }
.status-badge.status-locked { background: #ececf1; color: var(--muted); border: 1px dashed #c4c4cf; }
/* A locked row is read-only: muted so it visibly drops out of the to-do list. */
tr.is-locked td:not(.col-status) { color: var(--muted); }
tr.is-locked .col-select input { cursor: not-allowed; }

/* Reviewer pills on the Committee Review page: "Name (score)". An incomplete
   review (no score) is grey with "(-)"; score 1 is red; scores 2-5 deepen
   through blue to U of T Blue at 5 (strongest). Colour comes from the shared
   --score-bg/--score-fg palette below. */
.review-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.78rem;
  margin: 1px 2px;
  white-space: nowrap;
  background: var(--score-bg, #ececf1);
  color: var(--score-fg, var(--muted));
}
/* Badges in the assign modal, revealed by JS: an amber conflict-of-interest
   warning, and a green note that the reviewer has already submitted a score
   (unassigning them will delete their review). */
.conflict-badge, .completed-badge {
  display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 999px;
  font-size: 0.72rem;
}
.conflict-badge { background: #fdf2dc; color: #9a6a00; }
.completed-badge { background: #e3f6e8; color: #1e7a3c; }
.conflict-badge[hidden], .completed-badge[hidden] { display: none; }
/* When the conflict badge doubles as a hover tooltip (bulk assign modal),
   undo the circular .tooltip sizing so it stays a pill. */
/* Badges reuse .tooltip only for its hover bubble — they're text/icon
   badges, not the round italic-serif "i" mark, so reset that styling. */
.conflict-badge.tooltip, .completed-badge.tooltip, .flag-icon.tooltip {
  width: auto; height: auto; cursor: help;
  font-style: normal; font-family: inherit;
}
.conflict-badge .tip-list { margin: 4px 0 0; padding-left: 18px; }
/* Assign-reviewers modal: the badges collapse to icon-only flags, right-aligned
   in the row so two flags sit neatly side by side. Hover/focus expands the
   short label and shows the detail tip (anchored to the right edge so it
   doesn't overflow the modal). */
.row-flags { display: inline-flex; gap: 4px; margin-left: auto; }
.flag-icon.tooltip {
  width: auto; height: 20px; margin-left: 0; padding: 0 6px; border-radius: 999px;
  gap: 0; font-size: 0.72rem; font-weight: 600; cursor: help;
  transition: padding 0.15s;
}
.flag-icon .flag-glyph { font-size: 0.8rem; line-height: 1; }
.flag-icon .flag-label {
  display: inline-block; max-width: 0; overflow: hidden; white-space: nowrap;
  opacity: 0; transition: max-width 0.15s, opacity 0.15s, margin 0.15s;
}
.flag-icon:hover .flag-label, .flag-icon:focus .flag-label {
  max-width: 120px; margin-left: 4px; opacity: 1;
}
.flag-icon .tip-text { left: auto; right: 0; }
.flag-icon:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Score colour palette, shared by the pills, the inline selects, and the picker
   options' selected state (via custom properties, so all three stay in sync).
   1 = red (inadmissible); 2–5 deepen through blue to U of T Blue (#1E3765) at 5. */
.score-none { --score-bg: #ececf1; --score-fg: var(--muted); }
.score-1 { --score-bg: #fbe4e4; --score-fg: #b13030; }
.score-2 { --score-bg: #eff6ff; --score-fg: #1e3765; }
.score-3 { --score-bg: #bfdbfe; --score-fg: #1e3765; }
.score-4 { --score-bg: #2e5a92; --score-fg: #ffffff; }
.score-5 { --score-bg: #1e3765; --score-fg: #ffffff; }

/* Inline Score editor in the member Committee Review table: a compact 1–5 select
   that saves on change, colour-coded via the shared palette. */
.score-inline-form { margin: 0; }
.score-inline {
  padding: 3px 6px; border: 1px solid var(--border); border-radius: 6px;
  font-size: 0.85rem; font-weight: 600; cursor: pointer;
  background: var(--score-bg); color: var(--score-fg);
}
/* Unscored: a plain white box rather than the grey pill background. */
.score-inline.score-none { --score-bg: #fff; }

.round-label { color: var(--muted); font-size: 0.8rem; }
.empty { padding: 32px; text-align: center; color: var(--muted); }
a.slate { color: var(--secondary-blue); text-decoration: none; }

/* ----- Applicant detail ----- */
.breadcrumb { margin: 0 0 12px; font-size: 0.9rem; }
.breadcrumb a { color: var(--secondary-blue); text-decoration: none; }
.section { margin: 28px 0; }
/* A page's title heading is an h1 (one per page); section headings below it
   stay h2/h3. Both share the section-heading look, with the h1 a step larger. */
.section h1, .section h2 {
  margin: 0 0 10px; padding-bottom: 6px;
  border-bottom: 2px solid var(--border);
}
.section h1 { font-size: 1.3rem; }
.section h2 { font-size: 1.05rem; }
/* Space above a subsequent heading within a section (e.g. "Per-student support
   costs" below the details table); the first heading needs no extra gap. */
.section h2:not(:first-child) { margin-top: 28px; }
/* Modals nested inside a .section keep the modal heading style — without this
   the .section h2 rules above would add a 28px top margin and a grey rule. */
.section .modal h2 {
  font-size: 1.2rem; color: var(--accent);
  margin: 0 0 16px; padding-bottom: 8px; border-bottom: 2px solid var(--accent);
}
/* Subordinate heading inside a section (e.g. "Per-student support costs" /
   "Description" in Current Cycle): smaller and quieter than the section's h2. */
.section h3.form-subhead {
  font-size: 0.95rem; color: var(--muted); font-weight: 600;
  margin: 22px 0 10px; padding-bottom: 4px; border-bottom: 1px solid var(--border);
}
.detail-label { width: 220px; background: #f0f0f5; color: var(--muted); white-space: nowrap; }

/* Applicant detail: main content (left) beside a sticky right-hand panel that
   holds the Admin / Review / Comments sections and stays in view while the
   longer left column scrolls. Stacks on narrow screens. */
/* Two columns via grid: the left track has a 0 minimum, so a wide table can
   never push the column wider and overlap the panel — the table scrolls within
   its .table-scroll wrapper instead. The right panel is a bounded, sticky
   column. Below 1000px the grid collapses to one column and the panel drops
   below the left content. */
.detail-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
  gap: 24px; align-items: start;
}
.detail-main { min-width: 0; }
/* The heading/cycle/actions sit at the top of the left column (above the first
   section) so the sticky side panel starts level with the page title. */
.detail-main > h1 { margin-top: 0; }
/* The right column stacks each role's card (Admin / Committee Lead / Reviewer /
   Faculty / Comments) with spacing between them; the whole column is sticky
   and scrolls on its own when taller than the viewport (long comment threads),
   so the bottom cards are never cut off. */
.detail-side {
  /* Fill the wrapper's remaining width (it's a flex item beside the drawer
     handle); min-width: 0 lets wide content scroll inside a card instead of
     stretching the column. */
  flex: 1 1 auto; min-width: 0; width: 100%; box-sizing: border-box;
  align-self: flex-start;
  /* 100vh minus the page's top margin (24px), the breadcrumb row (~32px) and
     a matching 24px gap at the bottom, so the panel fits fully in view even
     before the page is scrolled. */
  max-height: calc(100vh - 80px); overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 24px;
  /* Keep the cards' shadows/outlines and the scrollbar from touching. */
  padding-right: 4px; margin-right: -4px;
}
.detail-side > .detail-panel { flex: none; min-width: 0; width: 100%; box-sizing: border-box; }
/* Tooltips inside the (overflow-clipped) side column: open downwards and
   centred on the icon, narrow enough to stay inside the card. */
/* Fix-positioned at the trigger (detail_side_panel.js stamps the --tip-*
   vars on hover/focus) so the bubble spills out of the scrolling column
   instead of being clipped by it. */
.detail-side .tooltip[data-tip]::after, .detail-side .tooltip .tip-text {
  position: fixed; bottom: auto; top: var(--tip-top, 0); left: var(--tip-left, 0);
  transform: none; width: 200px;
}
/* Wide content inside a card (tables) scrolls within the card. */
.detail-panel .table-scroll, .detail-panel table { max-width: 100%; }
@media (max-width: 1000px) {
  .detail-layout { grid-template-columns: minmax(0, 1fr); }
  .detail-side { max-height: none; overflow: visible; padding-right: 0; margin-right: 0; }
  .detail-side-wrap { position: static; }
  .detail-layout.side-hidden { grid-template-columns: minmax(0, 1fr); }
}
.detail-panel {
  background: #fff; border: 1px solid var(--border); border-radius: 8px;
  padding: 4px 18px 18px;
}
/* Sections stacked within the sticky panel; each has an underlined heading like
   .section h2. The first needs no top gap; later ones get breathing room. */
.panel-section { margin-top: 24px; }
.panel-section:first-child { margin-top: 10px; }
.panel-section > h2 {
  font-size: 1.05rem; margin: 0 0 10px; padding-bottom: 6px;
  border-bottom: 2px solid var(--border);
}
/* A status badge sitting beside a panel heading (e.g. the Reviewer card): normal
   weight and vertically centred against the larger heading text. */
.panel-section > h2 .status-badge {
  margin-left: 8px; vertical-align: middle; font-weight: 400;
}
.panel-placeholder { color: var(--muted); font-size: 0.88rem; margin: 0; }
/* The side column is a drawer: a slim handle on its left edge slides it
   closed (the column shrinks to just the handle) and open again. Cards collapse
   by clicking their heading. Both persist in localStorage
   (detail_side_panel.js). */
/* The wrapper (grid item) is what sticks — the aside and handle live inside
   it, so putting sticky on them would give them no room to move. */
.detail-side-wrap {
  display: flex; align-items: flex-start; gap: 6px; min-width: 0;
  align-self: start; position: sticky; top: 60px;
}
.detail-layout { transition: grid-template-columns 0.2s ease; }
.detail-layout.side-hidden { grid-template-columns: minmax(0, 1fr) 20px; }
.detail-side[hidden] { display: none; }
.side-drawer-handle {
  flex: none; width: 20px; height: 52px;
  display: flex; align-items: center; justify-content: center; padding: 0;
  background: #fff; border: 1px solid var(--border); border-radius: 6px 0 0 6px;
  color: var(--muted); cursor: pointer;
}
.side-drawer-handle:hover, .side-drawer-handle:focus-visible { color: var(--accent); border-color: var(--accent); }
.side-drawer-handle .chevron {
  display: inline-block; width: 7px; height: 7px; border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor; transform: rotate(-45deg); margin-left: -3px;
  transition: transform 0.15s, margin 0.15s;
}
/* Closed: the chevron points left ("pull the drawer back out"). */
.side-hidden .side-drawer-handle .chevron { transform: rotate(135deg); margin-left: 3px; }
/* Open: the handle hugs the panel; closed: it hugs the right edge of the page. */
.side-hidden .detail-side-wrap { justify-content: flex-end; }
.detail-panel[data-panel] .panel-section > h2 { cursor: pointer; user-select: none; display: flex; align-items: center; }
.detail-panel[data-panel] .panel-section > h2 .status-badge { margin-left: 8px; }
.panel-collapse {
  margin-left: auto; background: none; border: 0; padding: 2px 4px; cursor: pointer;
  color: var(--muted); line-height: 0;
}
.panel-collapse .chevron {
  display: inline-block; width: 8px; height: 8px; border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor; transform: rotate(45deg); transition: transform 0.15s;
  margin-bottom: 3px;
}
.detail-panel.is-collapsed .panel-collapse .chevron { transform: rotate(-45deg); margin-bottom: -2px; }
/* Collapsed: only the heading row remains; its underline becomes the card edge. */
.detail-panel.is-collapsed .panel-section > *:not(h2) { display: none; }
.detail-panel.is-collapsed .panel-section > h2 { margin-bottom: 0; border-bottom: none; padding-bottom: 0; }
.detail-panel.is-collapsed { padding-bottom: 10px; }
/* Committee Lead panel (applicant detail): Reviewers / Decision sub-sections,
   mirroring the applicant's row on the Committee Review page. */
.lead-subhead {
  display: flex; align-items: center; gap: 8px; font-size: 0.85rem; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; margin: 22px 0 6px;
}
/* A status pill beside a sub-heading keeps normal casing/weight. */
.lead-subhead .badge { text-transform: none; letter-spacing: 0; font-weight: 500; }
.lead-subhead .panel-placeholder { margin: 0; }
.lead-reviewers { display: flex; flex-wrap: wrap; gap: 4px; }
/* Faculty card: the viewer's own recommendations for the applicant — one
   compact row per group (name · date · Edit). */
.my-recs { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
/* One small card per recommendation: a coloured left tab (--rec-accent, one
   hue per group), two columns — left: group name / group type; right: round /
   Edit · Withdraw. */
.my-rec {
  display: flex; align-items: stretch; justify-content: space-between; gap: 10px;
  padding: 6px 10px 6px 12px; font-size: 0.88rem;
  border: 1px solid var(--border); border-left: 5px solid var(--rec-accent, var(--accent-2));
  border-radius: 6px; background: #fff;
}
.my-rec-left, .my-rec-right { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.my-rec-left { flex: 1 1 auto; align-items: flex-start; }
.my-rec-right { flex: none; align-items: flex-end; text-align: right; }
.my-rec-group { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.my-rec-round, .my-rec-type { color: var(--muted); font-size: 0.8rem; }
.my-rec-actions { display: inline-flex; gap: 8px; min-height: 1em; }
.my-rec-withdrawn { font-size: 0.8rem; }
/* A withdrawn card reads as disabled: greyed text, faded tab, muted surface. */
.my-rec.is-withdrawn { background: #f4f4f7; color: var(--muted); border-left-color: #c8c8d2 !important; }
.my-rec.is-withdrawn .my-rec-group { color: var(--muted); }
/* …and collapses to a single row: name left, "round | Withdrawn" right. */
.my-rec.is-withdrawn { align-items: center; padding-top: 4px; padding-bottom: 4px; }
.my-rec.is-withdrawn .my-rec-group { flex: 1 1 auto; }
.my-rec-inline { flex-direction: row; align-items: center; gap: 6px; white-space: nowrap; }
.my-rec-sep { color: #c8c8d2; }
.my-rec .link-btn { line-height: 1.3; }
.lead-reviewers.is-editable .review-pill { cursor: pointer; }
.lead-decision { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lead-decision-note { color: var(--muted); font-size: 0.82rem; }
#lead-panel .form-actions { margin-top: 10px; margin-bottom: 0; }
/* Group detail side cards: compact quota table (view + inline editor). */
.quota-table { width: 100%; font-size: 0.86rem; border-collapse: collapse; }
.quota-table th, .quota-table td { padding: 3px 6px; text-align: left; }
.quota-table thead th { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); font-weight: 600; }
.quota-table tbody th { font-weight: 500; color: var(--muted); white-space: nowrap; }
.quota-table td { text-align: right; }
.quota-table td:has(.quota-input), .quota-table td:has(.quota-blank) { text-align: left; }
.quota-input.form-control { width: 72px; padding: 0.2rem 0.4rem; font-size: 0.86rem; }
.quota-input[disabled] { background: #f4f4f7; color: var(--muted); }
/* A blank (not applicable) cell in the editable table: centred within the
   same 72px footprint as the inputs beside it. */
/* Collapsible section (e.g. Legal status mappings): the summary is the
   heading with a right-aligned chevron, like the side-panel cards. */
details.collapsible > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; }
details.collapsible > summary::-webkit-details-marker { display: none; }
/* The heading keeps its natural width so the caret sits right beside the text
   (not lost at the far edge of a wide window); the section underline moves to
   the summary so it still spans the full row. */
details.collapsible > summary { border-bottom: 2px solid var(--border); padding-bottom: 6px; margin-bottom: 10px; }
details.collapsible > summary h1, details.collapsible > summary h2 { margin: 0; flex: 0 1 auto; border-bottom: 0; padding-bottom: 0; }
details.collapsible > summary::after {
  content: ""; width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  color: var(--muted); transform: rotate(-45deg); transition: transform 0.15s; margin-right: 4px;
}
details.collapsible[open] > summary::after { transform: rotate(45deg); }
details.collapsible[open] > summary { margin-bottom: 8px; }
/* Inline-editable sections (Rounds, current cycle): fields use the same look as
   the site's other form inputs (.form-card) while editing... */
#rounds-form input:not([type="checkbox"]), #rounds-form select,
form[data-inline-editor] input:not([type="checkbox"]), form[data-inline-editor] select,
form[data-inline-editor] textarea {
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.95rem;
  font-family: inherit; color: inherit; background: #fff; box-sizing: border-box;
}
/* ...and in view mode the disabled inputs read as plain values. */
#rounds-form[data-viewing] input:disabled,
form[data-inline-editor][data-viewing] input:disabled,
form[data-inline-editor][data-viewing] textarea:disabled {
  border-color: transparent; background: transparent; color: inherit; padding: 0; border-width: 0;
}
/* Row headers stay on one line so the "?" tooltip sits beside the label. */
form[data-inline-editor] .cycle-table th { width: 180px; white-space: nowrap; }
.quota-blank { display: inline-block; width: 72px; text-align: center; color: var(--muted); }
.quota-actions { margin-top: 8px; }
/* Co-supervision cards: one row per supervisor (name + badge from their sole group). */
.co-member-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.co-member-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 0.88rem; }
.co-member-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.co-quota-name { margin: 8px 0 2px; font-size: 0.85rem; }
.quota-actions[hidden] { display: none; }
.detail-panel .form-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 6px; }
.detail-panel .form-actions + .lead-subhead { margin-top: 22px; }
/* The first sub-heading in a card sits close to the card title. */
.panel-section > h2 + .lead-subhead, .panel-section > .panel-placeholder + .lead-subhead, .panel-section > .reviewer-nav + .lead-subhead { margin-top: 12px; }
.detail-panel[data-panel="faculty"] .form-actions { margin: 0; }
/* Key/value table inside a side card (e.g. the group page's Admin card). */
.detail-panel table { width: 100%; font-size: 0.88rem; }
.detail-panel .detail-label { white-space: normal; }
/* Committee Panel score form: inline 1–5 buttons that save the score on click.
   The reviewer's current score is highlighted; the rest are outline buttons.
   "1" carries an "Inadmissible" caption beneath it (absolutely positioned so it
   doesn't disturb the even button spacing); .score-options reserves room for it. */
.review-score-form { margin: 0 0 8px; }
.review-score-form .form-label { display: block; margin-bottom: 6px; }
.score-options { display: flex; gap: 22px; padding: 0 0 22px 10px; }
.score-option-wrap { position: relative; }
.score-caption {
  position: absolute; top: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: 0.72rem; color: var(--muted);
}
.score-option {
  display: inline-flex; align-items: center; justify-content: center;
  position: relative;
  width: 36px; height: 36px; padding: 0; border: 1px solid var(--border);
  border-radius: 8px; background: #fff; color: var(--accent);
  font-size: 0.95rem; font-weight: 600; cursor: pointer;
}
.score-option:hover { border-color: var(--accent); background: #f0f0f5; }
/* Selected state: panel buttons toggle .is-current; the modal uses radio labels
   whose checked radio is matched with :has(). A selected option takes on its own
   score colour from the shared palette (blue for 2–5, U of T Blue at 5). */
.score-option.is-current,
.score-option:has(input:checked) {
  background: var(--score-bg); color: var(--score-fg); border-color: var(--score-fg);
}
/* Visually hide the radio inside a score label but keep it focusable; show a
   focus ring on the label instead. */
.score-option input[type="radio"] {
  position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
}
.score-option:has(input:focus-visible) {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
/* The reset ("—") option: muted so it reads as "clear" rather than a score. It
   sits to the left of the 1–5 group, set apart by a pipe divider with extra
   spacing so the two groups read as distinct. When selected it fills a neutral
   grey (not a blue score colour) so it never looks like a rating. */
.score-option.score-reset {
  font-weight: 400; --score-bg: var(--muted); --score-fg: #fff;
}
/* Muted "—" only while unselected; when selected the palette's white --score-fg
   (from the selected rule above) applies so the text stays legible on grey. This
   :not() scoping keeps it correct regardless of the selected rule's order. */
.score-option.score-reset:not(.is-current):not(:has(input:checked)) {
  color: var(--muted);
}

/* Reviewer card navigation: a "jump to" dropdown over the member's assigned
   applicants, plus prev/next buttons with a position indicator between them. */
.reviewer-nav { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
/* [<] [dropdown] [>] on one line; the skip toggle and position sit beneath. */
.reviewer-nav-row { display: flex; align-items: center; gap: 6px; }
.reviewer-nav-row .reviewer-jump { flex: 1 1 auto; min-width: 0; }
.reviewer-nav-btn { flex: none; padding-left: 8px; padding-right: 8px; }
.reviewer-nav-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.reviewer-nav-skip { font-size: 0.8rem; color: var(--muted); gap: 5px; }
.reviewer-nav-skip input[type="checkbox"] { width: 13px; height: 13px; }
/* The nav Filters control: a disclosure with one small labelled select per
   Committee Review field; narrows the jump list and prev/next. */
.nav-filters { position: relative; font-size: 0.8rem; }
.nav-filters > summary { cursor: pointer; color: var(--secondary-blue); list-style: none; }
.nav-filters > summary::-webkit-details-marker { display: none; }
.nav-filters > summary::after { content: " \25BE"; font-size: 0.7em; }
.nav-filters[open] > summary::after { content: " \25B4"; }
.nav-filters-body {
  position: absolute; left: 0; top: calc(100% + 6px); z-index: 20;
  display: flex; flex-direction: column; gap: 6px; width: 240px;
  background: #fff; border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}
.nav-filters-body { max-height: 320px; overflow-y: auto; width: 260px; }
.nav-filter-group { border: 0; margin: 0; padding: 0 0 4px; }
.nav-filter-group legend {
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted); padding: 0; margin-bottom: 3px;
}
.nav-filter-check { display: flex; align-items: center; gap: 6px; padding: 1px 0; cursor: pointer; }
.nav-filter-check input[type="checkbox"] { width: 13px; height: 13px; margin: 0; }
.reviewer-jump { width: 100%; font-size: 0.85rem; padding: 0.25rem 0.5rem; line-height: 1.35; }
.reviewer-nav-pos { color: var(--muted); font-size: 0.8rem; white-space: nowrap; }
/* A link styled as a .btn can't use :disabled; this mimics it for prev/next when
   there's no adjacent applicant. */
.btn.is-disabled { opacity: 0.5; pointer-events: none; cursor: not-allowed; }
/* Extra breathing room above the Set-score modal's Save/Cancel row. */
#set-score-form .modal-actions { margin-top: 24px; }
.score-divider {
  align-self: center; width: 1px; height: 28px; background: var(--muted);
}

/* Comments: a compact thread — no card per comment, just a thin divider. The
   header is two columns: left stacks author / group-or-role / audience pill,
   right stacks the short date / Edit·Delete (revealed on hover). Full
   timestamp, edit time, audience and identity live in title tips. */
.comment-list { list-style: none; margin: 0; padding: 0; }
.comment { padding: 8px 0; border-top: 1px solid var(--border); }
.comment:first-child { border-top: none; padding-top: 0; }
.comment-meta {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 0.8rem; line-height: 1.3; margin-bottom: 4px; color: var(--muted);
}
.comment-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.comment-who > * { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.comment-side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.comment-author { font-weight: 600; color: #1c1c22; }
.comment-time { color: var(--muted); white-space: nowrap; }
.comment-body { font-size: 0.9rem; line-height: 1.4; white-space: pre-wrap; }
.comment-list .empty { padding: 16px 0; }

.visibility {
  align-self: flex-start; display: inline-block; margin-top: 2px; padding: 0 7px; border-radius: 999px;
  font-size: 0.7rem; font-weight: 600; line-height: 1.6;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  cursor: default;
}
.vis-committee_admin { background: #fdf2dc; color: #9a6a00; }
.vis-all_nominators { background: #e3f6e8; color: #1e7a3c; }
.vis-groups { background: #e4eefb; color: #1E3765; }
.comment-group { color: var(--muted); }
.comment-anon { font-style: italic; font-weight: 400; color: var(--muted); }
.comment-edited { color: var(--muted); }
/* Edit/Delete are quiet text links on the meta line, revealed on hover/focus. */
.comment-actions { display: inline-flex; gap: 8px; }
.comment-actions[hidden] { display: none; }
.link-btn {
  background: none; border: none; padding: 0; margin: 0; cursor: pointer;
  font: inherit; font-size: 0.78rem; color: var(--secondary-blue); text-decoration: none;
}
.link-btn:hover, .link-btn:focus { text-decoration: underline; }
.link-btn.link-danger { color: #b13030; }
@media (hover: hover) {
  /* Fade only the header controls (Reply/Edit/Delete in .comment-meta) —
     the .comment-actions button rows inside the edit/reply forms belong to
     an explicitly opened form and must stay visible. */
  .comment .comment-meta .comment-actions { opacity: 0; transition: opacity 0.12s; }
  /* Only the innermost hovered/focused comment shows its actions: a root
     wraps its replies, so its own :hover also fires while a reply is
     hovered — the :has() rules re-hide the ancestor's actions then. */
  .comment:hover > .comment-meta .comment-actions,
  .comment:focus-within > .comment-meta .comment-actions { opacity: 1; }
  .comment:has(.comment:hover) > .comment-meta .comment-actions,
  .comment:has(.comment:focus-within) > .comment-meta .comment-actions { opacity: 0; }
}
.comment-edit-form { margin: 6px 0 0; padding: 8px 0 0; border-top: 1px dashed var(--border); border-bottom: none; }
.comment-audience ul { list-style: none; margin: 0; padding: 0; }
.comment-audience li { font-size: 0.88rem; margin: 2px 0; }
.comment-audience label { display: flex; align-items: center; gap: 6px; }
.comment-form .check-row { font-size: 0.88rem; }

/* Nominator comment form (top of the Comments panel). */
.comment-form {
  margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid var(--border);
}
.comment-form-row { display: flex; gap: 10px; }
.comment-form-row .comment-form-field { flex: 1 1 0; min-width: 0; }
.comment-form-field { margin-bottom: 10px; }
.comment-form .form-label { font-size: 0.85rem; margin-bottom: 4px; }
.comment-form .form-control { font-size: 0.9rem; padding: 0.3rem 0.6rem; }
.comment-form textarea.form-control { resize: vertical; }
.comment-form-note { color: var(--muted); font-size: 0.8rem; margin: 0 0 10px; }

/* ----- Login card ----- */
.login-card {
  max-width: 380px; margin: 48px auto; background: #fff;
  border: 1px solid var(--border); border-radius: 10px; padding: 28px 28px 32px;
}
.login-card h1 { font-size: 1.3rem; margin: 0 0 4px; }
.login-card .subtitle { color: var(--muted); margin: 0 0 22px; font-size: 0.9rem; }
.login-card .field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 16px; }
.login-card label { font-size: 0.82rem; color: var(--muted); }
.login-card input { padding: 9px 11px; border: 1px solid var(--border); border-radius: 6px; font-size: 0.95rem; }
.login-card button {
  width: 100%; padding: 10px; margin-top: 4px; border: none; border-radius: 6px;
  background: var(--accent); color: #fff; font-size: 0.95rem; cursor: pointer;
}

.errors { background: #fbe4e4; color: #b13030; border-radius: 6px;
          padding: 10px 12px; margin-bottom: 18px; font-size: 0.88rem; }
.errors ul { margin: 0; padding-left: 18px; }

/* Quota adjustments (group detail) */
.quota-adjustment-card {
  background: #fff; border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 10px; margin: 8px 0;
}
.quota-adjustment-card .qa-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.quota-adjustment-card .qa-delta { display: flex; align-items: center; gap: 4px; }
.quota-adjustment-card .qa-actions { display: flex; align-items: center; gap: 6px; }
.qa-add { margin-top: 10px; }
.qa-add summary { list-style: none; display: inline-block; cursor: pointer; }
.qa-add summary::-webkit-details-marker { display: none; }
.qa-edit-toggle { display: none; }
.qa-delete { display: none; }
.quota-adjustment-card .qa-note { margin: 4px 0 2px 14px; font-size: 0.85rem; }
.quota-adjustment-card .qa-meta { margin: 0 0 0 14px; font-size: 0.8rem; color: var(--muted); }
/* The Edit label toggles the hidden checkbox; the form shows while checked. */
.qa-edit-form { display: none; }
.quota-adjustment-card:has(.qa-edit-toggle:checked) .qa-edit-form { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 4px; }
.qa-edit-form input[name="delta"] { width: 70px; }
.qa-edit-form input[name="note"] { flex: 1 1 140px; }

.quota-adjustment-fields { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-top: 10px; }
.quota-adjustment-fields label { display: flex; flex-direction: column; gap: 3px; font-weight: 600; font-size: 0.8rem; }
/* Compact controls in the add/edit adjustment forms — the panel's scale. */
.quota-adjustment-fields .form-control, .qa-edit-form .form-control {
  font-size: 0.85rem; padding: 4px 6px;
}
.quota-adjustment-fields input[name="delta"] { width: 90px; }
.quota-adjustment-fields input[name="note"] { width: 260px; }

/* Confirm intent to supervise page */
.intent-message { margin-bottom: 16px; }
/* Links in the message and quota card (and the cycle-settings previews,
   which share .intent-message): underline on hover/focus only. */
.intent-message a, .intent-quota-card a { text-decoration: none; }
.intent-message a:hover, .intent-message a:focus,
.intent-quota-card a:hover, .intent-quota-card a:focus { text-decoration: underline; }
.intent-message ~ form .form-actions { margin-top: 16px; }
/* Markdown tables in the intent message (page and cycle-settings preview)
   size to their content instead of the global full-width table default. */
.intent-message table, #intent-message-preview table { width: auto; }
/* Headings in the rendered message follow the form-card family (.form-card
   h1 / .form-subhead / .form-subhead--sub): brand-coloured ruled section
   headings, muted subordinate ones. */
.intent-message h1 { font-size: 1.3rem; font-weight: 600; margin: 0 0 18px; }
.intent-message h2 {
  font-size: 1.05rem; color: var(--accent); font-weight: 600;
  margin: 30px 0 14px; padding-bottom: 6px; border-bottom: 2px solid var(--accent);
}
.intent-message h3 {
  font-size: 0.95rem; color: var(--muted); font-weight: 600;
  margin: 22px 0 10px; border-bottom: 1px solid var(--border);
}
.intent-layout { display: flex; gap: 18px; align-items: flex-start; }
.intent-layout > .intent-main { flex: 1 1 0; min-width: 0; }
.intent-main > .form-card--wide { max-width: none; }
.intent-quota-card { position: sticky; top: 60px; flex: 0 0 420px; max-width: 420px; box-sizing: border-box; padding: 18px 20px 20px; }
.intent-quota-card h2 {
  margin: 0 0 10px; font-size: 1.05rem; color: var(--accent);
  padding-bottom: 6px; border-bottom: 2px solid var(--accent); font-weight: 600;
}
.intent-quota-card table { width: 100%; margin: 10px 0; }
.intent-quota-card th { text-align: left; }
/* The row an approval will charge. */
.intent-quota-card .quota-row-active th, .intent-quota-card .quota-row-active td { background: #fff3b8; }
.intent-response-status { margin: 10px 0 14px; }
.decision-option--disabled { opacity: 0.5; cursor: not-allowed; }

/* Placeholder reference on the cycle settings page. */
.placeholder-reference { margin: 0 0 16px; }
.placeholder-reference summary { cursor: pointer; font-weight: 600; font-size: 0.9rem; }
.placeholder-table { margin-top: 10px; font-size: 0.9rem; }
.placeholder-table code { white-space: nowrap; }

/* Release-intent modal: toggle rows for the applicant's other unsent offers. */
.release-other-offers { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 4px; }
.release-other-row { display: flex; align-items: center; gap: 8px; }

/* Award Assignments: eligible-award pills, one per line, wrapping long names;
   each award keeps a stable colour from an 8-slot soft palette (pk-keyed). */
/* Width budget: the three list columns (Nominators / Nominated for /
   Eligible for) get the room; the flat value columns stay compact. */
#award-assignment-nominations-table th.col-nominators,
#award-assignment-nominations-table th.col-nominated,
#award-assignment-nominations-table th.col-eligible { min-width: 220px; width: 24%; }
#award-assignment-nominations-table th.col-applicant { min-width: 140px; }
#award-assignment-nominations-table th.col-compact { width: 90px; }
#award-assignment-nominations-table th.col-avg,
#award-assignment-nominations-table td.col-avg { width: 70px; min-width: 60px; }
.col-eligible > div, .col-nominated > div, .col-awarded > div { margin: 2px 0; }
.badge.award-pill { white-space: normal; display: inline-block; }
.badge.award-pill-0 { background: #e2ecfb; color: #2456a8; }
.badge.award-pill-1 { background: #ddf2ef; color: #1d7a6b; }
.badge.award-pill-2 { background: #ece4f7; color: #6a3fa0; }
.badge.award-pill-3 { background: #fdf2dc; color: #9a6a00; }
.badge.award-pill-4 { background: #fbe4ee; color: #a83268; }
.badge.award-pill-5 { background: #e4f2db; color: #3f7a1d; }
.badge.award-pill-6 { background: #e0f0f8; color: #1b6e8f; }
.badge.award-pill-7 { background: #f3e8de; color: #8a5a2a; }

/* Edit-awards bulk modal: scrollable award rows with breathing room. */
.edit-awards-rows { max-height: 320px; overflow-y: auto; padding-right: 6px; }
.edit-awards-rows .form-label { margin-top: 10px; display: block; }

/* Awards table: rows top-align (Assigned to can grow long); width budget
   favours Name, the rule columns and Assigned to — Description is clamped
   by .desc-clip with its Show more toggle, so it can be squeezed. */
#award-assignments-table { width: auto; max-width: 100%; }
#award-assignments-table td { vertical-align: top; }
#award-assignments-table th.col-name { min-width: 160px; }
#award-assignments-table th.col-rules { min-width: 110px; }
#award-assignments-table th.col-assigned-to { min-width: 340px; }
#award-assignments-table th.col-desc { min-width: 240px; max-width: 340px; }
/* .table-scroll's nowrap default would stop this table's cells (description
   clip, rule values, assigned-to lines) from wrapping — restore wrapping. */
.table-scroll #award-assignments-table th,
.table-scroll #award-assignments-table td,
.table-scroll #award-assignment-nominations-table th,
.table-scroll #award-assignment-nominations-table td { white-space: normal; }
/* Inside the scroll boxes (and width-frozen tables, whose cells clip
   overflow), tooltips fix-position at the trigger (dt_filter_kit stamps
   the --tip-* vars on hover/focus) so the bubble spills over the container
   instead of widening it or being clipped. */
.table-scroll .tooltip[data-tip]::after,
.table-scroll .tooltip .tip-text,
table.dt-fixed-cols .tooltip[data-tip]::after,
table.dt-fixed-cols .tooltip .tip-text {
  position: fixed; bottom: auto;
  top: var(--tip-top, 0); left: var(--tip-left, 0); transform: none;
}
/* Awards table: name links filter the applicant table below. */
.award-filter-link { text-decoration: none; }
.award-filter-link:hover, .award-filter-link:focus { text-decoration: underline; }

/* Multi-select filter dropdowns (Award Assignments filter row). */
.filter-multi { position: relative; display: block; }
.filter-multi > summary {
  list-style: none; cursor: pointer; background: #fff;
  border: 1px solid var(--border); border-radius: 6px; padding: 3px 20px 3px 7px;
  font-weight: 400; font-size: 0.85rem; white-space: nowrap; position: relative;
  /* A long selected value must not widen the column: cap and ellipsise
     (the full text sits in the title attribute). */
  max-width: 150px; overflow: hidden; text-overflow: ellipsis; box-sizing: border-box;
}
.filter-multi > summary::-webkit-details-marker { display: none; }
.filter-multi > summary::after {
  content: ""; position: absolute; right: 8px; top: 50%;
  width: 6px; height: 6px; border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted); transform: translateY(-70%) rotate(45deg);
}
.filter-multi-panel {
  position: absolute; z-index: 30; top: calc(100% + 4px); left: 0;
  min-width: 170px; max-height: 240px; overflow-y: auto;
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 10px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  display: flex; flex-direction: column; gap: 4px;
}
.filter-multi-panel { text-align: left; }
.filter-multi-panel label {
  display: flex; align-items: center; gap: 6px;
  font-weight: 400; font-size: 0.85rem; white-space: nowrap; text-transform: none;
}
/* Defend the checkboxes against per-table filter-control sizing rules. */
.filter-multi-panel input[type="checkbox"] { width: auto; margin: 0; flex: none; }

/* Awards table: the Assigned cell's background compares against Available —
   amber while under, green when met, red when over (badge palette). */
#award-assignments-table td.assigned-under { background: #fdf2dc; color: #9a6a00; }
#award-assignments-table td.assigned-met { background: #e3f6e8; color: #1e7a3c; }
#award-assignments-table td.assigned-over { background: #fbe4e4; color: #b13030; }

/* Width-frozen datatables (dt_filter_kit): later pages' longer values must
   not push columns around — nowrap cells clip with an ellipsis instead
   (wrapping cells simply wrap within their fixed width). */
table.dt-fixed-cols th, table.dt-fixed-cols td { overflow: hidden; text-overflow: ellipsis; }
