/* =========================================================
   AIPC Student Portal — Dashboard Component Layer
   Extends css/brand.css tokens for data-dense, authenticated UI.
   Design preview only — not wired to a real backend.
   ========================================================= */

:root {
  --status-good: #3F6B52;
  --status-good-soft: #E4EDE4;
  --status-progress: var(--gold);
  --status-progress-soft: #F6EAD2;
  --status-critical: var(--red);
  --status-critical-soft: #F3E3E1;
  --surface: var(--paper);
  --app-sidebar-w: 248px;
}

body.app { background: var(--ivory); }

.preview-banner {
  background: var(--gold); color: var(--royal-deep); text-align: center;
  font-size: .82rem; font-weight: 700; letter-spacing: .02em;
  padding: 10px 16px; position: sticky; top: 0; z-index: 60;
}
.preview-banner strong { text-transform: uppercase; letter-spacing: .08em; margin-right: .5em; }

.app-shell { display: flex; min-height: 100vh; }

/* ---------------- Sidebar ---------------- */
.app-sidebar {
  width: var(--app-sidebar-w); flex-shrink: 0; background: var(--royal-deep);
  color: rgba(247,244,236,.82); padding: 24px 18px; display: flex; flex-direction: column;
  position: sticky; top: 41px; height: calc(100vh - 41px);
}
.app-sidebar__brand { display: flex; align-items: center; gap: 10px; padding: 0 6px 22px; border-bottom: 1px solid var(--line-dark); margin-bottom: 18px; }
.app-sidebar__brand .brand__crest { width: 28px; height: 33px; }
.app-sidebar__brand span { font-family: var(--font-display); font-weight: 600; font-size: .88rem; color: #fff; }
.app-nav { list-style: none; margin: 0; padding: 0; flex: 1; }
.app-nav li { margin-bottom: 2px; }
.app-nav a {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 6px;
  color: rgba(247,244,236,.75); font-size: .88rem; font-weight: 600; position: relative;
  transition: background var(--dur-fast) ease, color var(--dur-fast) ease, padding-left var(--dur-fast) var(--ease-premium);
}
.app-nav a .ic { width: 18px; text-align: center; opacity: .8; font-size: .95rem; }
.app-nav a:hover { background: rgba(255,255,255,.06); color: #fff; padding-left: 16px; }
.app-nav li.active a { background: rgba(199,162,74,.14); color: var(--gold-bright); }
/* A gold accent bar on the active item, scaling in from the centre —
   the sidebar's equivalent of the marketing cards' top accent line,
   so the "current location" reads instantly without relying on
   colour alone. */
.app-nav li.active a::before {
  content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%) scaleY(0);
  width: 3px; height: 60%; background: var(--gold-gradient); border-radius: 3px 0 0 3px;
  animation: nav-accent-in var(--dur-med) var(--ease-premium) forwards;
}
@keyframes nav-accent-in { to { transform: translateY(-50%) scaleY(1); } }
[dir="rtl"] .app-nav li.active a::before { left: auto; right: 0; border-radius: 0 3px 3px 0; }
.app-sidebar__foot { border-top: 1px solid var(--line-dark); padding-top: 14px; display: flex; flex-direction: column; gap: 2px; }
.app-sidebar__foot a { color: rgba(247,244,236,.55); font-size: .82rem; padding: 8px 12px; border-radius: 6px; }
.app-sidebar__foot a:hover { background: rgba(255,255,255,.05); color: rgba(247,244,236,.85); }

/* ---------------- Main column ---------------- */
.app-main { flex: 1; min-width: 0; padding: 36px 40px 80px; }
.app-topline { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; margin-bottom: 30px; flex-wrap: wrap; }
.app-topline h1 { font-size: 1.6rem; margin-bottom: .2em; }
.app-topline .lede { margin: 0; color: var(--ink-soft); }
.app-student { display: flex; align-items: center; gap: 12px; }
.app-student__avatar {
  width: 40px; height: 40px; border-radius: 50%; background: var(--royal);
  color: var(--gold-bright); display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700; font-size: .9rem; flex-shrink: 0;
}
.app-student__name { font-weight: 700; font-size: .9rem; }
.app-student__level { font-size: .76rem; color: var(--ink-soft); }

/* ---------------- Status pills ---------------- */
.status-pill { display: inline-flex; align-items: center; gap: .5em; border-radius: 999px; padding: .35em .95em; font-size: .74rem; font-weight: 700; letter-spacing: .03em; }
.status-pill::before { content: ''; width: 7px; height: 7px; border-radius: 50%; }
.status-pill--good { background: var(--status-good-soft); color: var(--status-good); }
.status-pill--good::before { background: var(--status-good); }
.status-pill--progress { background: var(--status-progress-soft); color: #6E5218; }
.status-pill--progress::before { background: var(--status-progress); }
.status-pill--critical { background: var(--status-critical-soft); color: var(--status-critical); }
.status-pill--critical::before { background: var(--status-critical); }
.status-pill--muted { background: rgba(20,38,74,.06); color: var(--ink-soft); }
.status-pill--muted::before { background: var(--ink-soft); }

/* ---------------- Stepper (programme progress) ---------------- */
.stepper-card { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 28px 30px; margin-bottom: 24px; box-shadow: var(--shadow-sm); }
.stepper-card__head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 22px; flex-wrap: wrap; gap: 10px; }
.stepper-card__head h2 { font-size: 1.05rem; margin: 0; }
.stepper { display: flex; align-items: center; }
.stepper__node { display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.stepper__dot {
  width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700; font-size: .82rem; border: 2px solid var(--line); color: var(--ink-soft);
  background: var(--paper); flex-shrink: 0; z-index: 1;
}
.stepper__node.is-done .stepper__dot { background: var(--status-good); border-color: var(--status-good); color: #fff; }
.stepper__node.is-current .stepper__dot { background: var(--gold); border-color: var(--gold); color: var(--royal-deep); box-shadow: 0 0 0 4px var(--status-progress-soft); }
.stepper__label { font-size: .7rem; text-align: center; color: var(--ink-soft); font-weight: 600; line-height: 1.3; }
.stepper__node.is-current .stepper__label { color: var(--ink); }
.stepper__line { flex: 1; height: 2px; background: var(--line); margin: 0 -2px 26px; }
.stepper__line.is-done { background: var(--status-good); }

.progress-meter { height: 8px; border-radius: 999px; background: var(--line); overflow: hidden; margin-top: 18px; }
.progress-meter__fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--gold), var(--gold-bright)); }
.progress-meter__caption { display: flex; justify-content: space-between; font-size: .78rem; color: var(--ink-soft); margin-top: 8px; font-variant-numeric: tabular-nums; }

