/* ============================================================
   Asiatech Feedback Casefile — Design System
   Paper & Navy Theme | Fraunces + Public Sans + IBM Plex Mono
   ============================================================ */

:root {
  --paper: #eef0ea;
  --paper-raised: #f8f9f5;
  --paper-line: #cdd3c6;
  --ink: #1c231f;
  --ink-soft: #5b6660;
  --ink-faint: #8b9389;
  --brand: #2b3a67;
  --brand-soft: #e3e6f0;
  --brand-deep: #1c2749;
  --pos: #2f6f4e;
  --pos-bg: #dfeee3;
  --neu: #b7791f;
  --neu-bg: #f4e8cf;
  --neg: #b33a3a;
  --neg-bg: #f4dcdb;
  --font: "Public Sans", -apple-system, sans-serif;
  --font-display: "Fraunces", Georgia, serif;
  --font-mono: "IBM Plex Mono", Menlo, monospace;
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
}

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

html {
  font-size: 16px;
  scroll-behavior: smooth;
}

body {
  font-family: var(--font);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  background-image: repeating-linear-gradient(
    transparent,
    transparent 34px,
    rgba(28, 35, 31, 0.035) 35px
  );
  /* Sideways-scroll guard.
     The nav used to carry `overflow-x: hidden` to stop itself pushing the
     page, but that made the navbar a scroll container: it clipped the
     account menu (absolutely positioned, hanging below the nav) and grew a
     scrollbar inside the header. Clipping at the page level instead means
     one oversized element is cut off on its own rather than breaking the
     chrome for everything -- the account menu and alert panel both hang
     outside their parents and still render fully. */
  overflow-x: hidden;
}

a {
  color: var(--brand);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* ============================================================
   NAVBAR
   ============================================================ */
.navbar {
  background: var(--brand-deep);
  /* Left/right edge 1.5rem -> 1.25rem so the nav's outer edge lines up with
     .page-layout's content edge instead of sitting inboard of it. */
  padding: 0 0 0 1.25rem;
  display: flex;
  align-items: flex-end;
  gap: 0.25rem;
  position: sticky;
  top: 0;
  z-index: 1000;
  /* max-width: 100% keeps the nav from exceeding its container.
     There is deliberately NO overflow here. An earlier version used
     `overflow-x: hidden` to stop the nav pushing the page sideways, but that
     turns the navbar into a scroll container: it clips the account menu,
     which is absolutely positioned and hangs below the nav, and it grows a
     scrollbar of its own inside the header. The page-level
     `body { overflow-x: hidden }` guard handles the sideways-scroll case
     without clipping anything, and the tab strip manages its own overflow
     locally through .nav-links. */
  max-width: 100%;
}

.nav-brand {
  font-family: var(--font-display);
  font-weight: 600;
  font-style: italic;
  font-size: 1.05rem;
  color: #f2f0e6;
  padding: 0.9rem 1.25rem 0.9rem 0;
  white-space: nowrap;
  border-right: 1px solid rgba(255, 255, 255, 0.15);
  margin-right: 0.75rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-self: stretch;
}

.nav-brand i {
  display: none;
}

.nav-brand .nav-logo {
  display: block;
  width: 110px;
  height: auto;
}

.nav-brand small {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  color: #9aa4c4;
  text-transform: uppercase;
  margin-top: 2px;
}

.nav-links {
  list-style: none;
  display: flex;
  gap: 0.25rem;
  align-items: flex-end;
  /* The tab strip is the one part of the nav that yields when space runs
     short: it can shrink and scroll rather than widening the row and pushing
     the identity and logout controls off the end.
     `scrollbar-width: none` hides the scrollbar that otherwise appears as a
     grey bar across the middle of the navbar -- the strip is still scrollable
     by wheel, trackpad and keyboard, and the active tab is scrolled into
     view automatically when the tab changes. A visible scrollbar there read
     as broken chrome. */
  min-width: 0;
  flex: 1 1 auto;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* WebKit needs its own hiding, and the equivalent for the ::-webkit- pseudo
   is not reachable from the shorthand above. */
.nav-links::-webkit-scrollbar {
  display: none;
}

.nav-links li button {
  font-family: var(--font);
  font-weight: 600;
  font-size: 0.82rem;
  color: #c7cbe0;
  background: #232f57;
  border: none;
  padding: 0.75rem 1.35rem;
  cursor: pointer;
  border-radius: 8px 8px 0 0;
  position: relative;
  top: 2px;
  transition: background 0.15s, color 0.15s, top 0.15s;
  display: flex;
  align-items: center;
  gap: 0.45rem;
  white-space: nowrap;
}

.nav-links li button::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.6;
  flex-shrink: 0;
}

.nav-links li button:hover {
  background: #2d3a66;
  color: #fff;
}

.nav-links li button.active {
  background: var(--paper);
  color: var(--brand-deep);
  top: 0;
  box-shadow: 0 -2px 0 var(--pos) inset;
}

.nav-user {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0 1.25rem;   /* matches .navbar's left edge; see .page-layout */
  margin-left: auto;
  align-self: stretch;
  /* Identity and logout must never be compressed or clipped: they are the
     only way out of the app, and they sit on the dark background where they
     have to stay legible. */
  flex: 0 0 auto;
  background: var(--brand-deep);
}

/* The badge was a muted grey that read as disabled against the navy. A
   lighter tone restores the same weight as the logout button next to it. */
.user-badge {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: #dfe3f0;
  white-space: nowrap;
}

.btn-logout {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.4);
  color: #ffffff;
  padding: 0.4rem 0.7rem;
  border-radius: 4px;
  cursor: pointer;
  letter-spacing: 0.03em;
  white-space: nowrap;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}

.btn-logout:hover {
  border-color: #fff;
  color: #fff;
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.7rem 1.2rem;
  border: none;
  border-radius: 0;
  font-weight: 600;
  font-size: 0.82rem;
  cursor: pointer;
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: background 0.15s;
  text-decoration: none;
}

.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--brand-deep);
  color: #f2f0e6;
}
.btn-primary:hover:not(:disabled) {
  background: var(--brand);
}

.btn-secondary {
  background: var(--paper-raised);
  color: var(--ink);
  border: 1px solid var(--paper-line);
}

.btn-success {
  background: var(--pos);
  color: #fff;
}
.btn-success:hover:not(:disabled) {
  background: #255c40;
}

.btn-danger {
  background: var(--neg);
  color: #fff;
}
.btn-danger:hover:not(:disabled) {
  background: #943030;
}

.btn-warning {
  background: var(--neu);
  color: #fff;
}

.btn-outline {
  background: transparent;
  border: 1px solid var(--paper-line);
  color: var(--ink-soft);
}

.btn-sm {
  padding: 0.3rem 0.6rem;
  font-size: 0.68rem;
}

.btn-lg {
  padding: 0.85rem 1.25rem;
  font-size: 0.82rem;
}

.btn-block {
  width: 100%;
  justify-content: center;
}

