/* 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; }
/* Edit group Members table: Set as Primary + Delete side by side. */
.member-actions { white-space: nowrap; }
.member-actions .btn + .btn { margin-left: 6px; }
.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. */
/* Disabled inputs read as non-editable everywhere. */
.form-control:disabled { background: #f2f2f6; color: var(--muted); cursor: not-allowed; }

/* 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; }

/* Admissions Committee Review: per-reviewer cards (committee/admin only). */
.review-cards-head { margin: 16px 0 8px; }
.review-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.review-card { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; background: #fff; }
.review-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.review-card-rationale { margin: 0; font-size: 0.9rem; }

/* Member table: the show-unassigned toggle sits beside the bulk actions. */
.show-unassigned-toggle { display: inline-flex; align-items: center; gap: 6px; margin-left: 12px; font-size: 0.85rem; color: var(--muted); cursor: pointer; }

/* 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; }

/* Award Assignments: the Awards summary sticks below the top bar while the
   nominations table scrolls; its own scroller keeps a long awards list (or
   expanded clips) from filling the viewport. */
.awards-summary {
  position: sticky; top: 44px; z-index: 15;
  background: var(--bg); margin-top: 0; padding-top: 12px;
  border-bottom: 1px solid var(--border); box-shadow: 0 6px 12px -8px rgba(0, 0, 0, 0.18);
}
.awards-summary .table-scroll { max-height: 42vh; overflow-y: auto; margin-bottom: 2px; }
/* The drag bar under the table (JS-built): grab anywhere on it to resize the
   scroller vertically; the grip pill in the middle signals it. */
.awards-summary .scroll-resize-handle {
  display: flex; justify-content: center; align-items: center;
  height: 14px; margin-bottom: 4px; cursor: ns-resize; touch-action: none;
}
.awards-summary .scroll-resize-handle::before {
  content: ""; width: 64px; height: 5px; border-radius: 3px; background: var(--border);
}
.awards-summary .scroll-resize-handle:hover::before,
.awards-summary .scroll-resize-handle.is-dragging::before { background: var(--muted); }
/* Compact mode (scrolled away from the top, toggled by the JS sentinel):
   Name / Available / Assigned / Assigned to stay, with tighter chrome, so
   the stuck table takes little room. Assigned to gets the horizontal room
   the dropped columns free up. */
.awards-summary.is-compact .col-desc,
.awards-summary.is-compact .col-rules,
.awards-summary.is-compact .col-group-rules { display: none; }
.awards-summary.is-compact td.col-assigned-to { min-width: 420px; white-space: normal; }
.awards-summary.is-compact .table-scroll { max-height: 24vh; }
.awards-summary.is-compact th, .awards-summary.is-compact td { padding: 3px 10px; font-size: 0.85rem; }
.awards-summary.is-compact .section-head h1 { font-size: 1rem; margin-bottom: 2px; padding-bottom: 2px; }
.awards-summary.is-compact { padding-top: 6px; }

/* 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; }
/* A frozen cell must stay sticky while its editor is open (relative above
   would un-pin it and the card would drift with the horizontal scroll). */
table.dt-fixed-cols td.is-frozen:has(.decision-editor:not([hidden])) { position: sticky; 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);
}
/* The member Score editor also carries a rationale + Save: the whole form
   becomes the overlay card instead of just the options strip. */
table.dt-fixed-cols .score-editor:not([hidden]) {
  display: block; width: 352px; background: #fff; padding: 10px;
  border-radius: 8px; box-shadow: 0 1px 8px rgba(0, 0, 0, 0.25);
}
table.dt-fixed-cols .score-editor:not([hidden]) .decision-options {
  display: flex; flex-wrap: wrap; width: auto; max-width: none;
  background: none; padding: 0; margin: 0 0 6px; box-shadow: none;
}
.score-editor-rationale { width: 100%; box-sizing: border-box; margin-bottom: 6px; font-size: 0.85rem; }
/* Doubled class for specificity: the generic .form-label rule later in the
   file sets font-weight 400 and would win on source order otherwise. */
.score-editor .score-editor-label { display: block; font-size: 0.8rem; font-weight: 700; color: var(--text); margin: 0 0 4px; }
.score-editor .decision-options + .score-editor-label { margin-top: 14px; }
.score-editor-reset-warning { margin: 0 0 8px; }

/* 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).
   A bold red (1 = inadmissible) → green (5) range: dark red, orange,
   yellow, light green, dark green — saturated backgrounds so the steps
   read at a glance, with text colours picked per step for contrast. */
.score-none { --score-bg: #ececf1; --score-fg: var(--muted); }
.score-1 { --score-bg: #c62828; --score-fg: #ffffff; }
.score-2 { --score-bg: #ef8633; --score-fg: #502500; }
.score-3 { --score-bg: #f7c948; --score-fg: #4a3a00; }
.score-4 { --score-bg: #8fbf3f; --score-fg: #243f00; }
.score-5 { --score-bg: #2e7d32; --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;
  /* A plain length (not minmax) so the hide/show transition can interpolate
     420px <-> 20px; above the 1000px breakpoint it always resolved to 420. */
  grid-template-columns: minmax(0, 1fr) 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; }
/* Hide/show slide (detail_side_panel.js): while .side-animating the panel
   keeps its full width and the shrinking/growing column clips it, so handle +
   panel slide off/onto the right edge together. .no-anim applies a state
   instantly (page load, crossing the breakpoint). */
@media (min-width: 1001px) {
  .detail-side { flex: none; width: calc(420px - 20px - 6px + 4px); } /* column - handle - gap + scrollbar pad */
}
.detail-layout.side-animating .detail-side-wrap { overflow: hidden; justify-content: flex-start; }
.detail-layout.no-anim { transition: none; }
.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.
   every option carries its caption beneath it (absolutely positioned so it
   doesn't disturb the even button spacing); .score-options reserves room for them. */
.review-score-form { margin: 0 0 8px; }
.review-rationale-field { margin-bottom: 14px; }
.review-reset-warning { margin: -6px 0 14px; }
.review-score-form .form-label { display: block; margin-bottom: 6px; }
.score-options { display: flex; gap: 20px; padding: 0 0 22px 6px; }
.score-option-wrap { position: relative; }
.score-caption {
  position: absolute; top: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: 0.65rem; 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; }
/* Read-only (locked / inactive-cycle) panel: clearly non-editable — the
   unchecked pills grey out, the saved score keeps its colour but dimmed,
   and hovering changes nothing. */
.review-score-form.is-readonly .score-option {
  cursor: default; background: #f2f2f6; color: var(--muted); border-color: var(--border);
}
.review-score-form.is-readonly .score-option:hover {
  border-color: var(--border); background: #f2f2f6;
}
.review-score-form.is-readonly .score-option:has(input:checked),
.review-score-form.is-readonly .score-option:has(input:checked):hover {
  background: var(--score-bg); color: var(--score-fg);
  border-color: transparent; opacity: 0.65;
}
.review-score-form.is-readonly .score-caption { opacity: 0.7; }
/* 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; }

/* ===== Mobile / narrow screens =====
   Desktop: the toggle and backdrop are hidden. Below 900px the sidebar becomes
   an off-canvas drawer (nav_drawer.js toggles body.nav-open), the page drops
   to tighter padding, and anything wider than the screen scrolls inside its
   own box so the page itself never scrolls sideways. */
.nav-toggle { display: none; }
.sidebar-backdrop { display: none; }

@media (max-width: 900px) {
  /* -- Drawer -- */
  .sidebar {
    position: fixed; top: 0; left: 0; z-index: 60;
    width: min(280px, 85vw); height: 100vh; height: 100dvh; overflow-y: auto;
    transform: translateX(-100%); transition: transform 0.2s ease; visibility: hidden;
  }
  body.nav-open .sidebar { transform: none; visibility: visible; box-shadow: 4px 0 24px rgba(0, 0, 0, 0.25); }
  body.nav-open { overflow: hidden; }
  .sidebar-backdrop { display: block; position: fixed; inset: 0; z-index: 55; background: rgba(20, 20, 30, 0.45); }
  .sidebar-backdrop[hidden] { display: none; }
  .sidebar-nav a { padding: 10px 12px; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 40px; height: 40px; margin-left: -8px; padding: 0;
    background: none; border: 0; border-radius: 6px; cursor: pointer; color: var(--accent);
  }
  .nav-toggle:hover, .nav-toggle:focus-visible { background: #f0f4fa; }
  /* Three bars drawn from one span and its pseudo-elements. */
  .nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
    display: block; width: 20px; height: 2px; border-radius: 1px; background: currentColor; position: relative;
  }
  .nav-toggle-bars::before, .nav-toggle-bars::after { content: ""; position: absolute; left: 0; }
  .nav-toggle-bars::before { top: -6px; }
  .nav-toggle-bars::after { top: 6px; }

  /* -- Top bar: toggle on the left, the cluster on the right -- */
  .topbar { justify-content: space-between; gap: 8px; padding: 0 12px; }
  .topbar-right { gap: 10px; min-width: 0; }
  .user-menu-button { max-width: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .bell-menu, .impersonate-menu { position: fixed; top: 50px; left: 8px; right: 8px; width: auto; }
  /* Impersonating: keep "Viewing as X" + Stop; drop the long explanation. */
  .topbar--impersonating { height: auto; min-height: 44px; padding-block: 4px; }
  .topbar-impersonation { flex: 1 1 auto; gap: 8px; font-size: 0.82rem; flex-wrap: wrap; }
  .topbar-impersonation-detail { display: none; }
  /* Row 1: toggle + bell/user; row 2: the notice and Stop, full width. */
  .topbar--impersonating { flex-wrap: wrap; row-gap: 0; }
  .topbar--impersonating .topbar-right { margin-left: auto; }
  .topbar--impersonating .topbar-impersonation { order: 3; flex-basis: 100%; padding-bottom: 4px; }

  /* -- Page chrome -- */
  main { margin: 16px 0; padding: 0 12px; }
  h1 { font-size: 1.25rem; }
  .section { margin: 22px 0; }
  .section-head { gap: 8px 12px; }
  .form-card { padding: 18px 14px 20px; }
  .field-pair { flex-direction: column; gap: 0; }
  .detail-columns { gap: 16px; }
  .modal-overlay { padding: 10px; }
  .modal { padding: 18px 16px 20px; max-height: calc(100dvh - 20px); overflow-y: auto; }
  .tabs { overflow-x: auto; scrollbar-width: none; }
  .tabs .tab { white-space: nowrap; flex: none; }
  .cr-top-sections { gap: 16px; }
  .cr-top-sections > .section { min-width: 0; max-width: 100%; }
  /* Reset sits on its own line with the 1–5 scores together beneath it
     (the vertical divider makes no sense across lines); wider column gap +
     edge padding so the captions neither collide nor clip at the edges. */
  .score-options { gap: 26px 24px; flex-wrap: wrap; padding: 0 6px 22px; }
  .score-options .score-divider { display: none; }
  .score-options .score-option-wrap:first-child { flex-basis: 100%; }
  /* The full-width row would centre the caption on the row, not the button. */
  .score-options .score-option-wrap:first-child .score-caption { left: 17px; }
  .committee-members-table { min-width: 0; }
  .autoassign-main { flex-basis: 100%; }
  .detail-panel { padding: 4px 12px 14px; }

  /* -- Tables --
     DataTables: the table's layout cell scrolls (control rows stay put; the
     filter kit's open panels are fixed-positioned so they aren't clipped). */
  .dt-container .dt-layout-table > .dt-layout-cell { overflow-x: auto; max-width: 100%; }
  .dt-container .dt-layout-row:has(.bulk-actions) .dt-layout-end { flex-wrap: wrap; margin-left: 0; }
  /* Plain tables sit in a .table-scroll-x wrapper (table_scroll.js) that
     scrolls them; the table keeps table layout, so its box hugs its rows. */
  .table-scroll-x { max-width: 100%; overflow-x: auto; }
  /* Key/value tables (th.detail-label + td) stack the label above its value. */
  table:has(> tbody > tr > th.detail-label), table:has(> tbody > tr > th.detail-label) > tbody,
  table:has(> tbody > tr > th.detail-label) > tbody > tr,
  table:has(> tbody > tr > th.detail-label) > tbody > tr > th,
  table:has(> tbody > tr > th.detail-label) > tbody > tr > td { display: block; width: auto; }
  th.detail-label { white-space: normal; border-bottom: 0; padding-bottom: 4px; }
  th.detail-label + td { padding-top: 6px; overflow-wrap: anywhere; }
  .account-table th { width: auto; }
}

/* ----- Detail pages' right-hand panel: off-canvas drawer at <=1000px -----
   The panel column slides in from the right (detail_side_panel.js toggles
   body.side-drawer-open); its chevron handle sits outside the drawer's left
   edge, so while closed it is pinned to the screen's right edge. Mirrors the
   desktop column, which stays on the right and collapses to the same handle. */
.side-backdrop { display: none; }
@media (max-width: 1000px) {
  .detail-side-wrap {
    position: fixed; top: 0; right: 0; bottom: 0; z-index: 50;
    /* Explicit height: the desktop align-self: start would otherwise shrink
       this fixed grid child to its content. */
    height: 100vh; height: 100dvh; align-self: stretch;
    width: min(420px, 88vw); display: block;
    background: var(--bg); transform: translateX(100%); transition: transform 0.2s ease;
  }
  body.side-drawer-open .detail-side-wrap { transform: none; box-shadow: -4px 0 24px rgba(0, 0, 0, 0.25); }
  body.side-drawer-open { overflow: hidden; }
  /* The cards scroll inside the drawer; hidden (unfocusable) once it has slid away. */
  .detail-side {
    height: 100%; max-height: none; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
    padding: 16px 12px; margin: 0; gap: 16px;
    visibility: hidden; transition: visibility 0s linear 0.2s;
  }
  body.side-drawer-open .detail-side { visibility: visible; transition-delay: 0s; }
  .side-drawer-handle {
    position: absolute; top: 50%; right: 100%; transform: translateY(-50%);
    width: 28px; height: 64px; box-shadow: -2px 0 8px rgba(0, 0, 0, 0.12);
  }
  /* Closed: the chevron points left ("pull the drawer out"); open: right. */
  .side-drawer-handle .chevron { transform: rotate(135deg); margin-left: 3px; }
  body.side-drawer-open .side-drawer-handle .chevron { transform: rotate(-45deg); margin-left: -3px; }
  .side-backdrop { display: block; position: fixed; inset: 0; z-index: 45; background: rgba(20, 20, 30, 0.45); }
  .side-backdrop[hidden] { display: none; }
}

/* Reduced motion: the drawers and the desktop panel column snap instead of sliding. */
@media (prefers-reduced-motion: reduce) {
  .detail-layout, .detail-side-wrap, .detail-side, .sidebar { transition: none !important; }
}
