/* =============================================================
   Scheduler — design tokens
   A light "planner" theme (soft indigo-on-paper, dot-grid backdrop)
   with an optional dark mode, toggled via [data-theme] on <html>.
   Buttons keep a fixed deep-indigo gradient in both themes so
   white button text always stays readable; --accent/--accent-strong
   shift per-theme and are used for links, rings, and tinted text.
   ============================================================= */

/* The site's fonts: the reader's installed copy if they have one, otherwise
   the file the site's owner uploaded on /owner (served at /fonts/...).
   Until it's uploaded, the next font in each stack stands in. While a file
   is still on its way, the text shows in the next font and switches when it
   arrives (font-display: swap), rather than staying invisible. */
/* Roslindale Display Condensed as one variable font: every weight from 200
   to 900, italics (its "ital" axis) and optical sizes (finer when big,
   sturdier when small). The static Regular stands in until it's uploaded. */
@font-face { font-family: "Roslindale"; src: url("/fonts/roslindale-variable.woff2") format("woff2"); font-weight: 200 900; font-style: normal; font-display: swap; }
@font-face { font-family: "Roslindale"; src: url("/fonts/roslindale-variable.woff2") format("woff2"); font-weight: 200 900; font-style: italic; font-display: swap; }
@font-face { font-family: "Roslindale Display Condensed"; src: local("Roslindale Display Condensed Regular"), local("Roslindale-DisplayCondensedRegular"), url("/fonts/roslindale-display-condensed-regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "YaleNew"; src: local("YaleNew Regular"), local("YaleNew-Roman"), url("/fonts/yalenew-roman.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "YaleNew"; src: local("YaleNew Italic"), local("YaleNew-Italic"), url("/fonts/yalenew-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "YaleNew"; src: local("YaleNew Bold"), local("YaleNew-Bold"), url("/fonts/yalenew-bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "YaleNew"; src: local("YaleNew Bold Italic"), local("YaleNew-BoldItalic"), url("/fonts/yalenew-bolditalic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }
@font-face { font-family: "Old Style 7"; src: local("Old Style 7 Std Roman"), local("OldStyle7Std"), url("/fonts/oldstyle7-roman.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }

/* "Scheduler Text" is Old Style 7, which has only a roman, borrowing
   YaleNew's real italic and bold rather than letting browsers fake them. */
@font-face { font-family: "Scheduler Text"; src: local("Old Style 7 Std Roman"), local("OldStyle7Std"), url("/fonts/oldstyle7-roman.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Scheduler Text"; src: local("YaleNew Italic"), local("YaleNew-Italic"), url("/fonts/yalenew-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Scheduler Text"; src: local("YaleNew Bold"), local("YaleNew-Bold"), url("/fonts/yalenew-bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Scheduler Text"; src: local("YaleNew Bold Italic"), local("YaleNew-BoldItalic"), url("/fonts/yalenew-bolditalic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }

:root {
  /* Fonts: Roslindale for every heading and large figure, light, slim and
     tightly set, big; YaleNew for all text. Old Style 7 is used only when a
     reader picks it in the Appearance window (data-font, below). Free
     look-alikes stand in until the owner uploads the files on /owner. */
  --font-display: "Roslindale", "Roslindale Display Condensed", "Fraunces", "Instrument Serif", Georgia, serif;
  --font-text: "YaleNew", "Crimson Pro", Georgia, "Times New Roman", serif;
  --font-small: var(--font-text);
  --font-oldstyle: "Scheduler Text", "Old Style 7", "Old Style 7 Std", "Crimson Pro", Georgia, serif;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-ui: var(--font-text);
  --font-accent: var(--font-text);
  --font-body: var(--font-text);
  --display-weight: 700;
  /* Display weights (Roslindale's 200-900) and tracking, per level. Dark
     themes add a little weight (thin strokes look thinner on dark), and the
     high-contrast themes a lot. */
  --w-hero: 200; --w-h1: 210; --w-h2: 240; --w-h3: 310; --w-h4: 370; --w-num: 200; --w-brand: 380;
  --track-hero: -0.045em; --track-h1: -0.035em; --track-h2: -0.025em; --track-h3: -0.015em;
  --display-boost: 0;
  --on-accent: #fff;

  --bg: #ffffff;
  --dot: transparent;
  --card-bg: #ffffff;
  --surface-soft: #f6f6f8;
  --surface-strong: #ececf1;

  --text: #16161a;
  --muted: #63636e;
  --border: #e8e8ed;
  --border-strong: #d4d4dc;

  --accent: #4638d1;
  --accent-strong: #322aa8;
  --accent-soft: #ecebfe;
  --accent-btn-1: #4f46e5;
  --accent-btn-2: #4338ca;

  --primary: #4638d1;
  --primary-dark: #322aa8;

  --amber: #a15a06;
  --amber-soft: #fdf1de;

  --danger: #c0263f;
  --danger-bg: #fdeaed;
  --success: #157347;
  --success-bg: #e6f7ee;

  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --radius: var(--radius-lg);
  --radius-full: 999px;

  --shadow-sm: 0 1px 2px rgba(17, 17, 26, 0.05);
  --shadow-md: 0 8px 24px rgba(17, 17, 26, 0.06), 0 1px 3px rgba(17, 17, 26, 0.04);
  --shadow-lg: 0 24px 60px rgba(17, 17, 26, 0.14), 0 4px 14px rgba(17, 17, 26, 0.06);

  --glass-bg: rgba(255, 255, 255, 0.72);
  --glass-border: rgba(17, 17, 26, 0.07);
  --glass-shadow: 0 8px 32px rgba(17, 17, 26, 0.08);

  color-scheme: light;
}

[data-mode="dark"] {
  --bg: #0d0f1e;
  --dot: rgba(129, 140, 248, 0.09);
  --card-bg: #161930;
  --surface-soft: #1c2040;
  --surface-strong: #262b52;

  --text: #edeffb;
  --muted: #a0a4c6; /* (4.5:1 and more on the tinted boxes too) */
  --border: #2a2e56;
  --border-strong: #3a3f70;

  --accent: #9aa3fb;
  --accent-strong: #c2c8fd;
  --accent-soft: rgba(129, 140, 248, 0.16);

  --primary: #9aa3fb;
  --primary-dark: #c2c8fd;

  --amber: #f6bd52;
  --amber-soft: rgba(245, 158, 11, 0.16);

  --danger: #f8848f;
  --danger-bg: rgba(220, 38, 38, 0.18);
  --success: #58d896;
  --success-bg: rgba(21, 128, 61, 0.2);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 10px 28px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 24px 56px rgba(0, 0, 0, 0.5);

  --glass-bg: rgba(22, 25, 48, 0.55);
  --glass-border: rgba(255, 255, 255, 0.09);
  --glass-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);

  color-scheme: dark;
}

* { box-sizing: border-box; }

/* Base type scale. Everything sized in rem keys off this, so nudging it here
   scales the whole site at once. */
html {
  -webkit-text-size-adjust: 100%;
  font-size: calc(17px * var(--text-scale, 1));
}

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--text);
  min-height: 100vh;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
/* Links in the site's own color, not the browser's blue; any link with a
   style of its own (buttons, the footer, menus) keeps that. */
a { color: var(--accent-strong); text-underline-offset: 0.15em; }

.btn, .status-pill, .count-number {
  font-family: var(--font-body);
}
h1, h2, .card-heading, .brand-name, .modal-title {
  font-family: var(--font-display);
}

body,
.card,
.topbar,
input,
textarea,
select,
.btn,
.chip,
.tag,
.status-pill,
.rank-item {
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease,
    box-shadow 0.2s ease;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------
   Top bar — brand mark + theme toggle. Sits above every page.
   --------------------------------------------------------------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--glass-bg);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border-bottom: 1px solid var(--glass-border);
}

.topbar-inner {
  max-width: 792px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 16px;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  flex-wrap: nowrap;
}

/* Brand doubles as the Home link/icon */
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  text-decoration: none;
  padding: 4px 6px 4px 2px;
  margin: -4px 0 -4px -2px;
  border-radius: var(--radius-full);
  flex-shrink: 1;
}
.brand:active .brand-mark { transform: translateY(-1px); }
@media (hover: hover) { .brand:hover .brand-mark { transform: translateY(-1px); } }
.brand:focus-visible { outline-offset: 4px; }

.brand-mark {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s ease;
}
.brand-mark svg { width: 18px; height: 18px; }

.brand-name {
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: 0;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------------------------------------------------------------
   Icon dock — a single pill housing every icon action (nav links,
   the signed-in user's avatar, and the theme toggle).
   --------------------------------------------------------------- */
.icon-dock {
  display: flex;
  flex-wrap: wrap; /* (large text on a narrow window: wraps, never scrolls sideways) */
  max-width: 100%;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: var(--radius-full);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: var(--glass-shadow);
  flex-shrink: 0;
}

.icon-dock-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: none;
  background: none;
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  padding: 0;
  flex-shrink: 0;
}
.icon-dock-btn svg { width: 18px; height: 18px; }
@media (hover: hover) { .icon-dock-btn:hover { background: var(--accent-soft); color: var(--accent-strong); } }
.icon-dock-btn:active { transform: scale(0.93); }
.icon-dock-btn[aria-expanded="true"] { background: var(--accent-soft); color: var(--accent-strong); }
.icon-dock-btn[aria-current="page"] { background: var(--accent-soft); color: var(--accent-strong); }
.icon-dock-btn.dock-empty { opacity: 0.55; }
.stats-list { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 14px; }
.stats-sheet { padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-md, 12px); }
.stats-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px; align-items: baseline; }
.stats-title { font-weight: 700; font-size: 1.05rem; }
.stats-bar { display: block; width: 100%; height: 10px; margin: 10px 0 6px; border: 0; border-radius: 99px;
  background: var(--surface-soft, rgba(0, 0, 0, 0.06)); overflow: hidden; appearance: none; -webkit-appearance: none; }
.stats-bar::-webkit-progress-bar { background: var(--surface-soft, rgba(0, 0, 0, 0.06)); border-radius: 99px; }
.stats-bar::-webkit-progress-value { background: var(--accent); border-radius: 99px; }
.stats-bar::-moz-progress-bar { background: var(--accent); border-radius: 99px; }
.stats-line { margin: 0 0 4px; }
.stats-actions { margin-top: 10px; }
.stats-closed-heading { margin-top: 24px; }
.warn-text { color: var(--danger, #9b2c1f); }
.dock-sep { width: 1px; height: 22px; margin: 0 3px; background: var(--border); flex-shrink: 0; }
/* Each icon's name, right under it, at once on hover or keyboard focus
   (and "Copied" after a copy). Its window open: no tip over it. */
.dock-tip::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 7px);
  left: 50%;
  transform: translate(-50%, -3px);
  padding: 5px 9px;
  border-radius: 7px;
  background: var(--text);
  color: var(--bg);
  font: 600 0.76rem/1.2 var(--font-sans);
  letter-spacing: 0;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 80ms ease, transform 80ms ease, visibility 0s linear 80ms;
  z-index: 80;
}
.dock-tip:focus-visible::after, .dock-tip.tip-show::after {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s;
}
@media (hover: hover) { .dock-tip:hover::after {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s;
} }
.dock-tip.tip-end::after { left: auto; right: 0; transform: translateY(-3px); }
.dock-tip.tip-end:focus-visible::after, .dock-tip.tip-end.tip-show::after { transform: none; }
@media (hover: hover) { .dock-tip.tip-end:hover::after { transform: none; } }
.dock-tip[aria-expanded="true"]::after { display: none; }
/* Touch screens: no tips (a tap acts at once, and the names show as words,
   below); "Copied" still shows. */
@media (hover: none) { .dock-tip:not(.tip-show)::after { display: none; } }
@media (prefers-reduced-motion: reduce) { .dock-tip::after { transition: none; } }

/* ---------------------------------------------------------------
   The top bar on touch screens, where there's no hover to show a
   tip: each icon's name as a word. Tablets: a word beside each icon,
   in 44px pills; where they don't all fit, How ranking works and
   Appearance fold into the gear, renamed More (both are tiles in
   its window). Phones: the bar scrolls away with the page and holds
   the brand mark (Home) and the class or page you're on; the places
   move to the tab bar along the bottom (below). Pages without the
   tab bar (signed out, signing in) keep Help and Appearance up here,
   each with a word under it.
   --------------------------------------------------------------- */
.topbar-title, .dock-word, .word-more { display: none; }
/* The phone tab bar's More: its window says "More", and leaves out what the
   tab bar under it already goes to. */
.window-more { display: none; }
@media (max-width: 640px) {
  body.has-tabbar .window-settings, body.has-tabbar #account [data-in-tabbar] { display: none; }
  body.has-tabbar .window-more { display: inline; }
}
@media (pointer: coarse) and (min-width: 641px) {
  .topbar-inner { padding-top: 7px; padding-bottom: 7px; }
  .icon-dock { gap: 4px; }
  .icon-dock-btn { width: auto; min-width: 44px; height: 44px; gap: 6px; padding: 0 13px 0 11px; border-radius: var(--radius-full); }
  .icon-dock-btn .dock-word { display: inline; font: 600 0.8rem/1 var(--font-sans); letter-spacing: 0; white-space: nowrap; }
  /* (signed in: the words need the brand name's room) */
  .topbar:has([data-dock="fold"]) .brand-name { display: none; }
}
@media (pointer: coarse) and (min-width: 641px) and (max-width: 960px) {
  .icon-dock [data-dock="fold"], .word-settings { display: none; }
  .word-more { display: inline; }
}
/* Short screens (a phone on its side) and while typing on a touch screen:
   the top bar scrolls away with the page, leaving the room to what's being
   read or typed. */
@media (pointer: coarse) and (max-height: 500px) { .topbar { position: static; } }
html.kb-open .topbar { position: static; }
@media (max-width: 640px) {
  .topbar { position: static; backdrop-filter: none; -webkit-backdrop-filter: none; }
  .topbar-inner {
    min-height: 51px; padding: 3px 12px; gap: 8px;
    padding-left: max(12px, env(safe-area-inset-left, 0px)); padding-right: max(12px, env(safe-area-inset-right, 0px));
  }
  /* The class's name is in the top bar: not again just under it. */
  body:has(.topbar-title:not(:empty)) .eyebrow-sheet { display: none; }
  .brand { flex: 0 0 auto; padding: 5px; margin: 0 -5px; }
  .brand-name { display: none; }
  .topbar-title {
    display: block; flex: 1 1 auto; min-width: 0; margin-right: auto;
    font-family: var(--font-display); font-size: 1.15rem; line-height: 1.2; letter-spacing: -0.01em;
    font-weight: calc(var(--w-brand) + var(--display-boost)); color: var(--text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  body.has-tabbar .icon-dock, .icon-dock [data-dock="nav"], .dock-sep { display: none; }
  .icon-dock {
    flex-wrap: nowrap; gap: 2px; padding: 0; border: 0; background: none; box-shadow: none;
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .icon-dock-btn { flex-direction: column; width: auto; min-width: 48px; height: 44px; gap: 3px; padding: 2px 4px; border-radius: 12px; }
  .icon-dock-btn svg { width: 20px; height: 20px; }
  .icon-dock-btn .dock-word { display: block; font: 600 0.68rem/1 var(--font-sans); letter-spacing: 0; white-space: nowrap; }
}

/* ---------------------------------------------------------------
   The tab bar: a phone's main places along the bottom of the
   screen, within reach of a thumb, each a picture over its name.
   Bars pinned to the bottom of the screen (Save, Back and Next)
   sit just above it with bottom: var(--tabbar-h), and pad
   themselves with var(--safe-bottom): the iPhone's home bar, when
   there's no tab bar under them. It steps aside while the
   on-screen keyboard is up (html.kb-open, set by app.js), while a
   day is being dragged, and on short screens while the page
   scrolls down (html.tabbar-tucked, app.js). An open window
   covers it.
   --------------------------------------------------------------- */
:root { --tabbar-h: 0px; --safe-bottom: env(safe-area-inset-bottom, 0px); }
.tabbar { display: none; }
@media (max-width: 640px) {
  body.has-tabbar {
    --tabbar-h: calc(56px + env(safe-area-inset-bottom, 0px));
    --safe-bottom: 0px;
    /* (the end of the page, footer and all, clear of the bar) */
    padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px));
  }
  .tabbar {
    display: flex; position: fixed; z-index: 50; left: 0; right: 0; bottom: 0;
    height: calc(56px + env(safe-area-inset-bottom, 0px));
    padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
    background: var(--card-bg);
    border-top: 1px solid var(--border);
    transition: transform 0.2s ease, visibility 0s linear 0s;
  }
  .tabbar-item {
    flex: 1 1 0; min-width: 0; height: 56px; margin: 0; padding: 0 2px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    border: 0; border-radius: 0; background: none; color: var(--muted);
    font: 600 clamp(11.5px, 0.7rem, 15px)/1.15 var(--font-sans); letter-spacing: 0;
    text-decoration: none; cursor: pointer;
    -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none;
  }
  .tabbar-icon {
    display: flex; align-items: center; justify-content: center;
    width: 52px; height: 28px; border-radius: 14px; transition: background-color 0.15s ease;
  }
  .tabbar-icon svg { width: 22px; height: 22px; }
  .tabbar-label { max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tabbar-item[aria-current], .tabbar-item[aria-expanded="true"] { color: var(--accent-strong); }
  .tabbar-item[aria-current] .tabbar-icon { background: var(--accent-soft); }
  .tabbar-item:active .tabbar-icon { background: var(--surface-strong); }
  .tabbar-item:focus-visible { outline-offset: -3px; }
  html.kb-open body.has-tabbar { --tabbar-h: 0px; --safe-bottom: env(safe-area-inset-bottom, 0px); }
  html.kb-open .tabbar, body.is-dragging .tabbar {
    transform: translateY(100%); visibility: hidden; transition: transform 0.2s ease, visibility 0s linear 0.2s;
  }
}
@media (max-width: 640px) and (max-height: 500px) {
  html.tabbar-tucked body.has-tabbar { --tabbar-h: 0px; --safe-bottom: env(safe-area-inset-bottom, 0px); }
  html.tabbar-tucked .tabbar {
    transform: translateY(100%); visibility: hidden; transition: transform 0.2s ease, visibility 0s linear 0.2s;
  }
}
[data-theme^="contrast"] .tabbar { border-top-width: 2px; }

/* Text-label dock buttons — used where a bare pictogram (an eye, a list)
   would be ambiguous, e.g. Rank vs Results. Same footprint/behavior as
   .icon-dock-btn, but sized to its word instead of a fixed circle. */
.icon-dock-label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  padding: 0 14px;
  border-radius: var(--radius-full);
  color: var(--text);
  font-weight: 600;
  font-size: 0.86rem;
  white-space: nowrap;
  text-decoration: none;
  flex-shrink: 0;
}
@media (hover: hover) { .icon-dock-label:hover { background: var(--accent-soft); color: var(--accent-strong); } }
.icon-dock-label:active { transform: scale(0.96); }

/* Avatar variant of the dock button — student initials */
.icon-dock-avatar {
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  color: #fff;
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.01em;
}
@media (hover: hover) { .icon-dock-avatar:hover { background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2)); filter: brightness(1.08); color: #fff; } }

/* Theme toggle sun/moon crossfade, now living inside the dock */
.theme-toggle-icon {
  position: absolute;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.25s ease, transform 0.35s ease;
}
.theme-toggle-icon svg { width: 100%; height: 100%; }
.icon-sun { opacity: 1; transform: rotate(0deg) scale(1); }
.icon-moon { opacity: 0; transform: rotate(-70deg) scale(0.5); }

/* ---------------------------------------------------------------
   Popovers — a dropdown anchored to a trigger (user menu) and a
   centered modal (info pop-ups, e.g. the homepage format note).
   --------------------------------------------------------------- */
.popover-wrap { position: relative; }

.popover-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 208px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 6px;
  z-index: 60;
}
.popover-dropdown.open { display: block; }
.popover-name {
  padding: 9px 10px 3px;
  font-weight: 650;
  font-size: 0.95rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.popover-sub {
  padding: 0 10px 8px;
  margin-bottom: 4px;
  font-size: 0.8rem;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
}
.popover-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 9px 10px;
  border-radius: 8px;
  border: none;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
  text-align: left;
  cursor: pointer;
  text-decoration: none;
}
@media (hover: hover) { .popover-item:hover { background: var(--accent-soft); color: var(--accent-strong); } }
.popover-item svg { width: 16px; height: 16px; flex-shrink: 0; }
@media (hover: hover) { .popover-item.danger:hover { background: var(--danger-bg); color: var(--danger); } }

.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(10, 12, 30, 0.45);
  align-items: center;
  align-items: safe center; /* a window taller than the screen starts at its top */
  justify-content: center;
  padding: 20px;
}
.modal-overlay.open { display: flex; }
/* The page behind an open window doesn't scroll (popover.js), nor pull to
   refresh. */
.page-frozen, .page-frozen body { overflow: hidden; }
.page-frozen { overscroll-behavior: none; }
.page-frozen body { padding-right: calc(var(--scrollbar-gap, 0px) + env(safe-area-inset-right, 0px)); }
.modal-dialog { overscroll-behavior: contain; }
/* No taller than the screen as it is now (100dvh: with the phone browser's
   bars showing), scrolling inside when there's more. */
.modal-dialog {
  --dialog-pad: 26px;
  position: relative;
  width: 100%;
  max-width: 420px;
  max-height: calc(100vh - 40px);
  max-height: min(90vh, calc(100dvh - 40px));
  overflow-y: auto;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--dialog-pad);
}
/* A window's buttons along its bottom (Done) stay in sight while the rest
   scrolls: they stick to its bottom edge, on the window's own color, so
   what scrolls under them is hidden. */
.modal-dialog:has(> .appearance-foot, > .dialog-actions) { padding-bottom: 0; }
.modal-dialog > .appearance-foot,
.modal-dialog > .dialog-actions {
  position: sticky;
  bottom: 0;
  z-index: 2;
  margin-left: calc(-1 * var(--dialog-pad));
  margin-right: calc(-1 * var(--dialog-pad));
  padding-left: var(--dialog-pad);
  padding-right: var(--dialog-pad);
  padding-bottom: var(--dialog-pad);
  background: linear-gradient(var(--glass-bg), var(--glass-bg)), var(--bg);
}
.modal-dialog > .appearance-foot {
  border-top: 0;
  padding-top: 17px; /* the 1px line is drawn inside it */
  background:
    linear-gradient(var(--border), var(--border)) var(--dialog-pad) 0 / calc(100% - 2 * var(--dialog-pad)) 1px no-repeat,
    linear-gradient(var(--glass-bg), var(--glass-bg)), var(--bg);
}
html.kb-open .modal-dialog > .appearance-foot,
html.kb-open .modal-dialog > .dialog-actions { position: static; }
.modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: var(--surface-soft);
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
@media (hover: hover) { .modal-close:hover { background: var(--surface-strong); color: var(--text); } }
.modal-close:active { background: var(--surface-strong); }
.modal-close svg { width: 16px; height: 16px; }
.modal-title { margin: 0 0 10px; font-size: 1.2rem; font-weight: 650; padding-right: 26px; }
.modal-body { margin: 0; color: var(--muted); line-height: 1.6; font-size: 1rem; }

/* Phones: every window is a sheet that comes up from the bottom of the
   screen, the full width, with a grab handle on top. The handle, the title
   and the close button stay at the top and the buttons (Done) at the
   bottom while the middle scrolls. A swipe down on the top closes it
   (popover.js), as do Back, a tap above it and Escape. The sheet is solid
   (no frosted glass), which is quicker to draw on modest phones. */
@media (max-width: 640px) {
  .modal-overlay { align-items: flex-end; padding: 0; }
  .modal-overlay > .modal-dialog {
    --dialog-pad: 16px;
    max-width: none;
    max-height: calc(100vh - 12px);
    max-height: calc(100dvh - 12px - env(safe-area-inset-top, 0px));
    padding: 0 max(var(--dialog-pad), env(safe-area-inset-right, 0px)) 0 max(var(--dialog-pad), env(safe-area-inset-left, 0px));
    border-width: 1px 0 0;
    border-radius: 20px 20px 0 0;
    background: var(--card-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: 0 -12px 40px rgba(17, 17, 26, 0.18);
    overscroll-behavior: none;
    transform: translateY(var(--sheet-drag, 0px));
    transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
    animation: sheet-in 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .modal-overlay > .modal-dialog.is-dragged { transition: none; }
  .modal-overlay > .modal-dialog.is-leaving { transform: translateY(100%); transition-duration: 0.18s; }
  /* The grab handle, on a band that stays at the top. */
  .modal-overlay > .modal-dialog::before {
    content: ""; position: sticky; top: 0; z-index: 3; display: block; height: 20px;
    margin: 0 calc(-1 * var(--dialog-pad));
    background: linear-gradient(var(--border-strong), var(--border-strong)) 50% 8px / 40px 5px no-repeat, var(--card-bg);
  }
  .modal-overlay > .modal-dialog > .modal-close {
    position: sticky; top: 20px; right: auto; z-index: 4; margin: 0 -6px -44px auto; width: 44px; height: 44px;
  }
  .modal-overlay > .modal-dialog > .modal-title {
    position: sticky; top: 20px; z-index: 3;
    margin: 0 calc(-1 * var(--dialog-pad)) 8px; padding: 6px 58px 10px var(--dialog-pad);
    background: var(--card-bg); font-size: min(1.45rem, 34px); overflow-wrap: anywhere;
  }
  .modal-overlay > .modal-dialog > .appearance-foot,
  .modal-overlay > .modal-dialog > .dialog-actions {
    flex-wrap: wrap;
    margin-top: 16px;
    padding-top: 12px;
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--card-bg);
    border-top: 1px solid var(--border);
  }
  /* Room under the last thing in a window with no buttons along its
     bottom, clear of the home bar. */
  .modal-overlay > .modal-dialog::after {
    content: ""; display: block; height: calc(20px + env(safe-area-inset-bottom, 0px));
  }
  .modal-overlay > .modal-dialog:has(> .appearance-foot, > .dialog-actions)::after { content: none; }
  /* The calendars fill the screen: no handle, and no band under their Done. */
  #day-calendar .modal-dialog::before, #deadline-calendar .modal-dialog::before,
  #day-calendar .modal-dialog::after, #deadline-calendar .modal-dialog::after { content: none; }
}
@keyframes sheet-in { from { transform: translateY(100%); } }

/* Kept for any inline glass buttons still in use on individual pages */
.icon-btn.glass {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px 9px 13px;
  border-radius: var(--radius-full);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: var(--glass-shadow);
  color: var(--text);
  font-weight: 600;
  font-size: 0.88rem;
  text-decoration: none;
}
@media (hover: hover) { .icon-btn.glass:hover { transform: translateY(-1px); color: var(--accent); } }
.icon-btn.glass:active { transform: scale(0.97); }
.icon-btn.glass svg { width: 16px; height: 16px; flex-shrink: 0; }

.page {
  max-width: 760px;
  margin: 0 auto;
  padding: 28px 16px 64px;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-md);
}

.center-card {
  max-width: 420px;
  margin: 8vh auto 0;
  text-align: center;
}

h1 { margin: 0 0 8px; font-size: 1.6rem; font-weight: 700; letter-spacing: -0.015em; }
h2 { margin: 32px 0 12px; font-size: 1.12rem; font-weight: 650; letter-spacing: -0.01em; }
h3 { margin: 0 0 8px; font-size: 1rem; font-weight: 650; }
.move-heading { margin-top: 24px; }

.subtitle { color: var(--muted); margin: 0 0 20px; line-height: 1.5; }
.subtitle.locked { color: var(--muted); } /* (closed is how it should be: nothing wrong) */
/* On a phone the tab bar goes to My ranking and Schedule: home's own tiles
   for them, and the schedule's Back, would say it twice. */
@media (max-width: 640px) { body.has-tabbar .home-tile-tabbed, body.has-tabbar .back-link-tabbed { display: none; } }
.mini-hint { color: var(--muted); font-size: 0.88rem; margin: 12px 0 0; }
.hint { color: var(--muted); font-size: 0.88rem; margin-top: 16px; }
.muted { color: var(--muted); }

.stack { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }

input[type="text"], input[type="password"], input[type="number"], input[type="email"], input[type="search"],
input[type="file"], select, textarea {
  font: inherit;
  font-size: max(16px, 1em);
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text);
}
input[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus,
input[type="email"]:focus, input[type="search"]:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--card-bg);
  box-shadow: 0 0 0 4px var(--accent-soft);
}

.btn {
  font: inherit;
  font-weight: 600;
  border: none;
  border-radius: var(--radius-sm);
  padding: 10px 18px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
  text-decoration: none;
  display: inline-block;
}
@media (hover: hover) { .btn:hover { transform: translateY(-1px); } }
.btn:active { transform: scale(0.98); }
.btn-primary {
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  color: var(--on-accent);
  box-shadow: var(--shadow-sm);
}
@media (hover: hover) { .btn-primary:hover { box-shadow: var(--shadow-md); } }
.btn-secondary { background: var(--accent-soft); color: var(--accent-strong); }
@media (hover: hover) { .btn-secondary:hover { background: var(--surface-strong); } }
.btn-danger { background: var(--danger-bg); color: var(--danger); }
@media (hover: hover) { .btn-danger:hover { filter: brightness(0.97); } }

.link-muted { color: var(--muted); font-size: 0.9rem; text-decoration: none; }
@media (hover: hover) { .link-muted:hover { text-decoration: underline; color: var(--accent); } }

/* Name autocomplete */
.name-autocomplete { position: relative; }
.suggestions-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 6px;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  max-height: 240px;
  overflow-y: auto;
  z-index: 20;
}
.suggestion-item {
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.95rem;
}
.suggestion-item.active {
  background: var(--accent-soft);
  color: var(--accent-strong);
}
@media (hover: hover) { .suggestion-item:hover {
  background: var(--accent-soft);
  color: var(--accent-strong);
} }
/* Under a finger, with the keyboard up (name-autocomplete.js): no taller
   than the room the keyboard leaves, and above the box when there's no
   room for two names under it. */
@media (pointer: coarse) {
  .suggestions-list { max-height: min(240px, var(--suggest-room, 240px)); overscroll-behavior: contain; }
  .suggestions-list.opens-up { top: auto; bottom: 100%; margin: 0 0 6px; }
}
.roster-row { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; flex-wrap: wrap; }

.flash-stack { margin-bottom: 16px; display: flex; flex-direction: column; gap: 8px; }
.flash { padding: 10px 14px; border-radius: var(--radius-sm); font-size: 0.9rem; }
.flash-error { background: var(--danger-bg); color: var(--danger); }
.flash-success { background: var(--success-bg); color: var(--success); }

/* Home page */
.status-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  margin: 16px 0;
  font-size: 0.95rem;
  border: 1px solid transparent;
}
.status-icon { font-size: 1.1rem; flex-shrink: 0; }
.status-done { background: var(--success-bg); color: var(--success); }
.status-pending { background: var(--amber-soft); color: var(--amber); }