/* ---------------- Stat tiles ---------------- */
.stat-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; }
@media (max-width: 900px) { .stat-tiles { grid-template-columns: repeat(2, 1fr); } }
/* A 2-column phone width still only leaves ~140-160px per tile after
   padding — tight for a value like "$56,999.86" at 1.7rem. Drop to a
   single column below ~420px rather than let it crowd or wrap badly. */
@media (max-width: 420px) { .stat-tiles { grid-template-columns: 1fr; } }
.stat-tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 20px 22px;
  box-shadow: var(--shadow-sm); transition: box-shadow var(--dur-med) var(--ease-premium), transform var(--dur-med) var(--ease-premium);
}
.stat-tile:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.stat-tile__label { font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); font-weight: 700; margin-bottom: 10px; }
.stat-tile__value { font-family: var(--font-display); font-size: 1.7rem; font-weight: 600; color: var(--royal-deep); font-variant-numeric: tabular-nums; }
.stat-tile__sub { font-size: .8rem; color: var(--ink-soft); margin-top: 4px; }

/* ---------------- Panels / two-col layout ---------------- */
.app-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 22px; align-items: start; }
@media (max-width: 1080px) { .app-grid { grid-template-columns: 1fr; } }
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 24px 26px; margin-bottom: 22px; box-shadow: var(--shadow-sm); }
.panel__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
.panel__head h2 { font-size: 1rem; margin: 0; }
.panel__head a { font-size: .8rem; font-weight: 700; color: var(--red); transition: color var(--dur-fast) ease; }
.panel__head a:hover { color: var(--red-bright); }