/* ============================================================
   CARDS
   ============================================================ */
.card {
  background: var(--paper-raised);
  border: 1px solid #E5E7EB;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  padding: 1.5rem;
  margin-bottom: 1rem;
  position: relative;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 1.1rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--paper-line);
}

.card-header h2,
.card-header h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.1rem;
}

/* ============================================================
   STATS GRID
   ============================================================ */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 1.1rem;
  margin-bottom: 1.35rem;   /* was 2.25rem — a full card-height of dead space under the KPI row */
}

.stat-card {
  background: var(--paper-raised);
  border: 1px solid #E5E7EB;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  padding: 1rem 0.95rem 0.9rem;
  position: relative;
  display: flex;
  align-items: flex-start;   /* the 44px icon hugs the top; the text column may be taller */
  min-height: 124px;         /* a floor only — the grid row supplies equal height */
  gap: 0.9rem;
}

.stat-info {
  flex: 1;
  min-width: 0;              /* let a long caption wrap instead of widening the card */
  display: flex;
  flex-direction: column;
  /* Top-aligned on purpose. `space-between` used to fling the label into the
     middle of the card whenever a sibling had more rows than it did (a badge
     that wrapped, a four-line caption), leaving a dead void above and below
     it. Height differences now settle at the bottom of the card instead. */
  justify-content: flex-start;
}

/* The trend badge and the percentage share one row: one line shorter per card,
   and the row lines up across all four. The min-height keeps a card that has
   neither badge nor percentage exactly as tall as the rest. */
.stat-meta {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
  min-height: 1.55rem;
  margin-top: 0.2rem;
}

/* KPI captions, clamped to two lines. One long sentence rendered four lines,
   and because grid rows are equal height that single card stretched every
   other card in the row to ~400px. The full sentence stays in the title
   attribute, and two lines are reserved so the captions align across cards. */
.stat-info small.source-note {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  min-height: 2.2em;
  margin-top: 0.3rem;
  font-size: 0.62rem;
  line-height: 1.6;
  color: var(--ink-faint);
}

.stat-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.35rem;
  flex-shrink: 0;
}

.stat-icon.green {
  background: var(--pos-bg);
  color: var(--pos);
}
.stat-icon.yellow {
  background: var(--neu-bg);
  color: var(--neu);
}
.stat-icon.red {
  background: var(--neg-bg);
  color: var(--neg);
}
.stat-icon.blue {
  background: var(--brand-soft);
  color: var(--brand);
}
.stat-icon.purple {
  background: var(--brand-soft);
  color: var(--brand-deep);
}

.stat-info h3 {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 600;
  line-height: 1;
  color: var(--brand-deep);
}

.stat-info p {
  font-size: 0.82rem;
  color: var(--ink-soft);
  margin-top: 0.35rem;
}

.stat-info small {
  font-size: 0.72rem;
  font-family: var(--font-mono);
  color: var(--ink-faint);
}

/* ============================================================
   FORMS
   ============================================================ */
.form-group {
  margin-bottom: 1.1rem;
}

.form-group label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.4rem;
}

.form-group label i {
  margin-right: 0.35rem;
  color: var(--brand);
}

.form-control {
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--ink-soft);
  border-radius: 0;
  font-size: 0.92rem;
  font-family: var(--font);
  background: var(--paper);
  color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.form-control:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}

.form-control::placeholder {
  color: var(--ink-faint);
}

/* Password input with a show/hide "eye" toggle (login + reset forms).
   The wrapper is position:relative so the toggle can sit inside the input's
   right edge, matching the square, paper-theme form controls. */
.password-field {
  position: relative;
  display: block;
}

/* Keep the typed value clear of the icon. */
.password-field .form-control {
  padding-right: 2.5rem;
}

.password-toggle {
  position: absolute;
  top: 50%;
  right: 0.15rem;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink-soft);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s;
}

.password-toggle:hover {
  color: var(--brand);
}


textarea.form-control {
  resize: vertical;
  min-height: 90px;
}

select.form-control {
  appearance: auto;
  cursor: pointer;
}

.form-footer {
  text-align: center;
  margin-top: 1rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.form-inline {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
}

/* ============================================================
   TABLES
   ============================================================ */
.table-container {
  overflow-x: auto;
  border: 1px solid var(--paper-line);
  background: var(--paper-raised);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.87rem;
}

thead {
  background: var(--paper);
  border-bottom: 2px solid var(--ink);
}

th {
  padding: 0.75rem 1rem;
  text-align: left;
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--ink-soft);
  white-space: nowrap;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

td {
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--paper-line);
  vertical-align: middle;
}

tbody tr:hover {
  background: rgba(43, 58, 103, 0.04);
}

tbody tr:last-child td {
  border-bottom: none;
}

/* ============================================================
   LOGIN PAGE
   ============================================================ */
#page-login.page.active {
  display: flex;
}

.login-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 2rem;
  background: var(--paper);
  background-image: repeating-linear-gradient(
    transparent,
    transparent 34px,
    rgba(28, 35, 31, 0.035) 35px
  );
  width: 100%;
}

.login-container {
  background: var(--paper-raised);
  border: 1px solid var(--ink);
  box-shadow: 8px 8px 0 var(--brand-deep);
  padding: 2.5rem 2.25rem 2.25rem;
  width: 100%;
  max-width: 460px;
  position: relative;
}

.login-container::before {
  content: "";
  position: absolute;
  top: 14px;
  right: 14px;
  width: 64px;
  height: 64px;
  border: 2px solid var(--pos);
  border-radius: 50%;
  opacity: 0.5;
  transform: rotate(-8deg);
}

.login-container::after {
  content: "ASIATECH";
  position: absolute;
  top: 38px;
  right: 22px;
  font-family: var(--font-mono);
  font-size: 0.5rem;
  letter-spacing: 0.06em;
  color: var(--pos);
  opacity: 0.6;
  transform: rotate(-8deg);
}

.login-kicker {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: block;
  margin-bottom: 0.5rem;
}

.login-header {
  text-align: left;
  margin-bottom: 1.75rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--paper-line);
}

.login-header h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.85rem;
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin-bottom: 0.35rem;
}

.login-header .subtitle {
  font-size: 0.88rem;
  color: var(--ink-soft);
}

.demo-hint {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-faint);
  letter-spacing: 0.04em;
  margin-bottom: 1rem;
  padding: 0.5rem 0.6rem;
  border: 1px dashed var(--paper-line);
  line-height: 1.7;
}

.demo-hint strong {
  color: var(--ink-soft);
}

.role-selector {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 1.6rem;
}

