/* dibs.css: the one stylesheet for the prototype.
   Every token and component follows spec/system.md ("sys N" = section N).
   Order: tokens, base, shell, page header, controls, data display, overlays,
   page rules the current page code still depends on, responsive. */

/* ============ 1. Tokens ============ */

:root {
  /* type (sys 2). Source Sans 3 for all UI; Fraunces only for the wordmark. */
  --font-ui: 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mark: 'Fraunces', Georgia, serif;
  --t-wordmark: 700 22px/1 var(--font-mark);
  --t-title: 600 26px/32px var(--font-ui);
  --t-h2: 600 18px/24px var(--font-ui);
  --t-item: 600 16px/22px var(--font-ui);
  --t-body: 400 15px/22px var(--font-ui);
  --t-control: 500 14px/20px var(--font-ui);
  --t-meta: 400 14px/20px var(--font-ui);
  --t-label: 500 13px/18px var(--font-ui);
  --t-small: 500 12px/16px var(--font-ui);

  /* spacing (sys 4) */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-6: 24px; --s-8: 32px; --s-12: 48px;
  --w-list: 1140px; --w-form: 640px; --w-read: 720px;
  --sidebar: 240px;

  /* radius (sys 5): controls, panels, status pills. Nothing else. */
  --r-control: 6px; --r-panel: 8px; --r-pill: 999px;

  /* color (sys 3) */
  --bg: #f6f8fa;
  --surface: #ffffff;
  --surface-2: #eef1f4;
  --line: #e3e8ee;
  --line-strong: #d0d7de;
  --ink: #1f2328;
  --ink-2: #424a53;
  --muted: #59636e;
  --accent: #14405c;
  --accent-hover: #1b5375;
  --accent-subtle: #e7eff5;
  --on-accent: #ffffff;
  --positive: #16733a;  --positive-subtle: #e6f4ea;
  --warning: #8a5a00;   --warning-subtle: #fff4d6;
  --danger: #c2222b;    --danger-subtle: #fdecec;
  --scrim: rgba(31, 47, 66, 0.28);
  --shadow-overlay: 0 8px 24px rgba(15, 23, 32, 0.12), 0 2px 6px rgba(15, 23, 32, 0.06);
  --toast-bg: #24292f;  --toast-ink: #ffffff;  --toast-link: #9fd0f0;
  --focus: var(--accent);

  /* calendar course hues (sys 9.11): tint fill, full-hue bar, dark same-hue text */
  --hue-brand: #2f6f9a; --hue-brand-fill: #e3edf4; --hue-brand-ink: #14405c;
  --hue-teal:  #2a8c80; --hue-teal-fill:  #ddf1ed; --hue-teal-ink:  #145249;
  --hue-ochre: #b8862f; --hue-ochre-fill: #f6ecd8; --hue-ochre-ink: #5f4511;
  --hue-rose:  #b9667f; --hue-rose-fill:  #f6e3e9; --hue-rose-ink:  #6b2a3f;

  /* the fallback block tint when a block carries no course hue (blocks read --bf/--bh/--bi, sys 9.11) */
  --block: #dde8f0; --block-dis: #edf3f7;

  /* glyphs for selects and disclosures, in --muted */
  --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2359636e' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  --chevron-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2359636e' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 4l4 4-4 4'/%3E%3C/svg%3E");

  color-scheme: light;
}

/* Dark tokens, declared twice (sys 3): explicit choice, and system preference
   when no explicit light choice exists. */
:root[data-theme="dark"] {
  --bg: #0f1215;
  --surface: #161a1e;
  --surface-2: #1f2429;
  --line: #262c32;
  --line-strong: #353d44;
  --ink: #e6e9ec;
  --ink-2: #c3c9cf;
  --muted: #9ba4ad;
  --accent: #7db6db;  --accent-hover: #96c6e5;  --accent-subtle: #17303f;  --on-accent: #0b1114;
  --positive: #4ac26b; --positive-subtle: #12261a;
  --warning: #d6a03a;  --warning-subtle: #2b2111;
  --danger: #ff7b72;   --danger-subtle: #3a1715;
  --scrim: rgba(0, 0, 0, 0.5);
  --shadow-overlay: 0 8px 24px rgba(0, 0, 0, 0.5), 0 0 0 1px #262c32;
  --toast-bg: #2b3137; --toast-ink: #e6e9ec; --toast-link: #7db6db;
  --hue-brand: #7db6db; --hue-brand-fill: #17303f; --hue-brand-ink: #cfe6f5;
  --hue-teal:  #4fbfb0; --hue-teal-fill:  #11302c; --hue-teal-ink:  #c2ece5;
  --hue-ochre: #d6a54e; --hue-ochre-fill: #2e2412; --hue-ochre-ink: #f1dcb0;
  --hue-rose:  #d98ba2; --hue-rose-fill:  #331a22; --hue-rose-ink:  #f3cfd9;
  --block: #1b3a4d; --block-dis: #172b37;
  --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239ba4ad' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  --chevron-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239ba4ad' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 4l4 4-4 4'/%3E%3C/svg%3E");
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0f1215;
    --surface: #161a1e;
    --surface-2: #1f2429;
    --line: #262c32;
    --line-strong: #353d44;
    --ink: #e6e9ec;
    --ink-2: #c3c9cf;
    --muted: #9ba4ad;
    --accent: #7db6db;  --accent-hover: #96c6e5;  --accent-subtle: #17303f;  --on-accent: #0b1114;
    --positive: #4ac26b; --positive-subtle: #12261a;
    --warning: #d6a03a;  --warning-subtle: #2b2111;
    --danger: #ff7b72;   --danger-subtle: #3a1715;
    --scrim: rgba(0, 0, 0, 0.5);
    --shadow-overlay: 0 8px 24px rgba(0, 0, 0, 0.5), 0 0 0 1px #262c32;
    --toast-bg: #2b3137; --toast-ink: #e6e9ec; --toast-link: #7db6db;
    --hue-brand: #7db6db; --hue-brand-fill: #17303f; --hue-brand-ink: #cfe6f5;
    --hue-teal:  #4fbfb0; --hue-teal-fill:  #11302c; --hue-teal-ink:  #c2ece5;
    --hue-ochre: #d6a54e; --hue-ochre-fill: #2e2412; --hue-ochre-ink: #f1dcb0;
    --hue-rose:  #d98ba2; --hue-rose-fill:  #331a22; --hue-rose-ink:  #f3cfd9;
    --block: #1b3a4d; --block-dis: #172b37;
    --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239ba4ad' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    --chevron-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239ba4ad' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 4l4 4-4 4'/%3E%3C/svg%3E");
    color-scheme: dark;
  }
}

/* ============ 2. Base ============ */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: var(--t-body);
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}
button, input, :is(select, :where(.csel)), textarea { font: inherit; color: inherit; letter-spacing: 0; }
h1, h2, h3, h4, p { margin: 0 0 var(--s-3); }
h1 { font: var(--t-title); }
h2 { font: var(--t-h2); }
h3, h4 { font: var(--t-item); }
strong, b { font-weight: 600; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
small { display: block; font: var(--t-label); font-weight: 400; color: var(--muted); }
.muted { color: var(--muted); }
ul, ol { margin: 0 0 var(--s-3); padding-left: 20px; }
[hidden] { display: none !important; }

.icon {
  width: 16px; height: 16px; flex-shrink: 0; vertical-align: middle;
  fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
}

/* focus (sys 9.2): 2px accent ring at a 2px offset */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }

kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px;
  border: 1px solid var(--line); border-radius: var(--r-control);
  background: var(--surface); color: var(--muted);
  font: var(--t-small); font-family: var(--font-ui);
}

.skip {
  position: fixed; top: -80px; left: var(--s-4); z-index: 100;
  padding: var(--s-2) var(--s-3); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-overlay);
}
.skip:focus { top: var(--s-4); }

/* ============ 3. App shell (sys 7) ============ */

#sidebar {
  position: fixed; inset: 0 auto 0 0; z-index: 30;
  width: var(--sidebar);
  display: flex; flex-direction: column;
  padding: var(--s-4) var(--s-2) var(--s-3);
  background: var(--bg);
  border-right: 1px solid var(--line);
  overflow-y: auto;
}

/* wordmark: Fraunces 700 22px, alone, 16px from the top-left */
.wordmark {
  align-self: flex-start;
  padding: 0 var(--s-2);
  font: var(--t-wordmark); line-height: 28px;
  color: var(--ink);
}
.wordmark:hover { text-decoration: none; }

/* term switcher: 32px ghost select-button with one up-down glyph (V203, L39) */
.term-switch { position: relative; align-self: flex-start; max-width: 100%; margin-top: var(--s-3); }
.term-switch :is(select, :where(.csel)) {
  height: 32px; min-height: 32px;
  padding: 0 30px 0 var(--s-2);
  border: 0; background: transparent; background-image: none;
  color: var(--ink); font: var(--t-control);
  max-width: 100%;
}
.term-switch :is(select, :where(.csel)):hover { background: var(--surface-2); }
.term-switch .icon { position: absolute; right: 8px; top: 50%; margin-top: -8px; color: var(--muted); pointer-events: none; }

/* nav: 32px items, 2px apart, neutral active fill */
#nav { display: flex; flex-direction: column; gap: 2px; margin-top: var(--s-4); }
#nav a {
  display: flex; align-items: center; gap: var(--s-2);
  height: 32px; padding: 0 var(--s-2);
  border-radius: var(--r-control);
  color: var(--ink-2); font: var(--t-control);
  text-decoration: none;
}
#nav a .icon { color: var(--muted); }
#nav a:hover { background: var(--surface-2); color: var(--ink); }
#nav a.active { background: var(--surface-2); color: var(--ink); }
#nav a.active .icon, #nav a:hover .icon { color: var(--ink); }
.nav-rule { height: 1px; margin: var(--s-2); background: var(--line); }
.nav-label { padding: var(--s-4) var(--s-2) var(--s-1); font: var(--t-label); color: var(--muted); }

/* bottom: account row (40px) plus an icon-only 32px theme toggle in one grid cell. The row stops 4 short of
   the toggle (32 toggle + 4 inset + 4 gap), so its hover and active fill never run under the toggle
   (b1r1 m6; web/slack/jul-2024/0078, web/supabase/aug-2026/0012 keep the account row on its own). */
.sidebar-foot { display: grid; align-items: center; margin-top: auto; padding-top: var(--s-3); }
.sidebar-foot > * { grid-area: 1 / 1; }
.sidebar-foot > #theme { justify-self: end; margin-right: var(--s-1); }
.sidebar-foot > .account-slot { margin-right: 40px; }
.account-slot { flex: 1; min-width: 0; display: flex; }
.account-row {
  display: flex; align-items: center; justify-content: flex-start; gap: var(--s-2);
  width: 100%; height: 40px; min-height: 40px; padding: 0 var(--s-2);
  border: 0; background: transparent; color: var(--ink-2);
  text-align: left;
}
.account-row:hover { background: var(--surface-2); color: var(--ink); }
/* signed in: an Account link styled as a nav item, no name or initials (spec/page-account.md 2) */
a.account-row { border-radius: var(--r-control); font: var(--t-control); text-decoration: none; }
a.account-row .icon { color: var(--muted); }
a.account-row:hover { text-decoration: none; }
a.account-row:hover .icon, a.account-row.active .icon { color: var(--ink); }
a.account-row.active { background: var(--surface-2); color: var(--ink); }
.account-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avatar {
  display: inline-grid; place-items: center; flex-shrink: 0;
  width: 24px; height: 24px; border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--ink-2);
  font: var(--t-small); font-weight: 600;
}
.account-row .avatar { background: var(--line-strong); color: var(--ink); }
#theme { width: 32px; height: 32px; min-height: 32px; }

/* content column */
.shell { margin-left: var(--sidebar); min-height: 100vh; display: flex; flex-direction: column; }
.sample {
  display: flex; align-items: center; gap: var(--s-2);
  margin: 0; min-height: 33px; padding: 6px var(--s-8);
  border-bottom: 1px solid var(--line);
  font: var(--t-label); font-weight: 400; color: var(--muted);
}
.sample .icon { color: var(--muted); }
main { flex: 1; width: 100%; max-width: calc(var(--w-list) + 2 * var(--s-8)); padding: var(--s-8); }
main:focus { outline: none; }
.app-foot { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); padding: 0 var(--s-8) var(--s-8); font: var(--t-label); font-weight: 400; }
.app-foot a { color: var(--muted); }

/* Desktop: sidebar column plus content column. The sidebar sticks to the viewport;
   the 1px rule sits on the content column so it runs the full page height. */
@media (min-width: 1024px) {
  body { display: grid; grid-template-columns: var(--sidebar) minmax(0, 1fr); }
  #sidebar { position: sticky; top: 0; grid-column: 1; grid-row: 1; height: 100vh; height: 100dvh; border-right: 0; }
  .shell { grid-column: 2; grid-row: 1; margin-left: 0; border-left: 1px solid var(--line); }
}

/* under 768 the sidebar collapses behind a 32px icon button (sys 7, 10); 768 to 1023 is the icon rail */
.mobile-bar, .nav-scrim { display: none; }

/* ============ 4. Page header (sys 8) ============ */

.hero, .page-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  margin-bottom: var(--s-6);
}
.hero h1, .page-head h1 { margin: 0; }
.hero p, .page-sub { margin: var(--s-1) 0 0; font: var(--t-meta); color: var(--muted); max-width: var(--w-read); }
.page-actions { display: flex; align-items: center; gap: var(--s-2); flex-shrink: 0; }
.editorial-number { display: none; }
.section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin: var(--s-8) 0 var(--s-3); }
.section-head h2 { margin: 0; }

/* ============ 5. Buttons (sys 9.1) ============ */

/* Every bare <button> is the secondary md button. */
button, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 32px; padding: 5px var(--s-3);
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background: var(--surface); color: var(--ink);
  font: var(--t-control); text-align: center; text-decoration: none;
  cursor: pointer; touch-action: manipulation;
  /* colour changes on the rail spring (.smooth(duration: 0.14), spec/motion-apple-springs.md 3), sampled linear() */
  transition: background-color var(--dm-rail-ms, 206ms) var(--dm-rail-ease, linear), border-color var(--dm-rail-ms, 206ms) var(--dm-rail-ease, linear), color var(--dm-rail-ms, 206ms) var(--dm-rail-ease, linear);
}
button:where(:not(.csel)):hover, .btn:hover { background: var(--bg); text-decoration: none; } /* .csel: the select trigger keeps its chevron (select.js) */
button .icon, .btn .icon { width: 16px; height: 16px; }

.primary, .btn-primary {
  background: var(--accent); border-color: var(--accent); color: var(--on-accent);
}
.primary:hover, .btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--on-accent); }
.primary.selected { background: var(--surface-2); border-color: var(--line-strong); color: var(--ink); }

/* tertiary: no border, no fill; accent for navigation-like actions */
.text-btn, .btn-tertiary {
  border-color: transparent; background: transparent; color: var(--accent);
  padding: 5px var(--s-2); margin: 0 0 0 calc(-1 * var(--s-2)); /* text aligns with the column; neighbours keep a 16px gap */
  text-align: left;
}
.row > .text-btn:last-child { margin-right: calc(-1 * var(--s-2)); }
.text-btn:hover, .btn-tertiary:hover { background: var(--surface-2); color: var(--accent); }
.btn-quiet { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn-quiet:hover { background: var(--surface-2); color: var(--ink); }

/* danger: red label on the secondary box; solid only to confirm (sys 9.1, S251) */
.btn-danger { color: var(--danger); }
.btn-danger-solid { background: var(--danger); border-color: var(--danger); color: var(--surface); }
.btn-danger-solid:hover { background: var(--danger); filter: brightness(.94); }

.btn-lg { min-height: 36px; padding: 7px var(--s-4); }

/* icon-only: ghost 28 in rows and panels, secondary 32 in toolbars */
.icon-btn {
  width: 28px; height: 28px; min-height: 28px; padding: 0; margin: 0;
  border-color: transparent; background: transparent; color: var(--muted);
}
.icon-btn:hover { background: var(--surface-2); color: var(--ink); }
.icon-btn.in-toolbar { width: 32px; height: 32px; min-height: 32px; border-color: var(--line-strong); background: var(--surface); color: var(--ink-2); }

/* disabled by fill, never opacity (sys 3, GI2, GS2) */
button:where(:not(.csel)):disabled, .btn[aria-disabled="true"] {
  background: var(--surface-2); border-color: var(--line); color: var(--muted); cursor: not-allowed;
}
.text-btn:disabled, .icon-btn:disabled { background: transparent; border-color: transparent; }
button[aria-busy="true"] { cursor: progress; }

/* filter toggle (sys 9.4): pressed is a neutral fill with an ink-2 border */
button[aria-pressed="true"]:not(.primary) {
  background: var(--surface-2); border-color: var(--ink-2); color: var(--ink);
}

/* ============ 6. Inputs, search, selects, toggles (sys 9.2) ============ */

input:where(:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=file])),
:is(select, :where(.csel)), textarea {
  min-height: 32px; max-width: 100%;
  padding: 5px var(--s-3);
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background-color: var(--surface); color: var(--ink);
  font: var(--t-control); font-weight: 400;
}
textarea { display: block; width: 100%; padding: var(--s-2) var(--s-3); font: var(--t-body); resize: none; }
:is(select, :where(.csel)) {
  appearance: none; -webkit-appearance: none;
  padding-right: 36px;
  background-image: var(--chevron-down); background-repeat: no-repeat;
  background-position: right 12px center; background-size: 16px 16px;
  cursor: pointer;
}
::placeholder { color: var(--muted); opacity: 1; }
input:where(:not([type=checkbox], [type=radio], [type=range])):focus-visible,
:is(select, :where(.csel)):focus-visible, textarea:focus-visible { border-color: var(--accent); }
input:disabled, :is(select, :where(.csel)):disabled, textarea:disabled {
  background-color: var(--surface-2); border-color: var(--line); color: var(--muted); cursor: not-allowed;
}
/* custom select (spec/custom-select.md, owner 26 Oct 2026): select.js hides the real select and puts a button after it
   that carries the select's classes, so every rule above that names a select names .csel too. The button keeps the
   select's look (no button hover fill, no centred text); its box is as wide as the widest option, as a native select. */
/* the real select stays rendered (out of flow, transparent, clipped) rather than display:none, so test tools that
   drive a select (Playwright select_option needs a box) still reach it; it is out of the tab order and hidden from AT.
   Its padding, border and font are left alone: page code measures them to size the select (discover.js, progress.js
   and premed.js fitSelect), and the trigger takes that width from the select's inline style */
select[data-csel] {
  position: absolute !important; width: 1px !important; height: 1px !important; min-width: 0 !important; min-height: 0 !important;
  margin: 0 !important; opacity: 0 !important; pointer-events: none !important; clip-path: inset(50%) !important;
  overflow: hidden !important; flex: none !important;
}
button.csel { justify-content: flex-start; align-items: center; align-content: center; gap: 0; text-align: left; font-weight: 400; white-space: nowrap; transition: none; }
.csel-box { display: grid; grid-template-columns: minmax(0, auto); flex: 0 1 auto; min-width: 0; max-width: 100%; }
.csel-box > * { grid-area: 1 / 1; }
.csel-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.csel-sizer { height: 0; overflow: hidden; visibility: hidden; white-space: nowrap; }
/* the menu: sys 9.7 menu surface; 32 rows (44 on touch); a check marks the chosen row; one fill for hover and the
   keyboard's active row (Linear 0058, ChatGPT 0181); group labels in label type (Linear 0180) */
.csel-menu {
  position: fixed; inset: auto; z-index: 90; box-sizing: border-box;
  margin: 0; padding: var(--s-1); min-width: 0;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-panel);
  box-shadow: var(--shadow-overlay); font: var(--t-body); text-align: left;
}
.csel-opt {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 32px; padding: 0 var(--s-2); border-radius: var(--r-control);
  white-space: nowrap; cursor: pointer; user-select: none; -webkit-user-select: none;
}
.csel-opt-l { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.csel-check { flex: none; color: var(--ink); visibility: hidden; }
.csel-opt[aria-selected="true"] .csel-check { visibility: visible; }
.csel-opt.is-active { background: var(--surface-2); }
.csel-opt[aria-disabled="true"] { color: var(--muted); cursor: default; }
.csel-group + .csel-group, .csel-opt + .csel-group, .csel-group + .csel-opt { margin-top: var(--s-1); padding-top: var(--s-1); border-top: 1px solid var(--line); }
.csel-group-l { padding: 6px var(--s-2) 2px; font: var(--t-label); color: var(--muted); white-space: nowrap; cursor: default; }
@media (pointer: coarse), (max-width: 599px) {
  .csel-opt { min-height: 44px; }
  .csel-group-l { padding-top: var(--s-2); }
}
input[type=checkbox], input[type=radio] { width: 16px; height: 16px; margin: 0; accent-color: var(--accent); flex-shrink: 0; }
input[type=range] { width: 100%; accent-color: var(--accent); }

/* form labels: 14 semibold ink above the field, 6px gap (sys 2, 9.2) */
label { display: block; font: var(--t-control); font-weight: 600; color: var(--ink); }
label > :where(input:not([type=checkbox], [type=radio]), :is(select, :where(.csel)), textarea) { display: block; margin-top: 6px; }
label:has(> input[type=checkbox]), label:has(> input[type=radio]) {
  display: flex; align-items: center; gap: var(--s-2); font-weight: 400;
}
.field-help { font: var(--t-label); font-weight: 400; color: var(--muted); margin-top: 2px; }
.field-error { display: flex; align-items: center; gap: 6px; margin-top: 6px; font: var(--t-label); font-weight: 400; color: var(--danger); }
.is-invalid { border-color: var(--danger) !important; }

/* search: 16px magnifier at 12, trailing "/" chip, 36 at page level */
.searchbox {
  display: flex; align-items: center; gap: var(--s-2);
  flex: 1; min-width: 180px; max-width: 640px; height: 36px;
  padding: 0 var(--s-2) 0 var(--s-3);
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background: var(--surface); font-weight: 400; cursor: text;
}
.searchbox:focus-within { border-color: var(--accent); outline: 2px solid var(--focus); outline-offset: 2px; }
.searchbox .icon { color: var(--muted); }
.searchbox input {
  flex: 1; min-width: 0; height: 34px; min-height: 0; margin: 0; padding: 0;
  border: 0; background: transparent; font: var(--t-control); font-weight: 400;
}
.searchbox input:focus-visible { outline: none; }
.searchbox kbd { flex-shrink: 0; }

/* toggle switch: 34x20, toggle first then label (V224, CC2) */
input.switch {
  appearance: none; -webkit-appearance: none; position: relative;
  width: 34px; height: 20px; margin: 0; flex-shrink: 0;
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  background: var(--surface-2); cursor: pointer; transition: background-color var(--dm-rail-ms, 206ms) var(--dm-rail-ease, linear), border-color var(--dm-rail-ms, 206ms) var(--dm-rail-ease, linear);
}
input.switch::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px;
  border-radius: var(--r-pill); background: #fff; box-shadow: 0 1px 2px rgba(15, 23, 32, .25);
  transition: transform var(--dm-popover-ms, 368ms) var(--dm-popover-ease, linear);
}
input.switch:checked { background: var(--accent); border-color: var(--accent); }
input.switch:checked::after { transform: translateX(14px); }