.class-row { display: flex; align-items: center; gap: 16px; padding: 13px 10px; margin: 0 -10px; border-radius: 6px; border-bottom: 1px solid var(--line); transition: background var(--dur-fast) ease; }
.class-row:hover { background: rgba(199,162,74,.05); }
.class-row:last-child { border-bottom: none; }
.class-row__when { width: 92px; flex-shrink: 0; font-size: .78rem; color: var(--ink-soft); line-height: 1.3; }
.class-row__when strong { display: block; color: var(--ink); font-family: var(--font-display); font-size: .95rem; }
.class-row__body { flex: 1; min-width: 0; }
.class-row__body h3 { margin: 0 0 2px; font-family: var(--font-body); font-weight: 700; font-size: .9rem; }
.class-row__body span { font-size: .8rem; color: var(--ink-soft); }
.class-row .btn { flex-shrink: 0; padding: .6em 1.2em; font-size: .78rem; }

.assign-table { width: 100%; border-collapse: collapse; font-size: .86rem; }
.assign-table th { text-align: left; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); font-weight: 700; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.assign-table td { padding: 12px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; transition: background var(--dur-fast) ease; }
.assign-table tbody tr:hover td { background: rgba(199,162,74,.05); }
.assign-table tr:last-child td { border-bottom: none; }

.mini-list { list-style: none; margin: 0; padding: 0; }
.mini-list li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 10px; margin: 0 -10px; border-radius: 6px; border-bottom: 1px solid var(--line); font-size: .86rem; transition: background var(--dur-fast) ease; }
.mini-list li:has(a:not(.disabled-link)):hover { background: rgba(199,162,74,.05); }
.mini-list li:last-child { border-bottom: none; }
/* Applies everywhere .disabled-link is used — sidebar nav placeholders,
   "View all"/"View schedule" panel links, Sign Out before a real
   session exists, not just inside .mini-list. Previously scoped to
   `.mini-list a.disabled-link` only, which meant every other instance
   (most of them — the sidebar nav is the majority use) got none of
   this styling and, more importantly, remained genuinely clickable
   despite aria-disabled="true" and looking inert. pointer-events:none
   still doesn't stop keyboard activation on its own — see tabindex="-1"
   on each element in the markup, which is the part that actually
   removes them from the tab order. */
.disabled-link { color: var(--ink-soft); pointer-events: none; cursor: not-allowed; opacity: .55; }
.mini-list a.disabled-link { font-size: .74rem; font-weight: 700; }

.message-card { border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px; background: var(--ivory); transition: box-shadow var(--dur-med) var(--ease-premium), transform var(--dur-med) var(--ease-premium); }
.message-card:hover { box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.message-card__from { font-weight: 700; font-size: .84rem; display: flex; justify-content: space-between; }
.message-card__from time { font-weight: 400; color: var(--ink-soft); font-size: .74rem; }
.message-card p { margin: 6px 0 0; font-size: .84rem; color: var(--ink-soft); }

.disabled-note { font-size: .74rem; color: var(--ink-soft); margin-top: 6px; }
button.btn[disabled], a.btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; pointer-events: none; }

/* ---------------- Empty state ---------------- */
/* Generic, content-agnostic — any panel (Classes, Assignments, Library,
   Messages, and later Faculty/Admin equivalents) uses this same markup
   when it has nothing to show, instead of a blank panel or ad-hoc copy. */