.role-pill {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  text-align: center;
  padding: 0.6rem 0.3rem;
  border: 1px solid var(--paper-line);
  background: var(--paper);
  color: var(--ink-soft);
  cursor: pointer;
  text-transform: uppercase;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.role-pill:hover {
  background: var(--brand-soft);
  border-color: var(--brand);
}

.role-pill.active {
  background: var(--brand-deep);
  border-color: var(--brand-deep);
  color: #fff;
}

.course-year-card{
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
}
.course-year-grid{
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}
.form-group--tight{
    margin-bottom: 0;
}

/* Utility for elements toggled via JS */
.hidden-block{
    display: none;
}

/* ============================================================
   PAGE LAYOUT
   ============================================================ */
.page {
  display: none;
}

.page.active {
  display: block;
  animation: fadeIn 0.2s var(--ease);
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.page-layout {
  /* Width: was max-width 1180px + centered, which stranded the content in the
     middle of any wider screen and left large dead gutters either side. The
     cap is now generous enough to read as "use the space you have" while
     still keeping line lengths sane on an ultrawide monitor. */
  max-width: 1800px;
  margin: 0 auto;
  /* Side padding: 1.5rem -> 1.25rem (20px). The page edge was padded further
     than any card inside it, so the whole UI read as "too thick". */
  padding: 1.5rem 1.25rem 2.5rem;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 0.85rem;
  margin-bottom: 1.25rem;   /* was 2rem — 32px of air under every page title */
  gap: 1rem;
  flex-wrap: wrap;
}

.page-header h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2rem;
  letter-spacing: -0.01em;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.date-note {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-align: right;
  white-space: pre-line;
}

/* ============================================================
   EVALUATION FORM
   ============================================================ */
.eval-form-card {
  background: var(--paper-raised);
  border: 1px solid var(--paper-line);
  padding: 1.75rem;
  margin-bottom: 1.5rem;
  position: relative;
}

.eval-form-card::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 8px;
  background-image: radial-gradient(
    circle at 6px 4px,
    transparent 3px,
    var(--paper-raised) 3.3px
  );
  background-size: 12px 8px;
  background-repeat: repeat-x;
  border-top: 1px dashed var(--paper-line);
}

.eval-form-card h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.25rem;
  margin-bottom: 0.4rem;
}

.form-desc {
  font-size: 0.87rem;
  color: var(--ink-soft);
  margin-bottom: 1.4rem;
  padding-bottom: 1rem;
  border-bottom: 1px dashed var(--paper-line);
}

.recaptcha-widget {
  margin: 1rem 0 0.5rem;
  display: flex;
  justify-content: center;
  min-height: 78px;
}
.recaptcha-widget:empty {
  display: none;
}

.form-section {
  margin-top: 1.5rem;
}

.form-section h4 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.75rem;
}

/* Rating Groups */
.rating-group {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1rem;
  align-items: center;
  padding: 0.9rem 0;
  border-bottom: 1px dashed var(--paper-line);
}

.rating-group:last-child {
  border-bottom: none;
}

/* Highlight unanswered required questions */
.rating-group.error {
  background: rgba(214, 40, 40, 0.06);
  border-left: 3px solid var(--danger, #d62828);
  padding-left:0.6rem;
}

.rating-group.error .likert-btn {
  border-color:#d62828;
  color:#d62828;
}

.rating-group.error .rating-label {
  color:#d62828;
}

.form-group.error {
  background:rgba(214, 40, 40, 0.06);
  padding:0.4rem 0.6rem;
  border-left:3px solid #d62828;
}

.form-group.error label {
  color:#d62828;
}

.form-group.error .form-control {
  border-color:#d62828;
}

.rating-label {
  font-size: 0.92rem;
  color: var(--ink);
}

.likert-scale {
  display: flex;
  gap: 0.3rem;
  flex-shrink: 0;
}

.likert-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  padding: 0.15rem;
}

.likert-option input[type="radio"] {
  display: none;
}

.likert-btn {
  width: 34px;
  height: 34px;
  border: 1.5px solid var(--paper-line);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
  cursor: pointer;
  background: var(--paper);
  transition: background 0.12s, border-color 0.12s;
}

.likert-option input[type="radio"]:checked + .likert-btn {
  background: var(--brand-deep);
  border-color: var(--brand-deep);
  color: #fff;
}

.likert-option:hover .likert-btn {
  border-color: var(--brand);
  color: var(--brand);
}

.likert-label {
  font-size: 0.6rem;
  color: var(--ink-faint);
  margin-top: 0.15rem;
}

/* ============================================================
   CHARTS

   A consistent two-column grid keeps charts readable and aligns related
   panels. Detailed department tables render as separate cards so they can
   share rows with charts instead of creating one oversized panel.
   ============================================================ */
.chart-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.1rem;
  margin-bottom: 0.85rem;
  align-items: start;
}

.chart-grid > * {
  min-width: 0;
}

.chart-grid > .chart-card {
  margin-bottom: 0;
}

.chart-card.span-full {
  grid-column: 1 / -1;
}

.aspect-tables {
  display: contents;
}

.chart-grid > .aspect-tables > * {
  min-width: 0;
}

@media (max-width: 780px) {
  .chart-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Faculty "Top Comments": complaints and appreciations side by side, so both
   lists are readable at once instead of one stacked above the other. The
   auto-fit/minmax pair (same idiom as .chart-grid) collapses to a single
   column on its own when the card gets too narrow — no breakpoint needed.
   Each column scrolls independently. */
.faculty-comments-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.1rem;
  align-items: start;
}

.faculty-comments-col {
  min-width: 0;
  max-height: 400px;
  overflow-y: auto;
}

.chart-card {
  background: var(--paper-raised);
  border: 1px solid #E5E7EB;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  padding: 1.35rem;
  position: relative;
}

.chart-card h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  margin-bottom: 1rem;
}

.chart-container {
  position: relative;
  height: 280px;
  width: 100%;
}

.chart-container canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
  max-width: 100%;
  max-height: 100%;
  image-rendering: auto;
}

/* ============================================================
   TREND BADGES & SPARKLINES (KPI cards)
   ============================================================ */