.count-card {
  text-align: center;
  padding: 22px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin: 16px 0;
}
.count-number {
  font-size: 2.1rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
[data-mode="dark"] .count-number {
  background: linear-gradient(135deg, var(--accent), var(--accent-strong));
  -webkit-background-clip: text;
  background-clip: text;
}
.count-label { color: var(--muted); font-size: 0.9rem; margin-top: 4px; }

.home-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }

.nav-links { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* Preview disclaimers */
.disclaimer {
  padding: 12px 16px;
  border-radius: var(--radius-md);
  margin: 16px 0;
  font-size: 0.9rem;
  line-height: 1.5;
  border: 1px solid transparent;
}
.disclaimer-red { background: var(--danger-bg); color: var(--danger); font-weight: 600; }
.disclaimer-yellow { background: var(--amber-soft); color: var(--amber); font-weight: 600; }
.disclaimer-neutral { background: var(--accent-soft); color: var(--accent-strong); }

/* Verify page */
.code-input {
  font: inherit;
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.45em;
  text-align: center;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text);
}
.code-input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--card-bg);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
/* A new PIN's boxes: dots, as in a password box, without being one (so
   phones don't offer a "strong password" there). "Show the PIN" sits under
   them, on the right. */
.pin-input { -webkit-text-security: disc; }
.pin-input.is-shown { -webkit-text-security: none; }
.pin-show { align-self: flex-end; margin-top: -4px; }
.pin-show[hidden] { display: none; }
.verify-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 16px;
  flex-wrap: wrap;
  gap: 10px;
}
.resend-form { margin: 0; }

/* ---------------------------------------------------------------
   Tooltips — a small "?" button that reveals a bubble on hover,
   keyboard focus, or tap. No library; popover.js handles the tap
   case by toggling .tip-open.
   --------------------------------------------------------------- */
.tip { position: relative; display: inline-flex; vertical-align: middle; }
.tip-btn {
  width: 19px;
  height: 19px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: var(--card-bg);
  color: var(--muted);
  font: inherit;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: help;
  padding: 0;
}
@media (hover: hover) { .tip-btn:hover { background: var(--accent-soft); color: var(--accent-strong); border-color: var(--accent); } }
.tip-bubble {
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%) translateY(3px);
  width: max-content;
  max-width: min(268px, 72vw);
  background: var(--text);
  color: var(--card-bg);
  font-size: 0.82rem;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 70;
  pointer-events: none;
}
.tip-bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border: 5px solid transparent;
  border-top-color: var(--text);
}
/* A closed "?" bubble takes no room at all (not just invisible), or its
   box would make a narrow phone's page wider than the screen. */
.tip > .tip-bubble { display: none; }
.tip-btn:focus-visible + .tip-bubble, .tip.tip-open .tip-bubble {
  display: block;
  opacity: 1;
  visibility: visible;
  /* --tip-shift (set by rank.js) nudges an open bubble back inside the
     screen; the arrow moves the other way, so it still points at the "?". */
  transform: translateX(calc(-50% + var(--tip-shift, 0px))) translateY(0);
}
@media (hover: hover) { .tip:hover .tip-bubble {
  display: block;
  opacity: 1;
  visibility: visible;
  /* --tip-shift (set by rank.js) nudges an open bubble back inside the
     screen; the arrow moves the other way, so it still points at the "?". */
  transform: translateX(calc(-50% + var(--tip-shift, 0px))) translateY(0);
} }
.tip-btn:focus-visible + .tip-bubble::after, .tip.tip-open .tip-bubble::after { margin-left: calc(-5px - var(--tip-shift, 0px)); }
@media (hover: hover) { .tip:hover .tip-bubble::after { margin-left: calc(-5px - var(--tip-shift, 0px)); } }
/* Bubbles near the right edge flip so they don't run off screen */
.tip.tip-right .tip-bubble { left: auto; right: -4px; transform: translateX(0) translateY(3px); }
.tip.tip-right .tip-bubble::after { left: auto; right: calc(10px + var(--tip-shift, 0px)); margin-left: 0; }
.tip.tip-right .tip-btn:focus-visible + .tip-bubble, .tip.tip-right.tip-open .tip-bubble { transform: translateX(var(--tip-shift, 0px)) translateY(0); }
@media (hover: hover) { .tip.tip-right:hover .tip-bubble { transform: translateX(var(--tip-shift, 0px)) translateY(0); } }
/* The fade in, now that a closed bubble isn't displayed at all. */
@starting-style {
  .tip:hover .tip-bubble,
  .tip-btn:focus-visible + .tip-bubble,
  .tip.tip-open .tip-bubble { opacity: 0; transform: translateX(calc(-50% + var(--tip-shift, 0px))) translateY(3px); }
  .tip.tip-right:hover .tip-bubble,
  .tip.tip-right .tip-btn:focus-visible + .tip-bubble,
  .tip.tip-right.tip-open .tip-bubble { transform: translateX(var(--tip-shift, 0px)) translateY(3px); }
}

/* ---------------------------------------------------------------
   Rank page
   --------------------------------------------------------------- */
.rank-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }

/* Three-step "what am I looking at" strip above the list */
.steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 10px;
  margin: 18px 0 6px;
  padding: 0;
}
.step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: 0.92rem;
  line-height: 1.4;
}
.step-num {
  flex-shrink: 0;
  width: 23px;
  height: 23px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.step-optional { color: var(--muted); }

/* Collapsible "more detail" explainer */
.explainer {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card-bg);
  padding: 0 14px;
  margin: 14px 0 4px;
}
.explainer > summary {
  cursor: pointer;
  list-style: none;
  padding: 12px 0;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--accent-strong);
  display: flex;
  align-items: center;
  gap: 8px;
}
.explainer > summary::-webkit-details-marker { display: none; }
.explainer > summary::before {
  content: "▸";
  font-size: 0.8rem;
  transition: transform 0.15s ease;
}
.explainer[open] > summary::before { transform: rotate(90deg); }
.explainer-body { padding: 0 0 14px; color: var(--muted); font-size: 0.92rem; line-height: 1.6; }
.explainer-body p { margin: 0 0 10px; }
.explainer-body p:last-child { margin-bottom: 0; }
.explainer-body a { color: var(--accent); }

/* Most/least preferred rail above + below the list */
.rank-scale {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin: 18px 0 8px;
}
.rank-scale::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.rank-scale.bottom { margin: 10px 0 0; }

.rank-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.rank-item {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-left: 3px solid transparent;
  border-radius: var(--radius-md);
  padding: 12px 14px;
  /* A swipe that starts on a row scrolls the page (and pinch still zooms).
     Only the grip, and a row picked up by a long press, take the finger
     over: rank.js cancels the scroll while a drag is live. */
  touch-action: pan-y pinch-zoom;
}
.rank-item:first-child { border-left-color: var(--accent); background: var(--accent-soft); }
.rank-item.dragging {
  box-shadow: var(--shadow-lg);
  z-index: 10;
  position: relative;
  background: var(--card-bg);
  opacity: 0.97;
  cursor: grabbing;
  /* JS owns this row's transform while it's under the cursor */
  transition: none !important;
}
/* Whole-page state while a row is being dragged */
body.is-dragging { user-select: none; -webkit-user-select: none; cursor: grabbing; touch-action: none; overscroll-behavior: none; }
body.is-dragging .rank-item:not(.dragging) { pointer-events: none; }

/* Brief ring on a row that just moved via the arrow buttons, so the eye can
   follow where it went. */
.rank-item.just-moved { animation: just-moved-ring 0.7s ease-out; }
@keyframes just-moved-ring {
  0%   { box-shadow: 0 0 0 3px var(--accent-soft); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .rank-item.just-moved { animation: none; }
}
.rank-item.excluded { border-color: var(--border); border-left-color: var(--danger); background: var(--danger-bg); }
.rank-item.excluded .day-label { text-decoration: line-through; text-decoration-thickness: 1px; }
.rank-item-top { display: flex; align-items: center; gap: 10px; }
.drag-handle {
  cursor: grab;
  color: var(--muted);
  font-size: 1.2rem;
  padding: 2px 4px;
  border-radius: 6px;
  touch-action: none;
  user-select: none;
  flex-shrink: 0;
}
@media (hover: hover) { .drag-handle:hover { color: var(--accent); background: var(--card-bg); } }
.drag-handle:active { cursor: grabbing; }

/* Badge + its caption ("Top choice" / "Last choice") */
.rank-pos {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  width: 58px;
}
.rank-badge {
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  color: #fff;
  font-size: 0.8rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius-full);
  width: auto; min-width: 28px; padding: 0 0.3em;
  height: auto; min-height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.rank-item.excluded .rank-badge { background: var(--danger); }
.rank-pos-label {
  font-size: 0.68rem;
  font-weight: 650;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  text-align: center;
  line-height: 1.15;
}
.day-label { font-weight: 600; font-size: 1.05rem; flex: 1; min-width: 0; }

/* Up/down buttons — the accessible, no-drag-required path */
.rank-move { display: flex; flex-direction: column; gap: 3px; flex-shrink: 0; }
.rank-move button {
  width: 30px;
  height: 22px;
  border: 1px solid var(--border-strong);
  background: var(--card-bg);
  color: var(--muted);
  border-radius: 7px;
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  line-height: 1;
}
@media (hover: hover) { .rank-move button:hover:not(:disabled) { background: var(--accent-soft); color: var(--accent-strong); border-color: var(--accent); } }
.rank-move button:disabled { opacity: 0.35; cursor: default; }
.rank-move svg { width: 13px; height: 13px; }

/* Row of small toggles under the day name */
.rank-item-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 10px 0 0 68px;
}
.mini-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-strong);
  background: var(--card-bg);
  color: var(--muted);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}
@media (hover: hover) { .mini-toggle:hover { border-color: var(--accent); color: var(--accent-strong); } }
.mini-toggle input { margin: 0; accent-color: var(--danger); }
.mini-toggle.on { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); font-weight: 600; }
.note-toggle.has-note { border-color: var(--accent); color: var(--accent-strong); background: var(--accent-soft); }

.comment-wrap { margin: 10px 0 0 68px; }
.comment-box {
  width: 100%;
  min-height: 52px;
  resize: vertical;
  background: var(--card-bg);
  /* Never under 16px, even at a smaller text size: iPhones zoom into a
     smaller field and stay zoomed. */
  font-size: max(16px, 0.95rem);
  /* Typing a note: room for the bars below and above it on a phone. */
  scroll-margin-bottom: calc(var(--tabbar-h, 0px) + 96px);
  scroll-margin-top: 80px;
}
.comment-hint { display: block; font-size: 0.8rem; color: var(--muted); margin-top: 4px; }

/* Sticky save bar so the button is never scrolled out of reach */
.save-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 20px;
  position: sticky;
  /* Above the phone's tab bar, and clear of the iPhone's home bar. */
  bottom: var(--tabbar-h, 0px);
  padding: 14px 0 calc(4px + var(--safe-bottom, 0px));
  background: linear-gradient(to top, var(--card-bg) 72%, transparent);
  z-index: 5;
}
/* With the keyboard up, the bar gets out of the way of the note being typed. */
html.kb-open .save-row { position: static; }
.save-status { font-size: 0.9rem; color: var(--muted); }
.save-status.dirty { color: var(--amber); }
.save-status.success { color: var(--success); }
.save-status.error { color: var(--danger); }
/* rank.js gives phones a short version of each status (see the phone rules below). */
.save-status-short { display: none; }

/* ---------------------------------------------------------------
   Rank page on touch screens (phones, tablets, foldables): every
   control is a 44px target, ▲ and ▼ sit side by side, and hover
   bubbles open with a tap.
   --------------------------------------------------------------- */