.empty-state { text-align: center; padding: 40px 20px; color: var(--ink-soft); }
.empty-state__icon {
  width: 44px; height: 44px; margin: 0 auto 14px; border-radius: 50%;
  background: rgba(20,38,74,.06); display: flex; align-items: center; justify-content: center;
  font-size: 1.2rem; color: var(--ink-soft);
}
.empty-state h3 { font-size: .95rem; color: var(--ink); margin-bottom: 4px; }
.empty-state p { font-size: .84rem; margin: 0 auto 14px; max-width: 40ch; }

/* ---------------- Toast / notification ---------------- */
/* Generic transient feedback for any action across any portal —
   "Saved", "Submitted", "Link copied" — status-colored, not
   institution-specific. */
.toast-region { position: fixed; bottom: 24px; right: 24px; z-index: 200; display: flex; flex-direction: column; gap: 10px; }
[dir="rtl"] .toast-region { right: auto; left: 24px; }
.toast {
  display: flex; align-items: center; gap: 12px; background: var(--royal-deep); color: #fff;
  border-radius: 8px; padding: 14px 18px; box-shadow: var(--shadow); font-size: .86rem; font-weight: 600;
  min-width: 260px; max-width: 360px; opacity: 0; transform: translateY(8px) scale(.96);
  transition: opacity var(--dur-med) var(--ease-premium), transform var(--dur-med) var(--ease-premium);
}
.toast.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .toast, .class-row, .mini-list li, .message-card, .stat-tile, .app-nav a, .app-nav li.active a::before { transition-duration: .01ms !important; animation-duration: .01ms !important; } .stat-tile:hover, .message-card:hover { transform: none; } }
.toast::before { content: ''; width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--status-good); }
.toast--error::before { background: var(--status-critical); }

/* ---------------- Loading skeleton ---------------- */
/* Generic shimmer placeholder for any async panel while real data
   loads — same shape family as stat tiles / panels / table rows, so
   loading states don't introduce a different visual rhythm. */
.skeleton { position: relative; overflow: hidden; background: rgba(20,38,74,.08); border-radius: 6px; }
.skeleton::after {
  content: ''; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes skeleton-shimmer { 100% { transform: translateX(100%); } }
.skeleton--text { height: 14px; margin-bottom: 8px; }
.skeleton--title { height: 22px; width: 60%; margin-bottom: 14px; }
@media (prefers-reduced-motion: reduce) { .skeleton::after { animation: none; } }

/* ---------------- Auth gate ---------------- */
/* Full-page overlay shown only while js/portal-auth.js is checking a
   Clerk session (real deployments only — with no publishable key
   configured this markup is never inserted). Uses brand.css's
   btn-spin keyframe, already loaded on every page that includes
   dashboard.css. */
.auth-gate {
  position: fixed; inset: 0; z-index: 300; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px; background: var(--paper);
}
.auth-gate__spinner {
  width: 34px; height: 34px; border: 3px solid rgba(20,38,74,.15); border-top-color: var(--royal-deep);
  border-radius: 50%; animation: btn-spin .8s linear infinite;
}
.auth-gate__text { font-size: .86rem; color: var(--ink-soft); }
@media (prefers-reduced-motion: reduce) { .auth-gate__spinner { animation-duration: 1.6s; } }

/* ---------------- Profile / settings ---------------- */
.profile-header {
  display: flex; align-items: center; gap: 24px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 10px; padding: 30px 32px; margin-bottom: 24px; flex-wrap: wrap;
  box-shadow: var(--shadow-sm);
}
.profile-header__avatar {
  width: 84px; height: 84px; border-radius: 50%; background: var(--royal); color: var(--gold-bright);
  display: flex; align-items: center; justify-content: center; font-family: var(--font-display);
  font-weight: 700; font-size: 1.9rem; flex-shrink: 0; position: relative; border: 3px solid var(--gold);
}
.profile-header__avatar-edit {
  position: absolute; bottom: -4px; right: -4px; width: 30px; height: 30px; border-radius: 50%;
  background: var(--gold); color: var(--royal-deep); border: 2px solid var(--surface);
  display: flex; align-items: center; justify-content: center; font-size: .8rem; cursor: not-allowed; opacity: .8;
}
.profile-header__name { font-family: var(--font-display); font-size: 1.4rem; margin-bottom: 4px; }
.profile-header__meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: .84rem; color: var(--ink-soft); }
.profile-header__id { font-variant-numeric: tabular-nums; letter-spacing: .02em; }