.trend-badge {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-family: var(--font-mono);
  font-size: .62rem;
  font-weight: 600;
  letter-spacing: .04em;
  padding: .14rem .45rem;
  border-radius: 999px;
  margin-top: .3rem;
  margin-right: .4rem;
  border: 1px solid transparent;
  vertical-align: middle;
  cursor: default;
  white-space: nowrap;   /* was wrapping to two lines ("new this / month") in a KPI card */
}
.trend-badge.good {
  color: var(--pos);
  background: rgba(47, 111, 78, .1);
  border-color: rgba(47, 111, 78, .35);
}
.trend-badge.bad {
  color: var(--neg);
  background: rgba(179, 58, 58, .1);
  border-color: rgba(179, 58, 58, .35);
}
.trend-badge.flat {
  color: var(--ink-faint);
  background: rgba(0, 0, 0, .04);
  border-color: var(--paper-line, #ddd);
}
.sparkline {
  display: block;
  width: 80px;
  height: 24px;
  margin: .35rem 0 .1rem;
  opacity: .85;
}

/* ============================================================
   GLOBAL FILTER BAR (Overview tab)
   ============================================================ */
.filter-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem;
  justify-content: flex-end;
  background: var(--paper-alt, #f7f6f1);
  border: 1px solid var(--paper-line, #ddd);
  border-radius: 6px;
  padding: .5rem .75rem;
  margin: 0 0 .9rem;
}
.filter-bar .filter-label {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.filter-bar select {
  font-family: var(--font-mono);
  font-size: .72rem;
  padding: .28rem .5rem;
  border: 1px solid var(--paper-line, #ccc);
  border-radius: 4px;
  background: #fff;
  color: var(--ink, #222);
  cursor: pointer;
}
.filter-bar .filter-scope {
  flex-basis: 100%;
  font-family: var(--font-mono);
  font-size: .6rem;
  color: var(--ink-faint);
  text-align: right;
}

/* ============================================================
   SOURCE NOTES & INFO BADGES
   Long grey monospace explanations render as a subtle restyled
   caption (small, no wide letter-spacing); long ones collapse
   into a hover tooltip via an (i) badge added by
   ADMIN.compressNotes().
   ============================================================ */
.source-note {
  display: block;
  font-family: var(--font);
  font-size: .66rem;
  line-height: 1.45;
  letter-spacing: normal;
  color: var(--ink-faint);
  margin: .1rem 0 .6rem;
}
.source-note strong {
  color: var(--ink-soft);
}
.note-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  font-size: .58rem;
  color: var(--ink-faint);
  background: rgba(0, 0, 0, .05);
  border: 1px solid #E5E7EB;
  cursor: help;
  vertical-align: middle;
  margin: 0 .35rem .35rem 0;
}
.note-badge:hover {
  color: var(--brand);
  border-color: var(--brand);
}

/* ============================================================
   LEDGER BARS (Visual bar charts)
   ============================================================ */
/* ============================================================
   LEDGER BARS (Visual bar charts)
   ============================================================ */
.ledger-bars {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.ledger-row {
  display: grid;
  grid-template-columns: 130px 1fr 48px;
  align-items: center;
  gap: 0.8rem;
}

.ledger-row .label {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ink-soft);
}

.ledger-track {
  height: 14px;
  background: var(--paper);
  border: 1px solid var(--paper-line);
  display: flex;
  overflow: hidden;
}

.ledger-fill {
  height: 100%;
  flex: 0 0 auto;
}

.ledger-fill.pos {
  background: var(--pos);
}
.ledger-fill.neu {
  background: var(--neu);
}
.ledger-fill.neg {
  background: var(--neg);
}

.ledger-row .pct {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  text-align: right;
  color: var(--ink);
}

/* ============================================================
   BADGES
   ============================================================ */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: 1px solid currentColor;
}

.badge-positive {
  color: var(--pos);
  background: var(--pos-bg);
}
.badge-neutral {
  color: var(--neu);
  background: var(--neu-bg);
}
.badge-negative {
  color: var(--neg);
  background: var(--neg-bg);
}
.badge-admin {
  color: var(--brand-deep);
  background: var(--brand-soft);
}
.badge-faculty {
  color: var(--brand);
  background: var(--brand-soft);
}
.badge-staff {
  color: var(--neu);
  background: var(--neu-bg);
}
.badge-facilities {
  color: var(--ink-soft);
  background: var(--paper);
}
.badge-payment {
  color: var(--neg);
  background: var(--neg-bg);
}
.badge-student {
  color: var(--brand);
  background: var(--brand-soft);
}

/* ============================================================
   FILTER BAR
   ============================================================ */
.filter-bar { 
  display: flex;
  gap: 0.6rem;
  align-items: center;
  flex-wrap: wrap;
  padding: 1rem;
  background: var(--paper-raised);
  border: 1px solid var(--paper-line);
  margin-bottom: 0.75rem;
}

.filter-bar .form-control {
  width: auto;
  min-width: 180px;
}

/* ============================================================
   PAGINATION
   ============================================================ */
.pagination {
  display: flex;
  justify-content: center;
  gap: 0.4rem;
  margin-top: 1.25rem;
}

.pagination button {
  width: 36px;
  height: 36px;
  border: 1px solid var(--paper-line);
  background: var(--paper-raised);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
}

.pagination button.active,
.pagination button:hover {
  background: var(--brand-deep);
  color: #fff;
  border-color: var(--brand-deep);
}

.pagination-ellipsis,
.pagination-status {
  align-self: center;
  padding: 0 0.25rem;
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 0.72rem;
}

.bulk-delete-recovery {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--paper-line);
  background: var(--paper-alt, #f1f1ec);
  font-size: 0.85rem;
}

@media (max-width: 600px) {
  .bulk-delete-recovery {
    align-items: flex-start;
    flex-direction: column;
  }
}

/* ============================================================
   TABS
   ============================================================ */
.tabs {
  display: flex;
  border-bottom: 2px solid var(--ink);
  margin-bottom: 1.5rem;
  /* Scrolls its own long meta line (the "Compiled ..." stamp) rather than
     pushing the page sideways. Safe as a scroll container because nothing
     inside the header hangs outside it. */
  overflow-x: auto;
}

.tab-btn {
  padding: 0.7rem 1.2rem;
  border: none;
  background: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: flex;
  align-items: center;
  gap: 0.45rem;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: color 0.15s, border-color 0.15s;
}

.tab-btn:hover {
  color: var(--ink);
}

.tab-btn.active {
  color: var(--brand-deep);
  border-bottom-color: var(--pos);
}

/* ============================================================
   UPLOAD AREA
   ============================================================ */
.upload-area {
  border: 2px dashed var(--paper-line);
  padding: 3rem 2rem;
  text-align: center;
  cursor: pointer;
  background: var(--paper-raised);
}

.upload-area:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
}

.upload-area .upload-icon {
  font-size: 2.5rem;
  color: var(--ink-faint);
  margin-bottom: 1rem;
}

.upload-area h4 {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.upload-area p {
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/* ============================================================
   LOADING OVERLAY
   ============================================================ */
.loading-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(28, 35, 31, 0.72);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  color: #f2f0e6;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.06em;
}

.loading-overlay.show {
  display: flex;
}

.spinner {
  width: 48px;
  height: 48px;
  border: 3px solid rgba(242, 240, 230, 0.25);
  border-top-color: var(--pos);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  margin-bottom: 1rem;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ============================================================
   TOAST NOTIFICATIONS
   ============================================================ */
.toast-container {
  position: fixed;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 99999;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  pointer-events: none;
}

.toast {
  padding: 0.85rem 1.1rem;
  border: 1px solid;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  animation: slideIn 0.3s var(--ease);
  min-width: 280px;
  max-width: 420px;
  pointer-events: all;
}

.login-form-error {
  margin: 0 0 0.9rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid rgba(171, 58, 58, 0.45);
  border-radius: 0.75rem;
  background: rgba(171, 58, 58, 0.08);
  color: var(--neg, #b33a3a);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.toast.success {
  background: var(--pos-bg);
  color: var(--pos);
  border-color: var(--pos);
}
.toast.error {
  background: var(--neg-bg);
  color: var(--neg);
  border-color: var(--neg);
}
.toast.warning {
  background: var(--neu-bg);
  color: var(--neu);
  border-color: var(--neu);
}
.toast.info {
  background: var(--brand-soft);
  color: var(--brand-deep);
  border-color: var(--brand);
}

@keyframes slideIn {
  from {
    transform: translateX(110%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* ============================================================
   EMPTY STATE
   ============================================================ */
.empty-state {
  text-align: center;
  padding: 3.5rem 1rem;
  color: var(--ink-soft);
}

.empty-state .empty-icon {
  font-size: 2.5rem;
  margin-bottom: 1rem;
}

.empty-state h3 {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

/* ============================================================
   MODAL
   ============================================================ */
.modal-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(28, 35, 31, 0.6);
  z-index: 5000;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.modal-backdrop.show {
  display: flex;
}

.modal {
  background: var(--paper-raised);
  border: 1px solid var(--ink);
  box-shadow: 6px 6px 0 var(--brand-deep);
  max-width: 560px;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.1rem 1.35rem;
  border-bottom: 1px solid var(--paper-line);
}

.modal-header h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.1rem;
}

.modal-close {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1.2rem;
  color: var(--ink-soft);
  padding: 0.25rem 0.5rem;
}

.modal-body {
  padding: 1.35rem;
}

.faculty-access-controls,
.faculty-access-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6rem;
  margin-top: 1rem;
}

.faculty-access-controls {
  justify-content: flex-start;
}

.faculty-access-options {
  max-height: 45vh;
  overflow-y: auto;
  margin-top: 0.75rem;
  border-top: 1px solid var(--paper-line);
  border-bottom: 1px solid var(--paper-line);
}

.faculty-access-option {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.75rem 0.25rem;
  border-bottom: 1px solid var(--paper-line);
  cursor: pointer;
}

.faculty-access-option:last-child {
  border-bottom: 0;
}

.faculty-access-option input {
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
}

.modal-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.modal-field label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: block;
  margin-bottom: 0.2rem;
}

.modal-field p {
  font-size: 0.88rem;
}

/* ============================================================
   PERF TABLE (Model Performance)
   ============================================================ */
.perf-table th {
  font-size: 0.72rem;
}
.perf-table td {
  font-size: 0.85rem;
}
.crown {
  color: var(--pos);
}

/* ============================================================
   UTILITIES
   ============================================================ */
.text-muted {
  color: var(--ink-soft);
}
.text-center {
  text-align: center;
}
.text-right {
  text-align: right;
}
.text-success {
  color: var(--pos);
}
.text-warning {
  color: var(--neu);
}
.text-danger {
  color: var(--neg);
}

.mt-2 {
  margin-top: 1rem;
}
.mt-3 {
  margin-top: 1.5rem;
}
.mt-4 {
  margin-top: 2rem;
}
.mb-2 {
  margin-bottom: 1rem;
}
.mb-3 {
  margin-bottom: 1.5rem;
}

.hidden {
  display: none !important;
}

.two-col {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 1.75rem;
  align-items: start;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 900px) {
  .two-col {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .navbar {
    flex-wrap: wrap;
    /* No overflow-x here either: it would clip the account menu on exactly
       the phones where the menu is most needed. The tab strip already
       handles its own overflow, and the page-level body guard covers the
       rest. */
    padding: 0 0.75rem;
  }
  .nav-brand {
    padding: 0.75rem 0;
    border: none;
    margin: 0;
  }
  .nav-links li button {
    padding: 0.6rem 0.9rem;
    font-size: 0.78rem;
  }
  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .rating-group {
    grid-template-columns: 1fr;
  }
  .page-layout {
    padding: 1rem 0.75rem 1.5rem;   /* mirrors the tightened desktop rhythm */
  }
  .two-col {
    grid-template-columns: 1fr;
  }
  .modal-row {
    grid-template-columns: 1fr;
  }
  .filter-bar {
    flex-direction: column;
    align-items: stretch;
  }
  .filter-bar .form-control {
    width: 100%;
  }
  .form-inline {
    flex-direction: column;
    align-items: stretch;
  }
}

@media (max-width: 480px) {
  .stats-grid {
    grid-template-columns: 1fr;
  }
  .page-header {
    flex-direction: column;
    align-items: flex-start;
  }
}

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

/* ============================================================
   NEGATIVE SPIKE ALERTS (admin navbar bell)
   ============================================================ */
.page-kicker {
  display: block;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .3rem;
}

/* Scope banner — shown on a tab whenever the charts are not showing
   everything (a date/department filter, or the faculty preview). Without it
   the admin cannot tell which of two number sets they are looking at. */
.scope-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-soft);
  background: var(--paper-alt, #f1f1ec);
  border: 1px solid #E5E7EB;
  border-left: 3px solid var(--neu);
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.9rem;
}

/* The preview lens gets its own colour so it can never be mistaken for an
   ordinary filter — it changes what every chart means. */
.scope-banner.preview {
  border-left-color: var(--brand);
  color: var(--brand-deep);
  background: var(--brand-soft);
}

.scope-banner strong {
  font-weight: 600;
}

/* The "Faculty view" lens toggle now lives in the account menu as an
   .account-menu-item, so the old navbar-pill styling is gone. */

.aspect-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}

.aspect-table th,
.aspect-table td {
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--paper-line);
  text-align: center;
}

.aspect-table thead th {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: var(--paper-alt, #f1f1ec);
  white-space: nowrap;
}

.aspect-table tbody th {
  text-align: left;
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
}

.aspect-table td {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.aspect-table .col-n {
  width: 3.5rem;
  color: var(--ink-faint);
}

/* Cell tints follow the same 1-5 bands as the aspect bar chart. */
.aspect-table .t5,
.aspect-table .t4 { background: rgba(47, 111, 78, 0.16); color: var(--pos); }
.aspect-table .t3    { background: rgba(183, 121, 31, 0.16); color: var(--neu); }
.aspect-table .t2,
.aspect-table .t1    { background: rgba(179, 58, 58, 0.16); color: var(--neg); }

/* ============================================================
   ACCOUNT MENU

   Identity plus the two per-session controls (faculty lens, close file)
   behind one button. Inline in the nav row they consumed ~300px,
   which left the five tabs scrolling sideways with the active tab off screen;
   as a menu the nav row needs only the one button.
   ============================================================ */
.account-menu {
  position: relative;
  flex: 0 0 auto;
}

.account-menu-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  height: 34px;
  padding: 0 0.6rem 0 0.7rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 999px;
  background: transparent;
  color: #f2f0e6;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}

.account-menu-btn:hover,
.account-menu-btn.open {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.55);
}

.account-menu-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 1px;
}

.account-menu-name {
  max-width: 9rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

.account-menu-caret {
  font-size: 0.6rem;
  opacity: 0.7;
  transition: transform 0.15s;
}

.account-menu-btn.open .account-menu-caret {
  transform: rotate(180deg);
}

.account-menu-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 1100;
  min-width: 15rem;
  /* The panel is on the paper background, not the navy navbar, so it uses
     ink tones. The 8px solid shadow matches the rest of the paper theme. */
  background: var(--paper-raised);
  border: 1px solid var(--ink);
  border-radius: 8px;
  box-shadow: 6px 6px 0 var(--brand-deep);
  padding: 0.4rem;
  /* Anchored to the right edge and capped to the viewport, so it can never
     open off-screen on a narrow window. */
  max-width: calc(100vw - 2rem);
}

.account-menu-header {
  padding: 0.5rem 0.6rem 0.6rem;
  border-bottom: 1px solid var(--paper-line);
  margin-bottom: 0.3rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  color: var(--ink-faint);
  overflow: hidden;
  text-overflow: ellipsis;
}

.account-menu-item {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.55rem 0.6rem;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font-family: var(--font);
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s;
}

.account-menu-item:hover {
  background: var(--brand-soft);
}

/* The pressed state of a toggle is easy to miss inside a dropdown, so the
   menu item also carries an explicit On/Off readout on the right. */
.account-menu-item.active {
  background: var(--brand-soft);
  color: var(--brand-deep);
  font-weight: 600;
}

.account-menu-state {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}

.account-menu-item.active .account-menu-state {
  color: var(--brand);
}

.account-menu-danger {
  color: var(--neg);
}

.account-menu-danger:hover {
  background: rgba(179, 58, 58, 0.1);
}

.account-menu-sep {
  height: 1px;
  background: var(--paper-line);
  margin: 0.35rem 0.3rem;
}

.alert-bell-wrap {
  position: relative;
  display: none; /* shown via .visible once alerts init for a signed-in admin */
  align-items: center;
  margin-right: .75rem;
}

.alert-bell-wrap.visible {
  display: inline-flex;
}

.alert-bell {
  position: relative;
  background: transparent;
  border: 1px solid var(--paper-line);
  border-radius: 8px;
  color: var(--ink-soft);
  width: 34px;
  height: 34px;
  cursor: pointer;
  transition: border-color .15s var(--ease), color .15s var(--ease);
}
.alert-bell:hover {
  color: var(--neg);
  border-color: var(--neg);
}

.alert-bell-count {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--neg);
  color: #fff;
  font-family: var(--font-mono);
  font-size: .58rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

.alert-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 340px;
  max-height: 420px;
  overflow-y: auto;
  background: var(--paper-raised);
  border: 1px solid #E5E7EB;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  padding: .8rem;
  z-index: 1200;
}

.alert-panel-title {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--neg);
  margin-bottom: .6rem;
}

.alert-card {
  border: 1px solid #E5E7EB;
  border-left: 3px solid var(--neg);
  border-radius: 8px;
  background: var(--paper-alt, #f7f7f2);
  padding: .6rem .7rem;
  margin-bottom: .6rem;
}

.alert-message {
  font-size: .82rem;
  color: var(--ink);
  margin-bottom: .3rem;
}

.alert-actions {
  display: flex;
  gap: .4rem;
}

.alert-empty {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  align-items: flex-start;
  font-size: .82rem;
  color: var(--ink-soft);
}
.alert-empty i {
  color: var(--pos);
}

/* ============================================================
   OVERVIEW QUICK-GLANCE WIDGETS
   (Term-over-Term / Department Leaderboard / System Health)
   ============================================================ */

/* KPI cards now carry two micro-charts: the existing 6-month line and a new
   last-N-days bar sparkline, so they share one row and shrink slightly. */
.spark-pair {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem;
  margin: .35rem 0 .1rem;
}
.spark-pair .sparkline {
  width: 62px;
  height: 20px;
  margin: 0;
}

/* ---- Term-over-Term ---- */
.term-cmp {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: .5rem;
  align-items: center;
  margin-top: .2rem;
}
.term-cmp-side {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .15rem;
  min-width: 0;
}
.term-cmp-side-empty {
  justify-content: center;
  border: 1px dashed var(--paper-line);
  border-radius: 8px;
  padding: .75rem .5rem;
  text-align: center;
}
.term-cmp-tag {
  font-family: var(--font-mono);
  font-size: .58rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.term-cmp-term {
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 600;
  color: var(--ink);
  text-align: center;
  margin: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.term-cmp-donut {
  position: relative;
  width: 100%;
  height: 104px;
}
.term-cmp-strip {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: .12rem;
}
.term-cmp-strip-row {
  display: flex;
  align-items: center;
  gap: .3rem;
  font-family: var(--font-mono);
  font-size: .62rem;
}
.term-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
.term-dot.pos {
  background: var(--pos);
}
.term-dot.neu {
  background: var(--neu);
}
.term-dot.neg {
  background: var(--neg);
}
.term-cmp-name {
  flex: 1;
  color: var(--ink-faint);
}
.term-cmp-pct {
  color: var(--ink);
  font-weight: 600;
}
.term-cmp-vol {
  font-family: var(--font-mono);
  font-size: .6rem;
  color: var(--ink-faint);
  margin: .2rem 0 0;
}
.term-cmp-delta {
  display: flex;
  align-items: center;
  justify-content: center;
}
/* The shared .trend-badge margin only suits a stacked card layout. */
.term-cmp-delta .trend-badge {
  margin: 0;
}
.term-cmp-note {
  font-family: var(--font-mono);
  font-style: italic;
  font-size: .62rem;
  line-height: 1.45;
  color: var(--ink-faint);
  margin: .7rem 0 0;
  padding-top: .55rem;
  border-top: 1px dashed var(--paper-line);
}

/* ---- Department leaderboard ---- */
.leaderboard-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem;
  flex-wrap: wrap;
}
.leaderboard-header h3 {
  margin-bottom: .2rem;
}
.leaderboard-actions {
  display: inline-flex;
  gap: .3rem;
  flex-wrap: wrap;
}
.leaderboard-group + .leaderboard-group {
  margin-top: .7rem;
}
.leaderboard-heading {
  display: block;
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .4rem;
}
.leader-rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid var(--paper-line);
  color: var(--ink-soft);
  font-size: .56rem;
  font-weight: 600;
  margin-right: .15rem;
}
.leader-rank.top {
  background: var(--pos-bg);
  border-color: rgba(47, 111, 78, .35);
  color: var(--pos);
}
.leader-rank.bottom {
  background: var(--neg-bg);
  border-color: rgba(179, 58, 58, .35);
  color: var(--neg);
}
.leader-n {
  font-size: .6rem;
  color: var(--ink-faint);
}
.leaderboard-note {
  font-family: var(--font-mono);
  font-style: italic;
  font-size: .6rem;
  line-height: 1.45;
  color: var(--ink-faint);
  margin: .7rem 0 0;
  padding-top: .55rem;
  border-top: 1px dashed var(--paper-line);
}

/* ---- System health snapshot ---- */
.health-rows {
  display: flex;
  flex-direction: column;
  gap: .55rem;
}
.health-row {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  align-items: center;
  gap: .5rem;
  padding-bottom: .55rem;
  border-bottom: 1px dashed var(--paper-line);
}
.health-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.health-icon {
  width: 22px;
  height: 22px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .68rem;
}
.health-icon.good {
  background: var(--pos-bg);
  color: var(--pos);
}
.health-icon.warn {
  background: var(--neu-bg);
  color: var(--neu);
}
.health-icon.bad {
  background: var(--neg-bg);
  color: var(--neg);
}
.health-icon.neutral {
  background: var(--brand-soft);
  color: var(--brand);
}
.health-label {
  font-family: var(--font-mono);
  font-size: .66rem;
  color: var(--ink-soft);
  min-width: 0;
}
.health-value {
  font-family: var(--font-mono);
  font-size: .8rem;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
.health-value.good {
  color: var(--pos);
}
.health-value.warn {
  color: var(--neu);
}
.health-value.bad {
  color: var(--neg);
}
.health-value.neutral {
  color: var(--brand);
}


/* ============================================================
   ACTION UPDATE STATUS BADGES + PUBLIC BULLETIN
   ============================================================ */
.badge-acknowledged,
.badge-in-progress,
.badge-resolved {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: .2rem .55rem;
  border-radius: 999px;
  border: 1px solid transparent;
}
.badge-acknowledged {
  color: var(--neu);
  background: var(--neu-bg);
  border-color: var(--neu);
}
.badge-in-progress {
  color: var(--brand);
  background: var(--brand-soft);
  border-color: var(--brand);
}
.badge-resolved {
  color: var(--pos);
  background: var(--pos-bg);
  border-color: var(--pos);
}

.bulletin-intro {
  font-size: .78rem;
  margin-bottom: 1.25rem;
}

.bulletin-group {
  margin-bottom: 1.75rem;
}

.bulletin-group-header h2 {
  font-family: var(--font-display);
  font-size: 1.15rem;
  margin-bottom: .2rem;
}
.bulletin-group-header h2 i {
  color: var(--ink-faint);
  font-size: .95rem;
  margin-right: .35rem;
}

.bulletin-card {
  padding: 1.1rem 1.25rem;
}

.bulletin-card-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: .75rem;
  margin-bottom: .45rem;
}
.bulletin-card-header h3 {
  font-family: var(--font-display);
  font-size: 1.02rem;
}

.bulletin-summary {
  font-size: .88rem;
  color: var(--ink-soft);
  margin-bottom: .55rem;
}

.bulletin-resolution {
  display: flex;
  gap: .45rem;
  align-items: flex-start;
  font-size: .84rem;
  color: var(--pos);
  background: var(--pos-bg);
  border: 1px solid var(--pos);
  border-radius: 8px;
  padding: .5rem .7rem;
  margin-bottom: .55rem;
}

.bulletin-date {
  display: block;
  font-family: var(--font-mono);
  font-size: .66rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ============================================================
   MULTI-STEP EVALUATION STYLES
   ============================================================ */

.stepper-container {
  margin-bottom: 2rem;
  padding: 1.5rem;
  background: var(--paper-raised);
  border-radius: 12px;
  border: 1px solid var(--paper-line);
}

.stepper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
}

.stepper::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--paper-line);
  transform: translateY(-50%);
  z-index: 0;
}

.step-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  z-index: 1;
  flex: 1;
}