@media (pointer: coarse) {
  .rank-move { flex-direction: row; gap: 8px; }
  .rank-move button { width: 44px; height: 44px; border-radius: 12px; touch-action: manipulation; }
  .rank-move svg { width: 18px; height: 18px; }
  .drag-handle {
    min-width: 44px; min-height: 44px; padding: 0;
    display: inline-grid; place-items: center; font-size: 1.4rem;
  }
  .rank-item-actions { gap: 12px; }
  .mini-toggle { min-height: 44px; padding: 8px 14px; white-space: normal; text-align: left; max-width: 100%; }
  .mini-toggle input { width: 22px; height: 22px; flex-shrink: 0; }
  .tip-btn { position: relative; width: 24px; height: 24px; font-size: 0.8rem; }
  .tip-btn::before { content: ""; position: absolute; inset: -10px; } /* a 44px hit area */
  .rank-pos-label { font-size: 0.78rem; }
  /* A long press picks a row up: no text selection or callout menu in the way. */
  .rank-item-top { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
}
/* The moment between pressing a row and it lifting off. */
.rank-item.pressing { box-shadow: 0 0 0 3px var(--accent-soft); }


/* ---------------------------------------------------------------
   Rank page on phones (and phones on their side): compact rows
   with a drawer each, a short intro, and a small Save bar.
   rank.js adds .rank-compact under the same media query.
   --------------------------------------------------------------- */
.rank-intro-short { display: none; }
.rank-list.rank-compact { gap: 8px; }
.rank-compact .rank-item { padding: 6px 2px 6px 8px; }
.rank-compact .rank-item-top { gap: 4px; min-height: 48px; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
/* The grip goes to the right edge, under a right thumb. */
.rank-compact .drag-handle { order: 3; }
.rank-compact .rank-move { gap: 6px; }
.rank-compact .rank-pos { width: auto; }
.rank-compact .rank-pos-label { display: none; } /* the badge and "↑ Favorite" already say it */
.day-toggle {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 2px 0 0;
  border: 0;
  border-radius: 10px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: pan-y pinch-zoom;
}
.day-toggle-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 0 1 auto; }
.rank-compact .day-label { font-size: 1rem; line-height: 1.25; overflow-wrap: break-word; }
.day-toggle-chevron { width: 16px; height: 16px; flex-shrink: 0; margin-left: 6px; color: var(--muted); transition: transform 0.15s ease; }
@media (max-width: 340px) { .rank-compact .drag-handle { display: none; } } /* (press and hold a day, as the intro says) */
@media (max-width: 380px) {
  /* (narrow windows: tighter edges, so the date has room) */
  .rank-compact .rank-move { gap: 4px; }
  main.page { padding-left: max(12px, env(safe-area-inset-left, 0px)); padding-right: max(12px, env(safe-area-inset-right, 0px)); }
  main.page > .card:has(.rank-list) { padding-left: 12px; padding-right: 12px; }
}
@media (max-width: 400px) { html:not(.text-large) .rank-compact .day-label { white-space: nowrap; overflow-wrap: normal; } }
.rank-item.open .day-toggle-chevron { transform: rotate(180deg); }
.rank-flags { display: flex; flex-wrap: wrap; gap: 4px 8px; }
.rank-flags[hidden], .rank-flag[hidden] { display: none; }
.rank-flag {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--font-small); font-size: 0.78rem; font-weight: 650; line-height: 1.3; color: var(--accent-strong);
}
.rank-flag svg { width: 13px; height: 13px; }
.rank-flag-cant { padding: 0 8px; border-radius: var(--radius-full); background: var(--danger-bg); color: var(--danger); border: 1px solid var(--danger); }
.rank-drawer { display: grid; gap: 10px; margin: 6px 6px 4px 0; padding-top: 10px; border-top: 1px solid var(--border); }
.rank-drawer[hidden] { display: none; }
.rank-jump { display: flex; flex-wrap: wrap; gap: 8px; }
.rank-jump .btn {
  flex: 1 1 0; min-width: 0; min-height: 44px; padding: 6px 10px;
  font-size: 0.92rem; line-height: 1.2; touch-action: manipulation;
}
.rank-compact .rank-item-actions { margin: 0; gap: 8px; }
.rank-compact .mini-toggle { min-height: 44px; padding: 8px 14px; white-space: normal; text-align: left; max-width: 100%; }
.rank-compact .mini-toggle input { width: 22px; height: 22px; flex-shrink: 0; }
.rank-drawer-help { margin: 0; font-family: var(--font-small); font-size: 0.85rem; line-height: 1.45; color: var(--muted); }
.rank-compact .comment-wrap { margin: 0; }
.rank-deadline-chip {
  width: fit-content; max-width: 100%; margin: 0 0 4px; padding: 3px 12px; border-radius: var(--radius-full);
  background: var(--accent-soft); color: var(--accent-strong); font-size: 0.88rem;
}
.rank-howto { margin-top: 12px; }
.rank-howto .steps { grid-template-columns: 1fr; margin: 0 0 12px; }
.rank-howto .step > .step-num { position: static; } /* (badges in the steps, not the corner) */
.rank-howto-heading { font-weight: 650; color: var(--text); }

@media (max-width: 640px), (max-height: 500px) and (pointer: coarse) {
  .rank-intro-long { display: none; }
  .rank-intro-short { display: block; }
  .rank-header .subtitle.rank-intro-short { margin: 0 0 10px; font-size: 0.95rem; }
  .rank-scale { margin: 12px 0 6px; }
  /* The Save bar: one row, at most 64px with the home bar. */
  .save-row {
    flex-wrap: nowrap;
    gap: 10px;
    margin-top: 12px;
    padding: 8px 0 calc(8px + var(--safe-bottom, 0px));
    background: var(--card-bg);
    box-shadow: 0 -1px 0 var(--border);
  }
  .save-row .btn-large { flex-shrink: 0; min-height: 48px; padding: 8px 16px; font-size: 1rem; }
  .save-row .save-status { flex: 1 1 0; min-width: 0; font-size: 0.85rem; line-height: 1.3; }
  .save-status-full { display: none; }
  .save-status-short { display: inline; }
  /* After the first save it shrinks to a status pill: changes save by
     themselves from then on, so no button is needed. Taps go through the
     space around the pill to the days behind it. */
  .save-row.saved { justify-content: center; background: none; box-shadow: none; pointer-events: none; padding-top: 6px; }
  .save-row.saved #save-btn { display: none; }
  .save-row.saved .save-status {
    flex: 0 1 auto;
    display: inline-flex; align-items: center; min-height: 36px; padding: 4px 12px; font-size: 0.8rem;
    border-radius: var(--radius-full); border: 1px solid var(--border);
    background: var(--card-bg); box-shadow: var(--shadow-md);
    pointer-events: none; text-align: center; /* (nothing on it to press: the row under it keeps its taps) */
    max-width: calc(100vw - 32px); overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
    transition: opacity 0.3s ease, transform 0.3s ease;
  }
  .save-row.saved .save-status-short { font-size: min(1em, 17px); }
  .save-row.saved.quiet .save-status { opacity: 0; transform: translateY(8px); }
}
@media (prefers-reduced-motion: reduce) { .save-row.saved.quiet .save-status { transform: none; } }

/* Admin */
.admin-card { max-width: 100%; }
.admin-header { display: flex; justify-content: space-between; align-items: center; }
.status-row { display: flex; align-items: center; gap: 14px; margin: 16px 0; flex-wrap: wrap; }
.status-pill { padding: 6px 14px; border-radius: var(--radius-full); font-size: 0.85rem; font-weight: 700; white-space: nowrap; flex-shrink: 0; }
.status-pill.pending { background: var(--amber-soft); color: var(--amber); }
/* A pill that explains itself: hover it (or focus its row) for why, and
   what's next. Right-aligned, since pills sit at the right edge. */
.status-tip { position: relative; cursor: help; }
.status-tip .tip-bubble {
  left: auto; right: -4px; transform: translateY(3px);
  white-space: normal; font-family: var(--font-small); font-size: 0.86rem; letter-spacing: 0;
}
.status-tip .tip-bubble::after { left: auto; right: 22px; margin-left: 0; }
.status-tip:focus-visible .tip-bubble, .sheet-item:focus-visible .status-tip .tip-bubble { opacity: 1; visibility: visible; transform: translateY(0); }
@media (hover: hover) { .status-tip:hover .tip-bubble { opacity: 1; visibility: visible; transform: translateY(0); } }
.status-pill.open { background: var(--success-bg); color: var(--success); }
.status-pill.closed { background: var(--danger-bg); color: var(--danger); }
.submission-count { color: var(--muted); font-size: 0.9rem; }
.capacity-row { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.capacity-row input { width: 70px; }
.capacity-row select { flex: 1 1 220px; min-width: 180px; max-width: 100%; }

/* Algorithm comparison page */
.algo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 16px; }
.algo-card { background: var(--surface-soft); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.algo-card.current { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.algo-card h3 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.algo-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; margin: 4px 0; }
.algo-stat-value { font-size: 1.3rem; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--accent-strong); }
.algo-stat-label { font-size: 0.82rem; color: var(--muted); }
.algo-desc { font-size: 0.9rem; color: var(--muted); line-height: 1.5; }
.algo-form { margin-top: auto; }

.table-wrap { overflow-x: auto; position: relative; } /* (its hidden headers stay inside it: no sideways scroll on a phone) */
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.93rem; }
.admin-table th, .admin-table td {
  text-align: left;
  padding: 10px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.admin-table th { color: var(--muted); font-weight: 650; }
@media (hover: hover) { .admin-table tbody tr:hover { background: var(--surface-soft); } }
.chip {
  display: inline-block;
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-radius: var(--radius-full);
  padding: 2px 10px;
  font-size: 0.84rem;
}
.chip-danger { background: var(--danger-bg); color: var(--danger); margin-right: 4px; }
.comment-note { font-size: 0.85rem; color: var(--muted); margin-bottom: 4px; }
/* A ranking's chips carry their place (1 = favorite) only as cards, below;
   a wide table already reads left to right, with arrows. */
.chip-num { display: none; }
.tag-why { display: block; margin-top: 3px; font-size: 0.82rem; font-weight: 400; color: var(--muted); }
@media (min-width: 901px) { .tag-why { display: none; } }
@media (max-width: 900px), (horizontal-viewport-segments: 2) {
  /* Sign-ups and the class list as one card per student: each part named
     (data-label), its buttons in a row underneath, Delete last. */
  .table-wrap:has(#signups-table), .table-wrap:has(.roster-table) { overflow: visible; }
  #signups-table thead, .roster-table thead { display: none; }
  #signups-table, #signups-table tbody, #signups-table tr, #signups-table td,
  .roster-table, .roster-table tbody, .roster-table tr, .roster-table td { display: block; width: auto; }
  #signups-table tr, .roster-table tr { padding: 12px 0; border-bottom: 1px solid var(--border); }
  #signups-table tbody tr:hover, .roster-table tbody tr:hover { background: none; }
  #signups-table td, .roster-table td { border: 0; padding: 4px 0; }
  #signups-table td[data-label]:empty { display: none; }
  #signups-table td[data-label]::before {
    content: attr(data-label); display: block; margin-bottom: 4px; font-size: 0.8rem; font-weight: 650; color: var(--muted);
  }
  .signup-name, .roster-name { font-size: 1.02rem; font-weight: 650; overflow-wrap: anywhere; }
  .rank-chips { display: flex; flex-wrap: wrap; gap: 6px; }
  .rank-chips .chip { white-space: nowrap; }
  .chip-arrow { display: none; }
  .chip-num {
    display: inline-grid; place-items: center; min-width: 1.4em; height: 1.4em; margin-right: 6px; border-radius: 999px;
    background: var(--accent-strong); color: var(--card-bg); font-size: 0.75em; font-weight: 700;
  }
  .signup-saved { white-space: normal; }
  .roster-address { display: block; overflow: hidden; text-overflow: ellipsis; }
  .signup-actions .row-actions, .roster-table .row-actions { gap: 12px; margin-top: 4px; }
  .row-actions .row-delete { margin-left: auto; padding-left: 16px; } /* (Delete apart from the rest) */
  .roster-table details.row-edit[open] { display: block; width: 100%; }
  .roster-table details.row-edit[open] form { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
  .roster-table details.row-edit input { width: 100%; flex: 0 0 auto; } /* (in a column, flex: 1 1 200px would make each box 200px tall) */
}
.admin-table input { font-size: max(16px, 1rem); } /* (iOS zooms in on a smaller field) */

.day-columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin-top: 16px; }
.day-column { background: var(--surface-soft); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px; }
.assign-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.assign-list li { font-size: 0.93rem; padding: 4px 0 4px 8px; border-bottom: 1px dashed var(--border); border-left: 2px solid transparent; }
.assign-list li.flagged { color: var(--danger); border-left-color: var(--danger); }
.assign-index {
  display: inline-block;
  min-width: 1.4em;
  color: var(--muted);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.assign-list li.flagged .assign-index { color: var(--danger); }
.tag {
  font-size: 0.74rem;
  background: var(--accent-soft);
  color: var(--accent-strong);
  border-radius: var(--radius-full);
  padding: 1px 8px;
  margin-left: 6px;
}
.tag-danger { background: var(--danger-bg); color: var(--danger); }

.manual-move-row { display: flex; gap: 8px; align-items: center; margin: 12px 0; flex-wrap: wrap; }
/* A dropdown is as wide as its longest choice ("Maximiliana … (now Tue,
   Nov 17)"), and a file box as wide as its words: on a phone either one
   made the whole page wider than the screen, so it opened zoomed out and
   slid sideways under the thumb. Neither is ever wider than its row. */
select, input[type="file"] { max-width: 100%; min-width: 0; }
select { text-overflow: ellipsis; }

@media (max-width: 480px) {
  .card { padding: 20px; border-radius: var(--radius-md); }
  .rank-header { flex-direction: column; }
  .rank-pos { width: 46px; }
  .rank-item-actions, .comment-wrap { margin-left: 0; }
  .rank-item-top { gap: 8px; }
  .day-label { font-size: 1rem; }
  .steps { grid-template-columns: 1fr; }
  .brand-name { display: none; }
  .icon-dock-label { height: 34px; padding: 0 10px; font-size: 0.78rem; }
  .popover-dropdown { right: -6px; min-width: 190px; }
}

/* Homepage — simplified action tiles */
.home-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.home-hero h1 { margin: 0; }
.info-trigger {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
@media (hover: hover) { .info-trigger:hover { background: var(--accent-soft); color: var(--accent-strong); } }
.info-trigger svg { width: 18px; height: 18px; }

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px;
  border-radius: var(--radius-full);
  font-size: 0.92rem;
  font-weight: 600;
  margin: 16px 0;
}
.status-badge svg { width: 17px; height: 17px; flex-shrink: 0; }
.status-badge.status-done { background: var(--success-bg); color: var(--success); }
.status-badge.status-pending { background: var(--amber-soft); color: var(--amber); }

.action-tiles { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.action-tile {
  flex: 1 1 140px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 18px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-soft);
  color: var(--text);
  text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
}
@media (hover: hover) { .action-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); background: var(--card-bg); } }
.action-tile-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  color: #fff;
}
.action-tile-icon svg { width: 18px; height: 18px; }
.action-tile-label { font-weight: 650; font-size: 1rem; }
/* Sign-out row at the foot of the home card */
.signout-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.signout-who { color: var(--muted); font-size: 0.9rem; }
.signout-who strong { color: var(--text); font-weight: 650; }
.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--card-bg);
  border: 1px solid var(--border-strong);
  color: var(--muted);
}
/* (Only under a real pointer: a phone keeps :hover on what was tapped, which would leave it red.) */
@media (hover: hover) { .btn-ghost:hover { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); } }
.btn-ghost:active { background: var(--surface-strong); }
.btn-ghost svg { width: 16px; height: 16px; }

/* Admin — per-row delete + the delete-everything block */
.btn-icon-danger {
  border: 1px solid var(--border-strong);
  background: var(--card-bg);
  color: var(--muted);
  border-radius: 8px;
  padding: 3px 8px;
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  line-height: 1.3;
}
@media (hover: hover) { .btn-icon-danger:hover { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); } }

.danger-zone {
  margin-top: 18px;
  padding: 18px;
  border: 1px solid var(--danger);
  border-radius: var(--radius-md);
  background: var(--danger-bg);
}
.danger-zone h3 { margin: 0 0 6px; color: var(--danger); }
.danger-zone p { margin: 0 0 14px; font-size: 0.9rem; line-height: 1.5; }
.danger-zone code { font-size: 0.85em; word-break: break-all; }
.danger-zone .btn-danger { background: var(--danger); color: #fff; }
@media (hover: hover) { .danger-zone .btn-danger:hover { filter: brightness(1.06); } }
.danger-zone .btn-danger:disabled { opacity: 0.5; cursor: default; transform: none; }
.danger-zone .mini-hint { margin-top: 8px; }

/* =============================================================
   Added for the multi-instructor version
   ============================================================= */

/* Layout */
.page-wide { max-width: 980px; }
body:has(.page-wide) .topbar-inner { max-width: 1012px; }
.card + .card, .card + section, section + .card { margin-top: 18px; }
.card-heading { margin-top: 0; }
.eyebrow {
  margin: 0 0 6px;
  font-size: 0.82rem;
  font-weight: 650;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.eyebrow a { text-transform: none; letter-spacing: 0; font-weight: 500; }
.lead-line { margin: 0 0 14px; }
.note-text { white-space: pre-line; }
.nowrap { white-space: nowrap; }
.inline { display: inline; }
.plain-list { margin: 8px 0 16px; padding-left: 22px; text-align: left; }
.prose ul { padding-left: 22px; }
.prose li { margin-bottom: 6px; }
.prose h2 { margin-top: 26px; }

.visually-hidden, .visually-hidden-file {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.site-footer {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 16px 40px;
  color: var(--muted);
  font-size: 0.88rem;
}
.site-footer a { color: var(--muted); text-decoration: none; }
@media (hover: hover) { .site-footer a:hover { color: var(--accent); text-decoration: underline; } }

/* Messages */
.flash-info { background: var(--accent-soft); color: var(--accent-strong); }
.dev-note {
  background: var(--amber-soft);
  color: var(--amber);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 0.92rem;
}

/* Buttons */
.btn-large { padding: 12px 22px; font-size: 1.05rem; }
.btn-small { padding: 6px 12px; font-size: 0.9rem; }
.btn:disabled { opacity: 0.55; cursor: default; transform: none; }
.btn-link {
  font: inherit;
  font-size: 0.92rem;
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}
.btn-ghost.btn-small { gap: 6px; }

/* Landing */
.hero-card h1 { font-size: 1.9rem; line-height: 1.2; }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 8px; }
.split-panel {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 18px;
}
.split-panel h2 { margin-top: 0; }
.mini-steps { margin: 0 0 14px; padding-left: 20px; color: var(--muted); }
.mini-steps li { margin-bottom: 4px; }
.inline-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.inline-form input[type="text"], .inline-form input[type="email"] { flex: 1 1 200px; min-width: 0; }

/* Dashboard */
.sheet-list { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.sheet-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-soft);
  color: var(--text);
  text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
}
@media (hover: hover) { .sheet-item:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); background: var(--card-bg); } }
.sheet-main { display: flex; flex-direction: column; min-width: 0; }
.sheet-title { font-weight: 650; font-size: 1.08rem; }
.sheet-meta { color: var(--muted); font-size: 0.88rem; }
.empty-state { text-align: center; padding: 10px 0 6px; }
.empty-state .steps { text-align: left; }
.plain-rows { list-style: none; margin: 10px 0 0; padding: 0; }
.plain-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.plain-row:last-child { border-bottom: none; }
.row-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* Forms */
.form-stack { display: flex; flex-direction: column; gap: 20px; margin-top: 8px; }
fieldset.field { border: none; margin: 0; padding: 0; min-width: 0; }
.field label, .field legend { display: block; font-weight: 650; margin-bottom: 2px; padding: 0; }
.field-help { color: var(--muted); font-size: 0.88rem; margin: 0 0 8px; }
.field-help.warn { color: var(--amber); margin-top: 8px; }
.field input[type="text"], .field textarea { width: 100%; }
.input-short { width: 110px; }
.choice { display: flex; gap: 10px; align-items: flex-start; margin: 8px 0; font-weight: 400; cursor: pointer; }
.choice input { flex: 0 0 auto; margin-top: 5px; accent-color: var(--accent); }
/* Under a finger: a box big enough to see and hit, level with the first
   line of its sentence (half a line down, less half the box). The whole
   sentence is part of the target too. */
@media (pointer: coarse) {
  .choice > input[type="checkbox"], .choice > input[type="radio"] {
    width: 22px; height: 22px; margin-top: max(0px, calc(0.775em - 11px));
  }
}
.more-options {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 0 16px;
  margin: 12px 0;
}
.more-options > summary { cursor: pointer; padding: 12px 0; font-weight: 600; color: var(--accent-strong); }
.more-options[open] { padding-bottom: 14px; }
.more-options .field + .field, .more-options .field + .choice { margin-top: 16px; }
.form-actions { display: flex; gap: 10px; }
/* A dialog's way out (Done) on the right, as in the other dialogs; its smaller choice on the left. */
.dialog-actions { justify-content: space-between; align-items: center; }

.day-rows { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-direction: column; gap: 8px; counter-reset: day; }
.day-row { display: flex; gap: 6px; align-items: center; counter-increment: day; }
.day-row::before {
  content: counter(day);
  width: 22px;
  flex-shrink: 0;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.day-row input[type="text"] { flex: 1; min-width: 0; }
.row-btn {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: 1px solid var(--border-strong);
  background: var(--card-bg);
  color: var(--muted);
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.75rem;
}
@media (hover: hover) { .row-btn:hover { background: var(--accent-soft); color: var(--accent-strong); border-color: var(--accent); } }
@media (hover: hover) { .row-remove:hover { background: var(--danger-bg); color: var(--danger); border-color: var(--danger); } }

/* Sheet page */
.sheet-head h1 { margin-bottom: 4px; }
.share-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 4px; }
.share-input { flex: 1 1 260px; min-width: 0; font-variant-numeric: tabular-nums; }
/* Phones: the sheet's title in two lines at most, what its status means
   printed under the pill (nothing to hover on a touch screen), and one
   button that shares the student link, with the links folded under it. */
.status-say, .share-phone { display: none; }
.status-say { margin: 4px 0 0; color: var(--muted); font-family: var(--font-small); font-size: 0.9rem; line-height: 1.45; }
.share-phone { margin: 14px 0 0; }
.share-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 48px; }
.share-btn svg { width: 18px; height: 18px; flex-shrink: 0; }
.share-links > summary { cursor: pointer; padding: 12px 0; color: var(--accent-strong); font-weight: 600; font-size: 0.92rem; }
.share-link-item { display: flex; align-items: center; gap: 8px 12px; margin: 0 0 8px; }
.share-link-text {
  flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums;
  -webkit-user-select: all; user-select: all;
}
.share-links .mini-hint { margin: 4px 0 2px; }
@media (max-width: 640px), (pointer: coarse) {
  .status-say { display: block; }
  .status-tip { cursor: default; }
  .status-tip .tip-bubble { display: none; }
}
@media (max-width: 640px) {
  .sheet-head h1 {
    font-size: clamp(1.4rem, 6vw, 2rem); line-height: 1.12; margin-bottom: 0; overflow-wrap: anywhere;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
  }
  /* The Schedule and Settings tabs keep the header to its name and pill:
     their own content comes up first (the tab bar has Share). */
  .sheet-head:not(.on-class) .status-say, .sheet-head:not(.on-class) .share-phone { display: none; }
  .sheet-head .share-row, .sheet-head .short-row { display: none; }
  .share-phone { display: block; }
}
.section-nav { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 14px; }
.section-nav a {
  padding: 4px 12px;
  border-radius: var(--radius-full);
  background: var(--surface-soft);
  border: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
  font-size: 0.9rem;
}
@media (hover: hover) { .section-nav a:hover { background: var(--accent-soft); color: var(--accent-strong); } }
section[id], main[id] { scroll-margin-top: 80px; }