/* settings rows: label + one-line description left, control right (L270, V203) */
.settings { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); }
.setting-row { position: relative; display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 64px; padding: var(--s-3) var(--s-4); }
/* the rules between rows stop at the 16px row padding (L314), on every settings page */
.setting-row + .setting-row::before, .setting-row + .setting-disc::before {
  content: ''; position: absolute; top: 0; left: var(--s-4); right: var(--s-4); height: 1px; background: var(--line);
}
/* one row action on every settings page (sys 9.1, 9.2; L272): the md secondary, at least 88 wide so the
   labels share one column (N516). The red Delete on Account is the only text action. */
.setting-row > button:not(.text-btn):not(.icon-btn), .cs-r > button, .ac-ctl > button:not(.text-btn) { flex-shrink: 0; min-width: 88px; }
.setting-row .setting-label { font: var(--t-item); font-weight: 500; }
.setting-row .setting-desc { font: var(--t-meta); color: var(--muted); }

/* ============ 7. Badges (sys 9.3) ============ */

.badge, .pill {
  display: inline-block; max-width: 100%; min-height: 22px;
  padding: 2px var(--s-2);
  border-radius: var(--r-pill);
  background: var(--surface-2); color: var(--ink-2);
  font: var(--t-label); vertical-align: middle;
}
.badge { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pill { white-space: normal; } /* wraps into a taller capsule, never a box (ruling) */
.badge-info { background: var(--accent-subtle); color: var(--accent); }
.badge-positive { background: var(--positive-subtle); color: var(--positive); }
.badge-warning { background: var(--warning-subtle); color: var(--warning); }
.badge-negative { background: var(--danger-subtle); color: var(--danger); }
.badge .dot, .pill .dot {
  display: inline-block; width: 6px; height: 6px; margin: 0 6px 1px 0;
  border-radius: var(--r-pill); background: currentColor; vertical-align: middle;
}

/* ============ 8. Tabs, segmented, filter strip (sys 9.4) ============ */

.tabs {
  display: flex; gap: var(--s-6); min-height: 40px;
  border-bottom: 1px solid var(--line);
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs > a, .tabs > button {
  position: relative; display: inline-flex; align-items: center; flex-shrink: 0;
  height: 40px; min-height: 40px; padding: 0; margin: 0;
  border: 0; border-radius: 0; background: none;
  color: var(--muted); font: var(--t-control); white-space: nowrap; text-decoration: none;
}
.tabs > a:hover, .tabs > button:hover { background: none; color: var(--ink); text-decoration: none; }
.tabs > [aria-selected="true"], .tabs > [aria-current], .tabs > .active { color: var(--ink); }
.tabs > [aria-selected="true"]::after, .tabs > [aria-current]::after, .tabs > .active::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--accent);
}

.seg {
  display: inline-flex; gap: 2px; height: 32px; padding: 2px;
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background: var(--surface);
}
/* A segment can be a link (Plan's Week, Finals and Map views): it takes the button's box, centred in the pill,
   and [aria-current="page"] is its selected state (owner walk 2 W1: the links sat uncentred with no selected look). */
.seg > button, .seg > a {
  height: 26px; min-height: 26px; padding: 0 10px;
  border: 0; border-radius: var(--r-control); background: transparent;
  color: var(--muted); font: var(--t-control);
}
.seg > a { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; white-space: nowrap; }
.seg > button:hover, .seg > a:hover { background: var(--bg); color: var(--ink); text-decoration: none; }
.seg > button[aria-pressed="true"], .seg > button[aria-checked="true"], .seg > button[aria-selected="true"], .seg > a[aria-current="page"] {
  background: var(--surface-2); border: 0; color: var(--ink); font-weight: 600;
}

/* ============ 9. Lists, rows, tables, property list (sys 9.5, 9.6) ============ */

.list { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); overflow: hidden; }
.list > * + * { border-top: 1px solid var(--line); }
.list-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  min-height: 36px; padding: 0 var(--s-4); font: var(--t-label); color: var(--muted);
}
.list-row { display: block; padding: var(--s-3) var(--s-4); color: inherit; text-decoration: none; }
a.list-row:hover, .list-row.is-link:hover { background: var(--bg); text-decoration: none; cursor: pointer; }
.list-row.selected, .list-row[aria-selected="true"], .list-row[aria-current] { background: var(--surface-2); }
.list-foot { padding: var(--s-3) 0 0; font: var(--t-label); font-weight: 400; color: var(--muted); }

/* workload icons: 5 marks, accent fill (sys 9.5). W33 (owner 4 Nov 2026 02:2x PST, "is it icons?"): five 10px round
   marks with 2px gaps instead of a 6px bar, filled count = the BruinWalk band, so the fact reads as a rating at a
   glance (refs mercury 0325, link 0014 keep the key figure in view; spec/screens/discover-row-pane-open.SCREEN.md).
   58 wide, inside the old bar's 60, so no meta line wraps where it did not before. Every .bar markup gets them. */
.bar { display: flex; align-items: center; gap: 2px; width: 58px; margin-top: 6px; }
.bar i { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--line-strong); }
.bar i.on { background: var(--accent); }
.bar i.maybe { background: color-mix(in srgb, var(--accent) 45%, transparent); }

.table-wrap { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); overflow-x: auto; }
table.table { width: 100%; border-collapse: collapse; font: var(--t-meta); color: var(--ink-2); }
.table th {
  height: 36px; padding: 0 var(--s-4); text-align: left; white-space: nowrap;
  font: var(--t-label); color: var(--muted); border-bottom: 1px solid var(--line);
}
.table td { height: 40px; padding: var(--s-2) var(--s-4); border-bottom: 1px solid var(--line); }
.table tr:last-child td { border-bottom: 0; }
.table td:first-child { color: var(--ink); font-weight: 500; }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table.dense td { height: 36px; }
.table tr.is-link { cursor: pointer; }
.table tr.is-link:hover td { background: var(--bg); }
.tabular { font-variant-numeric: tabular-nums; }

.props { display: grid; grid-template-columns: 88px minmax(0, 1fr); column-gap: var(--s-4); margin: 0; }
.props dt { padding: 7px 0; font: var(--t-label); font-weight: 400; color: var(--muted); }
.props dd {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-4);
  min-height: 32px; margin: 0; padding: 6px 0;
  font: var(--t-meta); color: var(--ink);
}
.props dd .icon { color: var(--muted); }
.fact { display: inline-flex; align-items: center; gap: 6px; }

/* ============ 10. Overlays: drawer, modal, menu, toast (sys 9.7, 9.9) ============ */

dialog { color: var(--ink); }
dialog::backdrop { background: var(--scrim); }

#drawer, dialog.drawer {
  position: fixed; inset: 0 0 0 auto; margin: 0 0 0 auto;
  width: 480px; max-width: 100%; height: 100dvh; max-height: 100dvh;
  padding: 0; border: 0; border-left: 1px solid var(--line);
  background: var(--surface); box-shadow: var(--shadow-overlay);
  overflow-y: auto; overscroll-behavior: contain;
}
#drawer > .close { position: absolute; top: 14px; right: var(--s-4); z-index: 2; }
#drawer-content { padding: var(--s-4) var(--s-6) var(--s-6); }
#drawer-content > :first-child { padding-right: 40px; }
#drawer-content > h2 { margin-bottom: var(--s-3); }
#drawer-content > * + h3 { margin-top: var(--s-6); }
.drawer-meta { margin: 0 0 var(--s-1); font: var(--t-label); color: var(--muted); }
.drawer-head {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  min-height: 56px; padding: 0 var(--s-4) 0 var(--s-6);
  border-bottom: 1px solid var(--line); background: var(--surface);
}
.drawer-head h2 { margin: 0; }
.drawer-body { padding: var(--s-4) var(--s-6); }
.drawer-foot {
  position: sticky; bottom: 0;
  display: flex; align-items: center; justify-content: flex-end; gap: var(--s-2);
  min-height: 64px; padding: 0 var(--s-6);
  border-top: 1px solid var(--line); background: var(--surface);
}
.drawer-foot .text-btn:first-child { margin-right: auto; }

dialog.modal {
  width: min(480px, calc(100vw - 32px)); margin: auto; padding: 0;
  border: 0; border-radius: var(--r-panel);
  background: var(--surface); box-shadow: var(--shadow-overlay);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-4) var(--s-4) 0 var(--s-6); }
.modal-head h2 { margin: 0; }
.modal-body { padding: var(--s-3) var(--s-6) 0; font: var(--t-body); color: var(--ink-2); }
.modal-foot { display: flex; justify-content: flex-end; gap: var(--s-2); padding: var(--s-6); }

.menu {
  min-width: 180px; padding: var(--s-1);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel);
  box-shadow: var(--shadow-overlay);
}
.menu-item {
  display: flex; align-items: center; justify-content: flex-start; gap: var(--s-2);
  width: 100%; min-height: 32px; padding: 0 var(--s-2);
  border: 0; border-radius: var(--r-control); background: transparent;
  color: var(--ink); font: var(--t-body); text-align: left;
}
.menu-item:hover, .menu-item:focus-visible { background: var(--surface-2); }
.menu-item .icon { color: var(--muted); }
.menu-sep { height: 1px; margin: var(--s-1) calc(-1 * var(--s-1)); background: var(--line); }

/* Transient surfaces: one appear and one disappear for everything that comes and goes (owner 2 Nov 2026, "I want to
   emulate apple"; spec/motion-apple-springs.md 3 and 6). The springs live in motion.js, which writes each preset's
   sampled linear() easing, its settling time and its start values to --dm-<preset>-* on the root. Menus and popovers
   go through DibsMotion.enter() and leave() in their page scripts; dialogs, the drawer and the toast take the same
   presets here, so a dialog the page opens with showModal() or show() and shuts with close() moves with no script.
   Every dialog fades and settles from 0.97 (dialog preset, .smooth(duration: 0.3)), as an iPadOS form sheet or a
   macOS alert window appears; the drawer and every sheet slide on .smooth instead (below); all leave on dismiss
   (.smooth(duration: 0.15)) or sheetOut (.smooth(duration: 0.3)), faster than they came. While a closed dialog
   finishes leaving it takes no pointer, so a press right after a close reaches the page under it. */
dialog {
  transition: opacity var(--dm-dismiss-ms) var(--dm-dismiss-ease), scale var(--dm-dismiss-ms) var(--dm-dismiss-ease),
    translate var(--dm-sheetOut-ms) var(--dm-sheetOut-ease),
    overlay var(--dm-sheetOut-ms) allow-discrete, display var(--dm-sheetOut-ms) allow-discrete;
}
dialog:not([open]) { opacity: 0; scale: var(--dm-dialog-scale, 1); pointer-events: none; }
dialog[open] {
  opacity: 1; scale: 1;
  transition: opacity var(--dm-dialog-ms) var(--dm-dialog-ease), scale var(--dm-dialog-ms) var(--dm-dialog-ease),
    translate var(--dm-sheet-ms) var(--dm-sheet-ease), overlay 0s allow-discrete, display 0s allow-discrete;
}
@starting-style { dialog[open] { opacity: 0; scale: var(--dm-dialog-scale, 1); } }
dialog::backdrop { transition: opacity var(--dm-dismiss-ms) var(--dm-dismiss-ease), overlay var(--dm-sheetOut-ms) allow-discrete, display var(--dm-sheetOut-ms) allow-discrete; }
dialog:not([open])::backdrop { opacity: 0; }
dialog[open]::backdrop { opacity: 1; transition: opacity var(--dm-dialog-ms) var(--dm-dialog-ease); }
@starting-style { dialog[open]::backdrop { opacity: 0; } }
/* the drawer, its pane and every dialog drawn as a sheet slide in from their edge on .smooth with no fade and no
   scale (iOS sheets: the sheet preset, the iOS default spring for a sheet), and slide out on sheetOut. The right edge
   from 600 up; the bottom edge under 600, where the drawer is a full screen sheet. Reduced motion: no slide, a fade. */
:is(#drawer, dialog.drawer):not([open]) { opacity: calc(1 - var(--dm-fade, 0)); scale: 1; translate: calc(100% * var(--dm-slide, 1)) 0; }
:is(#drawer, dialog.drawer)[open] { translate: 0 0; }
@starting-style { :is(#drawer, dialog.drawer)[open] { opacity: calc(1 - var(--dm-fade, 0)); scale: 1; translate: calc(100% * var(--dm-slide, 1)) 0; } }
@media (max-width: 599px) {
  :is(#drawer, dialog.drawer):not([open]) { translate: 0 calc(100% * var(--dm-slide, 1)); }
  @starting-style { :is(#drawer, dialog.drawer)[open] { translate: 0 calc(100% * var(--dm-slide, 1)); } }
}

/* toast: dark, bottom center, one line, renders only with text (sys 9.9) */
#toast, .toast {
  position: fixed; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 70;
  display: flex; align-items: center; gap: var(--s-3);
  max-width: min(420px, calc(100vw - 32px)); padding: 10px 14px;
  border-radius: var(--r-panel);
  background: var(--toast-bg); color: var(--toast-ink); box-shadow: var(--shadow-overlay);
  font: var(--t-body);
  opacity: 0; visibility: hidden; pointer-events: none;
  /* motion: spec/motion-apple-springs.md 3, toast preset (.smooth(duration: 0.35), rising 8 px, as an iOS banner
     fades up); it leaves on dismiss (.smooth(duration: 0.15)) back down to where it came from */
  transform: translate(-50%, 0); translate: 0 var(--dm-toast-y, 8px);
  transition: opacity var(--dm-dismiss-ms) var(--dm-dismiss-ease), translate var(--dm-dismiss-ms) var(--dm-dismiss-ease), visibility 0s linear var(--dm-dismiss-ms);
}
#toast.show {
  opacity: 1; visibility: visible; pointer-events: auto;
  translate: 0 0;
  transition: opacity var(--dm-toast-ms) var(--dm-toast-ease), translate var(--dm-toast-ms) var(--dm-toast-ease);
}
@starting-style { #toast.show { opacity: 0; translate: 0 var(--dm-toast-y, 8px); } }
#toast:empty { display: none; }
/* W39 round 2 M1: over a modal drawer (the phone sheet) the toast rides in the drawer as a manual popover (app.js
   liftToast), so it sits above the sheet and its Undo can be pressed; these undo the UA popover box (inset 0, auto
   margin, border, fit-content) so it keeps its own place. app.js sets its bottom clear of the sheet's footer bar. */
#toast[popover] { top: auto; width: auto; height: auto; margin: 0; border: 0; overflow: visible; }
@media (min-width: 600px) { #toast[popover] { right: auto; } }
.toast-action { margin-left: auto; padding: 0; min-height: 0; border: 0; background: none; color: var(--toast-link); font: var(--t-control); }
.toast-action:hover { background: none; text-decoration: underline; }

/* tooltip-like hint for assignment icons (owner: hint on hover, focus or tap) */
.worktypes { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-3); position: relative; }
.worktypes:empty { display: none; }
.worktypes .assignment-hint { position: static; display: inline-block; }
.worktypes .assignment-trigger {
  display: inline-flex; align-items: center; gap: var(--s-1);
  min-height: 28px; padding: 0 var(--s-1); margin: 0 calc(-1 * var(--s-1));
  border: 0; border-radius: var(--r-control); background: transparent;
  color: var(--ink-2); font: var(--t-meta); font-weight: 600; font-variant-numeric: tabular-nums;
}
.worktypes .assignment-trigger:hover { background: var(--surface-2); }
.worktypes .assignment-trigger .icon { color: var(--muted); }
.worktypes .assignment-tooltip {
  display: none; position: absolute; z-index: 20; left: 0; bottom: calc(100% + 6px);
  width: 230px; max-width: 100%; padding: var(--s-2) var(--s-3);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel);
  box-shadow: var(--shadow-overlay);
  color: var(--ink); font: var(--t-label); font-weight: 400;
}
.worktypes .assignment-hint.hint-active .assignment-tooltip { display: block; }

/* ============ 11. Containers and empty state (sys 6, 9.8) ============ */

.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel);
  padding: var(--s-6); margin-bottom: var(--s-4);
}
.panel > :last-child { margin-bottom: 0; }
.panel > h2:first-child, .panel > h3:first-child { margin-bottom: var(--s-3); }

.empty {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: var(--s-12) var(--s-6);
}
.empty-icon {
  display: grid; place-items: center; width: 48px; height: 48px; margin-bottom: var(--s-4);
  border: 1px solid var(--line); border-radius: var(--r-panel); color: var(--muted);
}
.empty-icon .icon { width: 24px; height: 24px; }
.empty h2, .empty-title { margin: 0 0 var(--s-1); font: var(--t-h2); }
.empty p { max-width: 420px; margin: 0; font: var(--t-meta); color: var(--muted); }
.empty-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2); margin-top: var(--s-4); }

/* ============ 12. Rules the current page code depends on, on tokens ============ */

.row { display: flex; justify-content: space-between; align-items: center; gap: var(--s-4); }
.stack { display: grid; gap: var(--s-3); }
.stack > button { justify-self: start; }
.divider { height: 0; border-top: 1px solid var(--line); margin: var(--s-4) 0; }
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin-bottom: var(--s-4); }
.toolbar > .text-btn { margin: 0; }
.split { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: var(--s-6); align-items: start; }
.split > * { min-width: 0; }
.eyebrow, .tiny { margin-bottom: var(--s-1); font: var(--t-label); color: var(--muted); }
.serif { font-family: inherit; }
.notice { margin: var(--s-3) 0; font: var(--t-meta); color: var(--ink-2); }
.notice.warning, .warning { color: var(--warning); }
.mobile-only { display: none; }
details > summary {
  display: flex; align-items: center; gap: var(--s-2);
  min-height: 32px; padding: 6px 0;
  font: var(--t-control); color: var(--ink-2); cursor: pointer; list-style: none;
}
details > summary::-webkit-details-marker { display: none; }
details > summary::before {
  content: ''; width: 16px; height: 16px; flex-shrink: 0;
  background: var(--chevron-right) no-repeat center / 16px; transition: transform var(--dm-popover-ms, 368ms) var(--dm-popover-ease, linear);
}
details[open] > summary::before { transform: rotate(90deg); }
details > summary:hover { color: var(--ink); }
details > p { font: var(--t-meta); }
.upload { padding: var(--s-8); border: 1px dashed var(--line-strong); border-radius: var(--r-panel); text-align: center; }
.minirow { padding: var(--s-3) 0; border-bottom: 1px solid var(--line); font: var(--t-meta); overflow-wrap: anywhere; }
.minirow:last-child { border-bottom: 0; }
.minirow strong { font-weight: 600; color: var(--ink); }

/* course cards (Discover, Watching) until the course row (sys 9.5) replaces them */
.cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); }
.course {
  display: flex; flex-direction: column; min-width: 0;
  padding: var(--s-4);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel);
}
.course .topline { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s-3); }
.course .code { flex-shrink: 0; font: var(--t-item); color: var(--ink); font-variant-numeric: tabular-nums; }
.course .topline .pill {
  min-height: 0; padding: 0; border-radius: 0; background: none;
  color: var(--muted); font: var(--t-label); text-align: right;
}
.course h3 { margin: 2px 0 var(--s-2); font: var(--t-body); color: var(--ink-2); }
.course h3 button {
  display: inline; min-height: 0; padding: 0; margin: 0;
  border: 0; background: none; color: inherit; font: inherit; text-align: left;
}
.course h3 button:hover { background: none; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.meeting { display: flex; align-items: flex-start; gap: var(--s-2); margin: 0 0 var(--s-3); font: var(--t-meta); color: var(--ink-2); }
.meeting .icon { margin-top: 2px; color: var(--muted); }
.course-stats {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s-3) var(--s-6);
  padding-top: var(--s-3); border-top: 1px solid var(--line);
  font: var(--t-meta); color: var(--ink-2);
}
.grade { font: var(--t-item); color: var(--ink); font-variant-numeric: tabular-nums; }
.work { min-width: 120px; font: var(--t-meta); color: var(--ink-2); }
.work > span { font: var(--t-meta) !important; }
.course > .worktypes { margin-top: var(--s-3); }
.course-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-top: auto; padding-top: var(--s-3); }
.seat-status { font: var(--t-meta); color: var(--ink); }
.seats-open { color: var(--positive); }

.toolbar :is(select, :where(.csel)) { min-width: 0; }

/* Ask renders in section 18. Pricing: numbers never above --t-h2 (sys 2) */
.gpa, .price, .kpi strong { display: block; font: var(--t-h2); color: var(--ink); font-variant-numeric: tabular-nums; }
.kpis { display: flex; flex-wrap: wrap; gap: var(--s-8); margin-bottom: var(--s-6); }

/* ============ 13. Responsive (sys 10) ============ */

/* b3r1 B1: keyboard focus (Tab, Shift+Tab, the skip link) scrolls to a stop below whatever is pinned at the top
   of the page: the phone bar, Discover's search and toolbar, the Clubs search. shell.js measures that stack into
   --pin-h on focus and resize, so a head that grows (applied filter chips) still clears; 8 more keeps the focus
   ring off its edge. Reference: ui-reference/library/web/linear/may-2026/0038.png (the pinned toolbar never covers
   the active row). WCAG 2.4.11. */
html[data-pinned] { scroll-padding-top: calc(var(--pin-h) + var(--s-2)); }

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

/* phones only: from 768 up the icon rail replaces this bar (spec/page-shell.md 5; css/page-shell.css) */
@media (max-width: 767px) {
  .mobile-bar {
    position: sticky; top: 0; z-index: 20;
    display: flex; align-items: center; height: 48px; padding: 0 var(--s-4);
    background: var(--bg);
  }
  #menu { width: 32px; height: 32px; min-height: 32px; margin-left: -6px; color: var(--ink-2); }
  /* the wordmark once per screen (sys 7): beside the menu button while the sidebar is closed; the open drawer
     covers it and shows its own. 44 tall as a target, 28 of type. */
  .mobile-bar .bar-mark { align-self: center; margin-left: var(--s-1); padding: 8px 4px; line-height: 28px; }
  /* the phone sidebar is a sheet from the left edge: in on .smooth, out on sheetOut (spec/motion-apple-springs.md 3) */
  #sidebar {
    visibility: hidden; transform: translateX(-100%);
    transition: transform var(--dm-sheetOut-ms, .2s) var(--dm-sheetOut-ease, linear), visibility 0s linear var(--dm-sheetOut-ms, .2s);
  }
  body.menu-open #sidebar {
    visibility: visible; transform: none; box-shadow: var(--shadow-overlay);
    transition: transform var(--dm-sheet-ms, .2s) var(--dm-sheet-ease, linear);
  }
  body.menu-open .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 25;
    width: 100%; height: 100%; min-height: 0; padding: 0;
    border: 0; border-radius: 0; background: var(--scrim);
  }
  body.menu-open { overflow: hidden; }
  .shell { margin-left: 0; min-height: calc(100vh - 48px); }
  .sample { border-top: 1px solid var(--line); }
  main { padding-top: var(--s-6); }
}

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

@media (max-width: 599px) {
  .sample, .app-foot { padding-left: var(--s-4); padding-right: var(--s-4); }
  main { padding: var(--s-4) var(--s-4) var(--s-8); }
  .hero, .page-head { flex-wrap: wrap; margin-bottom: var(--s-4); }
  .panel { padding: var(--s-4); }
  .toolbar .searchbox { flex-basis: 100%; max-width: none; }
  .toolbar :is(select, :where(.csel)) { flex: 1 1 140px; }
  .course .topline { flex-wrap: wrap; gap: 2px var(--s-3); }
  .course .topline .pill { text-align: left; flex-basis: 100%; }
  #toast { left: var(--s-4); right: var(--s-4); max-width: none; transform: none; } /* the rise is the translate above */
}