.step-circle {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--paper-raised);
  border: 3px solid var(--paper-line);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: .9rem;
  color: var(--ink-faint);
  transition: all 0.3s ease;
}

.step-label {
  margin-top: .5rem;
  font-size: .75rem;
  font-weight: 500;
  color: var(--ink-faint);
  text-align: center;
  transition: all 0.3s ease;
}

.step-item.active .step-circle {
  background: var(--brand);
  border-color: var(--brand);
  color: white;
  transform: scale(1.1);
  box-shadow: 0 4px 12px rgba(43, 58, 103, 0.3);
}

.step-item.active .step-label {
  color: var(--brand);
  font-weight: 600;
}

.step-item.completed .step-circle {
  background: var(--pos);
  border-color: var(--pos);
  color: white;
}

.step-item.completed .step-label {
  color: var(--pos);
}

.step-navigation {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--paper-line);
}

.nav-left, .nav-right {
  flex: 1;
}

.nav-right {
  text-align: right;
}

.step-navigation .btn {
  min-width: 140px;
  padding: .75rem 1.5rem;
  font-size: .95rem;
}

.hidden {
  display: none !important;
}

.step-progress {
  text-align: center;
  font-size: .8rem;
  color: var(--ink-soft);
  margin-top: 1rem;
  font-family: var(--font-mono);
}