.guide { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft), var(--shadow-md); }
.checklist { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.check-item { display: flex; gap: 12px; align-items: flex-start; }
.check-mark {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 700;
  border: 1.5px solid var(--border-strong);
  color: var(--muted);
}
.check-item.done .check-mark { background: var(--success-bg); border-color: var(--success); color: var(--success); }
.check-item.done .check-text a { color: var(--muted); text-decoration: line-through; }
.check-text a { font-weight: 650; color: var(--accent-strong); }
.check-hint { display: block; color: var(--muted); font-size: 0.88rem; }

.report {
  background: var(--success-bg);
  border: 1px solid var(--success);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  margin-bottom: 14px;
}
.report-main { margin: 0 0 6px; color: var(--success); font-weight: 600; }
.tips { margin: 6px 0; padding-left: 20px; font-size: 0.92rem; }
.tips li { margin-bottom: 4px; }
.report-foot { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; font-size: 0.9rem; color: var(--muted); margin-top: 8px; }

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 28px 16px;
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-soft);
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone.dragover { border-color: var(--accent); background: var(--accent-soft); }
@media (hover: hover) { .dropzone:hover { border-color: var(--accent); background: var(--accent-soft); } }
.visually-hidden-file:focus-visible + .dropzone { outline: 2px solid var(--accent); outline-offset: 2px; }
.dropzone.busy { opacity: 0.7; cursor: progress; }
.dropzone-icon {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  color: #fff;
  font-size: 1.2rem;
}
.dropzone-title { font-weight: 650; font-size: 1.05rem; }
.dropzone-sub { color: var(--muted); font-size: 0.9rem; }
.dropzone-status { margin: 6px 0 0; color: var(--accent-strong); font-size: 0.9rem; font-weight: 600; text-align: center; }
.dropzone-status:empty { display: none; }
/* Phones and tablets can't drag a file onto the box: no need to say so. */
@media (hover: none) and (pointer: coarse) { .dropzone-drag { display: none; } }
/* Words for the way the page is used, anywhere on the site: "Tap" under a
   finger (phones, tablets, iPads), "Click" with a mouse or trackpad. No
   script needed, and the hidden word isn't read out either. */
/* Words for a touch screen or a mouse ("tap" or "click", "a spreadsheet
   file" where a download doesn't open in Excel): the site's one pair. */
@media (pointer: coarse) { .mouse-only { display: none !important; } }
@media not all and (pointer: coarse) { .touch-only { display: none !important; } }
.paste-box { margin-top: 10px; }
.paste-box > summary { cursor: pointer; color: var(--accent-strong); font-size: 0.92rem; padding: 4px 0; }
.paste-box textarea { width: 100%; margin: 6px 0 8px; }
.helper-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-top: 14px; }
.privacy-note { color: var(--muted); font-size: 0.86rem; }
.roster-details, .not-yet { margin-top: 16px; }
.roster-details > summary, .not-yet > summary { cursor: pointer; color: var(--accent-strong); font-weight: 600; }
.admin-table.compact th, .admin-table.compact td { padding: 6px 10px; }
.add-student { margin-top: 12px; }
.roster-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

.guide-steps { margin: 10px 0 14px; padding-left: 22px; }
.guide-steps li { margin-bottom: 8px; line-height: 1.5; }
.guide-tips {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  font-size: 0.9rem;
}
.guide-tips p { margin: 0 0 8px; }
.guide-tips p:last-child { margin-bottom: 0; }
.canvas-open { margin: 14px 0 6px; }
.modal-wide { max-width: 620px; max-height: 88vh; max-height: min(88vh, calc(100dvh - 40px)); }

.announcement { width: 100%; font-size: 0.95rem; line-height: 1.5; }
.count-inline { font-size: 1rem; }
.count-inline strong { font-size: 1.25rem; color: var(--accent-strong); }
.tag-warn { background: var(--amber-soft); color: var(--amber); }
.run-row { margin-top: 16px; }

/* Owner */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin: 16px 0 8px; }
.stat {
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 14px;
  text-align: center;
}
.stat-value { font-size: 1.5rem; font-weight: 800; color: var(--accent-strong); font-variant-numeric: tabular-nums; }
.stat-label { color: var(--muted); font-size: 0.85rem; }
.stat-warn { border-color: var(--amber); background: var(--amber-soft); }
.stat-warn .stat-value { color: var(--amber); }

@media (max-width: 640px) {
  .split { grid-template-columns: 1fr; }
  .hero-card h1 { font-size: 1.5rem; }
  .admin-header { flex-wrap: wrap; gap: 10px; }
  .share-row .btn { flex: 1 1 auto; }
}
/* (Fields, full width; never a checkbox, which would float alone in a
   stretched box with its sentence squeezed beside it.) */
.name-autocomplete input, .stack > input,
.center-card .stack input:not([type="checkbox"]):not([type="radio"]) { width: 100%; }

/* Messages float at the top of the window, so they're seen even when an
   action returns you to a section further down the page. */
.flash-stack {
  position: fixed;
  top: 66px;
  left: 50%;
  transform: translateX(-50%);
  width: min(720px, calc(100% - 32px));
  z-index: 70;
  margin: 0;
  pointer-events: none;
}
.flash-stack .flash {
  pointer-events: auto;
  box-shadow: var(--shadow-lg);
  border: 1px solid currentColor;
  cursor: pointer;
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.flash-stack .flash.leaving { opacity: 0; transform: translateY(-6px); }
.card .flash { position: static; }
.suggestions-list { text-align: left; }
.dock-form { display: contents; }
.popover-dropdown form { margin: 0; }
.row-actions form { margin: 0; }
.verify-actions form { margin: 0; }

/* =============================================================
   Added with the plain-language pass: next steps, undo, warnings,
   the student's day, and the confirm pages.
   ============================================================= */
/* Out of sight above the window until it has the keyboard's focus: moved
   up by its own height, so at any text size it never hangs over the top
   bar (where it would take the taps meant for the bar's buttons). */
.skip-link {
  position: absolute;
  left: 12px;
  top: 12px;
  max-width: calc(100vw - 24px);
  transform: translateY(calc(-100% - 24px));
  z-index: 100;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  background: var(--card-bg);
  color: var(--accent-strong);
  box-shadow: var(--shadow-md);
}
.skip-link:focus { transform: none; }

.preview-banner {
  background: var(--amber-soft);
  color: var(--amber);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  margin-bottom: 16px;
  font-size: 0.92rem;
  line-height: 1.5;
}
.preview-banner a { color: inherit; font-weight: 700; margin-left: 6px; }
.footer-contact { flex-basis: 100%; text-align: center; margin: 0 0 8px; } /* (a line of its own, above the site's links) */
.footer-contact a, .footer-credit a { overflow-wrap: anywhere; }

.field-label { display: block; font-weight: 650; text-align: left; }
.hint-tight { margin: 0; text-align: left; }
.deadline { margin: 0 0 14px; color: var(--accent-strong); }

.note-box {
  margin-top: 22px;
  padding: 14px 16px;
  border-radius: var(--radius-md);
  background: var(--surface-soft);
  border: 1px solid var(--border);
  text-align: left;
}
.note-box-label {
  margin: 0 0 6px;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.note-box p:last-child, .note-box ul:last-child { margin-bottom: 0; }
.note-text { white-space: pre-wrap; overflow-wrap: anywhere; }

.btn-block { width: 100%; justify-content: center; }
.match-choices { display: flex; flex-direction: column; gap: 10px; margin: 18px 0 12px; }
.match-choices form, .choice-stack { margin: 0; }
.match-new { margin-top: 18px; }
.choice-stack { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
.choice-small { font-size: 0.88rem; color: var(--muted); text-align: left; }
/* (A finger's worth of height; a short sentence beside its box, centred.) */
@media (pointer: coarse) {
  .choice-small { min-height: 44px; align-items: center; }
  .choice-small > input[type="checkbox"] { margin-top: 0; }
}

.big-email {
  margin: -10px 0 8px;
  font-size: 1.2rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}
.help-list { text-align: left; color: var(--muted); font-size: 0.88rem; padding-left: 20px; margin: 18px 0 0; }
.help-list li { margin-bottom: 4px; }

.day-card {
  margin: 14px 0 18px;
  padding: 18px 20px;
  border-radius: var(--radius-md);
  background: var(--success-bg);
  border: 1px solid var(--success);
}
.day-card-label { margin: 0; font-size: 0.85rem; font-weight: 700; color: var(--success); text-transform: uppercase; letter-spacing: 0.04em; }
.day-card-day { margin: 4px 0 0; font-size: 1.6rem; font-weight: 700; }
.day-card-warn { margin: 8px 0 0; color: var(--danger); font-weight: 600; }

.ranking-summary { margin: 12px 0 4px; }
.wizard-restored { margin: 0 0 12px; padding: 10px 14px; border-radius: var(--radius-sm); background: var(--accent-soft); font-size: 0.95rem; }
.report-cheer { margin: 0 0 4px; font-family: var(--font-display); font-size: 1.35rem; color: var(--success); }
details.ranking-summary > summary { cursor: pointer; font-weight: 650; color: var(--accent-strong); }
.summary-list { margin: 6px 0 0; padding-left: 24px; }
.summary-list li { margin-bottom: 2px; }
.save-status.warn { color: var(--amber); font-weight: 600; }

.day-heading { margin: 0 0 2px; font-size: 1rem; }
.assign-list li.me { font-weight: 700; border-left-color: var(--accent); }

.sheet-row { display: flex; gap: 8px; align-items: stretch; }
.sheet-row .sheet-item { flex: 1 1 auto; }
.sheet-actions { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; justify-content: flex-end; }
.sheet-next { display: block; margin-top: 4px; font-size: 0.86rem; color: var(--muted); }
@media (pointer: coarse) {
  .sheet-actions { gap: 8px; }
  .sheet-actions > [data-popover-target^="delete-"] { margin-left: 12px; } /* (Delete apart from the rest) */
  /* (NEW-3: what's next, on a line of its own under the name and status) */
  .sheet-item { flex-wrap: wrap; }
  .sheet-item > .sheet-main { flex: 1 1 12em; min-width: 0; }
  .sheet-next { flex: 1 0 100%; margin-top: 0; }
}
.sheet-actions form { margin: 0; }
@media (max-width: 760px), (horizontal-viewport-segments: 2) {
  .sheet-row { flex-direction: column; }
}
.short-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 8px; }
.short-row form { margin: 0; }
.share-short { width: 100%; max-width: 26em; } /* (the whole short link shows, code and all) */

.confirm-box {
  border: 1px solid var(--danger);
  background: var(--danger-bg);
  border-radius: var(--radius-md);
  padding: 16px 18px;
}
.confirm-box ul { margin: 6px 0; padding-left: 20px; }

.char-count { display: block; font-size: 0.82rem; color: var(--muted); margin-top: 4px; }

.undo-banner {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  margin-top: 18px;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--accent-strong);
  border: 1px solid var(--accent);
  font-weight: 600;
}
.undo-banner form { margin: 0; }
/* Undo and sign-in-code notes stay in view at the bottom of the screen,
   wherever the page scrolled to, until they're closed. */
.toast-dock {
  position: fixed;
  bottom: calc(16px + var(--tabbar-h, 0px) + var(--safe-bottom, 0px)); /* (above the phone tab bar and home bar) */
  left: 50%;
  transform: translateX(-50%);
  width: min(760px, calc(100% - 32px));
  z-index: 65;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.toast-dock .undo-banner {
  margin: 0;
  box-shadow: var(--shadow-lg);
  max-height: 45vh;
  overflow: auto;
}
.toast-dock .undo-banner > span { flex: 1 1 320px; }
.toast-close {
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 2px 6px;
}
.handoff-code { font-size: 1.35rem; letter-spacing: 0.12em; }

.next-step { border-color: var(--accent); }
.next-step .eyebrow { margin-bottom: 2px; }
.next-step-title { margin: 0 0 6px; font-size: 1.25rem; }
.next-step-title a { color: var(--accent-strong); text-decoration: none; }
@media (hover: hover) { .next-step-title a:hover { text-decoration: underline; } }
.next-step p:last-child { margin-bottom: 0; }

.warn-line { color: var(--amber); font-weight: 600; margin: 6px 0 12px; }
.warn-box, .problem-box {
  border-radius: var(--radius-md);
  padding: 12px 16px;
  margin: 12px 0;
  line-height: 1.5;
}
.warn-box { background: var(--amber-soft); color: var(--amber); }
.warn-box p { margin: 0 0 8px; font-weight: 600; }
.warn-box p:last-child { margin-bottom: 0; }
.warn-box form { margin: 0; }
.problem-box { background: var(--danger-bg); color: var(--danger); }
.problem-box p { margin: 0 0 6px; }
.problem-box ul { margin: 4px 0; padding-left: 20px; }
.problem-box form { margin: 6px 0 0; }
.problem-box .no-day-list li { margin: 2px 0; }
.soft-note {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  margin: 12px 0;
}
.soft-note p { margin: 0 0 6px; }
.soft-note form { margin: 0; }

.report-warn { background: var(--amber-soft); border-color: var(--amber); }
.report-warn .report-main { color: var(--amber); }

.add-student-box { margin-top: 20px; }
.add-student-box h3 { margin-bottom: 6px; }
.who-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 16px 0 0; font-size: 0.92rem; }
.row-edit { display: inline-block; }
.row-edit > summary { list-style: none; }
.row-edit > summary::-webkit-details-marker { display: none; }
.row-edit[open] { display: block; margin-top: 6px; }
.stack-tight { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; margin: 6px 0 0; }

.callout {
  border: 1px solid var(--amber);
  background: var(--amber-soft);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  margin: 14px 0;
}
.callout p { margin: 0 0 8px; }
.link-row { margin-top: 8px; }
.link-row select { max-width: 100%; }
.input-medium { flex: 1 1 220px; max-width: 320px; }

.settings-row { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.run-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 14px 0 6px; }
.run-row form { margin: 0; }
.day-column.over { border-color: var(--danger); }
.publish-box {
  margin-top: 22px;
  padding: 18px 20px;
  border-radius: var(--radius-md);
  border: 1px solid var(--success);
  background: var(--success-bg);
}
.publish-box h3 { margin-top: 0; }
.publish-box .announcement { background: var(--card-bg); }

.diff-list { padding-left: 20px; line-height: 1.6; }
details.guide > summary { cursor: pointer; list-style: revert; }
details.guide:not([open]) { padding-bottom: 20px; }
.card-heading + .mini-hint { margin-top: 0; }

.status-badge { border-radius: var(--radius-md); }
@media (max-width: 380px) {
  .dock-optional { display: none; }
  .icon-dock-label { padding: 0 7px; }
}

/* =============================================================
   Picking days on a calendar (create/edit form)
   ============================================================= */
.day-chips { list-style: none; margin: 8px 0 12px; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.day-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 6px 6px 12px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-strong); font-weight: 600;
}
.day-chip-empty { color: var(--muted); font-style: italic; }
.chip-remove {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  font-size: 1.1rem; line-height: 1; padding: 2px 6px; border-radius: 999px;
}
.chip-remove:focus-visible { background: var(--surface-strong); }
@media (hover: hover) { .chip-remove:hover { background: var(--surface-strong); } }
/* On a touch screen, everything tapped is at least 44px across, looking
   just as it does: buttons grow to 44px tall, and links and small x's get
   a bigger target around them (padding that doesn't move the text). */
@media (pointer: coarse) {
  .btn, .btn-small { min-height: 44px; }
  .chip-remove { min-width: 44px; min-height: 44px; margin: -10px -8px -10px -4px; font-size: 1.3rem; }
  a.link-muted, .btn-link, .page-jump a, .quiz-back { padding-top: 12px; padding-bottom: 12px; margin-top: -12px; margin-bottom: -12px; }
  .flash-close, .toast-close, .modal-close { min-width: 44px; min-height: 44px; }
}
.noscript-day { display: inline-block; margin: 0 8px 8px 0; }
.modal-calendar { max-width: 640px; }
/* Each calendar pop-up: a header, a middle that scrolls, and a footer with
   Done, so Done is always in view however short the window. */
#day-calendar .modal-dialog, #deadline-calendar .modal-dialog {
  display: flex; flex-direction: column; overflow: hidden;
  max-height: 88vh; max-height: min(88vh, calc(100dvh - 40px));
}
.cal-sheet-head, .cal-sheet-foot { flex: none; }
.cal-sheet-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  margin: 0 -6px; padding: 0 6px; /* (room for a focused date's outline) */
}
.cal-nav { display: flex; justify-content: space-between; margin: 12px 0 4px; }
/* A swipe up or down on the dates scrolls; picking a run of them by touch
   starts with a hold (calendar.js). */
.cal-months {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 18px;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: pan-y;
}
.cal-title { margin: 4px 0 8px; font-size: 1.05rem; text-align: center; }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; touch-action: pan-y; }
.cal-head { text-align: center; font-size: 0.8rem; color: var(--muted); padding-bottom: 2px; }
.cal-day {
  aspect-ratio: 1 / 1; min-height: 34px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--card-bg); color: var(--text);
  font: inherit; cursor: pointer;
}
@media (hover: hover) { .cal-day:hover { border-color: var(--accent); } }
.cal-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cal-day.today { border: 2px solid var(--accent); }
.cal-day.past { color: var(--muted); background: var(--surface-soft); }
.cal-day[aria-pressed="true"] {
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2));
  border-color: transparent; color: var(--on-accent); font-weight: 700;
}
.cal-summary { margin: 14px 0 6px; color: var(--muted); line-height: 1.5; }

/* Touch: every date at least 44px tall, with no grey flash on a tap. */
@media (pointer: coarse) {
  .cal-grid { gap: 2px; }
  .cal-day { aspect-ratio: auto; min-height: 44px; height: 48px; -webkit-tap-highlight-color: transparent; }
  .cal-nav .btn, .cal-sheet-foot .btn { min-height: 44px; }
}

/* Tablets and unfolded foldables: a wider pop-up, so the two months fit
   side by side with dates that size; where they can't, one month at a
   time. */
@media (pointer: coarse) and (min-width: 641px) {
  #day-calendar, #deadline-calendar { padding: 12px; }
  #day-calendar .modal-dialog { max-width: 760px; padding: 20px; }
}
@media (pointer: coarse) and (min-width: 641px) and (max-width: 739px) {
  #day-calendar .modal-dialog { max-width: 480px; }
  #day-calendar .cal-month + .cal-month { display: none; }
}
/* Phones: each calendar fills the screen and shows one month at a time;
   only the middle scrolls, between the title and Done. */
@media (max-width: 640px) {
  #day-calendar, #deadline-calendar { padding: 0; align-items: stretch; }
  #day-calendar .modal-dialog, #deadline-calendar .modal-dialog {
    max-width: none; height: 100vh; height: 100dvh; max-height: none;
    padding: 0; border: 0; border-radius: 0; box-shadow: none;
    background: var(--card-bg); -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .cal-sheet-head {
    position: relative; border-bottom: 1px solid var(--border);
    padding: calc(12px + env(safe-area-inset-top, 0px)) calc(58px + env(safe-area-inset-right, 0px)) 10px
      calc(12px + env(safe-area-inset-left, 0px));
  }
  #day-calendar .modal-close, #deadline-calendar .modal-close {
    top: calc(4px + env(safe-area-inset-top, 0px)); right: calc(6px + env(safe-area-inset-right, 0px));
    width: 44px; height: 44px;
  }
  #day-calendar .modal-title, #deadline-calendar .modal-title {
    margin: 0; padding: 0; font-size: 1.3rem; line-height: 1.2;
  }
  .cal-sheet-body {
    margin: 0;
    padding: 10px calc(12px + env(safe-area-inset-right, 0px)) 14px calc(12px + env(safe-area-inset-left, 0px));
  }
  .cal-sheet-body > .modal-body { font-size: 0.95rem; line-height: 1.45; }
  .cal-sheet-foot {
    border-top: 1px solid var(--border);
    padding: 8px calc(12px + env(safe-area-inset-right, 0px)) calc(10px + env(safe-area-inset-bottom, 0px))
      calc(12px + env(safe-area-inset-left, 0px));
  }
  .cal-sheet-foot .cal-summary {
    margin: 0 0 8px; font-size: 0.92rem; line-height: 1.4;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  }
  .cal-sheet-foot .btn-primary { flex: 1 1 auto; max-width: 260px; text-align: center; }
  .cal-nav { margin: 8px 0 2px; }
  .cal-months { grid-template-columns: minmax(0, 1fr); }
  .cal-month + .cal-month { display: none; }
}
/* Short screens (a phone on its side): the same, with the summary beside
   Done, so the dates get the room. */
@media (max-height: 500px) {
  #day-calendar, #deadline-calendar { padding: 0 12px; }
  #day-calendar .modal-dialog, #deadline-calendar .modal-dialog {
    height: 100vh; height: 100dvh; max-height: none; border-radius: 0; padding: 10px 20px 0;
  }
  .cal-sheet-foot {
    display: flex; align-items: center; gap: 4px 16px;
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
  }
  .cal-sheet-foot .cal-summary {
    flex: 1 1 0; min-width: 0; margin: 0; font-size: 0.9rem; line-height: 1.35;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  }
  .cal-sheet-foot .dialog-actions { flex: none; gap: 10px; margin: 6px 0; }
  #day-calendar .modal-title, #deadline-calendar .modal-title { margin: 0 0 4px; font-size: 1.2rem; }
}

/* Class list: privacy, and the list's two states */
.privacy-panel {
  border: 1px solid var(--border-strong); border-left: 4px solid var(--success);
  border-radius: var(--radius-md); padding: 14px 18px; margin: 14px 0; background: var(--card-bg);
}
.privacy-title { margin: 0 0 8px; font-weight: 700; color: var(--success); }
.privacy-panel ul { margin: 0 0 8px; padding-left: 20px; line-height: 1.55; }
.privacy-panel li { margin: 4px 0; }
.privacy-line { margin: 4px 0 12px; color: var(--muted); }
.replace-list { margin: 10px 0; }
.replace-list > summary { cursor: pointer; color: var(--accent-strong); font-weight: 600; }
.replace-list[open] > summary { margin-bottom: 10px; }
.canvas-open input { width: 100%; max-width: 520px; margin-top: 6px; }
.guide-steps .btn { margin: 6px 0 2px; }

.footer-credit { margin: 8px 0 0; font-size: 0.85rem; color: var(--muted); flex-basis: 100%; width: 100%; text-align: center; }

/* =============================================================
   White and glass: a plain white page, with frosted glass where
   something floats over it (the top bar, pop-ups, notices).
   ============================================================= */
.card { box-shadow: var(--shadow-sm); }
.modal-overlay {
  background: rgba(255, 255, 255, 0.35);
  backdrop-filter: blur(10px) saturate(120%);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
}
[data-mode="dark"] .modal-overlay { background: rgba(5, 6, 15, 0.5); }
.modal-dialog,
.toast-dock .undo-banner,
.flash-stack .flash {
  background: var(--glass-bg);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
}
.toast-dock .undo-banner { color: var(--text); }
.flash-stack .flash-error { color: var(--danger); }
.flash-stack .flash-success { color: var(--success); }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .modal-dialog, .toast-dock .undo-banner, .flash-stack .flash { background: var(--card-bg); }
}