.settings-group { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 28px 30px; margin-bottom: 22px; box-shadow: var(--shadow-sm); }
.settings-group__head { margin-bottom: 22px; }
.settings-group__head h2 { font-size: 1rem; margin-bottom: 4px; }
.settings-group__head p { font-size: .84rem; color: var(--ink-soft); margin: 0; }

.field-display { display: flex; flex-direction: column; gap: 6px; }
.field-display label { font-size: .72rem; letter-spacing: .07em; text-transform: uppercase; font-weight: 700; color: var(--ink-soft); }
.field-display input, .field-display select {
  font-family: var(--font-body); font-size: .92rem; padding: 11px 13px; border: 1px solid var(--line);
  border-radius: 5px; background: var(--paper); color: var(--ink); width: 100%;
}
.field-display input::placeholder { color: var(--ink-soft); opacity: .7; }
.field-display input:disabled, .field-display select:disabled { color: var(--ink-soft); cursor: not-allowed; }

.pref-row {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 16px 0; border-bottom: 1px solid var(--line);
}
.pref-row:last-child { border-bottom: none; }
.pref-row__label { font-weight: 700; font-size: .9rem; }
.pref-row__desc { font-size: .82rem; color: var(--ink-soft); margin-top: 2px; }

/* Toggle switch — generic on/off pattern, reusable anywhere a
   preference needs a binary state (notifications, 2FA, visibility). */