@media (max-width: 600px) {
  .stepper {
    flex-direction: column;
    gap: 1rem;
  }
  .stepper::before {
    display: none;
  }
  .step-item {
    flex-direction: row;
    gap: .75rem;
    width: 100%;
  }
  .step-circle {
    width: 36px;
    height: 36px;
    font-size: .8rem;
  }
  .step-label {
    margin-top: 0;
    text-align: left;
  }
}

.stepper-container { margin-bottom: 2rem; padding: 1.5rem; background: var(--paper-raised); border-radius: 12px; border: 1px solid var(--paper-line); }
.stepper { display: flex; justify-content: space-between; align-items: center; position: relative; }
.stepper::before { content: ""; position: absolute; top: 50%; left: 0; right: 0; height: 3px; background: var(--paper-line); transform: translateY(-50%); z-index: 0; }
.step-item { display: flex; flex-direction: column; align-items: center; position: relative; z-index: 1; flex: 1; }
.step-circle { width: 42px; height: 42px; border-radius: 50%; background: var(--paper-raised); border: 3px solid var(--paper-line); display: flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-weight: 600; font-size: .9rem; color: var(--ink-faint); transition: all 0.3s ease; }
.step-label { margin-top: .5rem; font-size: .75rem; font-weight: 500; color: var(--ink-faint); text-align: center; transition: all 0.3s ease; }
.step-item.active .step-circle { background: var(--brand); border-color: var(--brand); color: white; transform: scale(1.1); box-shadow: 0 4px 12px rgba(43, 58, 103, 0.3); }
.step-item.active .step-label { color: var(--brand); font-weight: 600; }
.step-item.completed .step-circle { background: var(--pos); border-color: var(--pos); color: white; }
.step-item.completed .step-label { color: var(--pos); }
.step-navigation { display: flex; justify-content: space-between; align-items: center; margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--paper-line); }
.nav-left, .nav-right { flex: 1; }
.nav-right { text-align: right; }
.step-navigation .btn { min-width: 120px; }
.hidden { display: none !important; }
@media (max-width: 600px) { .stepper { flex-direction: column; gap: 1rem; } .stepper::before { display: none; } .step-item { flex-direction: row; gap: .75rem; width: 100%; } .step-circle { width: 36px; height: 36px; font-size: .8rem; } .step-label { margin-top: 0; text-align: left; } }