/* =============================================================
   Type: display headlines, Inter for the rest (see the tokens)
   ============================================================= */
/* Headings and big figures: Roslindale, light, slim and tight, big. */
h1, h2, h3, h4, .card-heading, .modal-title, .brand-name, .next-step-title, .count-number,
.stat-value, .day-card-day {
  font-family: var(--font-display); font-optical-sizing: auto; font-kerning: normal;
}
h1 {
  font-size: clamp(2.05rem, 4.4vw, 2.75rem); line-height: 1.02; margin-bottom: 12px;
  font-weight: calc(var(--w-h1) + var(--display-boost)); letter-spacing: var(--track-h1);
}
h2, .card-heading {
  font-size: clamp(1.5rem, 2.9vw, 1.85rem); line-height: 1.06;
  font-weight: calc(var(--w-h2) + var(--display-boost)); letter-spacing: var(--track-h2);
}
h3 { font-size: 1.28rem; line-height: 1.12; font-weight: calc(var(--w-h3) + var(--display-boost)); letter-spacing: var(--track-h3); }
h4 { font-size: 1.1rem; line-height: 1.15; font-weight: calc(var(--w-h4) + var(--display-boost)); letter-spacing: -0.01em; }
.next-step-title {
  font-size: clamp(1.45rem, 2.8vw, 1.8rem);
  font-weight: calc(var(--w-h2) + var(--display-boost)); letter-spacing: var(--track-h2);
}
.modal-title {
  font-size: 1.7rem; line-height: 1.06;
  font-weight: calc(var(--w-h2) + var(--display-boost)); letter-spacing: var(--track-h2);
}
.brand-name {
  font-size: 1.45rem; letter-spacing: -0.02em;
  font-weight: calc(var(--w-brand) + var(--display-boost));
}
.count-number, .stat-value { font-weight: calc(var(--w-num) + var(--display-boost)); letter-spacing: -0.03em; }
.day-card-day {
  font-size: clamp(2.2rem, 5.6vw, 2.85rem); line-height: 1;
  font-weight: calc(var(--w-num) + var(--display-boost)); letter-spacing: var(--track-h1);
}
.hero-card h1 {
  font-size: clamp(3rem, 9vw, 4.9rem); line-height: 0.92;
  font-weight: calc(var(--w-hero) + var(--display-boost)); letter-spacing: var(--track-hero);
}
/* An italic turn inside a heading: <em> is Roslindale's light italic. */
:is(h1, h2, h3, .card-heading, .modal-title, .next-step-title, .privacy-title) em {
  font-style: italic; font-variation-settings: "ital" 1; color: var(--accent);
}
[data-mode="dark"] { --display-boost: 30; }
[data-theme^="contrast"] { --display-boost: 200; }
.btn, input, select, textarea, button, .flash { font-family: var(--font-text); }
/* Small text: YaleNew. */
.mini-hint, .hint, .field-help, .check-hint, .eyebrow, .tag, .chip, .status-pill, .muted, small,
.site-footer, .admin-table, .privacy-line, .dropzone-sub, .count-inline, .day-chip, .cal-head,
.cal-summary, .size-readout, .appearance-group > legend, .choice-name, .size-preset,
.btn-small, .link-muted { font-family: var(--font-small); }

[data-font="oldstyle"] { --font-text: var(--font-oldstyle); }
[data-font="sans"] {
  --font-text: var(--font-sans); --font-display: var(--font-sans); --display-weight: 650;
}
[data-font="readable"] {
  --font-text: "Atkinson Hyperlegible", Verdana, Tahoma, sans-serif;
  --font-display: var(--font-text);
  --display-weight: 700;
}
[data-font="sans"], [data-font="readable"] {
  --w-hero: 700; --w-h1: 700; --w-h2: 650; --w-h3: 650; --w-h4: 650; --w-num: 700; --w-brand: 700;
  --track-hero: -0.02em; --track-h1: -0.015em; --track-h2: -0.01em; --track-h3: 0;
  --display-boost: 0;
}
[data-font="readable"] { --track-hero: 0; --track-h1: 0; --track-h2: 0; }
[data-font="sans"] h1, [data-font="readable"] h1 { font-size: 1.9rem; }
[data-font="sans"] .hero-card h1, [data-font="readable"] .hero-card h1 { font-size: 2.6rem; }
[data-font="sans"] h2, [data-font="sans"] .card-heading,
[data-font="readable"] h2, [data-font="readable"] .card-heading { font-size: 1.3rem; }

/* =============================================================
   Themes, chosen in Display settings. Light is the standard; each
   dark theme builds on the dark tokens above (data-mode="dark").
   ============================================================= */
[data-theme="paper"] {
  --bg: #faf8f3; --card-bg: #fffdf8; --surface-soft: #f3efe6; --surface-strong: #e9e3d6;
  --text: #2b2924; --muted: #6c675c; --border: #e6dfd0; --border-strong: #d3cab6;
  --accent: #8a4b16; --accent-strong: #6b3a10; --accent-soft: #f5e9da;
  --accent-btn-1: #9a5520; --accent-btn-2: #7d4317;
  --glass-bg: rgba(250, 248, 243, 0.75);
}
[data-theme="solarized-light"] {
  --bg: #eee8d5; --card-bg: #fdf6e3; --surface-soft: #f5efdc; --surface-strong: #e8e1cb;
  --text: #4c5e63; --muted: #657b83; --border: #e2dbc4; --border-strong: #cfc6aa;
  --accent: #1f6fa8; --accent-strong: #185a8a; --accent-soft: rgba(38, 139, 210, 0.13);
  --accent-btn-1: #268bd2; --accent-btn-2: #1f78b8;
  --amber: #8f6c00; --amber-soft: rgba(181, 137, 0, 0.14);
  --danger: #c0291f; --danger-bg: rgba(220, 50, 47, 0.11);
  --success: #5f6e00; --success-bg: rgba(133, 153, 0, 0.14);
  --glass-bg: rgba(253, 246, 227, 0.78);
}
[data-theme="black"] {
  --bg: #000000; --card-bg: #0b0b0c; --surface-soft: #141416; --surface-strong: #1d1d21;
  --text: #ececec; --muted: #a2a2aa; --border: #232327; --border-strong: #34343a;
  --accent: #9fb0ff; --accent-strong: #c3ceff; --accent-soft: rgba(159, 176, 255, 0.14);
  --glass-bg: rgba(8, 8, 10, 0.72); --glass-border: rgba(255, 255, 255, 0.08);
}
[data-theme="solarized-dark"] {
  --bg: #002b36; --card-bg: #073642; --surface-soft: #0a3d4a; --surface-strong: #0f4a58;
  --text: #a6b3b3; --muted: #8a9a9b; --border: #0f4a58; --border-strong: #1d5e6e;
  --accent: #5aaee8; --accent-strong: #8cc8f0; --accent-soft: rgba(38, 139, 210, 0.2);
  --accent-btn-1: #268bd2; --accent-btn-2: #1f78b8;
  --amber: #d9a400; --amber-soft: rgba(181, 137, 0, 0.18);
  --danger: #f2625e; --danger-bg: rgba(220, 50, 47, 0.18);
  --success: #a6bf00; --success-bg: rgba(133, 153, 0, 0.18);
  --glass-bg: rgba(0, 43, 54, 0.75); --glass-border: rgba(147, 161, 161, 0.14);
}
[data-theme="contrast-light"] {
  --bg: #ffffff; --card-bg: #ffffff; --surface-soft: #ffffff; --surface-strong: #e6e6e6;
  --text: #000000; --muted: #1f1f1f; --border: #000000; --border-strong: #000000;
  --accent: #0000c8; --accent-strong: #00007a; --accent-soft: #e5e5ff;
  --accent-btn-1: #0000c8; --accent-btn-2: #0000c8;
  --amber: #6b4500; --amber-soft: #fff2d6; --danger: #a80000; --danger-bg: #ffe5e5;
  --success: #005a1e; --success-bg: #e2f7e8;
  --glass-bg: #ffffff; --glass-border: #000000; --shadow-sm: none; --shadow-md: none;
}
[data-theme="contrast-dark"] {
  --bg: #000000; --card-bg: #000000; --surface-soft: #000000; --surface-strong: #262626;
  --text: #ffffff; --muted: #f2f2f2; --border: #ffffff; --border-strong: #ffffff;
  --accent: #ffe600; --accent-strong: #fff27a; --accent-soft: #332e00;
  --accent-btn-1: #ffe600; --accent-btn-2: #ffe600; --on-accent: #000000;
  --amber: #ffcc4d; --amber-soft: #2e2200; --danger: #ff8080; --danger-bg: #330000;
  --success: #6dff9e; --success-bg: #002b10;
  --glass-bg: #000000; --glass-border: #ffffff; --shadow-sm: none; --shadow-md: none;
}

/* High contrast: solid surfaces, heavier lines, underlined links, and a
   focus ring nobody can miss. */
[data-theme^="contrast"] .card,
[data-theme^="contrast"] .modal-dialog,
[data-theme^="contrast"] .popover-dropdown,
[data-theme^="contrast"] .icon-dock,
[data-theme^="contrast"] input,
[data-theme^="contrast"] select,
[data-theme^="contrast"] textarea,
[data-theme^="contrast"] .btn-secondary,
[data-theme^="contrast"] .btn-ghost,
[data-theme^="contrast"] .cal-day,
[data-theme^="contrast"] .day-chip,
[data-theme^="contrast"] .tag { border: 2px solid var(--border); }
[data-theme^="contrast"] .topbar,
[data-theme^="contrast"] .modal-dialog,
[data-theme^="contrast"] .toast-dock .undo-banner,
[data-theme^="contrast"] .flash-stack .flash,
[data-theme^="contrast"] .icon-dock {
  background: var(--card-bg);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
[data-theme^="contrast"] .topbar { border-bottom: 2px solid var(--border); }
[data-theme^="contrast"] a:not(.btn) { text-decoration: underline; }
[data-theme^="contrast"] :focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
[data-theme^="contrast"] .btn-primary { background: var(--accent); }
[data-theme^="contrast"] .modal-overlay { background: rgba(0, 0, 0, 0.6); backdrop-filter: none; }

/* =============================================================
   The Appearance window: theme cards, a size slider, font cards
   ============================================================= */
.appearance-dialog { --dialog-pad: 28px; max-width: 640px; }
.appearance-note {
  margin: -2px 0 14px; padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--accent-soft); color: var(--accent-strong); font-size: 0.9rem; line-height: 1.45;
}
.appearance-group { border: 0; margin: 0 0 22px; padding: 0; min-width: 0; }
.appearance-group > legend {
  display: flex; width: 100%; justify-content: space-between; align-items: baseline;
  padding: 0; margin-bottom: 10px; font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted);
}
.choice-input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.choice-name { display: block; margin-top: 7px; font-size: 0.84rem; color: var(--text); text-align: center; }
.choice-input:checked ~ .choice-name { font-weight: 600; }

/* Theme cards: each a little picture of that theme. */
.theme-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.theme-card { cursor: pointer; display: block; }
.theme-preview {
  position: relative; display: block; height: 76px; padding: 18px 10px 10px; border-radius: 12px;
  background: var(--p-bg); border: 1px solid var(--p-border); overflow: hidden;
  box-shadow: 0 1px 2px rgba(17, 17, 26, 0.06);
  transition: transform 0.18s ease, box-shadow 0.18s ease, outline-color 0.18s ease;
  outline: 2px solid transparent; outline-offset: 3px;
}
@media (hover: hover) { .theme-card:hover .theme-preview { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(17, 17, 26, 0.12); } }
/* "Automatic (match my device)": a row of its own above the cards, its
   picture half light and half dark, lined up with the first column. */