/* touch: 44px targets (sys 9.1, 10). Phones get them too, since they are touch-first. */
@media (pointer: coarse), (max-width: 599px) {
  button, .btn, .btn-lg, :is(select, :where(.csel)),
  input:where(:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=file])) { min-height: 44px; }
  .searchbox { height: 44px; }
  .searchbox input { height: 42px; }
  .icon-btn, #theme, #menu { width: 44px; height: 44px; min-height: 44px; }
  .sidebar-foot > .account-slot { margin-right: 52px; } /* 44 toggle + 4 inset + 4 gap */
  #nav a { height: 44px; }
  .term-switch :is(select, :where(.csel)) { height: 44px; min-height: 44px; }
  .account-row { min-height: 44px; height: 44px; }
  .tabs > a, .tabs > button { height: 44px; }
  .seg { height: 44px; }
  .seg > button, .seg > a { height: 38px; min-height: 38px; }
  .course h3 button, .event, .toast-action { min-height: 0; }
  .worktypes .assignment-trigger { min-width: 44px; min-height: 44px; justify-content: center; }
  details > summary { min-height: 44px; }
}
@media (pointer: coarse) {
  input, :is(select, :where(.csel)), textarea, .searchbox input { font-size: 16px; } /* no iOS zoom (sys 2) */
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  /* the transient surfaces still fade, opacity only, 150 ms linear (spec/motion-apple-springs.md 4); motion.js sets
     every start scale to 1 and --dm-slide to 0 here, so nothing scales or slides */
  dialog, dialog::backdrop, #toast {
    transition-property: opacity, overlay, display, visibility !important; transition-duration: 150ms !important;
    transition-timing-function: linear !important; transition-behavior: allow-discrete !important; transition-delay: 0s !important;
  }
}

/* ============ 14. Discover, course row, course detail, Directory (spec/page-discover.md) ============ */

/* Discover frame (spec 3). The sticky block pins search, toolbar and chips (L39); opaque, no glass (sys 6). */
.disc { padding-bottom: var(--s-4); } /* with main's 32 this is the 48 bottom padding */
.disc-sticky {
  position: sticky; top: 0; z-index: 6;
  margin: calc(-1 * var(--s-4)) calc(-1 * var(--s-8)) 0;
  padding: var(--s-4) var(--s-8) var(--s-3);
  background: var(--bg);
}
.disc-sticky.is-pinned { box-shadow: 0 1px 0 var(--line); }
/* An open Filters menu stacks above the detail pane (z 35), as sys 9.7 overlays sit above page frames. */
.disc-sticky:has(.fmenu:not([hidden])) { z-index: 40; }
/* Discover's search is the page's primary control (owner walk 2 W5: "search feels small"): 44 tall, so it reads
   above the 32px segments and pills under it, as wide as the results list, its text at body size and its
   magnifier one step up. Only here; the generic .searchbox (toolbar, Dining, Libraries, error page) keeps 36. */
.disc-search { width: 100%; max-width: none; height: 44px; }
.disc-search input { height: 42px; font: var(--t-body); }
.disc-search .icon { width: 18px; height: 18px; }
@media (pointer: coarse) { .disc-search input { font-size: 16px; } } /* keeps the no iOS zoom floor above (sys 2) */
.disc-search input:not(:placeholder-shown) ~ kbd { display: none; }
.disc-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin-top: var(--s-3); }
.disc-select { flex: none; max-width: 260px; text-overflow: ellipsis; }
#filters-btn .filters-n { margin-left: -4px; }
#filters-btn .filters-n:empty { display: none; }

/* applied menu filters (R2b, L250) */
.disc-chips { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-2); }
.disc-chips:empty { display: none; }
.fchip {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 2px 0 var(--s-2);
  border: 1px solid var(--line-strong); border-radius: var(--r-control); background: var(--surface);
  font: var(--t-label); white-space: nowrap;
}
.fchip-field { color: var(--muted); }
.fchip-value { color: var(--ink); }
.fchip-x {
  position: relative; width: 20px; height: 20px; min-height: 20px; padding: 0; margin: 0;
  border: 0; border-radius: var(--r-control); background: transparent; color: var(--muted);
}
.fchip-x:hover { background: var(--surface-2); color: var(--ink); }

/* count line (R3) and under-container line (R5) */
.disc-count { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 32px; margin-top: var(--s-1); }
.disc-count-l { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); min-width: 0; }
.disc-count-n { font: var(--t-label); color: var(--ink-2); white-space: nowrap; }
/* N3 (R20 1): a Discover count line too long for the space left of the sort control wraps onto more lines beside it
   instead of running under it and off a phone; a line that fits stays one line, as before */
#disc-count .disc-count-l { flex: 1 1 auto; }
#disc-count .disc-count-n { white-space: normal; }
.disc-count-x { display: flex; align-items: center; column-gap: var(--s-4); font: var(--t-label); font-weight: 400; white-space: nowrap; }
.disc-count-x:empty { display: none; }
.disc-count-x .text-btn, .disc-under .text-btn { min-height: 28px; padding: 5px var(--s-2); margin: 0 0 0 calc(-1 * var(--s-2)); font: var(--t-label); }
.disc-count.is-zero { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.disc-under { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); min-height: 18px; margin-top: var(--s-3); font: var(--t-label); font-weight: 400; color: var(--muted); }
.disc-under:empty { display: none; }

/* results container (R4): one hairline container, 36px header row (sys 9.5, N333 muted header) */
.clist { margin-top: var(--s-3); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); overflow: hidden; }
.clist--embed { margin-top: 0; }
.clist-head {
  display: flex; align-items: center; justify-content: space-between; height: 36px; padding: 0 var(--s-4);
  border-bottom: 1px solid var(--line); font: var(--t-label); color: var(--muted);
}
.clist-head-gpa { width: 120px; margin-right: 36px; text-align: right; }

/* the course row (spec 5): [course 1fr] 16 [grades 120] 8 [action 28]; 92 tall with one meta line */
.crow {
  position: relative; display: grid;
  grid-template-columns: minmax(0, 1fr) 16px 120px 8px 28px; grid-template-rows: 22px 22px auto;
  padding: var(--s-3) var(--s-4); background: var(--surface);
  scroll-margin-bottom: var(--s-4); /* b3r1 B1: the top clearance is html's scroll-padding-top (section 13) */
}
.crow + .crow { border-top: 1px solid var(--line); padding-top: 11px; } /* the rule is part of the 92 */
.crow:hover { background: var(--bg); }
.crow.is-selected { background: var(--surface-2); }
.crow:has(.crow-main:focus-visible) { box-shadow: inset 0 0 0 2px var(--focus); }
.crow-main { grid-column: 1; grid-row: 1 / 3; display: block; min-width: 0; color: inherit; text-decoration: none; }
.crow-main:hover { text-decoration: none; }
.crow-main:focus-visible { outline: none; }
.crow-main::after { content: ''; position: absolute; inset: 0; }
.crow-l1 { position: relative; z-index: 1; display: flex; align-items: center; gap: var(--s-2); height: 22px; min-width: 0; }
.crow-code { font: var(--t-item); color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crow-l1 .badge { flex-shrink: 0; }
.crow-title { position: relative; z-index: 1; display: block; font: var(--t-body); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crow-grades {
  grid-column: 3; grid-row: 1 / 3; position: relative; z-index: 1;
  display: grid; grid-template-rows: 22px 22px; justify-items: end; pointer-events: none;
}
.crow-grades [data-tip] { pointer-events: auto; }
.crow-gpa { font: 600 15px/22px var(--font-ui); color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Native hint buttons preserve the plain figure and definition-list geometry. */
.crow-gpa.text-btn, .cp-stat .cp-stat-tip.text-btn {
  display: inline; min-height: 0; padding: 0; margin: 0; border: 0;
  background: transparent; color: inherit; vertical-align: baseline;
}
.cp-stat .cp-stat-tip.text-btn { font: inherit; font-variant-numeric: inherit; }
.crow-gpa.text-btn { color: var(--ink); }
.crow-gpa.is-none { font: var(--t-meta); line-height: 22px; color: var(--muted); }
.crow-figs { display: flex; gap: var(--s-3); font: var(--t-meta); line-height: 22px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.crow .crow-add { grid-column: 5; grid-row: 1; align-self: center; position: relative; z-index: 1; margin: -3px 0; }
.crow .crow-add[aria-pressed="true"] { border-color: transparent; background: transparent; color: var(--ink); }
.crow .crow-add:hover { background: var(--surface-2); color: var(--ink); }
.crow-meta {
  grid-column: 1 / -1; grid-row: 3; position: relative; z-index: 1;
  display: flex; flex-wrap: wrap; column-gap: var(--s-4); min-width: 0; margin-top: var(--s-1);
  pointer-events: none;
}
.crow-meta [data-tip], .crow-meta button { pointer-events: auto; }
.crow-a, .crow-b { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); min-width: 0; max-width: 100%; }
.fact { display: inline-flex; align-items: center; gap: var(--s-2); flex-shrink: 0; height: 20px; font: var(--t-meta); color: var(--ink); white-space: nowrap; }
/* the phone copy of the A range and DFW (head of group B) keeps the grades column's --muted, not .fact's ink (spec 4 #8) */
.crow .crow-figs.fact { gap: var(--s-3); line-height: 20px; color: var(--muted); }
/* group B copy of the A range and DFW: hidden while the grades column shows them (moved from page-discover.css) */
.crow .crow-figs-b { display: none; }
/* W11 (owner walk 4, 2 Nov 2026): on the Discover lists a third, muted line under the figures says whose figures
   they are, this term's instructor ("Smith, this term") or "Course average". The grades column runs down beside
   the first meta line, so the meta keeps to the course column; on phones and narrow lists, where the figures lead
   meta group B, the line follows them there (crow-gnote-b) and the grades column keeps its one line. */
.crow-grades.has-gnote { grid-row: 1 / 4; grid-template-rows: 22px 22px auto; align-self: start; }
.crow-gnote { max-width: 100%; margin-top: var(--s-1); font: var(--t-meta); line-height: 20px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crow:has(> .crow-grades.has-gnote) .crow-meta { grid-column: 1 / 3; }
.crow .crow-gnote-b { display: none; color: var(--muted); }
/* time, lecture count and clash travel together but may wrap inside the item on narrow rows */
.fact.when { flex-wrap: wrap; flex-shrink: 1; min-width: 0; height: auto; min-height: 20px; white-space: normal; line-height: 20px; }
.fact.when > span { white-space: nowrap; }
/* In group A the time, the lecture count and the clash are whole items of their own (spec 5 overflow), so a
   wrapped clash shares its line with the instructor and seats on the 20px rhythm. Trailing margins replace the
   column gap: 8 from the time to the clash (spec 4), 16 between facts, and no indent on a wrapped line. The group
   reaches 16 into the row padding so each line's trailing margin wraps nothing a gap would not. */
.crow-a { column-gap: 0; max-width: calc(100% + var(--s-4)); margin-right: calc(-1 * var(--s-4)); }
.crow-a > * { margin-right: var(--s-4); }
.crow-a > .fact.when { display: contents; }
.crow-a > .fact.when > span { flex-shrink: 0; height: 20px; margin-right: var(--s-2); }
.crow-a > .fact.when > span:last-child { margin-right: var(--s-4); }
.crow-ge {
  display: block; flex: 0 1 auto; min-width: 0; max-width: 100%; height: 20px; min-height: 0;
  padding: 0; margin: 0; border: 0; border-radius: 0; background: none;
  font: var(--t-label); line-height: 20px; color: var(--muted); text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: default;
}
.crow-ge:hover { background: none; color: var(--ink); }
.fact.work { gap: 6px; min-width: 0; color: var(--muted); } /* min-width resets the old card .work rule */
.fact .bar { margin: 0; }
.fact.assign { gap: var(--s-3); }
.hint {
  position: relative; display: inline-flex; align-items: center; gap: var(--s-1); height: 20px; min-height: 0;
  padding: 0; margin: 0; border: 0; border-radius: 0; background: none;
  font: 600 14px/20px var(--font-ui); color: var(--muted); font-variant-numeric: tabular-nums; cursor: default;
}
.hint:hover { background: none; color: var(--ink); }
.hint .icon { color: var(--muted); }

/* loading block (STb2): spinner and one line inside the container */
.loading { display: flex; flex-direction: column; align-items: center; gap: var(--s-2); padding: var(--s-12) var(--s-6); font: var(--t-meta); color: var(--muted); }
.spinner { width: 20px; height: 20px; border: 2px solid var(--muted); border-right-color: transparent; border-radius: var(--r-pill); animation: dibs-spin .8s linear infinite; }
@keyframes dibs-spin { to { transform: rotate(360deg); } }

/* Filters menu (sys 9.7 menus, L250): opaque, 240 wide, 32px items, submenus to the side */
.fmenu-anchor { position: relative; display: inline-flex; }
.fmenu { position: absolute; top: calc(100% + 4px); left: 0; z-index: 50; }
.fmenu[hidden] { display: none; }
.fmenu-main, .fmenu-sub { width: 240px; }
.fmenu-sub { position: absolute; top: 0; left: calc(100% + 4px); }
.fmenu-sub--dept { top: 32px; }
.fmenu--flip .fmenu-sub { left: auto; right: calc(100% + 4px); }
.fmenu .menu-item { cursor: pointer; }
/* b2r2 B1: a row is always one line (L250): the label keeps its words, the muted value gives way first */
.fmenu-label { flex: 1 0 auto; white-space: nowrap; }
.fmenu-value { flex: 0 1 auto; min-width: 0; max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--t-label); font-weight: 400; color: var(--muted); }
.fmenu-row.is-open { background: var(--surface-2); }
.fmenu-stack { display: flex; flex-direction: column; padding: 6px 0; }
.fmenu-hint { font: var(--t-label); font-weight: 400; color: var(--muted); }
.fmenu-filter { padding: 0 0 var(--s-1); margin-bottom: var(--s-1); border-bottom: 1px solid var(--line); }
.fmenu-filter input { display: block; width: 100%; border-color: transparent; background: transparent; }
.fmenu-filter input:focus-visible { outline: none; border-color: transparent; }
.fmenu-list { max-height: 296px; overflow-y: auto; scrollbar-width: thin; }
.fmenu-code { flex-shrink: 0; min-width: 72px; font-weight: 600; }
.fmenu-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--t-label); font-weight: 400; color: var(--muted); }
.fmenu-none { margin: 0; padding: var(--s-2); font: var(--t-meta); color: var(--muted); }

/* tips (spec 5.1): sys 9.7 popover, opaque, max 260 */
#tip {
  position: fixed; z-index: 90; max-width: 260px; padding: 6px var(--s-2);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); box-shadow: var(--shadow-overlay);
  color: var(--ink); font: var(--t-label); white-space: pre-line; pointer-events: none;
  opacity: 0; visibility: hidden;
}
#tip.show { opacity: 1; visibility: visible; }

/* detail frame: pane at 1280+ (Discover and Directory: whenever the list keeps 360, css/page-discover.css),
   drawer below that, sheet under 600 (spec 8, S261, L116, C120) */
#drawer.is-detail { scrollbar-width: thin; }
#drawer.is-detail > .close { display: none; }
#drawer.is-detail #drawer-content { display: flex; flex-direction: column; min-height: 100%; padding: 0; }
#drawer.is-detail #drawer-content > :first-child { padding-right: 0; }
#drawer.as-pane { z-index: 35; box-shadow: none; }
@media (min-width: 1280px) { body.pane-open .shell { --dock: 480px; } }
/* W10 (owner walk 4, 2 Nov 2026, "aprubtly leaves instead of following apple animation style"): the content gives
   way to a docked pane on the pane's own curve, so the shell's margin grows on sheet as the pane slides in and
   shrinks on sheetOut as it slides out (the --dm-sheet-* and --dm-sheetOut-* vars motion.js writes, the ones the
   drawer's translate uses above). While a closed pane leaves, discover.js keeps pane-open and as-pane on (z-index,
   no shadow) and adds body.pane-leaving, which takes the margin to 0 at once so it moves with the slide.
   Reduced motion: no move; the pane fades in place and the margin follows when it has gone.
   W22 (owner, 3 Nov 2026, "the chips move and wrap continously changing as the bar moves in looks bad"): the
   shell's children lay out once, at the final width, and never per frame. --dock is the docked pane's width, set
   at once by each docking rule (this file, page-discover.css, page-events.css, the busy hours pane below);
   --dock-now is the margin the shell shows, carried on the pane's curve. Each child of the shell takes the
   difference as its own right margin (main too, which stretches instead of taking 100%), so its width is the final
   one from the first frame: opening, the content stands at its narrow width while the shell's edge follows the
   pane in; closing, it stands at its full width and runs under the pane, which covers it until the slide ends. */
@property --dock-now { syntax: '<length>'; inherits: true; initial-value: 0px; }
.shell { --dock: 0px; --dock-now: var(--dock); margin-right: var(--dock-now); }
.shell > * { margin-right: calc(var(--dock) - var(--dock-now)); }
.shell > main { width: auto; }
/* whole pixels on both sides, so the child's width is exact on every frame (fractional margins left 0.02 px of
   jitter on full-width rows); a browser without round() keeps the fractional pair above */