.toggle { position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle__track {
  position: absolute; inset: 0; background: var(--line); border-radius: 999px; cursor: pointer; transition: background .2s ease;
}
.toggle__track::before {
  content: ''; position: absolute; width: 18px; height: 18px; left: 3px; top: 3px; background: #fff;
  border-radius: 50%; transition: transform .2s ease; box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.toggle input:checked + .toggle__track { background: var(--gold); }
.toggle input:checked + .toggle__track::before { transform: translateX(20px); }
.toggle input:focus-visible + .toggle__track { outline: 2px solid var(--gold); outline-offset: 2px; }
[dir="rtl"] .toggle input:checked + .toggle__track::before { transform: translateX(-20px); }

.security-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 14px 0; }
.security-row + .security-row { border-top: 1px solid var(--line); }

@media (max-width: 640px) {
  .stepper { overflow-x: auto; padding-bottom: 6px; }
  .stepper__node { flex: 0 0 68px; min-width: 68px; }
  .stepper__line { flex: 0 0 22px; min-width: 22px; }
  .stepper__label { font-size: .66rem; }
}

@media (max-width: 760px) {
  .app-shell { flex-direction: column; }
  .app-sidebar { width: 100%; height: auto; position: static; flex-direction: row; overflow-x: auto; padding: 14px; }
  .app-sidebar__brand, .app-sidebar__foot { display: none; }
  .app-nav { display: flex; gap: 6px; }
  .app-main { padding: 24px 18px 60px; }
}

/* ---------------------------------------------------------------------
   THE DASHBOARD ON A PHONE
   ---------------------------------------------------------------------
   `.app-shell` was a flex row with a fixed 248px sidebar and no
   breakpoint below it, so at 390px the sidebar took two thirds of the
   screen and the content ran off the edge — 40px of horizontal overflow,
   with the navigation list itself rendering 1003px wide inside a 390px
   viewport.

   It went unnoticed because the route audit only measured overflow at
   1440px. Most people who open a student dashboard do so on a phone, so
   the check was auditing the least common case and reporting it as the
   whole answer. Both are measured now.

   The sidebar becomes a horizontal band that SCROLLS INSIDE ITSELF
   rather than pushing the page sideways — the same rule the transcript
   table follows on the graduate record. */
@media (max-width: 860px) {
  .app-shell { flex-direction: column; }

  .app-sidebar {
    width: 100%;
    max-width: 100%;
    min-width: 0;
    flex-shrink: 1;
    padding: 14px 0 0;
    position: sticky;
    top: 0;
    z-index: 20;
  }
  .app-sidebar__brand {
    padding: 0 16px 12px;
    margin-bottom: 12px;
  }

  /* Horizontal, scrollable, and the scroll is contained.
     `min-width: 0` matters on a flex item because the default of
     `min-width: auto` refuses to shrink below content, so a declared
     overflow can fail to engage. See the note further down on which of
     these rules is actually load-bearing — measured, and it is not a
     single one of them. */
  .app-nav {
    display: flex;
    gap: 4px;
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding: 0 12px 12px;
    /* No scrollbar gutter on a touch device, but the overflow still
       works — and on a trackpad the shadow at the edge is the cue. */
    scrollbar-width: none;
    scroll-snap-type: x proximity;
  }
  .app-nav::-webkit-scrollbar { display: none; }
  .app-nav li { margin-bottom: 0; flex: 0 0 auto; scroll-snap-align: start; }
  .app-nav a {
    white-space: nowrap;
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  /* The hover indent shifts layout in a scrolling row, which reads as a
     jitter rather than as feedback. */
  .app-nav a:hover { padding-left: 12px; }

  .app-sidebar__foot {
    flex-direction: row;
    gap: 8px;
    padding: 10px 12px;
    overflow-x: auto;
    min-width: 0;
    max-width: 100%;
    scrollbar-width: none;
  }
  .app-sidebar__foot::-webkit-scrollbar { display: none; }
  .app-sidebar__foot a { white-space: nowrap; min-height: 44px; display: flex; align-items: center; }

  .app-main { min-width: 0; }
}

/* Nothing inside the dashboard may push the page sideways. A wide table
   or a long code string scrolls in its own box — the page never does. */
.app-main table { display: block; overflow-x: auto; max-width: 100%; }

/* THE SAME ROOT CAUSE, IN A THIRD PLACE.
   Grid and flex children both default to `min-width: auto`, which
   refuses to shrink below their content — that is what produced a 412px
   panel inside a 390px viewport.

   ON WHICH RULE ACTUALLY FIXES IT, measured rather than assumed:
   removing this declaration alone does NOT reintroduce the overflow, and
   neither does removing the whole 860px breakpoint alone. Removing BOTH
   does. The fix is overdetermined — the stacked layout and the
   shrinkable children each independently prevent it.

   Recorded because the first version of this comment claimed the
   min-width rule was the fix and the earlier attempts had "changed
   nothing measurable". Isolating them showed otherwise, and a comment
   that tells a tidier story than the evidence is how the next person
   deletes the half that was doing the work. Both are kept, and neither
   is load-bearing alone. */
.app-grid > *, .app-main > *, .panel, .stat-tiles > *, .class-row, .mini-list li {
  min-width: 0;
}
/* Long unbroken strings — verification codes, digests, email addresses —
   wrap rather than setting the width of everything around them. */
.panel, .class-row, .mini-list li { overflow-wrap: anywhere; }

/* The sidebar mark is the way back to the College. It was rendered but
   inert — the crest of an institution you could look at and not reach. */
a.app-sidebar__brand { text-decoration: none; }
a.app-sidebar__brand:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 4px; }