/* ============================================================
   VOICE IN A BOX — anonymous open-ended feedback stream
   Landing-page drop box card, submission modal, and the
   Responses-tab card feed. Same navy/cream paper theme, but
   deliberately a different shape from the structured
   "Open evaluation" button: dashed drop-box styling.
   ============================================================ */
.voice-box-card {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--brand-soft);
  border: 1.5px dashed var(--brand);
  border-radius: 10px;
  padding: 0.9rem 1.05rem;
  margin-top: 0.9rem;
  cursor: pointer;
  font-family: var(--font);
  color: var(--ink);
  transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.voice-box-card:hover {
  border-style: solid;
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(43, 58, 103, 0.14);
}
.voice-box-kicker {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 0.25rem;
}
.voice-box-kicker i {
  margin-right: 0.3rem;
}
.voice-box-title {
  display: block;
  font-family: var(--font-display);
  font-size: 1.12rem;
  font-weight: 600;
  color: var(--brand-deep);
}
.voice-box-desc {
  display: block;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0.25rem 0 0.6rem;
}
.voice-box-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brand);
  border: 1px solid var(--brand);
  border-radius: 6px;
  padding: 0.3rem 0.65rem;
  background: var(--paper-raised);
}
.voice-box-cta i {
  font-size: 0.75rem;
}