@supports (width: round(1.5px, 1px)) {
  .shell { margin-right: round(var(--dock-now), 1px); }
  .shell > * { margin-right: calc(var(--dock) - round(var(--dock-now), 1px)); }
}
.shell { transition: --dock-now var(--dm-sheetOut-ms) var(--dm-sheetOut-ease); }
body:is(.pane-open, .disc-pane):not(.pane-leaving) .shell { transition: --dock-now var(--dm-sheet-ms) var(--dm-sheet-ease); }
body.pane-leaving:is(.pane-open, .disc-pane) .shell { --dock: 0px; }
@media (prefers-reduced-motion: reduce) { .shell, body:is(.pane-open, .disc-pane):not(.pane-leaving) .shell { transition: none; } }
.dframe { display: flex; flex: 1; flex-direction: column; min-height: 100%; }
.dh {
  position: sticky; top: 0; z-index: 3; flex-shrink: 0;
  display: flex; align-items: center; gap: var(--s-2); height: 56px; padding: 0 var(--s-4) 0 var(--s-6);
  border-bottom: 1px solid var(--line); background: var(--surface);
}
.dh h2 { min-width: 0; margin: 0; font: var(--t-h2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dh .badge { flex-shrink: 0; }
.dh-nav { display: flex; align-items: center; flex-shrink: 0; margin-left: auto; }
.dh-count { margin-right: var(--s-2); font: var(--t-label); color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dh-nav .close { margin-left: var(--s-2); }
.db { flex: 1; padding: var(--s-6); }
.db > * + * { margin-top: var(--s-8); }
.db > .d-title:first-child { margin-top: calc(-1 * var(--s-4)); } /* b1r4 n7: 8 under the header, read as its subtitle */
.d-title { margin: 0; font: var(--t-body); color: var(--ink-2); }
.dsec h3 { margin: 0 0 var(--s-3); font: var(--t-item); color: var(--ink); }
.dsec-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-3); }
.dsec-head h3 { margin: 0; }
.dsec-note { font: var(--t-label); color: var(--muted); white-space: nowrap; }
.dtable { width: 100%; table-layout: fixed; border-collapse: collapse; font: var(--t-meta); color: var(--ink-2); }
.dtable th {
  height: 36px; padding: 0 var(--s-2); text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font: var(--t-label); color: var(--muted); border-bottom: 1px solid var(--line);
}
.dtable td { height: 36px; padding: var(--s-2); vertical-align: top; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.dtable tr > :first-child { padding-left: 0; }
.dtable tr > :last-child { padding-right: 0; }
.dtable tbody tr:last-child td { border-bottom: 0; }
.dtable .num { text-align: right; font-variant-numeric: tabular-nums; }
.dtable .w-sec { width: 64px; }
.dtable .w-when { width: 176px; }
.dtable .w-seats { width: 104px; } /* "Waitlist 3 of 10" on one line */
/* W7 (owner walk 3): the Sections table's last column is the row's pick; the instructor moved to a line under the
   time, so When takes the rest. W31 (owner 3 Nov, "the 50000 add buttons"): the pick is the row, marked by a trailing
   20 px circle in a 32 px target, never a labelled outlined button (references: class-drawer-sections.SCREEN.md);
   the held lecture and discussion fill it with the accent and a check, the footer keeps the one primary button */
.dtable .w-pick { width: 40px; }
.dtable--sections .c-pick { padding: 2px 0 2px var(--s-2); }
.dtable--sections tbody tr { cursor: pointer; }
.sec-pick, .sec-pick:where(:not(.csel)):hover { width: 32px; height: 32px; min-height: 32px; padding: 0; border: 0; border-radius: var(--r-pill); background: transparent; }
.sec-mark { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border: 1.5px solid var(--line-strong); border-radius: var(--r-pill); background: var(--surface); transition: border-color var(--dm-rail-ms, 206ms) var(--dm-rail-ease, linear), background-color var(--dm-rail-ms, 206ms) var(--dm-rail-ease, linear); }
.dtable--sections tbody tr:hover .sec-mark, .sec-pick:focus-visible .sec-mark { border-color: var(--ink-2); }
.sec-pick.is-on .sec-mark, .dtable--sections tbody tr:hover .sec-pick.is-on .sec-mark { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
.sec-pick .icon { width: 14px; height: 14px; }
/* W39a: while a plan write for the class is in flight its dots ignore clicks (plan.js guardPlan); the pointer says so */
.sec-pick[aria-busy="true"], .dtable--sections tbody tr:has(.sec-pick[aria-busy="true"]) { cursor: progress; }
.dtable--sections .is-held .c-sec { color: var(--ink); font-weight: 600; }
/* W31 2: a fact every row repeats is said once here, beside the read time; each fact keeps to one line */
.dsec--sections .dsec-note { display: flex; flex-wrap: wrap; justify-content: flex-end; column-gap: var(--s-3); row-gap: 2px; white-space: normal; text-align: right; }
.dsec--sections .dsec-note > span { white-space: nowrap; }
.dtable .w-gpa, .dtable .w-dfw { width: 56px; }
.dtable .w-a, .dtable .w-n { width: 72px; }
.dtable .is-lec .c-sec { color: var(--ink); font-weight: 500; }
.dtable .is-dis .c-sec { padding-left: var(--s-4); color: var(--ink-2); }
.dtable .c-when > span { display: block; }
.dtable .nw { white-space: nowrap; }
.dtable--sections .c-seats { padding-left: var(--s-1); white-space: nowrap; }
.dtable--sections tr > :nth-child(2) { padding-left: 0; padding-right: var(--s-1); }
.dtable .c-name { color: var(--ink); }
.dtable .is-all td { color: var(--ink); font-weight: 600; }
.d-sub { display: block; font: var(--t-label); color: var(--muted); }
.dsec--sections + .dsec--facts { margin-top: var(--s-6); padding-top: var(--s-6); border-top: 1px solid var(--line); }
.props .d-line { display: block; flex-basis: 100%; }
.d-workline { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); row-gap: var(--s-1); min-height: 32px; font: var(--t-meta); }
.d-workline .fact.work > span:last-child { color: var(--ink); }
.d-ext { display: inline-flex; align-items: center; gap: var(--s-1); }
.d-source { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--s-1); white-space: nowrap; }
.d-ext .icon { width: 12px; height: 12px; }
.nowrap { white-space: nowrap; }
.d-desc { margin: 0; font: var(--t-body); color: var(--ink-2); }
.d-cross { margin: var(--s-2) 0 0; font: var(--t-meta); color: var(--muted); }
.dframe > .df, #dfoot { position: sticky; bottom: 0; z-index: 3; flex-shrink: 0; border-top: 1px solid var(--line); background: var(--surface); }
.df { display: flex; align-items: center; gap: var(--s-2); min-height: 64px; padding: 0 var(--s-6); }
.df > .text-btn:first-child { margin-left: calc(-1 * var(--s-2)); }
.df-r { display: flex; align-items: center; gap: var(--s-2); margin-left: auto; }
.df-note { margin: 0; padding: var(--s-3) var(--s-6) 0; font: var(--t-label); color: var(--ink-2); }

/* phone filters sheet (spec 12) and busy-hours modal (spec 6) */
.sheet-body { display: grid; align-content: start; gap: var(--s-4); }
.sheet-body > * + * { margin-top: 0; }
.sheet-field :is(select, :where(.csel)) { width: 100%; }
.switch-row { min-height: 44px; gap: var(--s-3); font: var(--t-body); }
.switch-row small { margin-top: 2px; }
.modal-lede { margin: 0 0 var(--s-4); font: var(--t-meta); color: var(--muted); }

/* Directory (spec 10): S252 object page, GT underline tabs, GTb2 table */
.dir .page-head, .dept .page-head { margin-bottom: var(--s-4); }
.dir-tabs { min-height: 44px; }
.dir-tabs > a { height: 44px; min-height: 44px; }
.dir-toolbar { display: flex; margin-top: var(--s-4); }
.dir-search { flex: none; width: 320px; max-width: 100%; height: 32px; }
.dir-search input { height: 30px; }
#dir-table { margin-top: var(--s-4); }
.dir-table { container-type: inline-size; }
.dir-table .table { table-layout: fixed; }
.dir-table th.w-code { width: 120px; }
.dir-table th.w-num { width: 168px; }
.dir-table th.w-work { width: 200px; }
/* every body row stays one 40px line (spec 10); a long department ellipsizes and keeps its full name in title */
.dir-table .table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dir-table td:first-child a { color: var(--ink); }
.dir-table td:first-child a:hover { text-decoration: none; }
.dir-table td:first-child a:focus-visible { outline: none; }
.dir-table tr:has(a:focus-visible) { outline: 2px solid var(--focus); outline-offset: -2px; }
.table tr.is-selected td { background: var(--surface-2); }
.dept-meta { display: flex; flex-wrap: wrap; column-gap: var(--s-4); }

/* utilities used by the rows and detail; after .fact so they win */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.t-positive { color: var(--positive); }
.t-warning { color: var(--warning); }
.t-danger { color: var(--danger); }
.t-muted { color: var(--muted); }
.t-ink2 { color: var(--ink-2); }
.t-strong { font-weight: 600; }
.t-medium { font-weight: 500; }
.t-label { font: var(--t-label); }
.m-only { display: none; }

@media (max-width: 1023px) {
  .disc-sticky { top: 48px; }
}
@media (pointer: coarse), (max-width: 599px) {
  .disc-search kbd { display: none; }
  /* sort: transparent 6px top and bottom borders carry the 44 target around a 32 box (spec 12) */
  :is(#sort, :where(#sort + .csel)) {
    height: 44px; min-height: 44px; padding-top: 0; padding-bottom: 0;
    border-width: 6px 0; border-color: transparent; border-radius: var(--r-control) / 12px;
    background-clip: padding-box; box-shadow: inset 0 0 0 1px var(--line-strong);
  }
  :is(#sort, :where(#sort + .csel)):focus-visible { outline: none; border-color: transparent; box-shadow: inset 0 0 0 2px var(--focus); }
}
@media (pointer: coarse), (max-width: 599px) {
  .crow .crow-add { width: 28px; height: 28px; min-height: 28px; }
  .crow .crow-add::before { content: ''; position: absolute; inset: -9px; } /* from the 26 padding box: 44 */
  .hint::before { content: ''; position: absolute; inset: -12px -4px; }
  .fchip-x { min-height: 20px; width: 20px; height: 20px; }
  .fchip-x::before { content: ''; position: absolute; inset: -12px; }
  /* the GE tip: 44 tall target from padding cancelled by margins, since its ellipsis clip would cut a ::before */
  .crow-ge { height: 44px; min-height: 0; padding: 12px 0; margin: -12px 0; }
}
@media (max-width: 599px) {
  .desk-only { display: none !important; }
  span.m-only { display: inline; }
  /* only the search stays pinned: 16 + 44 + 8 */
  .disc-sticky { display: contents; }
  .disc-searchwrap { position: sticky; top: 48px; z-index: 6; margin: calc(-1 * var(--s-4)) calc(-1 * var(--s-4)) 0; padding: var(--s-4) var(--s-4) var(--s-2); background: var(--bg); }
  .disc-searchwrap.is-pinned { box-shadow: 0 1px 0 var(--line); }
  .disc-search { height: 44px; max-width: none; }
  .disc-toolbar { margin-top: var(--s-1); }
  .disc-chips { display: none; }
  /* N3 (R20 2): the other applied filters stay in the Filters sheet on phones, but a chosen Requirement area shows
     as the same removable chip as desktop, wrapping inside the column when the area name is long. W35: so does the
     Building chip, which arrives from the campus map card and is the only sign on the page that the list is narrowed */
  #disc-chips:has([data-chip-remove="req"], [data-chip-remove="geSlugs"], [data-chip-remove="building"]) { display: flex; }
  #disc-chips .fchip:not(:has([data-chip-remove="req"], [data-chip-remove="geSlugs"], [data-chip-remove="building"])) { display: none; }
  #disc-chips .fchip { height: auto; min-height: 24px; max-width: 100%; padding-top: 1px; padding-bottom: 1px; white-space: normal; }
  #disc-chips .fchip-x { flex: none; }
  .disc-count { margin-top: var(--s-3); }
  /* row at 324 inner width: code, badge, GPA, toggle; title full width; group A; group B led by A and DFW */
  .crow { grid-template-columns: minmax(0, 1fr) 8px auto 8px 28px; }
  .crow-main { grid-column: 1 / -1; }
  .crow-l1 { margin-right: 92px; }
  .crow-grades { grid-row: 1; grid-template-rows: 22px; }
  /* b2r2 m1: the A range and DFW leave the grades column and lead meta group B on every list, as Discover does
     (page-discover.md "Always visible (6 of 6)", refs/berkeleytime-catalog.png) */
  .crow-grades .crow-figs { display: none; }
  .crow .crow-figs-b { display: inline-flex; }
  /* W11: the muted line follows the figures into group B; the grades column keeps the GPA alone */
  .crow-grades.has-gnote { grid-row: 1; grid-template-rows: 22px; }
  .crow-grades .crow-gnote { display: none; }
  .crow:has(> .crow-grades.has-gnote) .crow-meta { grid-column: 1 / -1; }
  .crow .crow-gnote-b { display: inline-flex; }
  /* b1r5 m1: the meta keeps the page-discover.md row anatomy on phones: group A (time, clash, instructor, seats,
     restriction) opens line 3 and group B opens its own line led by "% A  DFW", so every fact keeps its place
     from row to row (refs/berkeleytime-catalog.png). Each group wraps whole items inside itself. The lecture count
     carries desk-only and waits in the detail; the watch history stays in group A (b6r1 m1). GE closes group B, as sys 9.5 orders
     the meta. */
  .crow-a { flex: 0 0 calc(100% + var(--s-4)); }
  .crow-b { flex: 0 0 100%; }
  /* b1r1 M1: GE no longer shrinks into an ellipsis. Phones show the short GE name (discover.js GE_SHORT) at its
     whole width; when the last line has no room for it, it opens the next line instead of being cut. */
  .crow-meta .crow-ge { order: 1; flex: 0 0 auto; min-width: 0; max-width: 100%; }
  /* b1r1 M1: the title wraps to two lines instead of clipping; line 2 of the grid grows with it */
  .crow { grid-template-rows: 22px minmax(22px, auto) auto; }
  .crow-title { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
  /* with the lecture count hidden, the time is the last visible part of its group and keeps the 16 after it */
  .crow-a > .fact.when > span:not(:has(~ span:not(.desk-only))) { margin-right: var(--s-4); }
  /* detail as a full-screen sheet; tables stack (sys 10). A full-width sheet has no left edge to rule. */
  #drawer { border-left: 0; }
  /* b14r2 m1: the course code or requirement name is the only identifier on the sheet, so on phones it wraps to two
     lines at its spaces instead of being cut mid-word (the .ev-detail .dh pattern in page-events.css; apple-maps 0093) */
  .dh { height: auto; min-height: 56px; padding: var(--s-1) var(--s-2) var(--s-1) var(--s-4); }
  .dh h2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; white-space: normal; }
  .db { padding: var(--s-4); }
  .df { padding: 0 var(--s-4); }
  .df-note { padding: var(--s-3) var(--s-4) 0; }
  .dframe > .df, #dfoot { padding-bottom: env(safe-area-inset-bottom, 0px); }
  .dtable, .dtable tbody { display: block; }
  .dtable thead, .dtable colgroup { display: none; }
  .dtable td { display: block; height: auto; padding: 0; border: 0; }
  .dtable tr { border-bottom: 1px solid var(--line); padding: var(--s-2) 0; }
  .dtable tbody tr:last-child { border-bottom: 0; }
  /* a fixed 64 label column, as on desktop, so every row's time starts at one x; the Dis indent sits inside it.
     Line 2 (seats, then instructor 16 later) starts under the time, a label column like LP2. */
  /* W7: the pick sits at the right edge beside the time and clash lines; the When cell's lines join the row's grid, so
     the instructor keeps its place on the seats line, which runs under the pick to the row's edge */
  .dtable--sections tr { display: grid; grid-template-columns: 64px auto minmax(0, 1fr) auto; column-gap: 0; }
  .dtable--sections .is-dis .c-sec { padding-left: var(--s-4); }
  .dtable--sections .c-sec { grid-column: 1; grid-row: 1; }
  .dtable--sections .c-when { display: contents; color: var(--ink); }
  .dtable--sections .c-when > span { grid-column: 2 / 4; grid-row: 1; }
  .dtable--sections .c-when > .d-clash { grid-row: 2; }
  .dtable--sections .c-seats { grid-column: 2; grid-row: 3; padding: 0; text-align: left; }
  .dtable--sections .c-when > .d-instr { grid-column: 3 / 5; grid-row: 3; padding-left: var(--s-4); color: var(--muted); }
  .dtable--sections .c-pick { grid-column: 4; grid-row: 1 / span 2; align-self: start; margin-top: -6px; padding: 0 0 0 var(--s-3); }
  /* W31: the phone pick is the same trailing circle in a 32 target; with no Seats cell the instructor line starts under the time */
  .sec-pick { width: 32px; }
  .dtable--sections.no-seats .c-when > .d-instr { grid-column: 2 / 5; padding-left: 0; }
  .dtable--grades tr { display: flex; flex-wrap: wrap; column-gap: var(--s-4); }
  .dtable--grades .c-name { flex-basis: 100%; }
  .dtable--grades .num { text-align: left; }
  .dir-search { width: 100%; height: 44px; }
  .dir-search input { height: 42px; }
}

/* Directory tables follow their own width, so the pane can narrow them (spec 10, 12) */
@container (max-width: 759px) {
  .dir-table th.w-num { width: 120px; }
  .dir-table th.w-code { width: 96px; }
  .dir-table th.w-name { width: 160px; } /* names are short; the department column gets the room */
  .dir-table .table .c-work { display: none; }
}
@container (max-width: 559px) {
  .dir-table .table, .dir-table tbody { display: block; }
  .dir-table thead { display: none; }
  .dir-table tr { display: flex; flex-wrap: wrap; align-content: center; column-gap: var(--s-4); min-height: 64px; padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); }
  .dir-table tbody tr:last-child { border-bottom: 0; }
  .dir-table tr.is-link:hover, .dir-table tr.is-selected { background: var(--bg); }
  .dir-table tr.is-selected { background: var(--surface-2); }
  .dir-table .table td { display: block; height: auto; padding: 0; border: 0; color: var(--muted); background: none; overflow: visible; white-space: normal; }
  .dir-table .table td:first-child { flex-basis: 100%; color: var(--ink); }
  .dir-table .num { text-align: left; }
  .dir-table .table td.desk-cell, .dir-table .table .c-work { display: none; }
  .dir-table span.m-only { display: inline; }
}

/* ============ 15. Plan, Busy hours, Calendar export, Share (spec/page-plan.md) ============ */

/* frame (page-plan 3.1): A title and Share, B facts and actions, C grid, D classes */
.plan { padding-bottom: var(--s-4); }
.plan-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 32px; }
.plan-head h1 { margin: 0; font: var(--t-title); color: var(--ink); } /* C120 period title: term 600, year 400 */
.plan-yr { font-weight: 400; }
.share-anchor { position: relative; flex-shrink: 0; }
/* open: the pressed secondary, as Busy hours shows while its pane is open (N214, N215; sys 9.4) */
.share-btn[aria-expanded="true"], .share-btn[aria-expanded="true"]:hover { background: var(--surface-2); border-color: var(--ink-2); color: var(--ink); }
.share-scrim { display: none; }
.share-pop:focus-visible, .ex-modal:focus-visible { outline: none; } /* opening focuses the overlay itself */

/* row B: facts 16 apart, no separators (L116); Busy hours then Export at the right end (S252) */
.plan-bar { display: flex; align-items: flex-start; gap: var(--s-2) var(--s-4); margin-top: var(--s-4); }
.plan-bar.is-empty { justify-content: flex-end; }
.plan-facts { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); row-gap: var(--s-1); flex: 1; min-width: 0; padding: 6px 0; font: var(--t-meta); color: var(--ink); }
.pf { display: inline-flex; align-items: center; min-height: 20px; white-space: nowrap; }
.pf-work { gap: var(--s-3); }
.pf-tip { height: 20px; min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 0; background: none; font: var(--t-meta); color: var(--ink-2); cursor: default; }
.pf-tip:hover { background: none; color: var(--ink); }
.pf-ge { color: var(--ink-2); white-space: normal; }
.plan-actions { display: flex; gap: var(--s-2); flex-shrink: 0; margin-left: auto; }

/* C: the grid (page-plan 3.2; C120 anatomy). overflow: clip, so the day header sticks to the viewport. */
.wk {
  --gut: 44px; --pitch: 48px;
  position: relative; margin-top: var(--s-4);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel);
  overflow: clip;
}
.wk-head, .wk-lane, .wk-body { display: grid; grid-template-columns: var(--gut) repeat(5, minmax(0, 1fr)); }
.wk-head { position: sticky; top: 0; z-index: 7; height: 32px; border-bottom: 1px solid var(--line); background: var(--surface); }
.wk-dh { display: flex; align-items: center; justify-content: center; font: var(--t-label); color: var(--ink-2); }
.wk-lane { grid-auto-rows: 24px; border-bottom: 1px solid var(--line); }
.wk-lane-label { grid-column: 1; padding: 4px var(--s-2) 0 0; font: var(--t-small); color: var(--muted); text-align: right; }
.wk-body { position: relative; height: calc(8px + var(--rows) * var(--pitch)); }
.wk-gutter { position: relative; }
.wk-hl { position: absolute; right: var(--s-2); transform: translateY(-50%); font: var(--t-small); color: var(--muted); white-space: nowrap; }
/* day dividers in --line, hour lines lighter in --surface-2, no half-hour lines (C120) */
.wk-col {
  position: relative; min-width: 0; border-left: 1px solid var(--line);
  background-image: linear-gradient(to bottom, var(--surface-2) 0 1px, transparent 1px);
  background-size: 100% var(--pitch); background-position: 0 8px;
}

/* blocks (sys 9.11): the course-hue tint, a 3px bar in the full hue and the code in its dark shade, 2px inset,
   no border, no shadow at rest. The hue comes from the course's color (--bh, --bf, --bi set on the block by
   plan.js and ask.js), the same map the class chat tiles use, so a course reads as one color everywhere. */
.wk-block, .wk-chip {
  position: absolute; z-index: 2;
  display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 0;
  min-height: 0; padding: 2px 6px 2px 9px; margin: 0;
  border: 0; border-radius: var(--r-control);
  background: var(--bf, var(--block)); color: var(--ink-2);
  text-align: left; overflow: hidden; cursor: pointer; transition: none;
}
.wk-block:hover, .wk-chip:hover { background: var(--bf, var(--block)); } /* C120 has no hover fill */
.wk-block::before, .wk-chip::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--bh, var(--accent)); }
.wk-code { display: block; min-width: 0; font: 600 13px/16px var(--font-ui); color: var(--bi, var(--accent)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.wk-time { display: block; min-width: 0; font: var(--t-small); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.wk-block.is-short .wk-time { display: none; }
.wk-dis, .wk-dis:hover { background: color-mix(in srgb, var(--bf, var(--block)) 50%, var(--surface)); } /* the same hue, lighter (owner, 10 Oct) */
.wk-dis::before { opacity: .5; }
/* async lane chip, spanning Mon to Fri (NC multi-day chips) */
.wk-chip { position: relative; grid-column: 2 / -1; flex-direction: row; align-items: center; gap: var(--s-2); height: 20px; margin: 2px; }
.wk-chip .wk-code { flex-shrink: 0; }
.wk-chip-title { min-width: 0; font: var(--t-small); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* busy time: 45 degree hatch rising to the right, period about 9 (C110) */
/* b1r4 n4: one hatch token for Plan and Calendar (moved from page-plan.css) */
:root { --busy-stripe: var(--line); }
:root[data-theme="dark"] { --busy-stripe: var(--surface-2); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --busy-stripe: var(--surface-2); } }
.wk-busy, .wk-busy:hover { z-index: 1; padding: 2px 6px; background: repeating-linear-gradient(135deg, var(--busy-stripe) 0 3px, var(--bg) 3px 6px); }
.wk-busy::before { display: none; }
.wk-busy .wk-code { color: var(--ink-2); }
.wk-busy .wk-time { color: var(--muted); }
/* clash: a 2px danger ring and the word, so colour is not the only signal (system 1.6) */
.wk-block.is-clash { box-shadow: inset 0 0 0 2px var(--danger); }
.wk-clash { color: var(--danger); font-weight: 600; }
/* selected: the class open in the detail turns solid and lifts (C120) */
/* selected: solid in the course's dark shade (--bi; dibs blue for the brand hue) with --surface text, above
   7:1 in both themes */
.wk-block.is-selected, .wk-block.is-selected:hover, .wk-chip.is-selected, .wk-chip.is-selected:hover { z-index: 3; background: var(--bi, var(--accent)); box-shadow: var(--shadow-overlay); }
.wk-block.is-selected.is-clash { box-shadow: inset 0 0 0 2px var(--danger), var(--shadow-overlay); }
.is-selected .wk-code, .is-selected .wk-time, .is-selected .wk-clash, .is-selected .wk-chip-title { color: var(--surface); }
.wk-block:focus-visible, .wk-chip:focus-visible { z-index: 5; }
/* the class-card landing: a newly added class drops in lifted, then settles (system 9.11), on the sheet spring
   (.smooth, sampled linear(); spec/motion-apple-springs.md 3) in one segment, so the curve is the spring's own */
@keyframes wk-land {
  0% { opacity: 0; transform: translateY(-14px) scale(1.04); box-shadow: var(--shadow-overlay); }
  100% { opacity: 1; transform: none; }
}
.wk-block.is-landing, .wk-chip.is-landing { z-index: 6; animation: wk-land var(--dm-sheet-ms, .55s) var(--dm-sheet-ease, linear) both; }
.adl-row.is-landing { z-index: 1; animation: wk-land var(--dm-sheet-ms, .55s) var(--dm-sheet-ease, linear) both; } /* the phone day list lands the same way */
/* painting busy time (page-plan 9.2): explicit mode, preview lifted */
.wk.is-painting .wk-col { cursor: crosshair; }
body.is-dragging { user-select: none; -webkit-user-select: none; cursor: crosshair; }
.wk-busy.is-preview { z-index: 6; box-shadow: var(--shadow-overlay); pointer-events: none; cursor: crosshair; }
/* hint chip (C110: bottom center of the grid, over time, never over data). The zero-height sticky dock at
   the grid's end keeps it 16 above the viewport bottom or the grid bottom, whichever is higher; the grid's
   clip keeps it off the class list. */
.wk-hint { position: sticky; bottom: 0; z-index: 8; height: 0; pointer-events: none; }
.paint-hint {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%);
  padding: 10px 14px; border-radius: var(--r-panel); background: var(--toast-bg); color: var(--toast-ink);
  box-shadow: var(--shadow-overlay); font: var(--t-body); white-space: nowrap; pointer-events: none;
}
body:has(#toast.show) .paint-hint { visibility: hidden; }
@media (pointer: coarse) { .paint-hint { display: none; } }

.plan-unplaced { margin: var(--s-2) 0 0; font: var(--t-meta); color: var(--muted); }

/* D: classes, the shared course row (page-discover 5) with the plan differences (page-plan 7) */
.plan-classes { margin-top: var(--s-8); }
.plan-sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); }
.plan-sec-head h2 { margin: 0; font: var(--t-h2); }
.plan-read { font: var(--t-label); font-weight: 400; color: var(--muted); white-space: nowrap; }
.crow-sec { flex-shrink: 0; font: var(--t-meta); color: var(--muted); white-space: nowrap; }
.plan-list > .idea-row, .plan-list > .add-row { border-top: 1px solid var(--line); }
.plan-list > :first-child { border-top: 0; }
.idea-row { display: grid; grid-template-columns: minmax(0, 1fr) 28px; column-gap: var(--s-2); align-items: start; padding: var(--s-3) var(--s-4); }
.idea-main { display: flex; flex-direction: column; min-width: 0; }
.idea-text { font: 500 16px/22px var(--font-ui); color: var(--ink); overflow-wrap: anywhere; }
.idea-sub { font: var(--t-meta); color: var(--muted); }
.idea-row .icon-btn { position: relative; margin: -3px 0; }
/* add row (N333 "+ New page") */
.add-row { display: flex; align-items: center; gap: var(--s-3); height: 40px; padding: 0 var(--s-4); }
.add-btn { gap: 6px; height: 28px; min-height: 28px; padding: 0 6px; margin: 0; border: 0; background: transparent; color: var(--muted); font: var(--t-control); }
.add-btn:first-child { margin-left: -6px; }
.add-btn:hover { background: var(--bg); color: var(--ink); }
.add-btn .icon { color: var(--muted); }
.add-btn:hover .icon { color: var(--ink); }
/* row menu (system 9.7; L250) */
.rmenu { position: fixed; z-index: 80; min-width: 200px; }
.menu-item.is-danger, .menu-item.is-danger .icon { color: var(--danger); }
/* detail pane Plan block (page-plan 9.1) */
.plan-dis { width: auto; max-width: 100%; }

/* Busy hours pane (page-plan 9.2): docked 320 from 1024, no scrim; a full-screen sheet below */
#hours-pane {
  position: fixed; inset: 0 0 0 auto; z-index: 35;
  width: 320px; max-width: 100%; height: 100dvh; max-height: 100dvh; margin: 0 0 0 auto; padding: 0;
  border: 0; border-left: 1px solid var(--line); background: var(--surface); color: var(--ink);
  overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
}
#hours-pane:modal { width: 100%; border-left: 0; }
@media (min-width: 1024px) { body.hours-open .shell { --dock: 320px; } }
.hp-head {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-2);
  height: 56px; padding: 0 var(--s-4) 0 var(--s-6); border-bottom: 1px solid var(--line); background: var(--surface);
}
.hp-head h2 { margin: 0; font: var(--t-h2); }
.hp-body { padding: var(--s-4) var(--s-6); overflow-x: clip; }
.hgroup { padding: var(--s-3) 0; }
.hgroup:first-child { padding-top: 0; }
.hgroup + .hgroup { border-top: 1px solid var(--line); }
.hg-l1, .hg-l2 { display: flex; align-items: center; gap: var(--s-2); }
.hg-name { flex: 1; min-width: 0; }
/* 272 inside the pane holds two time fields, "to" and "1h 30m"; a longer duration wraps, never overflows */
.hg-l2 { flex-wrap: wrap; gap: var(--s-1) 6px; margin-top: var(--s-2); }
.hg-l2 :is(select, :where(.csel)) { flex: none; width: auto; height: 32px; min-height: 32px; font-variant-numeric: tabular-nums; }
@media (pointer: coarse), (max-width: 599px) { .hg-l2 :is(select, :where(.csel)) { min-height: 44px; } } /* 44 targets, as the time inputs had */
.hg-to, .hg-dur { font: var(--t-meta); color: var(--muted); white-space: nowrap; }
.hg-dur { margin-left: 2px; }
.hg-days { display: flex; gap: var(--s-1); margin-top: var(--s-2); }
.hg-day { width: 32px; height: 32px; min-height: 32px; padding: 0; }
.hg-error { margin-top: var(--s-2); }
.hg-error .icon { width: 14px; height: 14px; }
.hp-add { display: flex; align-items: center; min-height: 40px; border-top: 1px solid var(--line); }