.theme-auto {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; align-items: center;
  margin: 0 0 16px; cursor: pointer;
}
.theme-auto-text { grid-column: 2 / -1; min-width: 0; }
@media (hover: hover) and (pointer: fine) {
  /* (on a computer, Automatic is one compact line, so the whole window fits) */
  .theme-auto { grid-template-columns: 56px 1fr; gap: 10px; margin-bottom: 12px; }
  .theme-auto .theme-preview { width: 56px; height: 34px; }
  .theme-auto-text { grid-column: 2; }
  .theme-auto-hint { display: none; }
}
.theme-auto .choice-name { margin: 0; font-size: 0.95rem; text-align: left; }
.theme-auto-hint { display: block; margin-top: 2px; font-family: var(--font-small); font-size: 0.84rem; line-height: 1.4; color: var(--muted); }
@media (hover: hover) { .theme-auto:hover .theme-preview { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(17, 17, 26, 0.12); } }
.theme-card:active .theme-preview, .theme-auto:active .theme-preview, .font-card:active .font-sample { transform: scale(0.97); }
.choice-input:checked + .theme-preview { outline-color: var(--accent); }
.choice-input:focus-visible + .theme-preview,
.choice-input:focus-visible + .font-sample { outline: 3px solid var(--accent); outline-offset: 3px; }
.tp-bar { position: absolute; inset: 0 0 auto 0; height: 10px; background: var(--p-card); border-bottom: 1px solid var(--p-border); }
.tp-card {
  display: block; height: 100%; padding: 7px 8px; border-radius: 7px;
  background: var(--p-card); border: 1px solid var(--p-border);
}
.tp-line { display: block; height: 5px; width: 72%; margin-bottom: 5px; border-radius: 3px; background: var(--p-text); opacity: 0.85; }
.tp-line.tp-short { width: 46%; opacity: 0.4; }
.tp-pill { display: block; height: 9px; width: 34px; border-radius: 5px; background: var(--p-accent); }
.tp-check {
  position: absolute; top: 6px; right: 6px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--accent); opacity: 0; transform: scale(0.6); transition: opacity 0.18s ease, transform 0.18s ease;
}
.tp-check::after {
  content: ""; position: absolute; left: 6px; top: 3px; width: 4px; height: 8px;
  border: solid var(--on-accent); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.choice-input:checked + .theme-preview .tp-check { opacity: 1; transform: scale(1); }
.preview-light { --p-bg: #ffffff; --p-card: #ffffff; --p-border: #e3e3ea; --p-text: #16161a; --p-accent: #4f46e5; }
.preview-paper { --p-bg: #f6f2e9; --p-card: #fffdf8; --p-border: #e3dbc9; --p-text: #2b2924; --p-accent: #9a5520; }
.preview-solarized-light { --p-bg: #eee8d5; --p-card: #fdf6e3; --p-border: #ddd5bd; --p-text: #586e75; --p-accent: #268bd2; }
.preview-dark { --p-bg: #0d0f1e; --p-card: #161930; --p-border: #2a2e56; --p-text: #edeffb; --p-accent: #9aa3fb; }
.preview-black { --p-bg: #000000; --p-card: #0b0b0c; --p-border: #26262b; --p-text: #ececec; --p-accent: #9fb0ff; }
.preview-solarized-dark { --p-bg: #002b36; --p-card: #073642; --p-border: #0f4a58; --p-text: #93a1a1; --p-accent: #268bd2; }
.preview-contrast-light { --p-bg: #ffffff; --p-card: #ffffff; --p-border: #000000; --p-text: #000000; --p-accent: #0000c8; }
.preview-contrast-dark { --p-bg: #000000; --p-card: #000000; --p-border: #ffffff; --p-text: #ffffff; --p-accent: #ffe600; }
.preview-auto {
  --p-border: #a9a49a; --p-text: #8b8a96; --p-accent: #9a5520;
  background: linear-gradient(90deg, #f6f2e9 50%, #0d0f1e 50%);
}
.preview-auto .tp-bar, .preview-auto .tp-card { background: linear-gradient(90deg, #fffdf8 50%, #161930 50%); }

/* Text size: a slider that fills as it moves, plus one-tap sizes. */
.size-readout { font-size: 0.95rem; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text); }
.size-control { display: flex; align-items: center; gap: 12px; }
.size-btn {
  display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; flex-shrink: 0;
  border-radius: 50%; border: 1px solid var(--border); background: var(--card-bg); color: var(--text);
  cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease, transform 0.12s ease;
}
@media (hover: hover) { .size-btn:hover { border-color: var(--accent); background: var(--accent-soft); } }
.size-btn:active { transform: scale(0.94); }
.size-glyph { font-family: var(--font-ui); font-weight: 600; line-height: 1; }
.size-glyph-small { font-size: 13px; }
.size-glyph-big { font-size: 20px; }
.size-range {
  -webkit-appearance: none; appearance: none; flex: 1; height: 8px; margin: 0; border-radius: 999px; cursor: pointer;
  background: linear-gradient(to right, var(--accent) 0, var(--accent) var(--fill, 33%), var(--surface-strong) var(--fill, 33%));
}
.size-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 24px; height: 24px; border-radius: 50%;
  background: #ffffff; border: 2px solid var(--accent); box-shadow: 0 2px 8px rgba(17, 17, 26, 0.22);
  transition: transform 0.15s ease;
}
.size-range:active::-webkit-slider-thumb { transform: scale(1.12); }
@media (hover: hover) { .size-range:hover::-webkit-slider-thumb { transform: scale(1.12); } }
.size-range::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%; background: #ffffff; border: 2px solid var(--accent);
  box-shadow: 0 2px 8px rgba(17, 17, 26, 0.22);
}
.size-range::-moz-range-track { background: transparent; }
.size-range:focus-visible { outline: 3px solid var(--accent); outline-offset: 6px; }
.size-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.size-preset {
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--border); background: var(--card-bg);
  color: var(--text); font: inherit; font-size: 0.82rem; cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
@media (hover: hover) { .size-preset:hover { border-color: var(--accent); } }
.size-preset[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* Font cards: "Aa" in each face. */
.font-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.font-card { cursor: pointer; display: block; }
.font-sample {
  display: flex; align-items: center; justify-content: center; height: 64px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--card-bg); color: var(--text); font-size: 1.7rem;
  transition: transform 0.18s ease, box-shadow 0.18s ease, outline-color 0.18s ease;
  outline: 2px solid transparent; outline-offset: 3px;
}
@media (hover: hover) { .font-card:hover .font-sample { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(17, 17, 26, 0.1); } }
.choice-input:checked + .font-sample { outline-color: var(--accent); }
.font-sample-mixed { font-family: "Roslindale Display Condensed", "Instrument Serif", Georgia, serif; font-size: 2.1rem; font-weight: 800; }
.font-sample-oldstyle { font-family: "Old Style 7", "Old Style 7 Std", "Crimson Pro", Georgia, serif; }
.font-sample-sans { font-family: "Inter", system-ui, sans-serif; font-weight: 600; }
.font-sample-readable { font-family: "Atkinson Hyperlegible", Verdana, sans-serif; font-weight: 700; }

.appearance-foot { display: flex; align-items: center; gap: 12px; border-top: 1px solid var(--border); padding-top: 16px; }
.appearance-status { flex: 1; font-size: 0.85rem; color: var(--muted); }

/* Phones: Text size first (theme.js moves it), then the themes and fonts as
   small swatches, four to a row, so the whole window fits in about a
   screen and a half. */
@media (max-width: 640px) {
  .appearance-group { margin-bottom: 20px; }
  .theme-cards, .font-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 8px; }
  .theme-auto { gap: 8px; margin-bottom: 12px; }
  .theme-preview { height: 48px; padding: 11px 6px 6px; border-radius: 10px; }
  .theme-preview .tp-bar { height: 6px; }
  .theme-preview .tp-card { padding: 5px 6px; border-radius: 5px; }
  .theme-preview .tp-line { height: 3px; margin-bottom: 3px; }
  .theme-preview .tp-pill { width: 20px; height: 5px; }
  .theme-preview .tp-check { top: 3px; right: 3px; }
  .choice-input:checked + .theme-preview .tp-check { transform: scale(0.8); }
  .choice-name { margin-top: 5px; font-size: 0.76rem; line-height: 1.25; }
  .theme-auto .choice-name { font-size: 0.9rem; }
  .theme-auto-hint { font-size: 0.8rem; }
  .font-sample { height: 52px; font-size: 1.4rem; }
  .font-sample-mixed { font-size: 1.75rem; }
}

/* =============================================================
   The owner's free-plan meters
   ============================================================= */
.meters { display: grid; gap: 14px; margin: 10px 0 12px; }
.meter { border: 1px solid var(--border); border-radius: var(--radius-md); padding: 12px 14px; background: var(--card-bg); }
.meter-top { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.meter-name { font-weight: 700; }
.meter-figure { font-family: var(--font-small); color: var(--muted); }
.meter-track { display: block; height: 10px; border-radius: 999px; background: var(--surface-strong); overflow: hidden; }
.meter-fill { display: block; height: 100%; border-radius: 999px; background: var(--success); min-width: 4px; }
.meter-warn .meter-fill { background: var(--amber); }
.meter-danger .meter-fill { background: var(--danger); }
.meter-danger { border-color: var(--danger); }
.meter p { margin: 8px 0 0; }
.meter-fill-0 { width: 0%; }
.meter-fill-1 { width: 1%; }
.meter-fill-2 { width: 2%; }
.meter-fill-3 { width: 3%; }
.meter-fill-4 { width: 4%; }
.meter-fill-5 { width: 5%; }
.meter-fill-6 { width: 6%; }
.meter-fill-7 { width: 7%; }
.meter-fill-8 { width: 8%; }
.meter-fill-9 { width: 9%; }
.meter-fill-10 { width: 10%; }
.meter-fill-11 { width: 11%; }
.meter-fill-12 { width: 12%; }
.meter-fill-13 { width: 13%; }
.meter-fill-14 { width: 14%; }
.meter-fill-15 { width: 15%; }
.meter-fill-16 { width: 16%; }
.meter-fill-17 { width: 17%; }
.meter-fill-18 { width: 18%; }
.meter-fill-19 { width: 19%; }
.meter-fill-20 { width: 20%; }
.meter-fill-21 { width: 21%; }
.meter-fill-22 { width: 22%; }
.meter-fill-23 { width: 23%; }
.meter-fill-24 { width: 24%; }
.meter-fill-25 { width: 25%; }
.meter-fill-26 { width: 26%; }
.meter-fill-27 { width: 27%; }
.meter-fill-28 { width: 28%; }
.meter-fill-29 { width: 29%; }
.meter-fill-30 { width: 30%; }
.meter-fill-31 { width: 31%; }
.meter-fill-32 { width: 32%; }
.meter-fill-33 { width: 33%; }
.meter-fill-34 { width: 34%; }
.meter-fill-35 { width: 35%; }
.meter-fill-36 { width: 36%; }
.meter-fill-37 { width: 37%; }
.meter-fill-38 { width: 38%; }
.meter-fill-39 { width: 39%; }
.meter-fill-40 { width: 40%; }
.meter-fill-41 { width: 41%; }
.meter-fill-42 { width: 42%; }
.meter-fill-43 { width: 43%; }
.meter-fill-44 { width: 44%; }
.meter-fill-45 { width: 45%; }
.meter-fill-46 { width: 46%; }
.meter-fill-47 { width: 47%; }
.meter-fill-48 { width: 48%; }
.meter-fill-49 { width: 49%; }
.meter-fill-50 { width: 50%; }
.meter-fill-51 { width: 51%; }
.meter-fill-52 { width: 52%; }
.meter-fill-53 { width: 53%; }
.meter-fill-54 { width: 54%; }
.meter-fill-55 { width: 55%; }
.meter-fill-56 { width: 56%; }
.meter-fill-57 { width: 57%; }
.meter-fill-58 { width: 58%; }
.meter-fill-59 { width: 59%; }
.meter-fill-60 { width: 60%; }
.meter-fill-61 { width: 61%; }
.meter-fill-62 { width: 62%; }
.meter-fill-63 { width: 63%; }
.meter-fill-64 { width: 64%; }
.meter-fill-65 { width: 65%; }
.meter-fill-66 { width: 66%; }
.meter-fill-67 { width: 67%; }
.meter-fill-68 { width: 68%; }
.meter-fill-69 { width: 69%; }
.meter-fill-70 { width: 70%; }
.meter-fill-71 { width: 71%; }
.meter-fill-72 { width: 72%; }
.meter-fill-73 { width: 73%; }
.meter-fill-74 { width: 74%; }
.meter-fill-75 { width: 75%; }
.meter-fill-76 { width: 76%; }
.meter-fill-77 { width: 77%; }
.meter-fill-78 { width: 78%; }
.meter-fill-79 { width: 79%; }
.meter-fill-80 { width: 80%; }
.meter-fill-81 { width: 81%; }
.meter-fill-82 { width: 82%; }
.meter-fill-83 { width: 83%; }
.meter-fill-84 { width: 84%; }
.meter-fill-85 { width: 85%; }
.meter-fill-86 { width: 86%; }
.meter-fill-87 { width: 87%; }
.meter-fill-88 { width: 88%; }
.meter-fill-89 { width: 89%; }
.meter-fill-90 { width: 90%; }
.meter-fill-91 { width: 91%; }
.meter-fill-92 { width: 92%; }
.meter-fill-93 { width: 93%; }
.meter-fill-94 { width: 94%; }
.meter-fill-95 { width: 95%; }
.meter-fill-96 { width: 96%; }
.meter-fill-97 { width: 97%; }
.meter-fill-98 { width: 98%; }
.meter-fill-99 { width: 99%; }
.meter-fill-100 { width: 100%; }

/* =============================================================
   The one bit of motion on the site: blocks (cards) rise into place
   as a page opens, one after another, and blocks further down rise
   in as you scroll to them (app.js adds .reveal / .is-in). Switched
   off for readers who ask for reduced motion (see the top). It only
   fills backwards, so once it ends a block's own styles take over.
   ============================================================= */
@keyframes rise-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
:is(main, .mode-frame) > .card { animation: rise-in 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) backwards; }
:is(main, .mode-frame) > .card:nth-child(2) { animation-delay: 0.05s; }
:is(main, .mode-frame) > .card:nth-child(3) { animation-delay: 0.1s; }
:is(main, .mode-frame) > .card:nth-child(4) { animation-delay: 0.15s; }
:is(main, .mode-frame) > .card:nth-child(5) { animation-delay: 0.2s; }
:is(main, .mode-frame) > .card:nth-child(n+6) { animation-delay: 0.25s; }

/* =============================================================
   Sending from your own email (email_links.html, the sign-in
   link note on a sheet, and the student's "Ask your instructor").
   ============================================================= */
.mail-picker { margin: 18px 0 6px; max-width: 520px; }
.mail-picker-label { display: block; font-weight: 600; font-size: 0.9rem; margin-bottom: 6px; }
.mail-picker select { width: 100%; }
.mail-picker .mini-hint { margin-top: 6px; }
.mail-ready { margin: 18px 0 8px; }
.mail-ready .mini-hint { margin-top: 8px; }
.mail-step { margin-top: 26px; }
.mail-step h2 { margin-bottom: 4px; }
.mail-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 12px; }
.mail-list { list-style: none; margin: 12px 0 0; padding: 0; border-top: 1px solid var(--border); }
.mail-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 14px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--border);
}
.mail-who { min-width: 0; overflow-wrap: anywhere; }
.mail-who .muted { margin-left: 4px; }
.mail-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: var(--radius-full);
  font-size: 0.78rem;
  color: var(--muted);
  border: 1px solid var(--border);
}
.mail-tag-warn { color: var(--amber); border-color: currentColor; }
.mail-tag-done { display: none; color: var(--success); border-color: currentColor; }
.mail-row.is-opened .mail-tag-done { display: inline-block; }
.mail-row.is-opened .btn-primary { background: transparent; color: var(--accent); box-shadow: inset 0 0 0 1px var(--border); }
.compose-status { display: block; font-size: 0.85rem; color: var(--success); margin-top: 6px; }
.undo-banner > .handoff-text { flex: 1 1 320px; }
.handoff-text p { margin: 0 0 6px; }
.handoff-text .mail-picker { margin: 8px 0; }
.handoff-more { font-size: 0.9em; }
.ask-instructor { margin: 14px 0 4px; }
.ask-instructor .mail-picker { margin-top: 12px; }

/* =============================================================
   More Roslindale: small labels above headings ("eyebrows") are
   its italic; the other font choices keep them plain.
   ============================================================= */
.eyebrow {
  font-family: var(--font-display); font-style: italic; font-variation-settings: "ital" 1;
  font-weight: calc(280 + var(--display-boost)); font-size: 1.08rem; letter-spacing: 0;
  text-transform: none; color: var(--accent);
}
.eyebrow a { font-weight: inherit; }
[data-font="sans"] .eyebrow, [data-font="readable"] .eyebrow {
  font-style: normal; font-variation-settings: normal; font-weight: 600; font-size: 0.85rem;
}

/* =============================================================
   Privacy: an editorial page. Big light headline, three facts up
   front, then numbered sections with their headings in a margin
   column that stays in view while you read the section.
   ============================================================= */
.editorial { counter-reset: part; }
.editorial-head h1 { max-width: 20ch; font-size: clamp(2.2rem, 4.8vw, 3.1rem); text-wrap: balance; }
.editorial-head .lead { font-size: 1.15rem; color: var(--muted); max-width: 46ch; margin: 0 0 8px; }
.policy-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin: 30px 0 14px; }
.policy-fact {
  padding: 20px 18px 16px; border-radius: var(--radius-md);
  background: var(--surface-soft); border: 1px solid var(--border);
}
.policy-fact-big {
  margin: 0 0 10px; font-family: var(--font-display); font-optical-sizing: auto;
  font-size: 1.75rem; line-height: 1; letter-spacing: var(--track-h1);
  font-weight: calc(var(--w-h1) + var(--display-boost));
}
.policy-fact p:last-child { margin-bottom: 0; }
.policy-section {
  display: grid; grid-template-columns: minmax(170px, 230px) minmax(0, 1fr); gap: 10px 36px;
  padding: 30px 0 8px; border-top: 1px solid var(--border);
}
.policy-section:first-of-type { margin-top: 14px; }
.policy-section h2 { margin: 0; align-self: start; position: sticky; top: 92px; }
.policy-section h2::before {
  counter-increment: part; content: counter(part, decimal-leading-zero);
  display: block; margin-bottom: 8px;
  font-style: italic; font-variation-settings: "ital" 1; font-size: 1rem; letter-spacing: 0.04em;
  font-weight: calc(220 + var(--display-boost)); color: var(--accent);
}
.policy-body > :first-child { margin-top: 0; }
.policy-body ul { margin-top: 0; }
@media (max-width: 760px) {
  .policy-facts { grid-template-columns: 1fr; }
  .policy-section { grid-template-columns: 1fr; padding-top: 24px; }
  .policy-section h2 { position: static; }
}

/* The class list's privacy panel on a sheet: plain and calm, a short title
   and four checked points, in the text font. */
.privacy-panel {
  border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 16px 20px 12px; margin: 14px 0; background: var(--card-bg);
}
.privacy-title {
  display: flex; align-items: center; gap: 8px; margin: 0 0 6px;
  font-family: var(--font-text); font-size: 1.02rem; font-weight: 700; letter-spacing: 0; color: var(--text);
}
.privacy-title svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--success); }
.privacy-panel .privacy-points { list-style: none; margin: 0 0 8px; padding: 0; }
.privacy-panel .privacy-points li {
  position: relative; margin: 0; padding: 9px 0 9px 26px; line-height: 1.5;
  border-top: 1px solid var(--border);
}
.privacy-panel .privacy-points li:first-child { border-top: 0; }
.privacy-panel .privacy-points li::before {
  content: ""; position: absolute; left: 3px; top: 0.95em;
  width: 11px; height: 6px; border-left: 2px solid var(--success); border-bottom: 2px solid var(--success);
  transform: rotate(-45deg);
}

/* Blocks further down rise in as you scroll to them (app.js). */
.reveal { opacity: 0; transform: translateY(18px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 0.75s cubic-bezier(0.2, 0.7, 0.2, 1), transform 0.75s cubic-bezier(0.2, 0.7, 0.2, 1);
}
@media print { .reveal { opacity: 1 !important; transform: none !important; } }
.hero-dot { color: var(--accent); }

/* Big light headings: even line breaks (no lone last word), and a size
   that fits narrow cards. */
h1, h2, h3, .card-heading, .modal-title, .next-step-title, .privacy-title { text-wrap: balance; }
.center-card h1 { font-size: clamp(1.95rem, 4.2vw, 2.4rem); }
.modal-dialog .modal-title { font-size: clamp(1.45rem, 3.2vw, 1.7rem); }
summary.card-heading::marker, summary.card-heading::-webkit-details-marker { font-size: 0.55em; color: var(--muted); }

/* =============================================================
   Instructor pages (and the owner's) sit in a black-outlined,
   round-cornered frame labeled on its top edge, so nobody mistakes
   them for the students' pages, or the instructor sign-in for theirs.
   ============================================================= */
.mode-frame {
  border: 2px solid var(--text);
  border-radius: 30px;
  padding: 34px 20px 20px;
  margin-top: 18px;
}
.mode-label {
  display: table;
  margin: -46px 0 22px 4px; /* up onto the frame's top edge */
  padding: 5px 14px;
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font-family: var(--font-text);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1;
  text-transform: uppercase;
}
.mode-frame:has(> .center-card) { max-width: 480px; margin: 7vh auto 0; }
.mode-frame > .center-card { margin-top: 0; }
.students-elsewhere { margin: 4px 0 18px; text-align: left; }
.students-elsewhere p { margin: 0; }
@media (max-width: 640px) {
  /* Phones: the frame is just a line across the top with the label on it
     as a small badge, and cards pad 16px, so the page's width goes to the
     words and tables (not to a frame, its padding, and the card's). */
  .mode-frame { padding: 22px 0 0; margin-top: 8px; border: 0; border-top: 2px solid var(--text); border-radius: 0; }
  .mode-label { margin: -33px 0 14px; padding: 4px 10px; font-size: 0.68rem; }
  .mode-frame .card { padding: 16px; }
  .mode-frame .publish-box { padding: 14px 16px; }
}
@media (max-width: 380px) {
  .page:has(> .mode-frame) { padding-left: 12px; padding-right: 12px; }
}

/* =============================================================
   The top bar's words. The page you're on is a raised pill; "My
   sheets" is greyed until there's a sheet; Settings is a gear and a
   word. On phones, shorter words.
   ============================================================= */
button.icon-dock-label { border: 0; background: none; font-family: inherit; cursor: pointer; }
.icon-dock-label[aria-current="page"] {
  background: var(--card-bg); color: var(--text);
  box-shadow: 0 1px 3px rgba(17, 17, 26, 0.12), inset 0 0 0 1px var(--border);
}
.icon-dock-label.dock-empty { color: var(--muted); font-weight: 500; }
.icon-dock-label.dock-empty[aria-expanded="true"] { background: var(--surface-soft); color: var(--text); }
@media (hover: hover) { .icon-dock-label.dock-empty:hover { background: var(--surface-soft); color: var(--text); } }
.label-short { display: none; }
.no-sheets-pop { left: 0; right: auto; width: min(270px, calc(100vw - 32px)); padding: 16px; }
.no-sheets-title {
  margin: 0 0 4px; font-family: var(--font-display); font-size: 1.25rem; line-height: 1.15;
  font-weight: calc(var(--w-h3) + var(--display-boost)); letter-spacing: var(--track-h3);
}
.no-sheets-text { margin: 0 0 12px; font-family: var(--font-small); font-size: 0.9rem; line-height: 1.45; color: var(--muted); }
.no-sheets-text:last-child { margin-bottom: 0; }
.no-sheets-pop .btn { display: flex; justify-content: center; text-align: center; }

.settings-btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 14px 0 11px;
  border: 0; border-radius: var(--radius-full);
  background: none; color: var(--text);
  font: inherit; font-size: 0.86rem; font-weight: 600; white-space: nowrap;
  cursor: pointer; flex-shrink: 0;
}
.settings-btn svg { width: 17px; height: 17px; }
.settings-btn[aria-expanded="true"] { background: var(--accent-soft); color: var(--accent-strong); }
@media (hover: hover) { .settings-btn:hover { background: var(--accent-soft); color: var(--accent-strong); } }
.settings-btn:active { transform: scale(0.96); }
@media (max-width: 640px) {
  .settings-btn { height: 34px; padding: 0 10px 0 9px; font-size: 0.78rem; }
}
@media (max-width: 560px) {
  .label-long { display: none; }
  .label-short { display: inline; }
}
@media (max-width: 400px) {
  .settings-word { display: none; }
  .settings-btn { width: 36px; padding: 0; justify-content: center; }
}

/* =============================================================
   The Settings and "How ranking works" windows, laid out like
   Appearance: small capital headings, cards with a picture each,
   and the buttons along the bottom.
   ============================================================= */
.group-label {
  margin: 0 0 10px; font-family: var(--font-small); font-size: 0.78rem; font-weight: 600; line-height: 1.3;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted);
}
.settings-dialog { max-width: 600px; }
.account-card {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--card-bg);
}
.account-mark {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 44px; height: 44px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-btn-1), var(--accent-btn-2)); color: var(--on-accent);
  font-family: var(--font-display); font-size: 1.2rem; font-weight: 500; letter-spacing: 0.01em;
}
.account-text { min-width: 0; }
.account-name { margin: 0; font-size: 1.05rem; font-weight: 650; line-height: 1.3; overflow-wrap: anywhere; }
.account-sub { margin: 2px 0 0; font-family: var(--font-small); font-size: 0.88rem; line-height: 1.4; color: var(--muted); }

.settings-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 12px; }
.settings-tile {
  display: block; padding: 0; border: 0; background: none; color: var(--text);
  font: inherit; text-align: center; text-decoration: none; cursor: pointer;
}
.tile-art {
  position: relative; display: flex; align-items: center; justify-content: center; height: 64px;
  border-radius: 12px; border: 1px solid var(--border); background: var(--card-bg); color: var(--accent-strong);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.tile-art svg { width: 26px; height: 26px; }
@media (hover: hover) { .settings-tile:hover .tile-art { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(17, 17, 26, 0.1); border-color: var(--accent); } }
@media (hover: hover) { .settings-tile:hover .choice-name { color: var(--accent-strong); } }
.settings-tile:focus-visible { outline: none; }
.settings-tile:focus-visible .tile-art { outline: 3px solid var(--accent); outline-offset: 3px; }
/* Appearance's card is a little picture of the look you have now. */
.tile-theme {
  --p-bg: var(--bg); --p-card: var(--card-bg); --p-border: var(--border); --p-text: var(--text); --p-accent: var(--accent);
  display: block; padding: 17px 10px 8px; background: var(--p-bg); overflow: hidden;
}
.tile-theme .tp-card { padding: 6px 8px; }
.tile-theme .tp-line { height: 4px; margin-bottom: 4px; }
.settings-dialog .appearance-foot form { margin: 0; }
.settings-signout .btn { display: inline-flex; align-items: center; gap: 8px; }
.settings-signout svg { width: 16px; height: 16px; }

.ranking-dialog { max-width: 660px; }
.ranking-lead { margin: -2px 0 18px; font-size: 1.02rem; line-height: 1.5; color: var(--muted); }
.ranking-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px;
}
.ranking-step { display: block; text-align: center; }
.ranking-step .tile-art { margin-bottom: 9px; }
/* (Only the tiles' numbers sit in a corner: the numbered steps on the
   ranking page and the empty dashboard keep theirs beside each step.) */