/* Submission modal */
.voice-box-modal .modal-body {
  padding-top: 0.75rem;
}
.voice-box-note-kicker {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.3rem;
}
.voice-box-note {
  font-size: 0.82rem;
  color: var(--ink-soft);
  background: var(--paper);
  border: 1px solid var(--paper-line);
  border-left: 3px solid var(--brand);
  border-radius: 6px;
  padding: 0.55rem 0.75rem;
  margin-bottom: 0.9rem;
}

/* ============================================================
   VOICE IN A BOX FEED (admin Responses tab)
   Card feed — separate from the evaluation table, with its own
   lightweight sentiment filter and its own empty state.
   ============================================================ */
.voice-feed-section {
  margin-top: 2rem;
}
.voice-feed-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.2rem;
}
.voice-feed-head .voice-kicker {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: block;
  margin-bottom: 0.35rem;
}
.voice-feed-head h2 {
  font-family: var(--font-display);
  font-size: 1.25rem;
  color: var(--ink);
}
.voice-feed-head h2 i {
  color: var(--brand);
  font-size: 1rem;
  margin-right: 0.4rem;
}
.voice-feed-count {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ink-faint);
}
.voice-feed-note {
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin-bottom: 0.7rem;
}
.voice-feed-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 0.75rem;
}

/* ============================================================
   MOBILE RESPONSIVENESS REFINEMENTS
   Scoped strictly to small viewports — desktop rules above are
   untouched. Reference widths: 375px, 414px, 768px.
   ============================================================ */

@media (max-width: 768px) {
  /* Navigation: brand + user controls share row 1, tabs get their
     own horizontally scrollable row below (no page-level overflow). */
  .nav-links {
    flex: 1 1 100%;
    min-width: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
  }
  .nav-links li button {
    min-height: 44px;
  }
  .nav-user {
    padding: 0.4rem 0;
  }

  /* Touch targets: >= 44px on primary controls */
  .btn,
  .tab-btn,
  .btn-logout {
    min-height: 44px;
  }
  .tab-btn {
    padding: 0.6rem 0.9rem;
  }
  .btn-logout {
    padding: 0.5rem 0.9rem;
  }
  .role-pill {
    min-height: 44px;
    padding: 0.75rem 0.5rem;
  }
  .modal-close {
    min-width: 44px;
    min-height: 44px;
  }
  .pagination button {
    min-width: 40px;
    min-height: 40px;
  }

  /* The analytics tab injects an inline grid-template-columns on
     .two-col (admin.js); !important guarantees single-column
     stacking on phones despite the inline style. */
  .two-col {
    grid-template-columns: 1fr !important;
  }

  /* The alerts panel is fixed at 340px — cap it so it cannot
     overflow a 375px viewport. */
  .alert-panel {
    max-width: calc(100vw - 2rem);
  }
  .alert-bell {
    width: 44px;
    height: 44px;
  }

  /* Tables: smooth touch scrolling; wrap long words inside cells
     (the .table-container itself still scrolls horizontally). */
  .table-container {
    -webkit-overflow-scrolling: touch;
  }
  .table-container td {
    overflow-wrap: break-word;
  }

  /* 16px inputs prevent iOS Safari's automatic zoom-on-focus */
  .form-control,
  select.form-control,
  textarea.form-control {
    font-size: 16px;
  }
}

@media (max-width: 480px) {
  /* Login card: reclaim padding so the form has usable width at
     375px (2.25rem side padding left only ~240px of form width). */
  .login-page {
    padding: 1.25rem 1rem;
  }
  .login-container {
    padding: 1.75rem 1.25rem 1.5rem;
  }

  /* Course/year selector cards stack vertically instead of two
     cramped columns */
  .course-year-grid {
    grid-template-columns: 1fr;
  }

  /* Slightly shorter charts keep donut/bar proportions pleasant */
  .chart-container {
    height: 240px;
  }

  /* Phone: 240px is still a lot of a short viewport, and a chart filling half
     the screen makes the page feel like a stack of slides. The two theme
     charts that set a literal inline height:300px need !important to be
     brought down to match -- a plain rule loses to an inline style. */
  .chart-container,
  .chart-card .chart-container {
    height: 210px !important;
  }

  /* Tighten the gaps between cards and masonry columns on a phone. */
  .stats-grid,
  .chart-grid,
  .two-col {
    gap: 0.85rem;
  }

  /* Chart cards are inset 1.35rem on desktop, generous once the card is the
     full width of the screen. */
  .chart-card {
    padding: 1rem;
  }

  .modal-body {
    padding: 1.1rem 1rem;
  }
}
.voice-feed-card {
  background: var(--paper-raised);
  border: 1px solid var(--paper-line);
  border-left: 4px solid var(--ink-faint);
  border-radius: 6px;
  padding: 0.85rem 0.95rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.voice-feed-card.sentiment-positive { border-left-color: var(--pos); }
.voice-feed-card.sentiment-neutral { border-left-color: var(--neu); }
.voice-feed-card.sentiment-negative { border-left-color: var(--neg); }
.voice-feed-msg {
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-line;
  word-break: break-word;
  margin: 0;
}
.voice-feed-meta {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.voice-feed-conf {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-faint);
}
.voice-feed-date {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-faint);
  margin-left: auto;
}
.voice-feed-delete {
  border: none;
  background: transparent;
  color: var(--ink-faint);
  cursor: pointer;
  font-size: 0.78rem;
  padding: 0.1rem 0.25rem;
}
.voice-feed-delete:hover {
  color: var(--neg);
}