/* Calendar export (page-plan 9.3; N245 rows: muted label left, value right) */
#export-modal, #plan-confirm { width: min(440px, calc(100vw - 32px)); }
.ex-rows { margin: 0; }
.ex-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-4); min-height: 32px; padding: 6px 0; }
.ex-row dt, .ex-row dt label { font: var(--t-label); font-weight: 400; color: var(--muted); }
.ex-row dd { margin: 0; max-width: 280px; font: var(--t-meta); color: var(--ink); text-align: right; }
.ex-row--toggle { align-items: center; }
.ex-none { margin: var(--s-2) 0 0; font: var(--t-meta); color: var(--muted); }
.ex-modal .modal-foot { padding-top: var(--s-2); } /* N245: about 43 from the last row to the footer buttons */
.pc-text { margin: 0; font: var(--t-body); color: var(--ink-2); }

/* Share popover (page-plan 9.4; N205, N214, N215): under Share, right edges aligned, opaque */
.share-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 40;
  width: 432px; max-width: calc(100vw - 32px); padding: var(--s-3) var(--s-4);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); box-shadow: var(--shadow-overlay);
}
.sp-link { display: block; width: 100%; min-height: 32px; height: 32px; margin: 0 0 2px; text-overflow: ellipsis; }
.sp-row { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 34px; font: var(--t-meta); color: var(--ink); }
.sp-k, label.sp-k { font: var(--t-meta); color: var(--ink); }
.sp-note { margin: var(--s-1) 0 0; font: var(--t-meta); color: var(--muted); }
.sp-more { margin: var(--s-2) 0 0; font: var(--t-meta); color: var(--muted); }
.sp-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); margin: var(--s-3) calc(-1 * var(--s-4)) 0; padding: var(--s-3) var(--s-4) 0; border-top: 1px solid var(--line); }
.sp-r { display: flex; gap: var(--s-2); }
.sp-what { gap: 6px; padding: 5px var(--s-2); margin-left: calc(-1 * var(--s-2)); }
.sp-what .icon { color: var(--muted); }

@media (max-width: 1023px) {
  .wk-head { top: 48px; } /* below the phone top row */
}
@media (pointer: coarse), (max-width: 599px) {
  .wk-block, .wk-chip { min-height: 0; }
  .hg-day { width: 44px; height: 44px; min-height: 44px; }
  /* 44 targets through a pseudo-element, visual sizes kept (sys 9.1, 10; page-plan 12). A ::before is
     placed from the padding box, so a 32 button with its 1px border needs 7 and a 28 ghost needs 9. */
  .plan-head .share-btn, .plan-actions > button, .sp-foot button, .ex-modal .modal-foot button, #plan-confirm .modal-foot button,
  .add-btn { position: relative; min-height: 32px; }
  .plan-head .share-btn::before, .plan-actions > button::before, .sp-foot button::before, .ex-modal .modal-foot button::before, #plan-confirm .modal-foot button::before { content: ''; position: absolute; inset: -7px 0; }
  .add-btn { height: 28px; min-height: 28px; }
  .add-btn::before { content: ''; position: absolute; inset: -9px 0; }
  .add-row { height: 44px; }
  .idea-row .icon-btn, .ex-modal .modal-head .icon-btn, #plan-confirm .modal-head .icon-btn { position: relative; width: 28px; height: 28px; min-height: 28px; }
  .idea-row .icon-btn::before, .ex-modal .modal-head .icon-btn::before, #plan-confirm .modal-head .icon-btn::before { content: ''; position: absolute; inset: -9px; }
  /* chrome-less tip buttons on 20px lines (summary seat risk; row GE): a 44 tall target */
  .pf-tip { position: relative; min-height: 0; }
  .pf-tip::before { content: ''; position: absolute; inset: -12px 0; }
}
@media (max-width: 599px) {
  /* row A: Share keeps its label like Busy hours and Export (b2r5 n1; S252 labelled header actions) */
  /* row B: facts, then Busy hours and Export on their own line, labels kept */
  .plan-bar { flex-direction: column; align-items: stretch; gap: var(--s-2); }
  .plan-bar.is-empty { align-items: flex-start; }
  .plan-actions { margin-left: 0; }
  /* compact 5-day grid (page-plan 12): code only, subject over number */
  .wk { --gut: 36px; }
  .wk-block { padding: 2px 4px 2px 7px; }
  .wk-busy { padding: 2px 4px; }
  .wk-block .wk-code { white-space: normal; }
  .wk-subj, .wk-no { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .wk-block .wk-time, .wk-sec { display: none; }
  .wk-block.is-clash:not(.is-short) .wk-time { display: block; }
  .wk-block.is-clash.is-mid .wk-no { display: none; }
  .wk-busy .wk-code { white-space: nowrap; }
  .wk-busy.is-short .wk-code { display: none; }
  .plan-sec-head { flex-wrap: wrap; column-gap: var(--s-4); row-gap: 0; }
  /* class rows: the shared phone meta run (section 14) */
  /* detail sheet: the Discussion select takes the full width under its label, so its seat status shows */
  .dsec-plan .pd-dis-k { grid-column: 1 / -1; padding-bottom: 0; }
  .dsec-plan .pd-dis-v { grid-column: 1 / -1; padding-top: 6px; }
  .dsec-plan .plan-dis { width: 100%; text-overflow: ellipsis; }
  /* overlays become centered modals with a scrim */
  .share-scrim { display: block; position: fixed; inset: 0; z-index: 39; background: var(--scrim); }
  .share-pop { position: fixed; top: 50%; left: 16px; right: 16px; width: auto; max-width: 432px; margin: 0 auto; transform: translateY(-50%); }
  .hp-head { padding: 0 var(--s-2) 0 var(--s-4); }
  .hp-body { padding: var(--s-4); }
}
@media (max-width: 599px) {
  .wk-hl { right: 5px; }
  .wk-lane-label { padding-right: 4px; }
}
/* b14r2 m1: under 360 a pager count gives its width to the title; the arrows still page.
   b14r3 m1: pager counts only; a wizard step label (followed by Close, no arrows) stays visible */
@media (max-width: 359px) { .dh-count:has(+ .icon-btn:not(.close)) { display: none; } }
@media (max-width: 359px) {
  .wk { --gut: 34px; }
  .wk-hl { right: 4px; }
  .crow-sec { display: none; } /* at 320 the code and the Impacted badge keep line 1; the detail names the section */
}

/* ============ 16. Progress and Course records (spec/page-progress.md) ============ */

/* R1 (2.1; V390): title left; the read date, then Replace audit and Course records on its center line */
.prog-head, .rec-head { min-height: 32px; }
.prog-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--s-2) var(--s-4); }
.prog-read { font: var(--t-meta); color: var(--muted); white-space: nowrap; }
.prog-btns { display: flex; gap: var(--s-2); }

/* R2 (2.2): two 240px meters 40px apart, no box (M108 strip); value then muted denominator over a 6px bar (V390) */
.pstrip { display: flex; gap: 40px; }
.pcell { display: flex; flex-direction: column; width: 240px; min-width: 0; }
.pcell-label { font: var(--t-label); color: var(--muted); }
.pcell-value { display: flex; align-items: baseline; gap: var(--s-1); height: 24px; margin-top: var(--s-1); }
.pv { font: var(--t-h2); color: var(--ink); font-variant-numeric: tabular-nums; }
.pv-of { font: var(--t-meta); color: var(--muted); font-variant-numeric: tabular-nums; }
.pmeter { display: flex; height: 6px; margin-top: var(--s-3); border-radius: var(--r-control); background: var(--line-strong); overflow: hidden; }
.pm-done { background: var(--accent); }
.pm-ip { background: color-mix(in srgb, var(--accent) 45%, var(--bg)); } /* the workload bar's uncertain part (sys 9.5) */

/* R3 (2.4): Fits my schedule at the left, sort at the right (sys 8, 9.4) */
.ptoolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin-top: var(--s-6); } /* at 320 the sort wraps rather than truncating */
#pfit { flex-shrink: 0; white-space: nowrap; }
.psort { position: relative; display: inline-flex; flex: 0 1 auto; min-width: 0; margin-left: auto; }
.psort > .icon { position: absolute; left: 12px; top: 50%; margin-top: -8px; color: var(--muted); pointer-events: none; }
.psort :is(select, :where(.csel)) { min-width: 0; max-width: min(260px, 100%); padding-left: 36px; text-overflow: ellipsis; }

/* R4 (2.3): one container; groups as bands one fill step darker (L55); rows split by 1px rules (sys 9.5) */
.plist { margin-top: var(--s-6); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); overflow: hidden; }
.ptoolbar + .plist { margin-top: var(--s-4); }
.prog-head + .plist { margin-top: 0; }
.pgroup + .pgroup, .pgroup > * + *, .popts > * + *, .pmet > * + * { border-top: 1px solid var(--line); }
.pband { display: flex; align-items: center; gap: var(--s-2); height: 36px; padding: 0 var(--s-4); background: var(--bg); }
.pglyph, .pchev { width: 16px; height: 16px; flex-shrink: 0; color: var(--muted); }
.pchev { transition: transform var(--dm-popover-ms, 368ms) var(--dm-popover-ease, linear); }
[aria-expanded="true"] > .pchev { transform: rotate(90deg); }
.pband-label { font: var(--t-control); color: var(--ink); }
.pband-n { font: var(--t-meta); color: var(--muted); font-variant-numeric: tabular-nums; }
.pinfo { position: relative; margin-left: calc(-1 * var(--s-1)); } /* 4px after the count (V372) */
.pinfo .icon { width: 14px; height: 14px; }
button.pband { width: 100%; min-height: 36px; justify-content: flex-start; border: 0; border-radius: 0; background: var(--bg); color: var(--ink); text-align: left; }
/* Met's caret sits in the band's 16px gutter (L55: caret left of the glyph), so all four glyphs and labels share one edge */
.pband--toggle .pchev { order: 1; margin: 0 0 0 auto; } /* b1r4 n3: trailing caret; glyphs stay in one column (L38) */
/* the option rows' GPA column head, its right edge on the GPA's (Discover's list head; V361, M108) */
.pband-col { margin-left: auto; margin-right: 36px; font: var(--t-label); color: var(--muted); white-space: nowrap; } /* clears the 8 + 28 trailing slot, as .clist-head-gpa does */
button.pband:hover { background: var(--surface-2); }
button.pband:focus-visible { outline-offset: -2px; }

/* requirement rows: name, owed 12px after; plan coverage, badge and "..." at the right end (L116, L55) */
.preq { display: flex; align-items: center; gap: var(--s-4); min-height: 44px; padding: 11px var(--s-4); }
.preq-text { flex: 1; min-width: 0; font: var(--t-item); } /* one 22px line box for the name and the owed amount */
.preq-name { font: var(--t-item); color: var(--ink); overflow-wrap: anywhere; }
.preq-owed { margin-left: var(--s-3); font: var(--t-meta); line-height: 16px; color: var(--muted); white-space: nowrap; }
.preq-note { display: block; margin-top: 2px; font: var(--t-meta); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.preq-end { display: flex; align-items: center; gap: var(--s-4); flex-shrink: 0; }
.preq-end:empty { display: none; }
.preq-plan, .preq-ip { font: var(--t-meta); color: var(--ink-2); white-space: nowrap; }
.preq .preq-more { position: relative; flex-shrink: 0; margin: -3px 0; }
.preq.is-collapsible { cursor: pointer; }
.preq.is-collapsible:hover { background: var(--bg); }
.preq-toggle { display: inline-flex; align-items: center; gap: var(--s-2); min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 0; background: none; text-align: left; vertical-align: top; }
.preq-toggle:hover { background: none; }
.preq--ct { align-items: flex-start; padding: var(--s-3) var(--s-4); }
.preq--ct .preq-name { display: block; }
.preq-line { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; margin-top: 2px; font: var(--t-meta); color: var(--ink-2); }
.preq--ct .preq-more { margin-top: -3px; }
.badge-btn { height: 22px; min-height: 22px; padding: 2px var(--s-2); border: 0; border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink-2); font: var(--t-label); cursor: default; }
.badge-btn:hover { background: var(--surface-2); color: var(--ink); }

/* option rows: the shared course row, indented 32 so the code starts under the name plus 32 (L116). Its
   columns are Discover's, so the GPA sits in the same place and the empty trailing slot lines up with the
   requirement rows' "..." (sys 9.5) */
.popts .crow { padding-left: 48px; }
.popts > .crow:first-child { padding-top: 11px; }
.crow-gpa-line { display: inline-flex; align-items: baseline; gap: var(--s-2); }
.crow-gpa-note { font: var(--t-label); color: var(--muted); }
.pmore, .pnone { display: flex; align-items: center; height: 36px; padding: 0 var(--s-4) 0 48px; }
.pmore .text-btn { position: relative; min-height: 28px; padding: 4px var(--s-2); }
.pnone { font: var(--t-meta); color: var(--muted); }

/* Met rows: the data-table row size (sys 9.5; GTb 40) */
.pmet-row { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--s-3); min-height: 40px; padding: 10px var(--s-4); }
.pmet-name { font: var(--t-control); color: var(--ink); }
.pmet-val { font: var(--t-meta); color: var(--muted); }

/* loading (M107): grey bars where values go, no spinner, no shimmer */
.skel { display: inline-block; height: 12px; border-radius: var(--r-control); background: var(--surface-2); vertical-align: middle; }
.skel-val { width: 40px; }
.skel-n { width: 16px; }
.preq--skel .skel { width: 40%; }
.pcell-value .skel { align-self: center; }

/* modals: audit text and note (sys 9.7) */
.pm-text { margin: 0; font: var(--t-body); color: var(--ink); }

/* Records R2 (3.4): label over value, no box (M108); info glyph after the label (V372) */
.rstrip { display: flex; flex-wrap: wrap; gap: var(--s-4) 40px; }
.rcell { display: flex; flex-direction: column; min-width: 120px; }
.rcell-label { display: flex; align-items: center; gap: var(--s-1); height: 18px; font: var(--t-label); color: var(--muted); white-space: nowrap; }
.rcell-label .pinfo { margin: -5px 0; } /* the 28px box does not grow the 18px line */
.rcell-value { height: 24px; margin-top: var(--s-1); font: var(--t-h2); color: var(--ink); font-variant-numeric: tabular-nums; }
.rcell-none { font: var(--t-meta); color: var(--muted); }

/* Records R3 (3.3): term, course, right-aligned units and grade, then text columns (M108, GTb) */
.rec-wrap { margin-top: var(--s-6); container-type: inline-size; }
.rec-head + .rec-wrap { margin-top: 0; }
/* fixed columns; Course and Counts toward share the rest (at least 212 each, since narrower containers stack) */
.rec { table-layout: fixed; }
.rec td, .rec th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rec .c-term { width: 128px; }
.rec .c-units, .rec .c-grade { width: 72px; }
.rec .c-bucket { width: 140px; }
.rec .c-menu { width: 44px; padding: 0 var(--s-2) 0 0; text-align: right; overflow: visible; }
.rec .c-counts { padding-left: var(--s-6); }
.rec td.c-term, .rec td.c-bucket { color: var(--ink-2); font-weight: 400; }
.rec td.c-grade { font: var(--t-control); font-weight: 600; color: var(--ink); }
.rec-l1 { display: flex; align-items: center; gap: var(--s-2); }
.rec-code { min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; font: var(--t-control); font-weight: 600; color: var(--ink); }
.rec-code:hover { background: none; }
.rec-code:focus-visible { outline: none; }
.rec tr:has(.rec-code:focus-visible) { outline: 2px solid var(--focus); outline-offset: -2px; }
.rec tr.is-editing td, .rec tr.is-editing:hover td { background: var(--surface-2); } /* M109: the edited row keeps a fill */
.rec .c-menu .icon-btn { position: relative; vertical-align: middle; }
.rec-meta { display: none; }

/* edit drawer (3.5; S261) */
.rec-fields { display: grid; gap: var(--s-4); }
.rec-field input, .rec-field :is(select, :where(.csel)) { display: block; width: 100%; margin-top: 6px; }
.rec-field .field-error .icon { width: 14px; height: 14px; }
.rec-props { grid-template-columns: 112px minmax(0, 1fr); }
.rec-remove, .rec-remove:hover { color: var(--danger); }
.rec-sci { align-items: flex-start; }
.rec-sci input { margin-top: 1px; }
.rec-sci small { margin-top: 2px; }

/* narrow containers stack each record (sys 10 tables): code and grade, then one meta line */
@container (max-width: 879px) {
  .rec, .rec tbody { display: block; }
  .rec thead { display: none; }
  .rec tr { display: grid; grid-template-columns: minmax(0, 1fr) auto 28px; align-items: start; column-gap: var(--s-3); min-height: 60px; padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); }
  .rec tbody tr:last-child { border-bottom: 0; }
  .rec td { display: none; width: auto; height: auto; padding: 0; border: 0; }
  .rec td.c-course, .rec td.c-grade, .rec td.c-menu { display: block; grid-row: 1; }
  /* the course cell spans the row so its meta line gets the full width; grade and "..." sit on line 1 */
  .rec td.c-course { grid-column: 1 / -1; white-space: normal; overflow: visible; }
  .rec td.c-grade { grid-column: 2; line-height: 22px; }
  .rec td.c-menu { grid-column: 3; margin: -3px 0; padding: 0; }
  .rec-l1 { margin-right: 84px; }
  .rec tr.is-link:hover { background: var(--bg); }
  .rec tr.is-editing { background: var(--surface-2); }
  .rec-meta { display: flex; flex-wrap: wrap; column-gap: var(--s-4); margin-top: 2px; font: var(--t-meta); color: var(--muted); }
  .rec-meta > span { white-space: nowrap; }
  .rec-meta > .rec-counts { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
}

@media (max-width: 599px) {
  .prog-head { flex-direction: column; align-items: flex-start; gap: var(--s-2); }
  .prog-actions { justify-content: flex-start; }
  .pstrip { gap: var(--s-4); }
  .pcell { flex: 1 1 0; width: auto; }
  .pcell-value { height: auto; min-height: 24px; }
  /* requirement rows: name (two lines at most) and "..." on top, then a meta line (2.7) */
  .preq { flex-wrap: wrap; align-items: flex-start; column-gap: var(--s-4); row-gap: 2px; }
  .preq-text, .preq-end { display: contents; }
  .preq-name, .preq-toggle { order: 1; flex: 1 1 calc(100% - 44px); min-width: 0; }
  .preq-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
  .preq .preq-more { order: 2; }
  .preq-owed { order: 3; margin-left: 0; line-height: 20px; }
  .preq-line { order: 3; flex-basis: 100%; }
  .preq-plan, .preq-ip { order: 4; }
  .preq .badge-btn { order: 5; }
  .preq-note { order: 6; flex-basis: 100%; }
  .popts .crow { padding-left: 32px; }
  .pmore, .pnone { padding-left: 32px; }
  .pband-col { display: none; } /* Discover drops its list head on phones too */
  /* option meta (2.7): the shared phone meta run (section 14) */
  /* records: three figures 16 apart (3.8); the "..." goes, the row opens the sheet, which holds Remove */
  .rstrip { gap: var(--s-4); }
  .rcell { min-width: 0; }
  .rec td.c-menu { display: none !important; }
  .rec tr { grid-template-columns: minmax(0, 1fr) auto; }
  .rec-l1 { margin-right: 44px; }
}
@media (max-width: 359px) {
  /* R3 at 320 (2.7): the toggle and the sort share one row; 4px less padding on each side of both controls, and the
     row never wraps, so the select shrinks (it ellipsizes) rather than dropping onto a line of its own */
  .ptoolbar { flex-wrap: nowrap; }
  #pfit { padding-left: 10px; padding-right: 10px; }
  .psort > .icon { left: 10px; }
  .psort :is(select, :where(.csel)) { padding-left: 32px; padding-right: 32px; background-position: right 8px center; }
}
@media (pointer: coarse), (max-width: 599px) {
  .preq .preq-more, .pinfo, .rec .c-menu .icon-btn { width: 28px; height: 28px; min-height: 28px; }
  .preq .preq-more::before, .pinfo::before, .rec .c-menu .icon-btn::before { content: ''; position: absolute; inset: -8px; }
  /* b1r3 m1: as Discover's .crow-add, lift the 28 buttons over the next .preq row and extend 9 from the 26 padding
     box (44). The Still needed band is the first row of .plist, which clips, so it grows to 44 to hold the target. */
  .preq .preq-more, .pinfo { z-index: 1; }
  .preq .preq-more::before, .pinfo::before { inset: -9px; }
  .pband:has(> .pinfo) { height: 44px; }
  .badge-btn { position: relative; min-height: 22px; }
  .badge-btn::before { content: ''; position: absolute; inset: -11px -4px; }
  .preq-toggle, .rec-code { min-height: 0; }
  button.pband { position: relative; min-height: 36px; }
  button.pband::before { content: ''; position: absolute; inset: -4px 0; }
  .pmore .text-btn { min-height: 28px; }
  .pmore .text-btn::before { content: ''; position: absolute; inset: -8px 0; }
  /* title-row and toolbar controls: 32 visual with a 44 target (2.7 R1, R3; sys 9.1). A ::before is placed from
     the padding box, so a 32 button with its 1px border needs 7 (as Plan's Share button) */
  .prog-btns button, #pfit, .rec-head [data-rec-add] { position: relative; min-height: 32px; }
  .prog-btns button::before, #pfit::before, .rec-head [data-rec-add]::before { content: ''; position: absolute; inset: -7px 0; }
  /* the sort select cannot carry a ::before: transparent 6px borders hold the 44 around a 32 box (Discover's #sort),
     and negative margins keep the toolbar row at 32 so the 24 and 16 gaps around it stay as drawn */
  :is(#psort, :where(#psort + .csel)) {
    height: 44px; min-height: 44px; margin: -6px 0; padding-top: 0; padding-bottom: 0;
    border-width: 6px 0; border-color: transparent; border-radius: var(--r-control) / 12px;
    background-clip: padding-box; box-shadow: inset 0 0 0 1px var(--line-strong);
  }
  :is(#psort, :where(#psort + .csel)):focus-visible { outline: none; border-color: transparent; box-shadow: inset 0 0 0 2px var(--focus); }
}

/* ============ 17. Premed (spec/page-premed.md); .labs is the lab finder's root (labs.js) ============ */

/* skeleton (3.1; L97): title row, one qualifier line, fact strip, 1px rule, sections split by whitespace only */
.pm, .labs { padding-bottom: var(--s-4); } /* with main's 32 this is the 48 bottom padding */
.pm-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 32px; }
.pm-head h1 { margin: 0; }
.pm-head > .text-btn, .pm-sec-head > .text-btn { flex-shrink: 0; margin: 0 calc(-1 * var(--s-2)) 0 0; } /* the label's edge sits on the column edge */
.pm-qual { margin: var(--s-2) 0 0; font: var(--t-meta); color: var(--muted); }
.pm-loading { display: flex; justify-content: center; margin-top: var(--s-12); } /* S110: one ring, centered, no skeleton */
.pm-loading .spinner { border-width: 1.5px; }