.tile-art .step-num {
  position: absolute; top: 6px; left: 6px; display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%; background: var(--accent); color: var(--on-accent);
  font-family: var(--font-small); font-size: 0.74rem; font-weight: 700; line-height: 1;
}
.step-name { display: block; font-size: 0.95rem; font-weight: 650; line-height: 1.25; }
.step-text { display: block; margin-top: 3px; font-family: var(--font-small); font-size: 0.84rem; line-height: 1.4; color: var(--muted); }
.ranking-facts { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.ranking-facts li { position: relative; padding-left: 28px; font-size: 0.97rem; line-height: 1.45; }
.ranking-facts li::before {
  content: ""; position: absolute; left: 0; top: 0.2em; width: 18px; height: 18px; border-radius: 50%;
  background: var(--accent-soft);
}
.ranking-facts li::after {
  content: ""; position: absolute; left: 6.5px; top: calc(0.2em + 4px); width: 4px; height: 8px;
  border: solid var(--accent-strong); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.foot-link { font-family: var(--font-small); font-size: 0.92rem; color: var(--accent-strong); text-decoration: none; }
@media (hover: hover) { .foot-link:hover { text-decoration: underline; } }
@media (max-width: 560px) {
  .ranking-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .settings-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The owner's "Delete everything": a red section, and a warning window
   listing what goes and what stays, above the word to type. */
.danger-zone > h2 { margin: 0 0 6px; color: var(--danger); }
.danger-dialog { max-width: 560px; }
.danger-dialog .modal-title { text-align: center; padding: 0 26px; }
.warning-mark.danger-mark { background: var(--danger-bg); color: var(--danger); }
.danger-lead { margin: -2px 0 20px; text-align: center; color: var(--danger); font-weight: 600; line-height: 1.45; }
.wipe-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.wipe-list li { position: relative; padding-left: 28px; font-size: 0.95rem; line-height: 1.45; }
.wipe-list li::before {
  content: ""; position: absolute; left: 0; top: 0.2em; width: 18px; height: 18px; border-radius: 50%;
}
.wipe-gone li::before { background: var(--danger-bg); }
.wipe-gone li::after {
  content: "\00d7"; position: absolute; left: 0; top: 0.2em; width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
  color: var(--danger); font: 700 15px/1 var(--font-sans);
}
.wipe-kept li::before { background: var(--success-bg); }
.wipe-kept li::after {
  content: ""; position: absolute; left: 6.5px; top: calc(0.2em + 4px); width: 4px; height: 8px;
  border: solid var(--success); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.wipe-form { display: grid; gap: 8px; }
.wipe-form input[name="confirm"] { font-size: 1.05rem; letter-spacing: 0.08em; }
.wipe-form .appearance-foot { margin-top: 12px; }
.danger-dialog .btn-danger { background: var(--danger); color: #fff; }
.danger-dialog .btn-danger:disabled { opacity: 0.45; cursor: not-allowed; filter: none; }

/* Instructor sign-in problems: front and center. A refused address gets a
   warning page of its own; a mistyped one, a box right above the field. */
.warning-card { border: 2px solid var(--amber); }
.warning-mark {
  width: 64px; height: 64px; margin: 2px auto 14px; padding: 13px;
  border-radius: 50%; background: var(--amber-soft); color: var(--amber);
}
.warning-mark svg { width: 100%; height: 100%; display: block; }
.warning-address {
  display: inline-block; margin: 2px 0 12px; padding: 4px 12px; border-radius: var(--radius-full);
  background: var(--surface-soft); font-weight: 650; overflow-wrap: anywhere;
}
.warning-card .btn-block { margin: 6px 0 16px; }
.form-error {
  margin: 4px 0 14px; padding: 12px 14px; border-radius: var(--radius-sm); text-align: left;
  border: 1.5px solid var(--danger); background: var(--danger-bg); color: var(--danger); font-weight: 600;
}

/* =============================================================
   Fonts first, briefly. Nothing shows until the page's fonts are in
   (app.js lifts .fonts-loading) or half a second has passed (0.6s
   here, in case app.js is slow to arrive), so text doesn't flash from
   a stand-in font to Roslindale or YaleNew when they're quick to come,
   and the blocks rise in once, together, when it appears.
   ============================================================= */
.fonts-loading body { visibility: hidden; animation: show-page 0s 0.6s forwards; }
@keyframes show-page { to { visibility: visible; } }
.fonts-loading :is(main, .mode-frame) > .card { animation-play-state: paused; }

/* =============================================================
   A soft light follows the pointer across a [data-glow] block: only
   the front page's, never a page people work in (app.js sets
   --mx/--my and .is-lit). Mice and trackpads only; not for readers
   who ask for reduced motion, and not in the high-contrast themes.
   ============================================================= */
@property --spot { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  [data-glow] {
    background-image: radial-gradient(560px circle at var(--mx, 50%) var(--my, 0%),
      color-mix(in srgb, var(--accent) var(--spot), transparent), transparent 70%);
    transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease,
      --spot 0.5s ease;
  }
  [data-glow].is-lit { --spot: 7%; }
  [data-mode="dark"] [data-glow].is-lit { --spot: 11%; }
}
[data-theme^="contrast"] [data-glow] { background-image: none; }

/* Example text in empty fields ("e.g., ..."): YaleNew italic, in the
   standard and Old Style looks (the sans and easy-to-read choices keep
   their own font, in italic). */
::placeholder { font-family: var(--font-text); font-style: italic; color: var(--muted); opacity: 1; }
.modal-dialog .privacy-panel { border: 0; padding: 0; margin: 0; background: none; }

/* =============================================================
   The class-list questions (sheet page): one question at a time,
   big tappable answers, a Back link, and the drop box under the
   steps that use it.
   ============================================================= */
.quiz { margin: 10px 0 16px; padding: 18px 18px 8px; border-radius: var(--radius-md); background: var(--surface-soft); }
.quiz-step[hidden], .quiz-drop[hidden], [data-school-search][hidden] { display: none; }
.quiz-q {
  margin: 4px 0 14px; font-size: clamp(1.3rem, 2.4vw, 1.55rem); line-height: 1.12;
  font-weight: calc(var(--w-h2) + var(--display-boost)); letter-spacing: var(--track-h2);
}
.quiz-q:focus { outline: none; }
.quiz-back {
  margin: 0 0 6px; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 0.88rem; color: var(--muted);
}
@media (hover: hover) { .quiz-back:hover { color: var(--accent-strong); } }
.quiz-choices { display: grid; gap: 10px; margin-bottom: 12px; }
.quiz-choice, .school-result {
  display: block; width: 100%; padding: 14px 16px; text-align: left; cursor: pointer;
  border: 1.5px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--text); font: inherit;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
@media (hover: hover) { .quiz-choice:hover, .school-result:hover { border-color: var(--text); } }
.quiz-choice strong, .school-result strong { display: block; font-size: 1.02rem; }
.quiz-choice span, .school-result span { display: block; margin-top: 3px; font-size: 0.9rem; color: var(--muted); }
.quiz-guess, .quiz-note, .quiz-school { margin: 0 0 14px; }
.school-search { margin: 6px 0 10px; }
.school-search input[type="search"] { width: 100%; max-width: 460px; }
.school-results { list-style: none; margin: 10px 0 6px; padding: 0; display: grid; gap: 8px; max-width: 520px; }
.school-result { padding: 10px 14px; }
.school-manual { margin-top: 10px; }
.school-manual > summary, .quiz-help > summary { cursor: pointer; color: var(--accent-strong); font-weight: 600; }
.quiz-help { margin: 4px 0 12px; }
.quiz .guide-steps { margin: 0 0 12px; }
.quiz-drop { margin: 6px 0 10px; }
.nudge { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin: 10px 0 14px; }
.nudge .mail-picker { flex-basis: 100%; margin: 4px 0 0; }

/* =============================================================
   A class's tabs (Class / Schedule / Settings), the Class tab's jump
   links, and the Settings tab's summary.
   ============================================================= */
.sheet-tabs { display: flex; gap: 2px; margin: 18px 0 -8px; border-bottom: 1px solid var(--border); overflow-x: auto; }
.sheet-tab {
  padding: 10px 16px 11px; color: var(--muted); font-weight: 650; text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
@media (hover: hover) { .sheet-tab:hover { color: var(--text); } }
.sheet-tab.is-current { color: var(--text); border-bottom-color: var(--text); }
/* Phones: the three tabs share the width as one segmented control, each
   a 44px target with its short name, so none is cut off ("Settings &
   backu") behind a strip that scrolls without saying so. */
@media (max-width: 640px) {
  .sheet-tabs {
    display: flex; flex-wrap: wrap; gap: 4px; margin: 16px 0 0; padding: 4px;
    border: 1px solid var(--border); border-radius: 14px; background: var(--surface-soft); overflow: visible;
  }
  .sheet-tab {
    display: flex; align-items: center; justify-content: center; min-height: 44px; padding: 6px 4px; margin: 0;
    flex: 1 1 0; min-width: max-content;
    border: 0; border-radius: 10px; text-align: center; white-space: normal; overflow-wrap: normal; word-break: normal; line-height: 1.15;
  }
  .sheet-tab.is-current {
    background: var(--card-bg); box-shadow: 0 1px 3px rgba(17, 17, 26, 0.12), inset 0 0 0 1px var(--border);
  }
}
.page-jump { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 4px 4px 14px; font-size: 0.9rem; }
@media (max-width: 640px) { .page-jump { display: none; } } /* (on a phone its sections are right below: a third list of them) */
.page-jump a { color: var(--muted); }
@media (hover: hover) { .page-jump a:hover { color: var(--accent-strong); } }
.tab-lead { margin: 4px 4px 16px; color: var(--muted); }
.settings-list { margin: 0 0 16px; display: grid; gap: 0; }
.settings-list > div { display: grid; grid-template-columns: minmax(150px, 220px) 1fr; gap: 4px 18px; padding: 9px 0; border-top: 1px solid var(--border); }
.settings-list > div:first-child { border-top: 0; }
.settings-list dt { color: var(--muted); }
.settings-list dd { margin: 0; }
@media (max-width: 560px) { .settings-list > div { grid-template-columns: 1fr; } }

/* =============================================================
   Setting up a new sheet: one question per screen.
   ============================================================= */
/* The whole setup's progress (the questions, then the students and the
   link): step N of 8, a bar, and its three parts. */
.setup-progress {
  margin: 6px 0 22px; padding: 14px 16px 12px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--surface-soft);
}
.setup-progress-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 4px 14px; }
.setup-progress-step { margin: 0; font-family: var(--font-small); font-size: 0.9rem; }
.setup-progress-step strong { font-weight: 650; }
.setup-bar {
  -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 8px; margin: 10px 0 11px;
  border: 0; border-radius: 999px; background: var(--surface-strong); color: var(--accent); overflow: hidden;
}
.setup-bar::-webkit-progress-bar { background: var(--surface-strong); border-radius: 999px; }
.setup-bar::-webkit-progress-value { background: var(--accent); border-radius: 999px; }
.setup-bar::-moz-progress-bar { background: var(--accent); border-radius: 999px; }
.setup-parts {
  list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px 20px;
  font-family: var(--font-small); font-size: 0.86rem; color: var(--muted);
}
.setup-part { position: relative; padding-left: 21px; line-height: 1.4; }
.setup-part::before {
  content: ""; position: absolute; left: 0; top: 0.2em; width: 14px; height: 14px; box-sizing: border-box;
  border-radius: 50%; border: 1.5px solid var(--border-strong);
}
.setup-part.is-now { color: var(--text); font-weight: 650; }
.setup-part.is-now::before { border: 4px solid var(--accent); }
.setup-part.is-done { color: var(--text); }
.setup-part.is-done::before { background: var(--accent); border-color: var(--accent); }
.setup-part.is-done::after {
  content: ""; position: absolute; left: 5px; top: calc(0.2em + 2.5px); width: 3px; height: 6.5px;
  border: solid var(--on-accent); border-width: 0 1.8px 1.8px 0; transform: rotate(45deg);
}

/* The class's name while it's set up: a dashed "Draft" pill. */
.draft-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin: -2px 0 16px; }
.draft-line[hidden] { display: none; }
.draft-pill {
  display: inline-flex; align-items: center; gap: 10px; max-width: 100%; margin: 0; padding: 6px 16px 6px 6px;
  border: 1.5px dashed var(--amber); border-radius: var(--radius-full); background: var(--amber-soft);
}
.draft-badge {
  flex-shrink: 0; padding: 3px 10px; border-radius: var(--radius-full); background: var(--amber); color: var(--card-bg);
  font-family: var(--font-small); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.draft-title {
  min-width: 0; overflow-wrap: anywhere; font-family: var(--font-display); font-size: 1.15rem; line-height: 1.25;
  font-weight: calc(var(--w-h3) + var(--display-boost)); color: var(--text);
}
.draft-note { margin: 0; font-family: var(--font-small); font-size: 0.86rem; color: var(--muted); }
@media (max-width: 640px) {
  .draft-note { display: none; } /* (the Draft pill says it) */
  .setup-parts { display: none; } /* (the step's own heading names it: "Step N of 8" and the bar stay) */
}
/* NEW-7: a message after making the schedule sits above its sticky Publish bar. */
@media (max-width: 640px) { body:has(.next-bar) .toast-dock, body:has(.next-bar) .flash-stack { margin-bottom: 72px; } }
.setup-part a { color: inherit; text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 0.2em; }
@media (hover: hover) { .setup-part a:hover { color: var(--accent-strong); text-decoration-color: currentColor; } }

/* The setup page: the students step, then sharing. */
.setup-step > .wizard-q { margin-top: 2px; }
.setup-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 18px 0 6px; }
.setup-sub { margin: 26px 0 10px; }
.setup-try { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 0; }
.setup-summary { margin: 0 0 6px; padding-left: 1.2em; line-height: 1.6; }
.setup-skip { margin-top: 18px; }
.wizard-step[hidden] { display: none; }
.wizard-q {
  margin: 4px 0 16px; font-size: clamp(1.45rem, 2.8vw, 1.8rem); line-height: 1.1;
  font-weight: calc(var(--w-h2) + var(--display-boost)); letter-spacing: var(--track-h2);
}
/* Making a sheet: no heading above the question, so the question leads,
   large, with a large box to answer in. */
.wizard-top { display: flex; justify-content: flex-end; margin: -4px 0 6px; }
form[data-wizard] .wizard-q { margin: 18px 0 14px; font-size: clamp(1.9rem, 4.2vw, 2.55rem); line-height: 1.05; }
form[data-wizard] .wizard-step .field input[type="text"],
form[data-wizard] .wizard-step .field input[type="number"] { font-size: 1.2rem; padding: 14px 16px; }
form[data-wizard] .wizard-step #title { width: 100%; }
.wizard-q:focus { outline: none; }
/* The question says what the field's own label would; keep the label for
   screen readers only. */
.wizard-step > .field > label:first-child, .wizard-step > .field > legend:first-child {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.wizard-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.wizard-actions [hidden] { display: none; }
/* Phones: the setup's progress as one line over a thin bar, the question
   near the top, and Back and Next held at the bottom of the screen (over
   the tab bar), where a thumb reaches them. While the keyboard is up they
   stay in place under the question, so they don't cover what's typed. */
@media (max-width: 640px) {
  .setup-progress {
    display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px;
    margin: 0 0 4px; padding: 0; border: 0; border-radius: 0; background: none;
  }
  .setup-progress-top { order: 1; }
  .setup-parts { order: 2; }
  .setup-part:not(.is-now) { display: none; }
  .setup-bar { order: 3; flex: 0 0 100%; height: 5px; margin: 6px 0 0; }
  .wizard-top { margin: -6px 0 2px; }
  form[data-wizard] .wizard-q { margin: 6px 0 12px; font-size: 1.6rem; line-height: 1.1; }
  .wizard-actions {
    position: sticky; bottom: var(--tabbar-h, 0px); z-index: 5;
    padding: 10px 0 calc(10px + var(--safe-bottom, 0px));
    border-top: 1px solid var(--border); background: var(--card-bg);
  }
  .wizard-actions .btn-large { flex: 1 1 auto; text-align: center; }
  html.kb-open .wizard-actions { position: static; }
}
@media (max-width: 380px) {
  form[data-wizard] .wizard-q { font-size: 1.45rem; }
}

/* The deadline: picker, warning, and what the instructor sees about it. */
.deadline-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.deadline-row input[type="date"] { min-width: 170px; }
.deadline-warning {
  margin: 12px 0 10px; padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--amber-soft); color: var(--text); border: 1px solid var(--amber);
}
.deadline-warning[hidden], .deadline-then[hidden] { display: none; }
.deadline-then { margin: 4px 0 0; padding: 0; border: 0; }
.deadline-then legend { font-weight: 650; margin-bottom: 6px; }
.deadline-line { margin: 8px 0 12px; }
.deadline-ask { border-color: var(--amber); }
input[type="date"] {
  font: inherit; padding: 10px 14px; border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface-soft); color: var(--text);
}
/* A radio or checkbox choice inside a form field: its lead phrase is the
   <strong>, the rest reads as normal text. */
.field label.choice { display: flex; font-weight: 400; }

/* The deadline picker: a month beside a list of times to scroll and click
   (the way scheduling apps pick a time), stacked on narrow screens. */
.deadline-dialog { max-width: 700px; }
.dcal-layout { display: grid; grid-template-columns: minmax(0, 1fr) 210px; gap: 26px; align-items: start; }
.dcal-time { min-width: 0; margin: 0; padding: 0; border: 0; }
.dcal-time-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 8px; width: 100%;
  margin: 0 0 10px; padding: 0; font-weight: 650;
}
.dcal-time-head .muted { font-family: var(--font-small); font-size: 0.85rem; font-weight: 400; }
/* (Positioned, so the hidden radio buttons inside sit in the list, not
   stretch the pop-up into blank space below Done.) */
.time-list {
  position: relative;
  display: grid; gap: 8px; max-height: 336px; overflow-y: auto; overscroll-behavior: contain;
  padding: 3px 6px 3px 3px; scroll-padding: 6px;
}
.time-slot { position: relative; display: block; cursor: pointer; }
.time-slot > span {
  display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 44px;
  padding: 8px 12px; border: 1.5px solid var(--border); border-radius: 12px; background: var(--card-bg);
  color: var(--accent-strong); font-weight: 650; line-height: 1.2;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.time-slot small { font-family: var(--font-small); font-size: 0.75rem; font-weight: 400; color: var(--muted); }
@media (hover: hover) { .time-slot:hover > span { border-color: var(--accent); } }
.choice-input:checked + span { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.choice-input:checked + span small { color: inherit; opacity: 0.85; }
.choice-input:focus-visible + span { outline: 3px solid var(--accent); outline-offset: 2px; }
/* Quick picks (a week before the first day, the evening before…), above
   the month. */
.dcal-presets { margin: 14px 0 4px; }
.dcal-presets[hidden] { display: none; }
.dcal-presets-head { margin: 0 0 8px; font-weight: 650; }
.dcal-preset-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 8px; }
.dcal-preset {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; min-height: 44px;
  padding: 8px 12px; border: 1.5px solid var(--border); border-radius: 12px; background: var(--card-bg);
  color: var(--accent-strong); font: inherit; font-weight: 650; line-height: 1.25; text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.dcal-preset small { font-family: var(--font-small); font-size: 0.8rem; font-weight: 400; color: var(--muted); }
@media (hover: hover) { .dcal-preset:hover { border-color: var(--accent); } }
.dcal-preset:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.dcal-preset[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.dcal-preset[aria-pressed="true"] small { color: inherit; opacity: 0.85; }
[data-theme^="contrast"] .dcal-preset { border: 2px solid var(--border); }
/* Phones: the times under the month, two to a row, scrolling with the
   rest of the pop-up (not a scrolling box inside a scrolling box). */
@media (max-width: 640px) {
  .dcal-layout { grid-template-columns: 1fr; gap: 16px; }
  .time-list { grid-template-columns: repeat(2, minmax(0, 1fr)); max-height: none; overflow: visible; padding: 3px; }
  .dcal-preset-list { grid-template-columns: minmax(0, 1fr); }
}
.cal-day:disabled { cursor: default; opacity: 0.55; }
@media (hover: hover) { .cal-day:disabled:hover { border-color: var(--border); } }
.deadline-row[hidden], [data-deadline-chip][hidden], [data-deadline-open][hidden] { display: none; }
[data-theme^="contrast"] .time-slot > span { border: 2px solid var(--border); }

/* =============================================================
   Messages about what just happened. With scripts on, they come up in
   the upper part of the window, larger, the page behind blurred for a
   moment (app.js). Without scripts, they sit at the top of the page.
   ============================================================= */
.flash-stack {
  position: static; transform: none; width: auto; margin: 0 0 16px; pointer-events: auto;
  display: flex; flex-direction: column; gap: 10px;
}
.js .flash-stack {
  position: fixed; top: clamp(84px, 17vh, 180px); left: 50%; transform: translateX(-50%);
  width: min(600px, calc(100% - 32px)); z-index: 75; margin: 0; pointer-events: none;
}
.flash-stack .flash {
  display: flex; align-items: flex-start; gap: 12px; padding: 16px 12px 16px 18px;
  border: 1.5px solid currentColor; border-radius: 16px; background: var(--card-bg);
  backdrop-filter: none; -webkit-backdrop-filter: none;
  box-shadow: 0 24px 60px rgba(17, 17, 26, 0.22), 0 2px 6px rgba(17, 17, 26, 0.08);
  font-size: 1.02rem; line-height: 1.45; cursor: default; pointer-events: auto;
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.js .flash-stack .flash { animation: flash-in 0.32s cubic-bezier(0.2, 0.7, 0.2, 1) backwards; }
@keyframes flash-in { from { opacity: 0; transform: translateY(-10px) scale(0.98); } }
.flash-stack .flash.leaving { opacity: 0; transform: translateY(-8px); }
.flash-icon {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 28px; height: 28px; border-radius: 50%; background: currentColor;
}
.flash-icon svg { width: 17px; height: 17px; color: var(--card-bg); }
.flash-text { flex: 1; min-width: 0; margin: 3px 0 0; color: var(--text); }
.flash-close {
  flex-shrink: 0; width: 30px; height: 30px; margin: -1px 0 0; border: 0; border-radius: 50%;
  background: none; color: var(--muted); font: inherit; font-size: 1.4rem; line-height: 1; cursor: pointer;
}
@media (hover: hover) { .flash-close:hover { background: var(--surface-soft); color: var(--text); } }
.flash-close:active { background: var(--surface-strong); }
:not(.js) > body .flash-close { display: none; }
.flash-veil {
  position: fixed; inset: 0; z-index: 74; pointer-events: none;
  background: rgba(255, 255, 255, 0.3);
  backdrop-filter: blur(8px) saturate(115%); -webkit-backdrop-filter: blur(8px) saturate(115%);
  animation: flash-veil 2.2s ease forwards;
}
[data-mode="dark"] .flash-veil { background: rgba(5, 6, 15, 0.42); }
[data-theme^="contrast"] .flash-veil { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(0, 0, 0, 0.2); }
@keyframes flash-veil { 0% { opacity: 0; } 12% { opacity: 1; } 68% { opacity: 1; } 100% { opacity: 0; } }
/* Phones: a bar along the bottom of the screen, just above the tab bar (and
   clear of the home bar), rising in; the page isn't blurred. With the
   keyboard up, at the top instead, where it can be seen. */
@media (max-width: 640px) {
  .js .flash-stack {
    top: auto;
    bottom: calc(12px + var(--tabbar-h, 0px) + var(--safe-bottom, env(safe-area-inset-bottom, 0px)));
    width: calc(100% - 24px);
  }
  .js.kb-open .flash-stack { top: calc(8px + env(safe-area-inset-top, 0px)); bottom: auto; }
  .flash-stack .flash { gap: 10px; padding: 10px 4px 10px 14px; font-size: 0.98rem; }
  .js .flash-stack .flash { animation-name: flash-up; }
  .flash-stack .flash.leaving { transform: translateY(10px); }
  .flash-icon { margin-top: 2px; }
  .flash-veil { display: none; }
}
@keyframes flash-up { from { opacity: 0; transform: translateY(14px) scale(0.98); } }
@media (prefers-reduced-motion: reduce) {
  .js .flash-stack .flash { animation: none; }
}

/* Canvas: the step to do next, after coming back from the Canvas tab. */
.guide-steps > li.is-next { border-radius: 12px; outline: 2px solid var(--accent); outline-offset: 6px; }
.canvas-welcome {
  margin: 14px 0 4px; padding: 12px 14px; border-radius: 12px; border: 1.5px solid var(--accent);
  background: var(--accent-soft); color: var(--accent-strong); font-weight: 600; line-height: 1.45;
}
.canvas-retry { display: block; margin-top: 6px; }
#canvas-open[aria-disabled="true"] { opacity: 0.55; }

/* Getting the link to students: two choices side by side (_send_link). */
.send-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin: 6px 0 18px; }
.send-choice { padding: 16px 18px; border: 1px solid var(--border); border-radius: 14px; background: var(--card-bg); }
.send-title { margin: 0 0 6px; font-size: 1.15rem; }
.send-text { margin: 0 0 12px; font-family: var(--font-small); font-size: 0.9rem; line-height: 1.45; color: var(--muted); }
.send-choice .helper-row { margin-top: 0; }
.send-choice .mail-picker { margin-top: 12px; }
.send-off { margin: 0; font-family: var(--font-small); font-size: 0.9rem; color: var(--muted); }
.setup-message-label { display: block; margin: 4px 0 6px; }
.just-added .send-choices { margin-bottom: 4px; }
@media (max-width: 640px) { .send-choices { grid-template-columns: 1fr; } .send-choice { padding: 12px; } }

/* The class list's own "Add students" box. */
.quick-add { margin: 16px 0 6px; }
.quick-add .field-help { margin: 2px 0 8px; }
.quick-add-row { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; }
.quick-add-row textarea { flex: 1 1 320px; min-height: 2.9em; resize: vertical; }
.owner-steps { margin: 6px 0 12px; padding-left: 1.3em; line-height: 1.55; }

/* "How days are assigned": the options, each with the same small example. */
.algo-options { display: grid; gap: 18px; margin: 16px 0 14px; }
.algo-option {
  padding: 20px 22px; border: 1px solid var(--border); border-radius: 16px; background: var(--card-bg);
  box-shadow: var(--shadow-sm);
}
.algo-option.is-recommended { border: 1.5px solid var(--accent); }
.algo-option.is-compare { background: var(--surface-soft); }
.algo-option-title { margin: 0 0 8px; }
.algo-option .algo-desc { margin: 0 0 14px; font-size: 0.97rem; color: var(--text); }
.algo-example { padding: 14px 16px; border-radius: 12px; background: var(--surface-soft); }
.algo-option.is-compare .algo-example { background: var(--card-bg); }
.algo-example-label {
  margin: 0 0 6px; font-family: var(--font-small); font-size: 0.74rem; font-weight: 600;
  letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted);
}
.algo-draw { margin: 0 0 12px; font-family: var(--font-small); font-size: 0.9rem; color: var(--muted); }
.ex-days { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.ex-day {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 10px; background: var(--card-bg);
}
.ex-day-name { flex-basis: 100%; font-weight: 650; }
.ex-person { padding: 3px 10px; border-radius: var(--radius-full); font-size: 0.9rem; }
.ex-person.is-first { background: var(--success-bg); color: var(--success); }
.ex-person.is-second { background: var(--amber-soft); color: var(--amber); }
.algo-verdict { margin: 12px 0 0; font-weight: 650; color: var(--success); }
.algo-verdict.is-bad { color: var(--amber); }
.algo-technical { margin: 12px 0 0; }
@media (max-width: 480px) { .ex-days { grid-template-columns: 1fr; } }

/* The Schedule tab's days, as calendar pages, each with its seats: blank
   until there's a schedule, then filled in. */
.board-lead { margin: 4px 0 12px; color: var(--muted); }
.day-board { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 14px; margin: 8px 0 18px; }
.day-sheet {
  display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: 14px;
  background: var(--card-bg); overflow: hidden; box-shadow: var(--shadow-sm);
}
.day-sheet.over { border-color: var(--danger); }
.day-sheet-head {
  display: grid; justify-items: center; margin: 0; padding: 8px 10px 10px;
  background: var(--accent-soft); color: var(--accent-strong); border-bottom: 1px solid var(--border);
}
.day-sheet-weekday, .day-sheet-month {
  font-family: var(--font-small); font-size: 0.74rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.day-sheet-date {
  font-family: var(--font-display); font-size: 2.1rem; line-height: 1.05;
  font-weight: calc(var(--w-num) + var(--display-boost));
}
.day-sheet-label { font-weight: 650; padding: 6px 0; }
.day-slots { list-style: none; counter-reset: seat; margin: 0; padding: 10px 12px 4px; display: grid; gap: 6px; }
.slot { counter-increment: seat; position: relative; min-height: 30px; padding: 4px 0 4px 26px; line-height: 1.35; }
.slot::before {
  content: counter(seat); position: absolute; left: 0; top: 5px; width: 18px; text-align: right;
  font-family: var(--font-small); font-size: 0.78rem; color: var(--muted);
}
.slot.open::after {
  content: ""; position: absolute; left: 26px; right: 0; bottom: 6px; border-bottom: 1.5px dashed var(--border-strong);
}
.slot.filled { font-weight: 600; }
.slot.filled .tag { font-weight: 500; }
.slot.flagged { color: var(--danger); }
.day-sheet-count { margin: auto 12px 10px; padding-top: 6px; font-family: var(--font-small); font-size: 0.8rem; color: var(--muted); }
.modify-days { margin: 4px 0 18px; padding: 12px 16px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-soft); }
.modify-days > summary { cursor: pointer; font-weight: 650; color: var(--accent-strong); }
.modify-days[open] > summary { margin-bottom: 12px; }
.modify-days .warn-box { margin-top: 0; }
/* A long name wraps inside its day (a one-word surname too) rather than
   being cut off at the card's edge, and a tag ("choice #1") moves to the
   next line whole rather than breaking in two. */
.slot bdi { overflow-wrap: anywhere; }
.slot .tag { display: inline-block; max-width: 100%; }
.move-heading { scroll-margin-top: 92px; } /* (where a move comes back to, below the top bar) */
.board-fold, .next-bar { display: none; }
.board-days { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.board-days li {
  padding: 3px 10px; border-radius: var(--radius-full); background: var(--accent-soft); color: var(--accent-strong);
  font-family: var(--font-small); font-size: 0.88rem; white-space: nowrap;
}
@media (min-width: 641px) and (max-width: 1023px) {
  .day-board { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
}
@media (max-width: 640px) {
  /* Phones, before there's a schedule: the empty days fold to one line. */
  .board-lead, .day-board.is-blank { display: none; }
  .board-fold { display: block; margin: 4px 0 14px; }
  .board-fold > summary { cursor: pointer; padding: 10px 0; font-weight: 650; color: var(--accent-strong); }
  .board-fold .mini-hint { margin-top: 8px; }
  /* Move a student: who, then to, then Move, each the full width. */
  .manual-move-row { flex-direction: column; align-items: stretch; }
  .manual-move-row select, .manual-move-row .btn { width: 100%; }
  /* The next step's button, pinned above the tab bar (and out of the way
     of the keyboard), across the whole width of the screen. */
  .next-bar {
    display: block; position: sticky; bottom: var(--tabbar-h, 0px); z-index: 40;
    margin: 16px -16px 0; padding: 10px 16px calc(10px + var(--safe-bottom, 0px));
    background: var(--card-bg); border-top: 1px solid var(--border); box-shadow: 0 -6px 18px rgba(17, 17, 26, 0.08);
  }
  .next-bar .btn { display: block; width: 100%; min-height: 48px; text-align: center; }
  html.kb-open .next-bar { position: static; }
}
@media (max-width: 380px) {
  .next-bar { margin-left: -12px; margin-right: -12px; padding-left: 12px; padding-right: 12px; }
}
@media (max-width: 480px) {
  /* Phones, once there's a schedule: one day per row, its date and seats
     on one line ("Tue Nov 17 · 2 of 3 seats"), the names below it. */
  .day-board { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .day-sheet { display: grid; grid-template-columns: minmax(0, 1fr) auto; }
  .day-sheet-head {
    grid-column: 1; grid-row: 1; display: flex; align-items: baseline; gap: 6px; justify-items: start; padding: 8px 12px;
  }
  .day-sheet-weekday, .day-sheet-month, .day-sheet-date {
    font-family: var(--font-small); font-size: 1rem; font-weight: 700; letter-spacing: 0; text-transform: none; line-height: 1.3;
  }
  .day-sheet-month { order: 1; }
  .day-sheet-date { order: 2; }
  .day-sheet-label { padding: 0; }
  .day-sheet-count {
    grid-column: 2; grid-row: 1; margin: 0; padding: 8px 12px; display: flex; align-items: center;
    background: var(--accent-soft); color: var(--accent-strong); border-bottom: 1px solid var(--border);
  }
  .day-slots { grid-column: 1 / -1; grid-row: 2; padding: 8px 12px 6px; }
}

/* Cards that fold away (the class page): the heading is the switch, with
   a chevron; folded, the Next step card still shows what the step is. */
.fold-card > summary {
  display: flex; align-items: center; gap: 12px; cursor: pointer; list-style: none;
}
.fold-card > summary::-webkit-details-marker { display: none; }
.fold-card > summary::after {
  content: ""; flex-shrink: 0; width: 9px; height: 9px; margin: 0 6px 0 auto;
  border: solid var(--muted); border-width: 0 2px 2px 0; transform: rotate(45deg) translateY(-2px);
  transition: transform 0.2s ease;
}
.fold-card[open] > summary::after { transform: rotate(-135deg) translateY(-2px); }
.fold-card > summary .card-heading { margin: 0; }
.fold-card[open] > summary { margin-bottom: 14px; }
@media (hover: hover) { .fold-card > summary:hover .card-heading, .fold-card > summary:hover .eyebrow { color: var(--accent-strong); } }
.fold-card > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 8px; }
.next-step > summary .eyebrow { margin: 0; }
.fold-peek { display: none; font-weight: 650; }
.next-step:not([open]) .fold-peek { display: inline; }
details.guide:not([open]) { padding-bottom: 20px; }
.card[id], .fold-card { scroll-margin-top: 92px; }  /* a link to a card lands below the top bar */
.canvas-update { scroll-margin-top: 92px; }
.helper-remove { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }
.helper-remove-buttons { display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center; margin-top: 8px; }
.algo-choices fieldset { border: 0; margin: 0 0 10px; padding: 0; display: grid; gap: 8px; }
.algo-choice { display: flex; gap: 10px; align-items: flex-start; }
.algo-choice input { margin-top: 4px; }
.algo-choice-desc { display: block; font-size: 0.88rem; color: var(--muted); margin-top: 2px; }
.option-label { margin: 0 0 10px; font-size: 1.05rem; font-weight: 650; color: var(--accent-strong, var(--text)); }
.canvas-paste { margin-top: 14px; }
.canvas-paste summary { cursor: pointer; font-weight: 600; }
.canvas-paste form { margin-top: 10px; }
.canvas-paste textarea { width: 100%; }
.helper-remove-steps { margin: 8px 0 0; padding-left: 1.4em; }
.helper-remove-steps li + li { margin-top: 4px; }
.helper-trouble { margin-top: 10px; }
.helper-trouble summary { cursor: pointer; font-weight: 600; }
.helper-trouble p { margin: 8px 0 0; }
.copy-said { display: inline-block; margin-left: 10px; }
.quiz-step { scroll-margin-top: 92px; }
.helper-remove[hidden], .helper-remove-buttons[hidden], .helper-remove-steps[hidden], [data-helper-chrome][hidden],
[data-helper-settings][hidden], .helper-remove p[hidden], [data-chromium-only][hidden], [data-not-chromium][hidden] { display: none; }

/* Canvas: steps with pictures of where to click (drawn like Canvas, in this
   site's colors). */
.canvas-guide-top { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: 8px 0 16px; }
.canvas-steps { margin: 0 0 12px; padding: 0; list-style: none; counter-reset: canvas-step; display: grid; gap: 14px; }
.canvas-step { counter-increment: canvas-step; position: relative; padding-left: 38px; }
.canvas-step::before {
  content: counter(canvas-step); position: absolute; left: 0; top: 0; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; background: var(--accent); color: var(--on-accent);
  font-family: var(--font-small); font-size: 0.85rem; font-weight: 700;
}
.canvas-step > p { margin: 2px 0 8px; line-height: 1.5; }
.canvas-step.is-next { border-radius: 12px; outline: 2px solid var(--accent); outline-offset: 6px; }
.canvas-pic { display: block; width: 100%; max-width: 420px; height: auto; }
.pic-frame { fill: var(--card-bg); stroke: var(--border); }
.pic-nav { fill: var(--surface-strong); }
.pic-dot { fill: var(--border-strong); }
.pic-heading { font-family: var(--font-display); font-size: 15px; fill: var(--text); }
.pic-small { font-family: var(--font-small); font-size: 11px; fill: var(--muted); }
.pic-tiny { font-family: var(--font-small); font-size: 9.5px; fill: var(--muted); }
.pic-small.is-strong, .pic-tiny.is-strong { fill: var(--accent-strong); font-weight: 700; }
.pic-card { fill: var(--surface-soft); stroke: var(--border); }
.pic-card-top { fill: var(--surface-strong); }
.pic-card.is-target { stroke: var(--accent); stroke-width: 2.5; }
.pic-card-top.is-target-top { fill: var(--accent-soft); }
.pic-target { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 2; }
.pic-pointer { fill: var(--text); stroke: var(--card-bg); stroke-width: 1.2; }
.pic-line { fill: var(--surface-strong); }
.pic-box { fill: var(--card-bg); stroke: var(--border-strong); }
.pic-icon { fill: none; stroke: var(--muted); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.pic-icon.is-strong { stroke: var(--accent-strong); stroke-width: 2; }
.pic-underline { fill: var(--accent); }
.pic-badge { fill: var(--accent); }
.pic-badge-text { font-family: var(--font-small); font-size: 10px; font-weight: 700; fill: var(--on-accent); text-anchor: middle; }
.canvas-more { margin: 10px 0; }
.canvas-more > summary { cursor: pointer; font-weight: 650; color: var(--accent-strong); }
.canvas-more[open] > summary { margin-bottom: 8px; }
.canvas-more textarea { width: 100%; font-size: 0.9rem; }
.canvas-step code { font-size: 0.85em; }

/* Canvas, the easy way: Scheduler Helper's one button (or Connect Canvas),
   then a list that arrives right here to look over. */
.canvas-easy {
  margin: 6px 0 16px; padding: 16px 18px; border: 1.5px solid var(--accent); border-radius: 14px;
  background: var(--accent-soft);
}
.canvas-easy-title { margin: 0 0 10px; font-size: 1.2rem; }
.canvas-easy .canvas-guide-top { margin: 0; }
.canvas-easy kbd {
  display: inline-block; min-width: 1.6em; padding: 1px 6px; border: 1px solid var(--border-strong); border-bottom-width: 2px;
  border-radius: 6px; background: var(--card-bg); font-family: var(--font-small); font-size: 0.85em; text-align: center;
}
.canvas-arrived-here, .canvas-arrived {
  margin-top: 14px; padding: 16px 18px; border: 1.5px solid var(--success); border-radius: 14px; background: var(--card-bg);
}
.canvas-arrived-here[hidden] { display: none; }
.canvas-arrived-here .eyebrow { margin: 0 0 4px; }
.canvas-arrived-title { margin: 0 0 4px; font-size: 1.25rem; }
.arrived-names { margin: 8px 0 12px; }
.arrived-names > summary { cursor: pointer; color: var(--accent-strong); font-weight: 600; }
.arrived-list {
  max-height: 280px; overflow: auto; margin: 8px 0 0; padding: 8px 12px 8px 2.4em; font-size: 0.92rem; line-height: 1.55;
  border: 1px solid var(--border); border-radius: 10px; background: var(--card-bg);
}
.arrived-form { margin: 0; }
.canvas-by-hand { margin: 4px 0 12px; }
.canvas-by-hand > summary { cursor: pointer; font-weight: 650; color: var(--accent-strong); }
.canvas-by-hand[open] > summary { margin-bottom: 12px; }
.canvas-arrived .arrived-form .field { margin: 6px 0 14px; }
.canvas-copy-courses { display: grid; gap: 8px; margin-top: 8px; }
.canvas-copy-courses .quiz-choice, .helper-courses-q, .canvas-arrived-title, .arrived-list li { overflow-wrap: anywhere; }
.canvas-copy-courses[hidden] { display: none; }
.canvas-copy-courses > p { margin: 0; font-weight: 650; }
.pic-box.is-dashed { stroke: var(--accent); stroke-dasharray: 4 3; }
.canvas-easy-lead { margin: 0 0 10px; font-size: 1.05rem; line-height: 1.5; }

/* Who a class list just added, by name (_roster_people.html). */
.report-people { margin: 10px 0 12px; }
.report-people > summary { cursor: pointer; color: var(--accent-strong); font-weight: 650; }
.report-people-list {
  max-height: 280px; overflow: auto; margin: 8px 0 6px; padding: 8px 12px 8px 2.4em; line-height: 1.55;
  font-size: 0.92rem; border: 1px solid var(--border); border-radius: 10px; background: var(--card-bg);
}
.report-people-list .muted { font-size: 0.88em; }
.report-people .mini-hint { margin: 4px 0 0; }

/* Scheduler Helper, the one-click way (extension/). */
.canvas-helper[hidden], [data-helper-ready][hidden], [data-helper-install][hidden]{ display: none; }
.canvas-helper .btn-large { margin: 2px 0 8px; }
.helper-install-steps { margin: 10px 0 0; padding-left: 1.3em; display: grid; gap: 6px; line-height: 1.5; font-size: 0.95rem; }
/* Its checklist: add it, import the class list, then delete it. Each step
   is done (a green ✓), the one to do now (ringed), or still to come (muted). */
.helper-checklist { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 16px; }
.helper-check { display: flex; gap: 12px; align-items: flex-start; }
.helper-check .check-mark { width: 30px; height: 30px; margin-top: 1px; background: var(--card-bg); }
.helper-check.is-now .check-mark { border: 2px solid var(--accent); color: var(--accent-strong); box-shadow: 0 0 0 3px var(--accent-soft); }
.helper-check.is-done .check-mark { background: var(--success-bg); border-color: var(--success); color: var(--success); }
.helper-check.is-done .check-num { display: none; }
.helper-check.is-done .check-mark::after {
  content: ""; width: 12px; height: 6px; border: solid currentColor; border-width: 0 0 2.5px 2.5px;
  transform: translateY(-2px) rotate(-45deg);
}
.check-body { flex: 1; min-width: 0; }
.check-title { margin: 3px 0 6px; font-family: var(--font-body); font-size: 1.08rem; font-weight: 650; line-height: 1.35; }
.helper-check:not(.is-now):not(.is-done) .check-title { color: var(--muted); }
.check-later, .check-done-said { margin: 0; color: var(--muted); font-size: 0.95rem; line-height: 1.5; }
.check-done-said { color: var(--success); font-weight: 600; }
.check-later[hidden], .check-done-said[hidden] { display: none; }
.helper-remove .helper-checklist { gap: 10px; }
.helper-remove .check-title { margin-bottom: 4px; }
/* "Is any of this recorded?": what the helper and the site keep. */
.nothing-kept { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border); font-size: 0.95rem; }
.nothing-kept > summary { cursor: pointer; font-weight: 650; color: var(--accent-strong); }
.nothing-kept ul { margin: 10px 0 0; padding-left: 1.2em; display: grid; gap: 8px; line-height: 1.5; }

/* The Canvas step, simplified: the helper's one button, or Canvas's file. */
.helper-said { margin: 8px 0 0; font-weight: 650; color: var(--accent-strong); line-height: 1.5; }
.helper-said[hidden] { display: none; }
.canvas-upload.is-first {
  margin: 6px 0 16px; padding: 16px 18px; border: 1.5px solid var(--accent); border-radius: 14px;
  background: var(--accent-soft);
}
.canvas-upload.is-first > summary {
  list-style: none; cursor: default; pointer-events: none; font-size: 1.2rem; font-weight: 600;
  color: var(--text); margin-bottom: 10px;
}
.canvas-upload.is-first > summary::-webkit-details-marker { display: none; }
.canvas-upload .canvas-guide-top { margin: 0 0 10px; }
.helper-install-steps[hidden] { display: none; }

/* The Canvas step, after review: status lines that are always there (so
   screen readers hear them), a busy button, and the list's other way. */
.helper-said:empty, .canvas-welcome:empty { margin: 0; padding: 0; border: 0; }
[data-helper-go].is-busy { cursor: progress; } /* (still works: a second press brings Canvas's sign-in back) */
.helper-courses-q { margin: 0; font-weight: 650; }
.helper-courses-q:focus { outline: none; }
.arrived-other { display: inline-block; margin: 10px 0 0; }
.canvas-arrived-here[hidden], .canvas-upload[hidden], .quiz-help[hidden] { display: none; }
[data-safari-only][hidden], [data-phone-only][hidden], [data-desktop-only][hidden], [data-quiz-leave][hidden],
.quiz-help p[hidden], .canvas-connect[hidden], [data-not-safari][hidden], [data-windows-only][hidden],
[data-not-windows][hidden], [data-picker-downloads][hidden], [data-picker-plain][hidden], [data-first-only][hidden],
[data-canvas-starts][hidden], .came-back[hidden] { display: none; }

/* The class list at a glance, and Update from Canvas, out in the open on
   the class page; deleting the list, quietly at the bottom of its card. */
.class-glance {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 14px;
  margin: 0 0 16px; padding: 12px 16px; border: 1px solid var(--border); border-radius: 12px; background: var(--card-bg);
}
.list-delete { margin: 14px 0 0; text-align: right; font-size: 0.9rem; }

/* Back from Canvas: one press to choose its file, pinned to the bottom of
   the window (the page itself doesn't move). */
.came-back {
  position: fixed; z-index: 60; left: 16px; right: 16px;
  bottom: calc(16px + var(--tabbar-h, 0px) + var(--safe-bottom, env(safe-area-inset-bottom, 0px)));
  max-width: 640px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  padding: 12px 16px; border: 1.5px solid var(--accent); border-radius: 14px; background: var(--card-bg);
  box-shadow: var(--shadow-lg);
}
.came-back-text { margin: 0; flex: 1 1 220px; font-weight: 650; }

/* A problem with the file, said under its box. */
.dropzone-status.is-error {
  color: var(--danger, #b42318); background: var(--danger-bg, #fdecea); padding: 8px 12px; border-radius: 8px; text-align: left;
}
.canvas-step [data-dropzone] { margin-top: 8px; }
.canvas-phone-note { margin: 0 0 10px; }
@media (max-width: 560px) {
  /* Phones: less frame, more room for the steps and their pictures. */
  .quiz { padding: 12px; }
  .canvas-easy, .canvas-upload.is-first, .canvas-arrived-here { padding: 12px; }
  .canvas-step { padding-left: 0; padding-top: 34px; }
  .canvas-pic { max-width: none; }
}

/* (Last in the file, so these win over the rules for one screen above.) */
/* ---------------------------------------------------------------
   Two screens with a hinge between them (Surface Duo, a foldable
   spanned across its fold). Side by side: the page keeps to the
   left screen, and windows and messages open there, so no line of
   text or button straddles the hinge; the top bar folds its words
   as on a small tablet. One above the other (a foldable half open,
   like a laptop): windows open on the top screen.
   --------------------------------------------------------------- */
@media (horizontal-viewport-segments: 2) {
  .topbar-inner, body:has(.page-wide) .topbar-inner, main.page, .site-footer {
    max-width: env(viewport-segment-width 0 0, 50vw); margin-left: 0; margin-right: auto;
  }
  .modal-overlay { right: auto; width: env(viewport-segment-width 0 0, 50vw); }
  .flash-stack, .toast-dock { left: calc(env(viewport-segment-width 0 0, 50vw) / 2); width: calc(env(viewport-segment-width 0 0, 50vw) - 32px); }
}
@media (horizontal-viewport-segments: 2) and (pointer: coarse) {
  .icon-dock [data-dock="fold"], .word-settings { display: none; }
  .word-more { display: inline; }
  /* (a word under each icon, as on a phone, so they fit one screen) */
  .icon-dock-btn { flex-direction: column; width: auto; min-width: 48px; height: 44px; gap: 3px; padding: 2px 4px; border-radius: 12px; }
  .icon-dock-btn .dock-word { font: 600 0.68rem/1 var(--font-sans); }
}
@media (vertical-viewport-segments: 2) {
  /* (the lower screen is the dimmed backdrop: a tap there closes the window, as elsewhere) */
  .modal-overlay { bottom: 0; height: auto; align-items: flex-start; padding-bottom: calc(100dvh - env(viewport-segment-bottom 0 0, 50vh)); }
  #day-calendar .cal-sheet-body > .modal-body, #deadline-calendar .cal-sheet-body > .modal-body { display: none; }
  .modal-overlay > .modal-dialog, #day-calendar .modal-dialog, #deadline-calendar .modal-dialog {
    max-height: calc(env(viewport-segment-height 0 0, 50vh) - 24px); overflow-y: auto;
  }
}

/* Very large text (Appearance, 150% and up): one month at a time in the
   calendars, with day cells that grow with the text. */
html.text-large #day-calendar .cal-month + .cal-month, html.text-large #deadline-calendar .cal-month + .cal-month { display: none; }
html.text-large .cal-day { min-width: 2.4em; min-height: 1.9em; height: auto; aspect-ratio: auto; }
html.text-large #day-calendar .cal-sheet-body > .modal-body, html.text-large #deadline-calendar .cal-sheet-body > .modal-body { display: none; }

/* Phones: sign-in cards start right under the top bar (after the base
   rules above, so this wins). */
@media (max-width: 640px) {
  .center-card { margin-top: 0; }
  .mode-frame:has(> .center-card) { margin-top: 8px; }
}