/* fact strip (3.4; L97, S126 second data point): label over value, 48 apart, no box, fill or rules */
.pm-strip { display: flex; flex-wrap: wrap; column-gap: var(--s-12); row-gap: var(--s-4); margin-top: var(--s-6); }
.pm-cell { display: flex; flex-direction: column; min-width: 0; }
.pm-cell-l { font: var(--t-label); color: var(--muted); white-space: nowrap; }
.pm-cell-v { margin-top: var(--s-1); font: 500 15px/22px var(--font-ui); color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pm-unit { margin-left: 6px; font: var(--t-meta); color: var(--muted); }
.pm-none { font: var(--t-meta); line-height: 22px; color: var(--muted); }
.pm-rule { height: 0; margin-top: var(--s-8); border-top: 1px solid var(--line); }

/* sections (3.1): a 32px heading row with its action on the heading's center line, the container 12 below */
.pm-sec { margin-top: var(--s-12); }
.pm-sec--first { margin-top: var(--s-8); }
.pm-sec-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 32px; }
.pm-sec-head h2 { margin: 0; font: var(--t-h2); color: var(--ink); }
.pm-sec-head h2:focus { outline: none; }
.pm-count { margin-left: var(--s-2); font: 400 18px/24px var(--font-ui); color: var(--muted); font-variant-numeric: tabular-nums; } /* L97 "Requests 0" */
.pm-sec-head + * { margin-top: var(--s-3); }
.pm-wrap { overflow: hidden; } /* narrow containers stack the rows; never a horizontal scrollbar */

/* Requirements (3.5; L49): a wide flexible name column, then 144px school columns packed at the right */
.pm-req { table-layout: fixed; }
.pm-req .w-school { width: 144px; }
.pm-req td { height: 44px; padding: 0 var(--s-4); }
.pm-name-cell { display: flex; align-items: baseline; gap: var(--s-3); min-width: 0; }
.pm-req-btn {
  flex: none; max-width: 100%; min-height: 0; padding: 0; margin: 0;
  border: 0; border-radius: 0; background: none;
  font: 500 15px/22px var(--font-ui); color: var(--ink); text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pm-req-btn:hover { background: none; }
.pm-req-btn:focus-visible { outline: none; }
.pm-req tr:has(.pm-req-btn:focus-visible) { outline: 2px solid var(--focus); outline-offset: -2px; }
.pm-reason { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: var(--t-meta); color: var(--muted); } /* L39 muted context after the title */

/* status cells: 16px icon, 6px, the word (L49 Health column); not pills */
.pm-st { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; font: var(--t-meta); color: var(--ink-2); white-space: nowrap; vertical-align: middle; }
.pm-ico { display: inline-block; width: 16px; height: 16px; flex-shrink: 0; }
.pm-st.is-done .pm-ico { color: var(--positive); }
.pm-st.is-ip .pm-ico { color: var(--ink-2); }
.pm-st.is-missing .pm-ico { color: var(--warning); }
.pm-st.is-ct, .pm-st.is-nl { color: var(--muted); }
.pm-tick { stroke: var(--surface); }
.pm-st-school { display: none; }

/* Courses to take (3.6): L55 group bands, then the shared course row; its trailing slot stays empty */
.pm-ghead { display: flex; align-items: center; gap: var(--s-2); height: 34px; padding: 0 var(--s-4); background: var(--bg); border-bottom: 1px solid var(--line); }
.crow + .pm-ghead { border-top: 1px solid var(--line); }
.pm-ghead-l { font: var(--t-control); color: var(--ink); }
.pm-ghead-n { font: var(--t-meta); color: var(--muted); font-variant-numeric: tabular-nums; }
.pm-ghead-r { margin-left: auto; font: var(--t-label); color: var(--muted); white-space: nowrap; }
/* the requirement a course fills: muted, 12px after the title on line 2; the title truncates first (L39) */
.crow-l2 { position: relative; z-index: 1; display: flex; align-items: baseline; gap: var(--s-3); min-width: 0; }
.crow-l2 .crow-title { flex: 0 1 auto; min-width: 0; }
.crow-ctx { flex: none; font: var(--t-meta); line-height: 22px; color: var(--muted); white-space: nowrap; }

/* Science courses (3.7; sys 9.5 data table, GTb2): fixed columns, Bucket takes the rest */
.pm-sci { table-layout: fixed; }
.pm-sci .w-course { width: 160px; }
.pm-sci .w-term { width: 140px; }
.pm-sci .w-src { width: 120px; }
.pm-sci .w-units, .pm-sci .w-grade { width: 80px; }
.pm-sci .w-in { width: 160px; }
.pm-sci th, .pm-sci td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pm-l1 { display: flex; align-items: baseline; gap: var(--s-2); min-width: 0; }
.pm-code { font: var(--t-meta); font-weight: 500; color: var(--ink); white-space: nowrap; }
/* "Repeat" is a qualifier, not a state, so it is plain muted text wherever an attempt is listed (sys 9.3:
   badges are for state): Course records and Premed's Science courses read the same */
.repeat-mark { font: var(--t-label); font-weight: 400; color: var(--muted); white-space: nowrap; }
.pm-sci .badge { margin-left: var(--s-2); }
.pm-sci td.c-grade { color: var(--ink); font-weight: 500; }
.pm-sci-meta { display: none; }
/* what-if rows, edited in place (N333) */
.pm-sci tr.pm-wi td { padding-top: var(--s-1); padding-bottom: var(--s-1); overflow: visible; }
.pm-wi :is(select, :where(.csel)) { height: 32px; min-height: 32px; padding: 0 28px 0 var(--s-2); background-position: right 6px center; }
.pm-wi td.c-grade { padding-left: var(--s-1); }
.pm-in-wi { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.pm-in-wi .badge { margin-left: 0; }
.pm-in-wi .icon-btn { position: relative; margin-right: calc(-1 * var(--s-2)); }
/* add row (N333 "+ New page"): a 40px button spanning the row */
.pm-sci tr.pm-add-tr td { height: 40px; padding: 0; }
.pm-addrow {
  display: flex; align-items: center; justify-content: flex-start; gap: var(--s-2);
  width: 100%; height: 40px; min-height: 40px; padding: 0 var(--s-4); margin: 0;
  border: 0; border-radius: 0; background: transparent;
  color: var(--muted); font: var(--t-control); font-weight: 400;
}
.pm-addrow:hover { background: var(--bg); color: var(--ink); }
.pm-addrow .icon { color: var(--muted); }
.pm-addrow:hover .icon { color: var(--ink); }
.pm-addrow:focus-visible { outline-offset: -2px; }
/* notes under the table, each only when it applies (S252 "3 results" line) */
.pm-notes { margin-top: var(--s-2); font: var(--t-label); font-weight: 400; color: var(--muted); }
.pm-notes p { margin: 0; }
.pm-notes p + p { margin-top: var(--s-1); }
.pm-notes .text-btn { display: inline; min-height: 0; padding: 0 var(--s-1); margin: 0 0 0 var(--s-1); font: var(--t-label); vertical-align: baseline; }

/* requirement drawer (3.9): property list, one school per row; label column wraps, never truncates */
.pm-props dt { overflow-wrap: anywhere; }
.pm-props dd.pm-dd { display: block; padding: 6px 0 var(--s-3); }
.pm-dd .pm-st { display: flex; }
/* W36 RULING M2: the drawer reason is printed in full at every width, never clamped */
.pm-dd-why { display: block; margin-top: 2px; font: var(--t-meta); color: var(--muted); overflow-wrap: anywhere; }
.pm-dd-srclink { display: inline-flex; margin-top: 2px; font: var(--t-label); }
/* W36: the model reading under a Can't tell cell, quieter than the reason and never clamped away */
.pm-dd-model { display: block; margin-top: 4px; padding-left: 8px; border-left: 2px solid var(--line); font: var(--t-meta); color: var(--muted); }
.pm-dd-src { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); margin-top: var(--s-1); font: var(--t-label); font-weight: 400; color: var(--muted); }
.pm-dd-src .d-ext { font: var(--t-label); }
.pm-dd-check { display: block; margin-top: 2px; font: var(--t-label); font-weight: 400; color: var(--muted); }
.pm-yc { display: flex; gap: var(--s-2); }
.pm-yc + .pm-yc { margin-top: 2px; }
.pm-yc-code { font: var(--t-meta); font-weight: 500; color: var(--ink); }
.pm-yc-grade { font: var(--t-meta); color: var(--muted); }
.db.pm-db > .pm-check { margin-top: var(--s-2); }
.pm-addrow--inset { padding: 0 var(--s-2); margin-left: calc(-1 * var(--s-2)); width: calc(100% + var(--s-4)); border-radius: var(--r-control); }
.pm-check-form { display: grid; gap: var(--s-4); padding-top: var(--s-4); border-top: 1px solid var(--line); }
.pm-check-actions { display: flex; justify-content: flex-end; align-items: center; gap: var(--s-2); }
.pm-check-form .field-error .icon { width: 14px; height: 14px; }

/* form fields (S261): 14 semibold label, helper between label and field, then the field */
.pm-fields { display: grid; gap: var(--s-4); }
.pm-field label { display: block; font: var(--t-control); font-weight: 600; color: var(--ink); }
.pm-field .field-help { margin: 2px 0 0; }
.pm-field input, .pm-field :is(select, :where(.csel)), .pm-field textarea { display: block; width: 100%; margin-top: 6px; }
.pm-opt { font: var(--t-label); font-weight: 400; color: var(--muted); }
.d-ext-btn { gap: var(--s-1); }
.d-ext-btn .icon { width: 12px; height: 12px; }

/* Edit schools menu (3.8; L250, sys 9.7): opaque, 280 wide, filter on top, 32px checkbox items */
.pm-menu { position: fixed; z-index: 80; width: 280px; max-width: calc(100vw - 16px); display: flex; flex-direction: column; max-height: calc(100vh - 16px); }
.pm-menu-filter { flex-shrink: 0; }
.pm-menu-filter input { height: 32px; min-height: 32px; }
/* the list scrolls inside the menu (owner, 3 Nov 2026: 20 schools ran past the window with no scroll) */
.pm-menu-list { flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.pm-menu .menu-item { cursor: pointer; }
.pm-mi.is-disabled { color: var(--muted); cursor: default; }
.pm-mi.is-disabled:hover { background: transparent; }
.pm-menu-note { margin: var(--s-1) 0 0; padding: 0 var(--s-2) var(--s-1); font: var(--t-label); color: var(--muted); }
.pm-menu-label { margin: 0; padding: var(--s-1) var(--s-2); font: var(--t-label); color: var(--muted); }
a.pm-mi-link { gap: 6px; color: var(--ink); text-decoration: none; }
a.pm-mi-link:hover { text-decoration: none; }
a.pm-mi-link .icon { width: 12px; height: 12px; color: var(--muted); }
.pm-menu-foot { display: none; }

/* stacked rows (section 5, sys 10 tables): a container narrower than the columns stacks each row */
.pm-wrap.is-stacked table, .pm-wrap.is-stacked tbody { display: block; }
.pm-wrap.is-stacked thead, .pm-wrap.is-stacked colgroup { display: none; }
.pm-wrap.is-stacked tr { border-bottom: 1px solid var(--line); }
.pm-wrap.is-stacked tbody tr:last-child { border-bottom: 0; }
.pm-wrap.is-stacked td { display: block; height: auto; padding: 0; border: 0; }
.pm-wrap.is-stacked tr.is-link:hover, .pm-wrap.is-stacked tr.is-link:hover td { background: var(--bg); }
.pm-wrap.is-stacked tr.is-selected, .pm-wrap.is-stacked tr.is-selected td { background: var(--surface-2); }
/* requirements: the name, its reason (two lines at most), then school and state pairs 16 apart */
.pm-req-wrap.is-stacked tr { display: flex; flex-wrap: wrap; column-gap: var(--s-4); row-gap: var(--s-1); min-height: 44px; padding: var(--s-3) var(--s-4); }
.pm-req-wrap.is-stacked td.c-name { flex-basis: 100%; }
.pm-req-wrap.is-stacked .pm-name-cell { display: block; }
.pm-req-wrap.is-stacked .pm-req-btn { display: block; white-space: normal; }
.pm-req-wrap.is-stacked .pm-reason { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; margin-top: 2px; white-space: normal; }
.pm-req-wrap.is-stacked .pm-st-school { display: inline; font: var(--t-label); color: var(--muted); }
.pm-req-wrap.is-stacked span.pm-ico { display: none; } /* the empty Not listed slot only aligns table columns */
/* science courses: code and grade on line 1, then term, bucket, units 16 apart */
.pm-sci-wrap.is-stacked tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; column-gap: var(--s-3); padding: var(--s-3) var(--s-4); }
.pm-sci-wrap.is-stacked td { display: none; }
.pm-sci-wrap.is-stacked td.c-course, .pm-sci-wrap.is-stacked td.c-grade { display: block; grid-row: 1; }
.pm-sci-wrap.is-stacked td.c-course { grid-column: 1 / -1; white-space: normal; overflow: visible; }
.pm-sci-wrap.is-stacked td.c-grade { grid-column: 2; font: 500 16px/22px var(--font-ui); }
.pm-sci-wrap.is-stacked .pm-l1 { margin-right: 48px; }
.pm-sci-wrap.is-stacked .pm-code { font: var(--t-item); }
.pm-sci-wrap.is-stacked .pm-sci-meta { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); row-gap: 2px; margin-top: 2px; font: var(--t-meta); color: var(--muted); }
.pm-sci-wrap.is-stacked .pm-sci-meta > span { white-space: nowrap; }
.pm-sci-wrap.is-stacked tr.pm-wi { grid-template-columns: 120px minmax(0, 1fr); gap: var(--s-2); }
.pm-sci-wrap.is-stacked tr.pm-wi td.c-course { grid-column: 1 / -1; grid-row: 1; }
.pm-sci-wrap.is-stacked tr.pm-wi td.c-grade { grid-column: 1; grid-row: 2; padding: 0; text-align: left; }
.pm-sci-wrap.is-stacked tr.pm-wi td.c-in { display: block; grid-column: 2; grid-row: 2; align-self: center; }
.pm-sci-wrap.is-stacked tr.pm-wi :is(select:not([data-csel]), :where(.csel)) { width: 100% !important; } /* full width over the measured hug width; never the hidden real select (select.js), which a 100% width widened the phone page to 423 px (check 0, M1) */
.pm-sci-wrap.is-stacked tr.pm-add-tr { display: block; padding: 0; }
.pm-sci-wrap.is-stacked tr.pm-add-tr td { display: block; height: auto; }

@media (max-width: 599px) {
  .pm-strip { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s-4); }
  .pm-cell-v { white-space: normal; }
  .pm-rule { margin-top: var(--s-6); }
  /* Edit schools becomes a full-height sheet: filter on top, the list, a sticky Done (section 5; sys 10) */
  .pm-menu { inset: 0; width: 100%; max-width: none; height: 100dvh; display: flex; flex-direction: column; padding: var(--s-2) var(--s-4) 0; border: 0; border-radius: 0; }
  .pm-menu-filter input { height: 44px; min-height: 44px; font-size: 16px; }
  .pm-menu-list { flex: 1; overflow-y: auto; overscroll-behavior: contain; }
  .pm-menu .menu-item { min-height: 44px; }
  .pm-menu-foot { display: flex; justify-content: flex-end; margin: 0 calc(-1 * var(--s-4)); padding: var(--s-3) var(--s-4) calc(var(--s-3) + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--line); background: var(--surface); }
}
@media (pointer: coarse), (max-width: 599px) {
  .pm-wi :is(select, :where(.csel)) { height: 44px; min-height: 44px; }
  .pm-in-wi .icon-btn { width: 28px; height: 28px; min-height: 28px; }
  .pm-in-wi .icon-btn::before { content: ''; position: absolute; inset: -8px; }
  .pm-notes .text-btn { position: relative; min-height: 0; }
  .pm-notes .text-btn::before { content: ''; position: absolute; inset: -12px -4px; }
  .pm-addrow { height: 44px; min-height: 44px; }
  .pm-sci tr.pm-add-tr td { height: 44px; }
}

/* ============ 18. Ask (spec/page-ask.md) ============ */

/* frame (2): the page owns main's padding, so the thread header and composer band span the content area;
   the column is 780, left-aligned 32 from the sidebar rule (L20 width; RUBRIC: no centred chat column) */
main:has(> .ask) { max-width: none; padding: 0; }
.ask-col, .ask-turn { max-width: 780px; }

/* empty thread (8; N21): title, composer, helper, then Recent chats and Suggested side by side */
/* the title sits where every page title sits: main's padding (32; 24 under 1024; 16 on phones), so "What should I take?"
   (the owner's wording for the Ask heading, CONTEXT 4.6, 8 Oct) lines up with Plan, Progress and the rest (sys 8) */
.ask-empty { max-width: calc(780px + 2 * var(--s-8)); padding: var(--s-8) var(--s-8) var(--s-12); }
@media (max-width: 1023px) { .ask-empty { padding-top: var(--s-6); } }
.ask-empty h1 { margin: 0; font: var(--t-title); color: var(--ink); }
.ask-empty .ask-composer { margin-top: var(--s-3); }
.ask-lists { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6); margin-top: var(--s-8); }
.ask-list-label { margin: 0 0 var(--s-2); font: var(--t-label); color: var(--muted); }
.ask-ul { list-style: none; margin: 0; padding: 0; }
.ask-li {
  display: flex; align-items: center; justify-content: flex-start; gap: var(--s-2);
  width: calc(100% + 2 * var(--s-2)); height: 32px; min-height: 32px; padding: 0 var(--s-2); margin: 0 calc(-1 * var(--s-2));
  border: 0; border-radius: var(--r-control); background: transparent;
  color: var(--ink); font: var(--t-body); text-align: left; text-decoration: none;
}
.ask-li:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.ask-li-icon { display: inline-flex; flex-shrink: 0; color: var(--muted); }
.ask-li-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ask-none { display: flex; align-items: center; height: 32px; margin: 0; font: var(--t-meta); color: var(--muted); }
.ask-all { margin-top: var(--s-1); }

/* composer (6; L20): the text on top, one icon control row at the bottom right; Send 12 from the right, 10 from the bottom */
.ask-composer {
  display: flex; flex-direction: column; min-height: 96px;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-panel); cursor: text;
}
.ask-composer:focus-within { border-color: var(--accent); outline: 2px solid var(--focus); outline-offset: 2px; }
.ask-composer textarea {
  flex: 1; min-height: 48px; max-height: 240px; margin: 0; padding: var(--s-3) var(--s-4) 0;
  border: 0; border-radius: var(--r-panel) var(--r-panel) 0 0; background: transparent;
  font: var(--t-body); color: var(--ink); resize: none; field-sizing: content; overflow-y: auto;
}
.ask-composer textarea:focus-visible { outline: none; }
.ask-ctl { display: flex; justify-content: flex-end; padding: var(--s-2) var(--s-3) 10px; cursor: default; }
.ask-send, .ask-stop { position: relative; width: 28px; height: 28px; min-height: 28px; padding: 0; border-radius: var(--r-control); }
.ask-send { border: 0; background: var(--accent); color: var(--on-accent); }
.ask-send:hover { background: var(--accent-hover); color: var(--on-accent); }
.ask-send:disabled, .ask-send:disabled:hover { border: 0; background: var(--surface-2); color: var(--muted); }
.ask-stop { border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink); }
.ask-stop:hover { background: var(--bg); }
/* Send is absent while the box is empty and grows in when there is text (owner 26 Oct, reference shots in
   shots/ask-send-ref-20261026; spec/motion-apple-springs.md). motion.js presence() drives the move with the control
   spring; these are the two rest states. The button keeps its box, so the text box never moves. Chats matches. */
.ask-send[data-shown="0"], .gc-send[data-shown="0"] { opacity: 0; transform: scale(0.6); pointer-events: none; }
.ask-send[data-gone], .gc-send[data-gone] { visibility: hidden; }
.ask-help { margin: var(--s-2) 0 0; font: var(--t-label); font-weight: 400; color: var(--muted); }

/* thread (2): sticky header bar, the turns, then the composer block pinned on an opaque band. The thread
   fills the content column to the viewport bottom, so the composer always sits 16 above it (L20 has no
   page footer under its composer; the shell footer links stay on every other page and the empty thread). */
body:has(.ask-thread) .shell { min-height: 100vh; min-height: 100dvh; }
body:has(.ask-thread) .app-foot { display: none; }
main:has(> .ask-thread) { display: flex; flex-direction: column; }
.ask-thread { flex: 1; display: flex; flex-direction: column; }
.ask-head {
  position: sticky; top: 0; z-index: 8;
  display: flex; align-items: center; gap: var(--s-1); height: 48px; padding: 0 var(--s-8);
  background: var(--bg); border-bottom: 1px solid var(--line);
}
.ask-head h1 { min-width: 0; margin: 0; font: var(--t-control); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ask-head-r { display: flex; gap: var(--s-2); margin-left: auto; padding-left: var(--s-4); }
.ask-nav { display: none; }
.ask-log { flex: 1; padding: var(--s-4) var(--s-8); }
.ask-dock { position: sticky; bottom: 0; z-index: 6; padding: var(--s-4) var(--s-8); background: var(--bg); }

/* one turn (2, 3): the student's message boxed at the right; the answer unboxed at the left */
.ask-turn { scroll-margin-top: 64px; }
.ask-turn + .ask-turn { margin-top: var(--s-8); }
.ask-msg {
  width: fit-content; max-width: min(560px, 100%); margin-left: auto; padding: var(--s-2) var(--s-3);
  border-radius: var(--r-control); background: var(--surface-2); color: var(--ink); font: var(--t-body);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.ask-msg p { margin: 0; }
/* status (9; L19, L20): Thinking... with one sentence replaced in place, then the collapsed Worked line */
.ask-worked-wrap, .ask-status, .ask-error { margin-top: var(--s-3); }
.ask-worked-wrap { display: flex; flex-direction: column; align-items: flex-start; }
.ask-worked {
  position: relative; display: inline-flex; align-items: center; gap: var(--s-1);
  height: 18px; min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 0; background: none;
  color: var(--muted); font: var(--t-label);
}
.ask-worked:hover { background: none; color: var(--ink); }
.ask-worked .ask-chev { width: 12px; height: 12px; transition: transform var(--dm-popover-ms, 368ms) var(--dm-popover-ease, linear); }
.ask-worked[aria-expanded="true"] .ask-chev { transform: rotate(90deg); }
.ask-steps { list-style: none; margin: var(--s-1) 0 0; padding: 0; font: var(--t-meta); color: var(--muted); }
.ask-steps li + li { margin-top: 2px; }
.ask-thinking { margin: 0; font: var(--t-label); color: var(--muted); }
.ask-step { margin: var(--s-1) 0 0; font: var(--t-meta); color: var(--muted); }
.ask-stopped { margin: var(--s-3) 0 0; font: var(--t-label); color: var(--muted); }
.ask-error-line { display: flex; align-items: center; gap: 6px; margin: 0; font: var(--t-meta); color: var(--danger); }
.ask-error > button { margin-top: var(--s-2); }

/* the answer (3): verdict, the embedded component(s), at most two bullets, the footnote */
.ask-verdict { margin: var(--s-2) 0 0; font: var(--t-body); color: var(--ink); }
.ask-answer > .clist, .ask-answer > .ask-panel { margin-top: var(--s-3); }
.ask-answer > .ask-week { margin-top: var(--s-4); }
.ask-answer > .ask-verdict + .ask-week { margin-top: var(--s-3); }
.ask-actions { display: flex; justify-content: flex-end; gap: var(--s-2); margin-top: var(--s-2); }
.ask-under { margin-top: var(--s-2); }
.ask-bullets { list-style: none; margin: var(--s-3) 0 0; padding: 0; font: var(--t-body); color: var(--ink); }
.ask-bullets li { position: relative; padding-left: 20px; }
.ask-bullets li + li { margin-top: var(--s-1); }
.ask-bullets li::before { content: ''; position: absolute; left: 4px; top: 8px; width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--muted); }
.ask-foot { margin: var(--s-3) 0 0; font: var(--t-label); font-weight: 400; color: var(--muted); }

/* option rows (4): the shared course row; line 4 is the fit line; a static check once the class is planned */
.crow-fit {
  grid-column: 1 / -1; grid-row: 4; position: relative; z-index: 1;
  display: flex; flex-wrap: wrap; column-gap: var(--s-4); row-gap: var(--s-1); margin-top: var(--s-1);
  font: var(--t-meta); color: var(--ink); pointer-events: none;
}
.fit-pair { display: inline-flex; align-items: center; gap: 6px; min-height: 20px; white-space: nowrap; }
.fit-pair .icon { color: var(--muted); }
.fit-pair.t-warning .icon { color: currentColor; }
.fit-pair > .t-ink2 { display: inline-flex; }
.fit-pair > .t-ink2 .icon { color: var(--ink-2); }
.crow .ask-inplan { display: inline-grid; place-items: center; width: 28px; height: 28px; color: var(--ink-2); cursor: default; }
.ask-rows > .ask-role + *, .ask-rows > * + .ask-role { border-top: 1px solid var(--line); padding-top: 11px; }
.ask-role { display: flex; flex-direction: column; padding: var(--s-3) var(--s-4); }
.ask-role-name { font: var(--t-item); color: var(--ink); overflow-wrap: anywhere; }
.ask-role-sub { font: var(--t-meta); color: var(--muted); }

/* GPA what-if (10): one property list (sys 9.6); values at body 600, never a hero number */
.ask-panel { padding: var(--s-1) var(--s-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); }
.ask-props { grid-template-columns: max-content minmax(0, 1fr); }
.ask-props dt, .ask-props dd { display: flex; align-items: center; min-height: 36px; padding: 0; }
.ask-props dt label { font: inherit; color: inherit; }
.ask-grade { width: auto; }
.ask-num { font: 600 15px/22px var(--font-ui); color: var(--ink); font-variant-numeric: tabular-nums; }
button.ask-num { height: auto; min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 0; background: none; cursor: default; }
button.ask-num:hover { background: none; color: var(--ink); }

/* week strip (5): the Plan week grid trimmed to what it draws; options dashed in the planner hue (C120, NC) */
.ask-week { container-type: inline-size; }
.ask-week .wk { margin-top: 0; }
.ask-week .wk-head { position: static; }
.ask-week .wk-block, .ask-week .wk-chip { cursor: default; }
.wk-opt, .wk-opt:hover { padding: 1px 5px; border: 1px dashed var(--bh, var(--accent)); background: var(--surface); }
.wk-opt::before { display: none; }
.wk-opt .wk-code { color: var(--bi, var(--accent)); }
.wk-opt.is-warn { border-color: var(--warning); }
.wk-opt.is-warn .wk-code, .wk-warn { color: var(--warning); font-weight: 600; }
.wk-chip.wk-opt { padding: 0 5px; }
/* narrow blocks (a strip under 640, or blocks sharing a column) put the subject over the number, as Plan does on phones */
.ask-week .wk-block.is-narrow .wk-code { white-space: normal; }
.ask-week .wk-block.is-narrow .wk-subj, .ask-week .wk-block.is-narrow .wk-no { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ask-week .wk-block.is-narrow.is-mid .wk-time { display: none; }
@container (max-width: 640px) {
  .ask-week .wk-block .wk-code { white-space: normal; }
  .ask-week .wk-block .wk-subj, .ask-week .wk-block .wk-no { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ask-week .wk-block.is-mid .wk-time { display: none; }
}
/* phones: the sys 10 day list, 44 rows with the 3px course bar in the course hue; options dashed, clashes in
   --warning. Ask's week and Plan's week (.wk-days, rows as buttons) share it. */
.ask-days, .wk-days { display: none; }
.adl-label { margin: 0; padding: var(--s-2) var(--s-2) var(--s-1); font: var(--t-label); color: var(--muted); }
.adl { list-style: none; margin: 0; padding: 0; }
.adl-row {
  position: relative; display: flex; align-items: center; gap: var(--s-3); height: 44px; padding: 0 var(--s-3) 0 var(--s-4);
  border: 1px solid transparent; border-radius: var(--r-control); background: var(--bf, var(--block)); overflow: hidden;
}
.adl-row + .adl-row, .adl > li + li { margin-top: 2px; }
button.adl-row { width: 100%; min-height: 44px; justify-content: flex-start; text-align: left; font: inherit; color: inherit; }
button.adl-row:hover { background: var(--bf, var(--block)); }
button.adl-row.is-busy:hover { background: repeating-linear-gradient(135deg, var(--line) 0 3px, var(--bg) 3px 6px); }
button.adl-row:focus-visible { outline-offset: -2px; }
.adl-row.is-selected, .adl-row.is-selected:hover { background: var(--bi, var(--accent)); }
.adl-row.is-selected .adl-time, .adl-row.is-selected .adl-code, .adl-row.is-selected .adl-sub, .adl-row.is-selected .adl-warn { color: var(--surface); }
.adl-row::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--bh, var(--accent)); }
.adl-row.is-opt { border-style: dashed; border-color: var(--bh, var(--accent)); background: var(--surface); }
.adl-row.is-busy { background: repeating-linear-gradient(135deg, var(--line) 0 3px, var(--bg) 3px 6px); }
.adl-row.is-opt::before, .adl-row.is-busy::before { display: none; }
.adl-row.is-warn { border-color: var(--warning); }
.adl-time { flex: none; width: 64px; font: var(--t-meta); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.adl-code { font: var(--t-label); font-weight: 600; color: var(--bi, var(--accent)); white-space: nowrap; }
.adl-row.is-busy .adl-code { color: var(--ink-2); }
.adl-row.is-warn .adl-code, .adl-warn { color: var(--warning); }
.adl-sub { min-width: 0; font: var(--t-meta); color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adl-warn { margin-left: auto; font: var(--t-label); font-weight: 600; }

/* menus (11; sys 9.7, L250): opaque, a filter field on top, groups split by a rule, actions on hover */
.ask-pop { position: fixed; z-index: 80; overflow-y: auto; }
.ask-cmenu { min-width: 180px; }
.ask-hist { display: flex; flex-direction: column; width: max-content; min-width: 240px; max-width: min(320px, calc(100vw - 16px)); overflow: hidden; }
.ask-hist-filter { flex-shrink: 0; margin: 0 calc(-1 * var(--s-1)) var(--s-1); padding: 0 var(--s-1) var(--s-1); border-bottom: 1px solid var(--line); }
.ask-hist-filter input { display: block; width: 100%; height: 32px; min-height: 32px; border-color: transparent; background: transparent; }
.ask-hist-filter input:focus-visible { outline: none; border-color: transparent; }
.ask-hist-list { min-height: 0; overflow-y: auto; }
.ask-hist-label { margin: 0; padding: var(--s-1) var(--s-2); font: var(--t-label); color: var(--muted); }
.ask-hist-none { margin: 0; padding: var(--s-2); font: var(--t-meta); color: var(--muted); }
.ask-hi { position: relative; border-radius: var(--r-control); }
.ask-hi.is-current, .ask-hi.is-current .ask-hi-link { background: var(--surface-2); }
.ask-hi-link, .ask-hi-link:hover { color: var(--ink); text-decoration: none; }
.ask-hi-act { position: absolute; top: 2px; right: 2px; display: none; border-radius: var(--r-control); background: var(--surface-2); }
.ask-hi:hover .ask-hi-act, .ask-hi:focus-within .ask-hi-act { display: flex; }
.ask-hi:hover .ask-hi-link, .ask-hi:focus-within .ask-hi-link { padding-right: 64px; background: var(--surface-2); }

/* toast (6): centred on the column, 12 above the pinned composer block */
body.ask-docked #toast { bottom: var(--ask-toast-b, 16px); }
@media (min-width: 600px) { body.ask-docked #toast { left: var(--ask-toast-x, 50%); } }

/* under 1024 the sidebar button moves into the thread header (2, 12) */
@media (max-width: 1023px) {
  body:has(.ask-thread) .mobile-bar { display: none; }
  .ask-nav { display: inline-flex; width: 32px; height: 32px; min-height: 32px; margin: 0 var(--s-1) 0 -6px; color: var(--ink-2); }
}
@media (max-width: 599px) {
  .ask-empty { padding: var(--s-4) var(--s-4) var(--s-8); }
  .ask-lists { grid-template-columns: minmax(0, 1fr); gap: var(--s-8); }
  .ask-head { padding: 0 var(--s-4); }
  .ask-log { padding: var(--s-4); }
  .ask-dock { padding: var(--s-3) var(--s-4) calc(var(--s-4) + env(safe-area-inset-bottom, 0px)); }
  .ask-msg { max-width: calc(100% - 48px); }
  .ask-week .wk, .plan .wk { display: none; }
  .ask-days, .wk-days { display: block; padding: var(--s-1) var(--s-2) var(--s-2); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); }
  .plan .wk-days { margin-top: var(--s-4); }
}
/* touch: 44 targets through padding, visual sizes kept (sys 9.1, 10) */
@media (pointer: coarse), (max-width: 599px) {
  .ask-head .icon-btn, .ask-hi-act .icon-btn { width: 28px; height: 28px; min-height: 28px; }
  .ask-head .icon-btn { position: relative; }
  .ask-head .icon-btn::before, .ask-send::before, .ask-stop::before { content: ''; position: absolute; inset: -8px; }
  .ask-head .ask-nav { width: 32px; height: 32px; min-height: 32px; }
  .ask-head .ask-nav::before { inset: -6px; }
  .ask-head-r { gap: var(--s-4); }
  .ask-send, .ask-stop { min-height: 28px; }
  .ask-li { height: 44px; min-height: 44px; }
  .ask-worked::before { content: ''; position: absolute; inset: -13px -4px; }
  button.ask-num { min-height: 0; }
}

/* ============ 19. Watching, Alert preferences, Class chats, Chat safety (spec/page-watching.md) ============ */

/* Watching frame (3.1; S125): hold banner, title row, strip 8 below, the list 24 below, 48 at the bottom */
.watching { padding-bottom: var(--s-4); }
.w-banner {
  display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; column-gap: var(--s-3); align-items: center;
  min-height: 72px; margin-bottom: var(--s-6); padding: var(--s-4);
  background: var(--warning-subtle); border: 1px solid color-mix(in srgb, var(--warning) 22%, var(--warning-subtle));
  border-radius: var(--r-panel); color: var(--warning);
}
.w-banner > .icon { align-self: start; margin-top: 3px; }
.w-banner-title { margin: 0; font: var(--t-item); color: var(--warning); }
.w-banner-line { margin: 0; font: var(--t-meta); color: var(--warning); }
.w-head { display: flex; align-items: center; min-height: 32px; }
.w-head h1 { margin: 0; }
.w-strip { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-4); row-gap: var(--s-1); margin-top: var(--s-2); font: var(--t-meta); color: var(--ink-2); }
.w-item { display: inline-flex; align-items: center; gap: 6px; min-height: 20px; }
.w-item .icon { color: var(--muted); }
.w-strip .text-btn { min-height: 32px; margin: -6px 0 -6px calc(-1 * var(--s-2)); padding: 6px var(--s-2); font: var(--t-meta); font-weight: 500; }
.w-item .text-btn { margin-left: -2px; }
.w-list { margin-top: var(--s-6); }
.w-loading { display: flex; justify-content: center; padding-top: 40px; }

/* the watch row: the shared course row with a line-1 state cell (3.3): [course 1fr] 16 [state] 8 [gpa] 8 [28] */
.crow.has-state { grid-template-columns: minmax(0, 1fr) 16px auto 8px auto 8px 28px; }
.crow.has-state .crow-grades { grid-column: 5; }
.crow.has-state .crow-add { grid-column: 7; }
.crow-state { grid-column: 3; grid-row: 1; position: relative; z-index: 1; display: flex; align-items: center; justify-content: flex-end; height: 22px; }
.w-enroll { gap: 4px; min-height: 32px; margin: -5px 0; padding: 5px var(--s-2); white-space: nowrap; }
.w-ext { display: inline-flex; }
.w-ext .icon, .btn .w-ext .icon { width: 12px; height: 12px; }
.w-paused { display: inline-flex; align-items: center; gap: 6px; font: var(--t-label); color: var(--ink-2); white-space: nowrap; }
.w-paused .icon { color: var(--ink-2); }
.w-chat { gap: var(--s-1); color: var(--ink-2); text-decoration: none; }
.w-chat > span { font-weight: 600; font-variant-numeric: tabular-nums; }
.w-chat .icon { color: var(--muted); }
.w-chat:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.w-chat:hover .icon { color: var(--ink); }
/* other terms: one L55 band, 36 tall, on --bg */
.w-band { display: flex; align-items: center; gap: var(--s-2); height: 36px; padding: 0 var(--s-4); background: var(--bg); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.w-band-term { font: var(--t-control); color: var(--ink); }
.w-band-n { font: var(--t-label); color: var(--muted); font-variant-numeric: tabular-nums; }

/* watch detail (3.5): the course detail frame; Open course under the properties; L33 activity rows */
.db > .d-title + .w-props { margin-top: var(--s-4); } /* the properties follow the title line directly (3.5) */
.w-props .w-open-course { margin-top: var(--s-2); }
.w-hist-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-2); }
.w-hist-head h3 { margin: 0; font: var(--t-h2); }
.w-hist-head .text-btn { margin: 0 calc(-1 * var(--s-2)) 0 0; }
.w-hist-list { list-style: none; margin: 0; padding: 0; }
.w-hist-list li { display: flex; align-items: center; gap: var(--s-2); min-height: 28px; font: var(--t-meta); color: var(--ink); }
.w-hist-list .icon { color: var(--muted); }
.w-hist-list .is-failed, .w-hist-list .is-failed .icon { color: var(--danger); }
.w-hist-time { font: var(--t-label); color: var(--muted); white-space: nowrap; }
.w-hist-none { margin: 0; font: var(--t-meta); color: var(--muted); }
.df .btn.primary .icon { color: inherit; }

/* modals (3.4, 5.3): label, helper, then the field; two fields share a row (CC2) */
.wm-field { display: block; width: 100%; margin-top: var(--s-2); }
.modal-body label + .wm-field { margin-top: 6px; }
.modal-body label + select[data-csel] + .wm-field { margin-top: 6px; } /* the custom select trigger sits after its hidden select, so it keeps the 6 px the select had (check 0, m1) */
.wm-lede { margin: 0 0 var(--s-3); }
.wm-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-3); }
.wm-text { margin: 0; font: var(--t-body); color: var(--ink-2); }
.wm-guide { padding-bottom: var(--s-6); }
.wm-guide p { margin: 0; color: var(--ink); }
.wm-guide p + p { margin-top: var(--s-3); }
#w-modal .field-error:empty { display: none; }
#w-modal .field-error .icon { width: 14px; height: 14px; }

/* settings column: one layout for Alert preferences, Chat safety, Account, Support and Status (L270, L272:
   every settings page keeps its column in the same place). 640 max, left-aligned at the page gutter like the
   other object pages, the title 24 above the first section as .page-head sets it (sys 8). */
.settings-col { max-width: var(--w-form); padding-bottom: var(--s-4); }
.settings-col > h1 { margin: 0 0 var(--s-6); }
@media (max-width: 599px) { .settings-col > h1 { margin-bottom: var(--s-4); } }
.set-sec + .set-sec { margin-top: 40px; }
.set-sec > h2 { margin: 0; font: var(--t-h2); }
.set-desc { margin: 0; font: var(--t-meta); color: var(--muted); }
.set-sec > .settings { margin-top: var(--s-3); }
.setting-text { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.setting-row .setting-label { color: var(--ink); }
.setting-row .setting-desc.t-ink2 { color: var(--ink-2); }
.setting-row .setting-desc.t-warning { color: var(--warning); }
.setting-row > .text-btn { flex-shrink: 0; margin: 0 calc(-1 * var(--s-2)) 0 0; }
.cs-slot { width: 88px; flex-shrink: 0; } /* a row without its action keeps the column, so badges line up (N516) */
.ap-times { display: flex; align-items: center; gap: var(--s-2); flex-shrink: 0; }
.ap-times :is(select, :where(.csel)) { width: auto; }
.ap-to { font: var(--t-meta); color: var(--muted); }
.setting-disc { position: relative; }
.setting-disc > summary { justify-content: space-between; gap: var(--s-4); min-height: 64px; padding: var(--s-3) var(--s-4); border-radius: 0 0 var(--r-panel) var(--r-panel); color: var(--ink); }
.setting-disc > summary::before { display: none; }
.setting-disc > summary .setting-label { font: var(--t-item); font-weight: 500; color: var(--ink); }
.setting-disc > summary .icon { color: var(--muted); transition: transform var(--dm-popover-ms, 368ms) var(--dm-popover-ease, linear); }
.setting-disc[open] > summary .icon { transform: rotate(180deg); }
.setting-disc > summary:focus-visible { outline-offset: -2px; }
.setting-disc > p { margin: 0; padding: 0 var(--s-4) var(--s-4); max-width: 560px; font: var(--t-meta); color: var(--ink-2); }
/* Chat safety (6) */
.cs-r { display: flex; align-items: center; gap: var(--s-4); flex-shrink: 0; }
.cs-excerpt { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.settings > .empty { padding: var(--s-12) var(--s-6); }

/* Class chats (5.1; L33): sidebar, a 380 room list, then the room pane; both run full height */
body:has(.chats) .app-foot { display: none; }
main:has(> .chats) { max-width: none; padding: 0; display: flex; flex-direction: column; min-height: 0; }
.chats { flex: 1; min-height: 0; display: grid; grid-template-columns: 380px minmax(0, 1fr); background: var(--surface); }
@media (min-width: 1024px) {
  body:has(.chats) .shell { height: 100vh; height: 100dvh; min-height: 0; }
}
.ch-list { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--line); overflow-y: auto; scrollbar-width: thin; }
.ch-list-head { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; height: 40px; padding: 0 var(--s-3) 0 var(--s-4); border-bottom: 1px solid var(--line); }
.ch-list-head h1 { margin: 0; font: var(--t-h2); }
.ch-rooms { list-style: none; margin: 0; padding: var(--s-2) 0; }
.ch-room {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: 22px 18px; column-gap: var(--s-3); align-content: center;
  height: 56px; margin: 0 var(--s-2); padding: 0 var(--s-2); border-radius: var(--r-control); color: var(--muted); text-decoration: none;
}
.ch-room:hover { background: var(--bg); text-decoration: none; }
.ch-room.is-selected { background: var(--surface-2); }
.ch-room:focus-visible { outline-offset: -2px; }
.ch-room-name { min-width: 0; font: var(--t-item); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ch-room.is-unread .ch-room-name { color: var(--ink); }
.ch-room-unread, .ch-room-sub, .ch-room-time { font: var(--t-label); font-weight: 400; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.ch-room-unread, .ch-room-time { align-self: center; text-align: right; }
.ch-pane { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.ch-center { align-items: center; justify-content: center; }
.ch-none { display: flex; flex-direction: column; align-items: center; }
.ch-none p { margin: 0; font: var(--t-meta); color: var(--muted); }
.ch-pane-head { display: flex; align-items: center; gap: var(--s-2); flex-shrink: 0; height: 40px; padding: 0 var(--s-6); border-bottom: 1px solid var(--line); }
.ch-pane-head h2 { display: flex; align-items: baseline; gap: var(--s-2); min-width: 0; margin: 0; font: var(--t-body); }
.ch-room-code { font-weight: 600; color: var(--ink); white-space: nowrap; }
.ch-room-course { min-width: 0; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ch-back { display: none; }
.ch-scroll { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; scrollbar-width: thin; }
.ch-feed { flex: none; width: 100%; max-width: calc(var(--w-read) + 2 * var(--s-6)); padding: var(--s-6) var(--s-6) 0; }
.ch-post + .ch-post { margin-top: var(--s-4); }
.ch-post-l1 { display: flex; align-items: center; gap: var(--s-2); min-height: 22px; }
.ch-alias { font: 600 15px/22px var(--font-ui); color: var(--ink); }
.ch-time { font: var(--t-label); color: var(--muted); white-space: nowrap; }
.ch-post-more { position: relative; margin: -3px 0 -3px auto; opacity: 0; }
.ch-post:hover .ch-post-more, .ch-post:focus-within .ch-post-more, .ch-post-more[aria-expanded="true"] { opacity: 1; }
.ch-body { margin: 0; font: var(--t-body); color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }
.ch-empty { padding: var(--s-12) 0; }
/* composer (5.2; L33, sys 9.10): sticky at the pane bottom once the feed overflows, 16 under the last post until then */
.ch-dock { position: sticky; bottom: 0; z-index: 2; flex: none; width: 100%; max-width: calc(var(--w-read) + 2 * var(--s-6)); padding: var(--s-4) var(--s-6); background: var(--surface); }
.ch-composer { display: flex; flex-direction: column; min-height: 80px; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-panel); cursor: text; }
.ch-composer:focus-within { border-color: var(--accent); outline: 2px solid var(--focus); outline-offset: 2px; }
.ch-composer textarea { flex: 1; min-height: 44px; max-height: 240px; margin: 0; padding: var(--s-3) var(--s-4) 0; border: 0; border-radius: var(--r-panel) var(--r-panel) 0 0; background: transparent; font: var(--t-body); color: var(--ink); resize: none; field-sizing: content; overflow-y: auto; }
.ch-composer textarea:focus-visible { outline: none; }
.ch-ctl { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); height: 36px; padding: 0 var(--s-2) 2px; cursor: default; }
.ch-as { position: relative; gap: var(--s-1); height: 28px; min-height: 28px; padding: 0 6px 0 var(--s-2); border: 0; background: transparent; color: var(--ink-2); font: var(--t-label); }
.ch-as:hover { background: var(--surface-2); color: var(--ink); }
.ch-as .icon { color: var(--muted); }
.ch-send { position: relative; width: 28px; height: 28px; min-height: 28px; padding: 0; border: 0; background: var(--accent); color: var(--on-accent); }
.ch-send:hover { background: var(--accent-hover); color: var(--on-accent); }
.ch-send:disabled, .ch-send:disabled:hover { border: 0; background: var(--surface-2); color: var(--muted); }
/* toasts sit 12 above the composer while it is pinned to the pane bottom (set in watching.js) */
body:has(.chats.has-room) #toast { bottom: calc(var(--ch-toast-b, 16px) + env(safe-area-inset-bottom, 0px)); }

/* touch: 44 targets through padding, visual sizes kept (sys 9.1) */
@media (pointer: coarse) {
  .ch-post-more { opacity: 1; }
  .w-enroll { min-height: 44px; margin: -11px 0; }
  /* b1r4 m4: 44 targets by transparent extension, as .crow-add (b1r3 m1). The chat count sits over the row's own
     stretched link, so it is lifted above it and its target is at least 44 wide whatever the count's width. */
  .w-chat { position: relative; z-index: 2; }
  .w-chat::before { content: ''; position: absolute; top: -12px; bottom: -12px; left: 50%; width: max(calc(100% + 10px), 44px); transform: translateX(-50%); }
  input.switch::before { content: ''; position: absolute; inset: -13px -6px; }
  /* tabs: the 24 gap becomes 15 of padding each side, so "All" (15 wide) is a 45 target; the underline keeps the label width */
  .gc-tabs { gap: 0; margin-left: -15px; margin-right: -15px; }
  .gc-tabs > [role=tab] { padding: 0 15px; }
  .gc-tabs > [role=tab]::after { left: 15px; right: 15px; }
  .app-foot { row-gap: 0; }
  .app-foot a { padding-block: 13px; }
}
@media (pointer: coarse), (max-width: 599px) {
  .ch-post-more, .ch-list-head .icon-btn { width: 28px; height: 28px; min-height: 28px; }
  .ch-post-more::before, .ch-list-head .icon-btn::before, .ch-send::before { content: ''; position: absolute; inset: -8px; }
  .ch-list-head .icon-btn { position: relative; }
  .ch-as, .ch-send { min-height: 28px; }
  .ch-as::before { content: ''; position: absolute; inset: -8px 0; }
  .setting-row > .text-btn, .cs-r .text-btn, .w-strip .text-btn { min-height: 44px; margin-top: -12px; margin-bottom: -12px; }
}

/* single pane below 1024 (5.5): the room list, or one room with a back button */
@media (max-width: 1023px) {
  .chats { display: block; min-height: calc(100dvh - 48px - 33px); }
  .chats.has-room .ch-list, .chats.is-empty .ch-list .ch-rooms { display: none; }
  .chats:not(.has-room):not(.is-empty) .ch-pane { display: none; }
  .chats.is-empty .ch-pane { padding: var(--s-6) 0; }
  .ch-list { border-right: 0; overflow: visible; }
  .ch-list-head { position: sticky; top: 48px; z-index: 5; height: 48px; background: var(--surface); }
  .ch-pane-head { position: sticky; top: 48px; z-index: 5; height: 48px; padding: 0 var(--s-4) 0 var(--s-2); background: var(--surface); }
  .ch-back { display: inline-flex; align-items: center; justify-content: center; position: relative; width: 32px; height: 32px; min-height: 32px; color: var(--ink-2); }
  .ch-back::before { content: ''; position: absolute; inset: -6px; }
  .ch-back:hover { text-decoration: none; }
  .ch-scroll { overflow: visible; }
  .ch-feed { padding: var(--s-4) var(--s-4) 0; }
  .ch-dock { padding: var(--s-4) var(--s-4) calc(var(--s-4) + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 599px) {
  .w-banner { grid-template-columns: 16px minmax(0, 1fr); }
  .w-banner > button { grid-column: 2; justify-self: start; margin-top: var(--s-3); }
  /* Enroll leaves line 1 and becomes the row's last line (3.8); line 1 keeps code, section, badge, GPA and "..." */
  .crow.has-state { grid-template-columns: minmax(0, 1fr) 8px auto 8px 28px; }
  .crow.has-state .crow-grades { grid-column: 3; }
  .crow.has-state .crow-add { grid-column: 5; }
  .crow-state { grid-column: 1 / -1; grid-row: 4; justify-content: flex-start; height: auto; margin-top: var(--s-1); }
  .crow-state:empty { display: none; }
  .w-enroll { margin: 0 0 0 calc(-1 * var(--s-2)); }
  .ap-quiet { flex-wrap: wrap; }
  .ap-quiet .setting-text { flex-basis: 100%; }
  .ap-times { margin-top: var(--s-2); }
  .setting-row .setting-label { overflow-wrap: anywhere; }
  .cs-excerpt { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .wm-pair { grid-template-columns: minmax(0, 1fr); }
}
@media (pointer: coarse) and (max-width: 599px) {
  .w-enroll { min-height: 44px; margin: 0 0 0 calc(-1 * var(--s-2)); }
  /* b1r4 m4: the GE tip above reaches 12 below its line (its 44 target), so Enroll's line starts 12 under it */
  .crow-state:has(.w-enroll) { margin-top: var(--s-3); }
}

/* ============ 20. Pricing, Account, Sign in, Guest, Support, Legal, Status, Error (spec/page-account.md) ============ */

/* shared: title with a data line under it, actions on the title's center line (sys 8, S252) */
.ac-head { align-items: flex-start; }
.ac-head h1 { margin: 0; }
.ac-sub { margin: var(--s-1) 0 0; max-width: 880px; font: var(--t-meta); color: var(--ink-2); }
.ac-sub a { white-space: nowrap; }
/* settings and form pages: a left-aligned 640 column (sys 4, 12.15; L314 610, L352 607) */
.ac-col { max-width: var(--w-form); padding-bottom: var(--s-4); }
button.is-pending:disabled, button.is-pending:disabled:hover { background: var(--surface-2); border-color: var(--line); color: var(--muted); cursor: progress; }

/* ---- Pricing (spec 3; L434): one comparison table, 280 + 3 x 200, rows on a 40 pitch ---- */
/* b5r1 B1: .pr is a size container so the offer tabs take over whenever the 896 table cannot fit (L434: every offer column stays whole) */
.pr { padding-bottom: var(--s-4); container-type: inline-size; }
/* the standard data-table container (sys 9.5: one --surface box, 1px --line, radius 8), as every other table */
.pr-wrap { max-width: 898px; /* border-box: the 896 table plus its 1px border each side (b5r1 B1) */  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); overflow: hidden; }
.pr-table { width: 100%; table-layout: fixed; border-collapse: collapse; }
.pr-table th:first-child, .pr-table td:first-child { padding-left: var(--s-4); }
.pr-table thead tr:first-child > * { padding-top: var(--s-4); }
.pr-table tbody tr:last-child > * { border-bottom: 0; }
.pr-c-label { width: 296px; } /* 280 of label plus the container's 16 inset */
.pr-c-offer { width: 200px; }
.pr-table th, .pr-table td { padding: 0 var(--s-4) 0 0; text-align: left; vertical-align: middle; }
.pr-h { vertical-align: bottom; }
.pr-name { display: block; font: var(--t-h2); color: var(--ink); }
.pr-price { display: block; margin-top: var(--s-1); font: 400 15px/22px var(--font-ui); color: var(--ink-2); white-space: nowrap; }
.pr-amt { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.pr-ends { font: var(--t-meta); color: var(--muted); }
.pr-slots td { padding-top: var(--s-4); padding-bottom: var(--s-4); border-bottom: 1px solid var(--line); }
.pr-slot { display: flex; align-items: center; height: 32px; }
.pr-buy { width: 144px; }
.pr-table tbody th, .pr-table tbody td { height: 40px; border-bottom: 1px solid var(--line); font: var(--t-meta); color: var(--ink); }
.pr-table tbody th { font-weight: 400; }
.pr-label {
  display: inline; min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 0; background: none;
  font: var(--t-meta); color: var(--ink); text-align: left;
  text-decoration: underline dotted var(--line-strong); text-decoration-thickness: 1px; text-underline-offset: 4px; cursor: help;
}
button.pr-label:hover { background: none; text-decoration-color: var(--muted); }
.pr-label.is-plain { text-decoration: none; cursor: auto; }
.pr-v { display: flex; align-items: center; gap: var(--s-2); font-variant-numeric: tabular-nums; }
.pr-v .icon { color: var(--ink-2); }
.pr-err { max-width: 880px; margin: var(--s-3) 0 0; }
.pr-err .icon { width: 14px; height: 14px; }
.pr-foot { max-width: 880px; margin: var(--s-4) 0 0; font: var(--t-meta); color: var(--muted); }
.pr-check { display: inline; min-height: 0; padding: 0; margin: 0; border: 0; font: inherit; font-weight: 500; color: var(--accent); }
.pr-check:hover { background: none; text-decoration: underline; text-underline-offset: 2px; }
.pr-m { display: none; }

/* ---- Account (spec 4; L314, L352, N505, N516): sections of bordered rows, values then controls at right ---- */
.ac .set-sec > h2 { margin: 0; }
.ac-row .setting-label { margin: 0; }
label.setting-label { cursor: pointer; }
.ac-r { display: flex; align-items: center; justify-content: flex-end; gap: var(--s-4); flex-shrink: 0; min-width: 0; }
.ac-val { font: var(--t-meta); color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ac-ctl { display: inline-flex; align-items: center; gap: var(--s-3); flex-shrink: 0; }
.ac-ctl :is(select, :where(.csel)) { width: auto; }
.ac-ctl .badge { flex-shrink: 0; }
.text-btn.ac-danger { margin: 0 calc(-1 * var(--s-2)) 0 0; color: var(--danger); }
.text-btn.ac-danger:hover { color: var(--danger); }
.ac-col > .settings > .empty { padding: var(--s-12) var(--s-6); }
/* modals: one per action; devices list (S261 footer order) */
#a-modal .field-error:empty { display: none; }
#a-modal .field-error .icon { width: 14px; height: 14px; }
#a-modal .am-f + .am-f { margin-top: var(--s-4); }
#a-modal .wm-text a { white-space: nowrap; }
.am-split { justify-content: space-between; }
.am-split > :first-child { margin-left: calc(-1 * var(--s-2)); }
.ac-devs > .ac-dev + .ac-dev { border-top: 1px solid var(--line); }
.ac-dev { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 56px; padding: var(--s-2) 0; }
.ac-dev-text { display: flex; flex-direction: column; min-width: 0; }
.ac-dev-name { display: flex; align-items: center; gap: var(--s-2); font: var(--t-item); font-weight: 500; color: var(--ink); }
.ac-dev-meta { font: var(--t-meta); color: var(--muted); }
.ac-dev > .btn-quiet { margin-right: calc(-1 * var(--s-2)); }

/* ---- Sign in (spec 5; V385, L441): no shell, mark top-left, a 320 column, policy line at the foot ---- */
body.bare { display: block; }
body.bare #sidebar, body.bare .mobile-bar, body.bare .sample, body.bare .app-foot, body.bare .nav-scrim { display: none !important; }
body.bare .shell { margin: 0; border-left: 0; min-height: 100vh; min-height: 100dvh; }
body.bare main { max-width: none; padding: 0; }
.si { position: relative; display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
/* the wordmark where the sidebar puts it: text at 16 from the left, a 28 line 16 from the top (sys 7) */
.si-mark { position: absolute; top: var(--s-4); left: var(--s-4); padding: 0; line-height: 28px; }
.si-col { width: 320px; max-width: calc(100% - 2 * var(--s-4)); margin: 136px auto 0; text-align: center; }
.si-col h1 { margin: 0; }
.si-ctx { margin: var(--s-2) 0 0; font: var(--t-meta); color: var(--ink-2); }
.si-full { display: flex; width: 100%; }
.si-first, .si-form { margin-top: var(--s-6); }
.si-rule { height: 0; margin: var(--s-4) 0; border: 0; border-top: 1px solid var(--line); }
.si-col > .si-ter { display: flex; margin: var(--s-6) auto 0; }
.si-col > .si-full + .si-ter { margin-top: var(--s-4); }
.si-fine { margin: var(--s-6) 0 0; font: var(--t-label); font-weight: 400; color: var(--muted); }
.si-form { text-align: left; }
.si-input { display: block; width: 100%; height: 36px; margin-top: var(--s-2); }
.si-form .field-error:empty { display: none; }
.si-form .field-error .icon { width: 14px; height: 14px; }
.si-send { margin-top: var(--s-4); }
/* the shell footer's links and type (.app-foot), centred under the centred column */
.si-foot { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2) var(--s-4); margin-top: auto; padding: var(--s-12) var(--s-4) var(--s-8); font: var(--t-label); font-weight: 400; color: var(--muted); }
.si-foot a { color: var(--muted); }
.si-foot a:hover { color: var(--ink); }

/* ---- Guest (spec 6; S252 header, sys 9.5 rows) ---- */
.gu { padding-bottom: var(--s-4); }
.gu-h { margin: 0 0 var(--s-3); font: var(--t-h2); }
.gu .clist { margin-top: 0; }
.gu .crow { cursor: pointer; }

/* ---- Support (spec 7; L270 form group, primary right-aligned under it) ---- */
.sup-group { padding: var(--s-6); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); }
.sup-group > label { margin: 0; }
.sup-help { margin: 2px 0 0; }
.sup-group textarea { display: block; width: 100%; min-height: 104px; margin-top: var(--s-2); overflow: hidden; }
.sup-group .field-error:empty { display: none; }
.sup-group .field-error .icon { width: 14px; height: 14px; }
.sup-group > .sup-l2 { margin-top: var(--s-4); }
.sup-opt { font-weight: 400; color: var(--muted); }
.sup-group input { display: block; width: 100%; margin-top: var(--s-2); }
.sup-page { margin: var(--s-3) 0 0; font: var(--t-label); font-weight: 400; color: var(--muted); }
.sup-actions { display: flex; align-items: center; justify-content: flex-end; gap: var(--s-2); margin-top: var(--s-4); }
.sup-actions .text-btn { margin: 0; }
.sup-group > .sup-done { padding: var(--s-6) 0; }
.sup-done h2:focus { outline: none; }
.sup-done .empty-actions .text-btn { margin: 0; }

/* ---- Legal (spec 8; PB, SB): a 720 reading column and a sticky 200 list at 1280 and up ---- */
.lg { display: grid; grid-template-columns: minmax(0, var(--w-read)) 200px; column-gap: var(--s-12); align-items: start; padding-bottom: var(--s-4); }
.lg-read { min-width: 0; max-width: var(--w-read); }
.lg-read h1 { margin: 0; }
.lg-read .lg-date { margin: var(--s-1) 0 0; font: var(--t-meta); color: var(--muted); }
.lg-sum { margin: var(--s-4) 0 0; font: var(--t-body); color: var(--ink); }
.lg-intro { margin: var(--s-6) 0 0; }
.lg-read p, .lg-read li { font: var(--t-body); color: var(--ink); }
.lg-sec p { margin: 0 0 var(--s-3); }
.lg-sec { margin-top: 40px; scroll-margin-top: var(--s-8); }
.lg-sec > :last-child { margin-bottom: 0; }
.lg-sec h2 { margin: 0 0 var(--s-3); }
.lg-sec h2:focus { outline: none; }
.lg-sec h3 { margin: var(--s-6) 0 var(--s-2); font: var(--t-item); }
.lg-sec h2 + h3 { margin-top: 0; }
.lg-sec ul { margin: 0 0 var(--s-3); padding-left: 20px; }
.lg-sec li + li { margin-top: var(--s-2); }
.lg-sec strong { font-weight: 600; }
.lg-table { margin: 0 0 var(--s-3); }
.lg-table .table td { vertical-align: top; padding-top: 10px; padding-bottom: 10px; }
.lg-ext { display: inline-flex; margin-left: 2px; vertical-align: 1px; }
.lg-ext .icon { width: 12px; height: 12px; }
.lg-read .lg-legal { margin: var(--s-12) 0 0; font: var(--t-label); font-weight: 400; color: var(--muted); }
.lg-toc { position: sticky; top: var(--s-8); display: flex; flex-direction: column; }
.lg-toc-label { margin: 0 0 var(--s-1); font: var(--t-label); color: var(--muted); }
.lg-toc a, .lg-toc-m nav a { display: block; padding: 4px 0; font: var(--t-meta); color: var(--ink-2); }
.lg-toc a:hover, .lg-toc-m nav a:hover { color: var(--ink); text-decoration: none; }
.lg-toc a[aria-current], .lg-toc-m nav a[aria-current] { color: var(--ink); font-weight: 500; }
.lg-toc-m { display: none; }
@media (max-width: 1279px) {
  .lg { display: block; }
  .lg-toc { display: none; }
  .lg-toc-m { display: block; margin-top: var(--s-4); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
  .lg-toc-m > summary { min-height: 32px; color: var(--ink-2); }
  .lg-toc-m nav { padding: 0 0 var(--s-3) var(--s-6); }
}

/* ---- Status (spec 9): two L314 rows, a 6px dot and the value at right ---- */
.st-val { display: inline-flex; align-items: center; gap: var(--s-2); flex-shrink: 0; font: var(--t-meta); color: var(--ink); white-space: nowrap; }
.st-dot { width: 6px; height: 6px; flex-shrink: 0; border-radius: var(--r-pill); background: var(--positive); }
.st-val.is-warn { color: var(--warning); }
.st-val.is-warn .st-dot { background: var(--warning); }
button.st-val { position: relative; min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 0; background: none; cursor: help; }
button.st-val:hover { background: none; text-decoration: underline dotted var(--line-strong); text-underline-offset: 4px; }

/* ---- Error (spec 10; H89): a quiet block centered in the content area; the sidebar stays ---- */
main:has(> .err) { display: flex; flex-direction: column; }
.err { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 360px; }
.err-block { width: 100%; max-width: 480px; text-align: center; }
.err-block h1 { margin: 0; font: var(--t-h2); }
.err-line { margin: var(--s-2) 0 0; font: var(--t-meta); color: var(--ink-2); }
.err-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--s-2); margin-top: var(--s-4); }
.err-actions .text-btn { margin: 0; }
.err-diag { margin: var(--s-6) 0 0; font: var(--t-small); font-weight: 400; color: var(--muted); }
.err-search { display: flex; gap: var(--s-2); margin-top: var(--s-4); text-align: left; }
.err-search .searchbox { max-width: none; }
.err-search input::-webkit-search-cancel-button { display: none; }
.err--bare { position: relative; min-height: 100vh; min-height: 100dvh; padding: var(--s-4); }

/* touch: 44 targets through padding, visual sizes kept (sys 9.1, 10) */
@media (pointer: coarse), (max-width: 599px) {
  .pr-label, .pr-check, button.st-val { position: relative; min-height: 0; }
  .pr-label::before, .pr-check::before, button.st-val::before { content: ''; position: absolute; inset: -12px -4px; }
  /* b5r2 m1: the full-width offer Buy is the phone and touch pattern only; elsewhere it keeps .pr-buy (144) */
  .pr-m-slot > button { width: 100%; }
}

/* b5r1 B1: the offer tabs replace the table whenever .pr is narrower than the table box
   (296 + 3 x 200 = 896, plus the 1px border each side = 898), not only below 600 */
@container (max-width: 897px) {
  .pr-wrap { display: none; }
  /* b5r2 m1: the tabs take the Account settings column (.ac-col, --w-form 640), not the whole content width */
  .pr-m { display: block; max-width: var(--w-form); }
  .pr-seg { display: flex; width: 100%; }
  .pr-seg > button { flex: 1 1 0; min-width: 0; padding: 0 var(--s-1); }
  .pr-m-head { margin-top: var(--s-6); }
  .pr-m-head h2 { margin: 0; }
  .pr-m-slot { display: flex; margin-top: var(--s-4); }
  .pr-m-rows { margin-top: var(--s-4); padding: 0 var(--s-4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-panel); }
  .pr-m-row { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 44px; padding: var(--s-2) 0; border-bottom: 1px solid var(--line); font: var(--t-meta); }
  .pr-m-row:last-child { border-bottom: 0; }
  .pr-m-row .pr-label { flex: 0 1 auto; }
  .pr-m-val { flex-shrink: 0; max-width: 50%; text-align: right; }
  .pr-m-val .pr-v { justify-content: flex-end; }
}

/* phone (spec 3 to 10 at 390, provisional per sys 10) */
@media (max-width: 599px) {
  /* account rows stack: label, then the value, then the description; the control stays at the right of line 1 */
  .ac-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "label ctl" "val ctl" "desc desc"; gap: 2px var(--s-3); align-items: center; }
  .ac-row .setting-text, .ac-row .ac-r { display: contents; }
  .ac-row .setting-label { grid-area: label; }
  .ac-row .setting-desc { grid-area: desc; }
  .ac-row .ac-val { grid-area: val; text-align: left; white-space: normal; }
  .ac-row .ac-ctl { grid-area: ctl; justify-self: end; }
  .ac-row .ac-ctl :is(select, :where(.csel)) { max-width: 180px; }
  #ac-open .ac-ctl :is(select, :where(.csel)) { max-width: 200px; } /* "Only seats I can take" needs about 183 px at 16 px type; 180 cut it (check 0, m4) */
  #a-modal[open] { width: 100%; max-width: 100%; height: 100%; max-height: 100%; margin: 0; border-radius: 0; display: flex; flex-direction: column; }
  #a-modal[open] > form { display: flex; flex: 1; flex-direction: column; }
  #a-modal .modal-body { flex: 1; padding: var(--s-3) var(--s-4) var(--s-4); }
  #a-modal .modal-foot { padding: var(--s-4); padding-bottom: calc(var(--s-4) + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--line); }
  #a-modal .modal-head { min-height: 56px; padding: var(--s-2) var(--s-2) 0 var(--s-4); }
  .si-mark { top: var(--s-4); left: var(--s-4); }
  .si-col { margin-top: 64px; }
  .gu .ac-head { flex-direction: column; align-items: stretch; gap: var(--s-4); }
  .gu .page-actions > button { flex: 1 1 0; }
  .sup-group { padding: var(--s-4); }
  .lg-toc-m > summary { min-height: 44px; }
  .lg-table .table, .lg-table .table tbody, .lg-table .table tr, .lg-table .table td { display: block; }
  .lg-table .table thead { display: none; }
  .lg-table .table tr { padding: var(--s-2) var(--s-4); border-bottom: 1px solid var(--line); }
  .lg-table .table tr:last-child { border-bottom: 0; }
  .lg-table .table td { height: auto; padding: 2px 0; border: 0; }
  .err-actions { flex-direction: column; align-items: stretch; }
  .err-actions > * { width: 100%; justify-content: center; }
  .err-search { flex-direction: column; }
}
