/* ---------- typeface ----------
   Inter, served from this repo rather than from a font CDN. The site promises
   it contacts nobody, and a webfont link would quietly break that: every
   visitor's browser would tell Google's servers who was reading. Three weights,
   Latin only, about 72 KB in total. SIL Open Font License — see
   assets/fonts/Inter-LICENSE.txt. font-display: swap so text is readable
   immediately and simply re-renders when the font lands. */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../fonts/inter-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('../fonts/inter-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('../fonts/inter-latin-700-normal.woff2') format('woff2');
}

/* ---------- design tokens ---------- */
:root {
  --bg: #f4f6fb;
  --surface: #ffffff;
  --surface-2: #eef1f8;
  --text: #161c2b;
  --muted: #5c6780;
  --line: #dfe4ef;
  --accent: #2f5bd6;
  --accent-soft: #e5ecff;
  --good: #12855c;
  --good-soft: #dff5eb;
  --bad: #c0362c;
  --bad-soft: #fde8e6;
  --warn: #b0730c;
  --warn-soft: #fdf0d8;
  --shadow: 0 1px 2px rgba(20, 28, 50, .06), 0 8px 24px rgba(20, 28, 50, .07);
  --radius: 14px;
  --maxw: 1080px;
}
:root[data-theme="dark"] {
  --bg: #0e1220;
  --surface: #171d31;
  --surface-2: #202844;
  --text: #eef1f9;
  --muted: #a2acc6;
  --line: #2c3453;
  --accent: #7d9dff;
  --on-accent: #101733;
  --accent-soft: #222e57;
  --good: #48d29b;
  --good-soft: #14332a;
  --bad: #ff8b80;
  --bad-soft: #3a1f1e;
  --warn: #f0c069;
  --warn-soft: #372a13;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 28px rgba(0, 0, 0, .35);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font: 16px/1.6 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  /* Inter's own spacing, and figures that line up in a column of scores. */
  letter-spacing: -.006em;
  font-variant-numeric: tabular-nums;
}
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }
.hidden { display: none !important; }
.muted { color: var(--muted); }
.small { font-size: .875rem; }
h1, h2, h3 { line-height: 1.25; margin: 0 0 .4em; }
h1 { font-size: 1.9rem; letter-spacing: -.02em; }
h2 { font-size: 1.15rem; }
a { color: var(--accent); }

/* ---------- buttons ---------- */
button, .primary-btn, .secondary-btn, .ghost-btn {
  font: inherit; cursor: pointer; border-radius: 10px;
  padding: .6rem 1.05rem; border: 1px solid transparent;
  transition: background .15s, border-color .15s, transform .05s;
  text-decoration: none; display: inline-flex; align-items: center; gap: .4rem;
}
button:active { transform: translateY(1px); }
.primary-btn { background: var(--accent); color: var(--on-accent, #fff); font-weight: 600; }
.primary-btn:hover { filter: brightness(1.07); }
.secondary-btn { background: var(--surface); color: var(--text); border-color: var(--line); }
.secondary-btn:hover { background: var(--surface-2); }
.ghost-btn { background: transparent; color: var(--muted); border-color: var(--line); }
.ghost-btn:hover { background: var(--surface-2); color: var(--text); }
.small.primary-btn, .small.secondary-btn, .ghost-btn.small { padding: .4rem .8rem; font-size: .875rem; }
button:disabled { opacity: .45; cursor: not-allowed; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.5rem;
}

/* ---------- home ---------- */
.site-header { border-bottom: 1px solid var(--line); background: var(--surface); }
.header-inner { display: flex; align-items: center; justify-content: space-between; height: 62px; }
.brand {
  display: flex; align-items: center; gap: .65rem; font-weight: 700;
  color: inherit; text-decoration: none;      /* it is a link on the subject page */
}
/* The mark is finely detailed — rays, a caduceus, lettering — so it needs
   room to read as anything but a smudge. */
.brand-logo { height: 42px; width: auto; display: block; }
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-name { letter-spacing: -.01em; }
.brand-sub {
  font-size: .68rem; font-weight: 600; letter-spacing: .12em;
  color: var(--muted); text-transform: uppercase;
}
.footer-brand { display: flex; align-items: flex-start; gap: .9rem; min-width: 0; }
.footer-brand img { height: 58px; width: auto; flex: none; }
.footer-brand p { margin: 0; }
.hero { padding: 2.6rem 0 1.4rem; max-width: 640px; }
.lede { color: var(--muted); margin: 0; }

.subject-grid { padding-bottom: 1rem; }
.course { margin-bottom: 2.4rem; }

/* ---------- first screen: subjects by year ---------- */
.year { margin-bottom: 2.4rem; }
.year-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: .9rem;
  border-bottom: 1px solid var(--line); padding-bottom: .5rem;
}
.year-title {
  margin: 0; font-size: .82rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); font-weight: 700;
}
.course-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 1.25rem; text-align: left; color: inherit;
  text-decoration: none; transition: transform .12s, border-color .12s;
  display: flex; flex-direction: column; gap: .7rem; align-items: stretch;
  border-left: 3px solid var(--card-accent, var(--accent));
}
.course-card:hover { transform: translateY(-2px); border-color: var(--card-accent, var(--accent)); }
.course-card .name { font-size: 1.05rem; font-weight: 650; }
.course-card .sub { margin-top: .15rem; }
/* An emoji renders differently on every device; a disc of the subject's colour
   around it gives it a consistent size and footing, and carries the colour. */
.course-icon {
  flex: none; width: 46px; height: 46px; border-radius: 13px;
  display: grid; place-items: center; font-size: 1.45rem; line-height: 1;
  background: var(--surface-2);
  background: color-mix(in srgb, var(--card-accent, var(--accent)) 15%, var(--surface));
}
.card-titles { min-width: 0; }
.course-go {
  margin-top: auto; font-size: .85rem; font-weight: 600;
  color: var(--card-accent, var(--accent));
}

/* ---------- second screen: one subject's papers ---------- */
.crumb { padding-top: 1.4rem; font-size: .9rem; }
.crumb a { color: var(--muted); text-decoration: none; }
.crumb a:hover { color: var(--text); }

/* The subject's own colour, washed across the top of its page. Browsers
   without color-mix keep the plain background, which is what it looked like
   before, so nothing is lost. */
.course-banner {
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  background: color-mix(in srgb, var(--card-accent, var(--accent)) 9%, var(--bg));
  margin-bottom: 1.8rem;
}
.course-hero { display: flex; align-items: center; gap: 1.1rem; padding-bottom: 1.8rem; }
.course-hero h1 { margin-bottom: .25rem; }
.course-hero-icon {
  flex: none; width: 58px; height: 58px; border-radius: 16px;
  display: grid; place-items: center; font-size: 1.9rem; line-height: 1;
  background: var(--surface);
  background: color-mix(in srgb, var(--card-accent, var(--accent)) 16%, var(--surface));
  border: 1px solid var(--line);
  border-color: color-mix(in srgb, var(--card-accent, var(--accent)) 30%, var(--line));
}
@media (max-width: 480px) {
  .course-hero-icon { width: 46px; height: 46px; font-size: 1.5rem; border-radius: 13px; }
  .course-hero { gap: .8rem; }
}

/* ---------- links out to Drive and Notion ---------- */
.resources { padding-bottom: 2rem; }
.resources-title {
  font-size: .82rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--muted); font-weight: 700; margin: 0 0 .8rem;
  border-bottom: 1px solid var(--line); padding-bottom: .5rem;
}
.resource-row {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.resource-card {
  display: flex; align-items: center; gap: .85rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .95rem 1.1rem; text-decoration: none; color: inherit;
  transition: transform .12s, border-color .12s;
}
.resource-card:hover { transform: translateY(-2px); border-color: var(--accent); }
.resource-icon { font-size: 1.5rem; line-height: 1; }
.resource-text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.resource-name { font-weight: 650; }
.resource-go { margin-left: auto; color: var(--muted); font-size: 1.1rem; }
.course-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: .8rem;
  border-bottom: 1px solid var(--line); padding-bottom: .5rem;
}
.course-title { margin: 0; font-size: 1.05rem; letter-spacing: .01em; }
.course-title::before {
  content: ''; display: inline-block; width: 10px; height: 10px; border-radius: 3px;
  background: var(--card-accent, var(--accent)); margin-right: .55rem;
}
.subset-title {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  font-size: .82rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); font-weight: 700;
  margin: 1.4rem 0 .6rem;
}
.subset-title:first-of-type { margin-top: .2rem; }
.subset-count { text-transform: none; letter-spacing: 0; font-weight: 400; }
.course-grid {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
}
.card-head { display: flex; gap: .7rem; align-items: flex-start; }
/* Drawn icons take the colour of whatever they sit in, so a paper's icon is
   its subject's colour without anything being said twice. */
.icon-svg { width: 100%; height: 100%; display: block; }
.icon.has-icon { color: var(--card-accent, var(--accent)); }
.paper-icon.has-icon {
  flex: none; width: 34px; height: 34px; padding: 5px;
  border-radius: 10px;
  background: var(--surface-2);
  background: color-mix(in srgb, var(--card-accent, var(--accent)) 12%, var(--surface));
}
.course-icon.has-icon { padding: 11px; }
.course-hero-icon.has-icon { padding: 13px; }
.exam-title { display: flex; align-items: center; gap: .45rem; }
.title-icon { flex: none; width: 20px; height: 20px; }
.title-icon.has-icon { color: var(--accent); }
.chip.badge {
  background: var(--card-accent, var(--accent)); color: #fff;
  font-weight: 700; letter-spacing: .04em; text-transform: uppercase; font-size: .7rem;
}
:root[data-theme="dark"] .chip.badge { color: var(--surface); }
.card-head .icon { font-size: 1.6rem; line-height: 1.2; }
.subject-card .sub { margin-top: .1rem; }
.subject-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 1.25rem; text-align: left; color: inherit;
  text-decoration: none; transition: transform .12s, border-color .12s;
  display: flex; flex-direction: column; gap: .55rem; align-items: stretch;
  border-top: 3px solid var(--card-accent, var(--accent));
}
.subject-card:hover { background: var(--surface); transform: translateY(-2px); border-color: var(--card-accent, var(--accent)); }
.subject-card .icon { font-size: 1.7rem; }
.subject-card .name { font-size: 1.15rem; font-weight: 650; }
/* Papers describe themselves at very different lengths, and one long
   description used to stretch its whole row, leaving its neighbours mostly
   blank. Both the subtitle and the description are clamped so the cards stay
   comparable; the full text is on the paper's own start screen. */
/* Not flex: 1 — line-clamp is ignored on an element a flex parent has
   stretched, and the text then gets cropped mid-line instead of ending in an
   ellipsis. The chips take the slack instead, which also lines them up along
   the bottom of a row of cards. */
.subject-card .desc {
  color: var(--muted); font-size: .9rem;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4;
  line-clamp: 4; overflow: hidden;
}
.subject-card .chips { margin-top: auto; }
.subject-card .sub {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  line-clamp: 2; overflow: hidden;
}
.chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip {
  background: var(--surface-2); border-radius: 999px; padding: .18rem .6rem;
  font-size: .78rem; color: var(--muted); white-space: nowrap;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis;
}
.chip.best { background: var(--good-soft); color: var(--good); font-weight: 600; }
.chip.best.below { background: var(--bad-soft); color: var(--bad); }
.chip.resume { background: var(--warn-soft); color: var(--warn); font-weight: 600; }
/* Question count and length: what you compare papers by, so they read as
   quiet metadata under the title rather than as another pill to scan past. */
.card-facts { margin-top: .15rem; font-variant-numeric: tabular-nums; }
.subject-card .sub { color: var(--muted); }

.stats-panel { padding-bottom: 3rem; }
.stats-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.history-list { display: grid; gap: .5rem; }
.history-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: .7rem 1rem;
}
.history-row .score { font-weight: 700; }
.history-row .score.pass { color: var(--good); }
.history-row .score.fail { color: var(--bad); }
.site-footer { border-top: 1px solid var(--line); padding: 1.2rem 0 1.6rem; }
.footer-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.footer-inner p { margin: 0; }
.credit {
  color: var(--muted); white-space: nowrap;
  display: inline-flex; align-items: center; gap: .45rem;
}
.credit strong { color: var(--text); font-weight: 650; }
/* The way through to the credits page: small enough to be a footnote on the
   footer line, big enough to be a tap target on a phone. */
.credit-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; flex: none;
  border: 1px solid var(--line); border-radius: 50%;
  color: var(--muted); text-decoration: none;
  transition: color .12s, border-color .12s;
}
.credit-link svg { width: 15px; height: 15px; display: block; }
.credit-link:hover, .credit-link:focus-visible { color: var(--accent); border-color: var(--accent); }

/* ---------- the credits page ---------- */
.credit-page {
  display: grid; gap: 1rem; margin-bottom: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  /* Each card as tall as its own contents: one member has a note under their
     name, and stretching the whole row to match leaves the others hollow. */
  align-items: start;
}
.credit-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.1rem 1.2rem;
}
.credit-card p { margin: 0; }
.credit-role {
  color: var(--muted); text-transform: uppercase;
  letter-spacing: .07em; font-weight: 650;
}
/* The nickname is what anyone in the cohort would actually call them, so it
   leads and the full name sits under it. */
.credit-who { font-size: 1.45rem; font-weight: 700; margin: .15rem 0 .1rem !important; }
.credit-full { margin-bottom: .4rem !important; }
.credit-card .muted + .muted { margin-top: .5rem !important; }

/* ---------- contact ---------- */
.contact { margin-bottom: 2.4rem; }
.contact h2 { margin-bottom: .2rem; }
.contact-who { color: var(--accent); }
.contact-quote {
  margin: .6rem 0 1.1rem; padding: .1rem 0 .1rem 1rem;
  border-left: 3px solid var(--accent);
  color: var(--muted); font-size: 1.05rem; font-style: italic;
}
.contact-btns { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: 1.2rem; }
.contact-btn {
  display: inline-flex; align-items: center; gap: .5rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: .55rem 1.05rem; text-decoration: none; color: inherit; font-weight: 650;
  transition: transform .12s, border-color .12s, color .12s;
}
.contact-btn svg { width: 19px; height: 19px; flex: none; }
.contact-btn:hover, .contact-btn:focus-visible {
  transform: translateY(-2px); border-color: var(--accent); color: var(--accent);
}
/* Label above value, so a long address never has to share a line with its
   label on a phone. */
.contact-mail { margin: 0; display: grid; gap: .15rem; }
.contact-mail dt { color: var(--muted); font-size: .85rem; }
.contact-mail dd { margin: 0 0 .7rem; }
.contact-mail dd:last-child { margin-bottom: 0; }
.contact-mail a { color: var(--accent); overflow-wrap: anywhere; }

/* ---------- the credits-page easter egg ----------
   One card turns over to a photo when it is tapped enough times. The back is
   absolutely positioned, so the card keeps the height of its front and the
   grid does not shift when it flips. */
.egg-card { position: relative; perspective: 900px; cursor: pointer; user-select: none; }
.egg-face { transition: transform .5s cubic-bezier(.4, .1, .3, 1); backface-visibility: hidden; }
.egg-back {
  position: absolute; inset: 0; overflow: hidden;
  border-radius: var(--radius); transform: rotateY(180deg);
}
.egg-card.flipped .egg-front { transform: rotateY(180deg); }
.egg-card.flipped .egg-back { transform: rotateY(360deg); }
/* The card is a wide, short letterbox, so a portrait gets cropped to a band
   across it. Sitting that band above centre keeps a face in it rather than a
   chin and a collar. */
.egg-photo {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: center 32%;
}
/* A scrim under the words, so the line reads on a dark photo and a light one. */
.egg-caption {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0;
  padding: 1.6rem .9rem .7rem; color: #fff; font-weight: 650; font-size: .92rem;
  background: linear-gradient(to top, rgba(0, 0, 0, .72), rgba(0, 0, 0, 0));
}
@keyframes egg-nudge {
  0%, 100% { transform: scale(1); }
  40%      { transform: scale(.975); }
}
.egg-card.nudge:not(.flipped) { animation: egg-nudge .18s ease-out; }
@media (prefers-reduced-motion: reduce) {
  /* No turn and no squeeze: the photo simply appears. */
  .egg-face, .egg-card.flipped .egg-front, .egg-card.flipped .egg-back { transition: none; transform: none; }
  .egg-card.flipped .egg-front { visibility: hidden; }
  .egg-card.nudge:not(.flipped) { animation: none; }
}

.credit-notes { margin-bottom: 3rem; }
/* Quieter than the notes above it: something to read out when a page looks
   wrong, not something to notice on the way past. */
.site-version {
  margin: 1.4rem 0 0; font-size: .78rem;
  font-variant-numeric: tabular-nums;
}
/* The cohorts the past papers came from, set as a row of tags rather than a
   sentence: it is a roll of names, and a roll of names should look like one.
   Every tag is weighted the same — some cohorts are traceable for far more
   questions than others, but that reflects what happened to get written down,
   not what anybody contributed. */
.credit-source { margin-bottom: 2.4rem; }
.credit-source .lede { margin-bottom: .8rem; }
.source-intro { line-height: 1.55; margin: 0; max-width: 640px; }
.cohort-row {
  list-style: none; margin: 1.1rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .45rem;
}
.cohort {
  padding: .3rem .62rem; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface);
  font-size: .82rem; font-weight: 600; letter-spacing: .01em;
  font-variant-numeric: tabular-nums; color: var(--text);
}

.credit-list { margin: .8rem 0 0; padding-left: 1.1rem; display: grid; gap: .6rem; }
.credit-list li { color: var(--muted); line-height: 1.55; }
.credit-list strong { color: var(--text); }

/* The printable copy, under the buttons rather than beside them: it is a
   different kind of thing from starting the paper, and putting it in the row
   of buttons would make it look like a third way to begin. */
.intro-pdf {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin: .9rem 0 0;
}
.intro-pdf a {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .9rem; font-weight: 600; text-decoration: none;
}
.intro-pdf a:hover { text-decoration: underline; }
.intro-pdf svg { width: 17px; height: 17px; flex: none; }

/* ---------- start screen: which lectures to sit ---------- */
.lecture-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
}
.lecture-head h2 { margin: 0; }
.lecture-options {
  display: grid; gap: .5rem; margin: .8rem 0 .6rem;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.lecture-opt {
  display: flex; align-items: flex-start; gap: .6rem; min-width: 0;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px;
  padding: .6rem .75rem; cursor: pointer;
}
.lecture-opt.selected { border-color: var(--accent); }
.lecture-opt input { margin: .15rem 0 0; flex: none; accent-color: var(--accent); }
.lecture-opt-text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.lecture-opt-name { font-size: .9rem; }

/* ---------- the companion ----------
   A study buddy — a photo from assets/img/companion/, or a drawn cat when
   there are none — that climbs into the corner after a long quiet spell on one
   question. It sits above the page but takes no clicks except its own, so it
   can never swallow a tap meant for an answer or the Next button. */
.companion {
  position: fixed; right: 16px; bottom: 18px; z-index: 30;
  display: flex; align-items: flex-end; gap: .5rem;
  color: var(--accent); cursor: pointer;
  transition: opacity .25s, transform .25s;
}
.companion.hidden { display: none !important; }
.companion-face { display: block; }
.cat-svg { width: 62px; height: auto; }
/* A photo is shown whole, never cropped: half of these have writing on them,
   and a square crop would cut the joke in half. So it keeps its own shape and
   is only bounded — tall ones by the height, wide ones by the width. */
.companion-photo {
  width: auto; height: auto;
  max-width: 132px; max-height: 104px;
  border-radius: 12px; background: var(--surface);
  border: 2px solid var(--surface); box-shadow: var(--shadow);
}
.companion-bubble {
  margin: 0 0 .6rem; max-width: 46vw;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: 12px 12px 2px 12px;
  box-shadow: var(--shadow); padding: .5rem .7rem;
  font-size: .82rem; line-height: 1.35;
}
/* A picture that already has writing on it comes with no bubble at all. */
.companion-bubble.gone { display: none; }

/* It arrives the size of the page and shrinks into the corner over a couple of
   seconds. Scaling from its own bottom-right corner means it grows up and
   across the page and lands back exactly where it rests, with no drift. */
@keyframes cat-arrive {
  /* It holds at full size for the first stretch — an ease that starts fast
     swallows the big moment in a blink — then comes down and settles. */
  0%   { transform: scale(var(--cat-scale, 6)); opacity: .13; }
  22%  { transform: scale(calc(var(--cat-scale, 6) * .88)); opacity: .26; }
  65%  { opacity: .62; }
  92%  { transform: scale(.95); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes cat-blink {
  0%, 92%, 100% { transform: scaleY(1); }
  95%           { transform: scaleY(.12); }
}
/* The bubble waits for the cat to be nearly down before speaking. */
@keyframes cat-speak {
  0%, 72% { opacity: 0; transform: translateY(6px); }
  100%    { opacity: 1; transform: translateY(0); }
}
.companion.is-in .companion-face {
  transform-origin: 100% 100%;
  animation: cat-arrive 3s cubic-bezier(.45, .05, .3, 1) both;
}
.companion.is-in .companion-bubble { animation: cat-speak 3s ease-out both; }
.cat-eye { transform-box: fill-box; transform-origin: center; animation: cat-blink 5.5s infinite; }
.cat-eye:last-of-type { animation-delay: .12s; }

@media (prefers-reduced-motion: reduce) {
  .companion.is-in .companion-face,
  .companion.is-in .companion-bubble { animation: none; }
  .cat-eye { animation: none; }
}
@media (max-width: 560px) {
  .cat-svg { width: 50px; }
  .companion-photo { max-width: 104px; max-height: 84px; }
  .companion { right: 10px; bottom: 12px; }
  .companion-bubble { max-width: 50vw; font-size: .78rem; }
}

/* ---------- results: how each lecture went ---------- */
.breakdown {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 1.25rem; margin-bottom: 1.5rem;
  /* The review list is a grid, and a grid item will not shrink below its own
     content unless told to. Without this the longest lecture name — which does
     not wrap — widens the whole page on a phone. */
  min-width: 0;
}
.breakdown-head h2 { margin: 0 0 .25rem; font-size: 1.05rem; }
.breakdown-head p { margin: 0 0 1rem; }
.breakdown-list { display: grid; gap: .8rem; }
.breakdown-list { min-width: 0; }
.breakdown-row { min-width: 0; }
.breakdown-label {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .8rem; margin-bottom: .3rem; min-width: 0;
}
.breakdown-name {
  font-size: .92rem; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.breakdown-score { font-size: .85rem; font-weight: 650; white-space: nowrap; margin-left: auto; }
.breakdown-drill {
  flex: none; border: 1px solid var(--line); background: var(--surface-2);
  color: var(--muted); border-radius: 999px; padding: .1rem .6rem;
  font-size: .78rem; font-weight: 600; cursor: pointer; font-family: inherit;
}
.breakdown-drill:hover { border-color: var(--accent); color: var(--accent); }
.subset-note { margin: -.4rem 0 .8rem; font-size: .9rem; }
.breakdown-bar {
  height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden;
}
.breakdown-fill { height: 100%; border-radius: 999px; }
.breakdown-row.bad  .breakdown-fill  { background: var(--bad); }
.breakdown-row.warn .breakdown-fill  { background: var(--warn); }
.breakdown-row.good .breakdown-fill  { background: var(--good); }
.breakdown-row.bad  .breakdown-score { color: var(--bad); }
.breakdown-row.warn .breakdown-score { color: var(--warn); }
.breakdown-row.good .breakdown-score { color: var(--good); }

/* ---------- exam chrome ---------- */
.exam-body { padding-top: 0; }
.exam-header { position: sticky; top: 0; z-index: 20; background: var(--surface); border-bottom: 1px solid var(--line); }
.exam-header-inner {
  max-width: 1240px; margin: 0 auto; padding: .7rem 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.exam-id { display: flex; align-items: center; gap: .8rem; min-width: 0; flex: 1; }
.exam-id > div { min-width: 0; }
.back-link {
  text-decoration: none; font-size: 1.2rem; color: var(--muted);
  border: 1px solid var(--line); border-radius: 8px; padding: .1rem .55rem;
}
.exam-title { font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.exam-tools { display: flex; align-items: center; gap: .5rem; flex: none; }
.timer {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 1.05rem;
  background: var(--surface-2); border-radius: 8px; padding: .35rem .7rem; min-width: 88px; text-align: center;
}
.timer.warning { background: var(--warn-soft); color: var(--warn); }
.timer.danger { background: var(--bad-soft); color: var(--bad); animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .55; } }
.progress-rail { height: 3px; background: var(--surface-2); }
.progress-fill { height: 100%; width: 0; background: var(--accent); transition: width .25s; }

.screen { padding: 1.6rem 0 3rem; }
.intro-card { max-width: 720px; margin: 0 auto; }
.fact-list { list-style: none; padding: 0; margin: 1.2rem 0; display: grid; gap: .5rem; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.fact-list li { background: var(--surface-2); border-radius: 10px; padding: .7rem .9rem; }
.fact-list .k { display: block; font-size: .75rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.fact-list .v { font-weight: 650; }
.pace { margin: 1.4rem 0; }
.pace h2 { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.pace-options { display: flex; flex-wrap: wrap; gap: .4rem; margin: .5rem 0 .6rem; }
.pace-btn {
  background: var(--surface); border: 1px solid var(--line); color: var(--text);
  border-radius: 10px; padding: .45rem .85rem; font-size: .9rem;
}
.pace-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
.pace-btn.selected {
  background: var(--accent); border-color: var(--accent);
  color: var(--on-accent, #fff); font-weight: 650;
}
.pace p { margin: 0; }
.mode-options { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); margin-top: .5rem; }
.mode-btn {
  display: block; text-align: left; background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: 12px; padding: .8rem .9rem;
}
.mode-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
.mode-btn.selected { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: var(--accent-soft); }
.mode-name { display: block; font-weight: 650; margin-bottom: .1rem; }
.mode-blurb { display: block; font-size: .82rem; color: var(--muted); line-height: 1.45; }
.mode-btn.selected .mode-blurb { color: var(--text); opacity: .8; }

/* practice mode: the answer revealed under the question */
.option.is-correct { border-color: var(--good); background: var(--good-soft); }
.option.is-chosen-wrong { border-color: var(--bad); background: var(--bad-soft); }
.option .mark { margin-left: auto; font-size: .8rem; font-weight: 650; white-space: nowrap; padding-left: .6rem; }
.option.is-correct .mark { color: var(--good); }
.option.is-chosen-wrong .mark { color: var(--bad); }
.reveal { margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.reveal .explanation { margin-top: .6rem; }
.timer.tally { background: var(--accent-soft); color: var(--accent); }

/* ---------- signing in ----------
   One card, two boxes, nothing else to look at. */
.signin-card { max-width: 420px; margin: 3rem auto; }
.signin-card h1 { margin-bottom: .3rem; }
.signin-card .lede { margin-bottom: 1.4rem; }
.field { display: block; margin-bottom: 1rem; }
.field-label {
  display: block; margin-bottom: .3rem; font-size: .85rem;
  font-weight: 600; color: var(--muted);
}
.field input {
  font: inherit; width: 100%; padding: .65rem .8rem;
  color: var(--text); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 10px;
}
.field input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.signin-go { width: 100%; justify-content: center; margin-top: .3rem; }
.signin-error {
  margin: 0 0 .9rem; padding: .6rem .8rem; border-radius: 10px;
  background: var(--bad-soft); color: var(--bad); font-size: .9rem; font-weight: 600;
}
.signin-note { margin: 1.3rem 0 0; }

/* Signed in as … · Sign out, in the footer. */
.who-line { margin: .6rem 0 0; }
.link-btn {
  background: none; border: 0; padding: 0; font: inherit; font-size: inherit;
  color: var(--accent); text-decoration: underline; text-underline-offset: 3px;
}
.link-btn:hover { filter: brightness(1.15); }

/* ---------- the bell ----------
   A button in the exam toolbar, and a strip under the header while something
   is playing. The toolbar is already tight on a phone — timer, Questions and
   Submit have to fit — so below the wide breakpoint this is the bell alone. */
.calm-btn { display: inline-flex; align-items: center; gap: .4rem; }
.calm-btn svg { width: 17px; height: 17px; flex: none; }
.calm-btn.playing { color: var(--accent); border-color: var(--accent); }
/* The bell leans as it rings, so it is obvious which button turns it off. */
.calm-btn.playing svg { animation: calm-ring 2.2s ease-in-out infinite; transform-origin: 50% 15%; }
@keyframes calm-ring {
  0%, 70%, 100% { transform: rotate(0); }
  76% { transform: rotate(9deg); }
  84% { transform: rotate(-7deg); }
  92% { transform: rotate(4deg); }
}
.calm-bar {
  display: flex; align-items: center; gap: .8rem;
  padding: .55rem 20px; border-top: 1px solid var(--line);
  background: var(--accent-soft); color: var(--accent);
}
.calm-say { margin: 0; flex: 1; min-width: 0; font-size: .88rem; font-weight: 600; }
.calm-stop { flex: none; }
@media (max-width: 860px) {
  .calm-word { display: none; }
  .calm-bar { padding-left: 14px; padding-right: 14px; }
  .calm-say { font-size: .82rem; }
}
/* A fourth control costs the paper's name the room it had. Buy some back by
   tightening the toolbar on a phone. */
@media (max-width: 430px) {
  .exam-tools .ghost-btn.small, .exam-tools .primary-btn.small { padding: .32rem .45rem; font-size: .78rem; }
  .exam-tools .timer { padding: .28rem .45rem; font-size: .92rem; }
}
/* On a phone there is genuinely no room for four controls and the paper's
   name on one line: the name was coming out as "Lec". Give the toolbar its
   own row instead — a header one row taller costs less than a paper you
   cannot identify when you come back to the tab. */
@media (max-width: 430px) {
  .exam-header-inner { flex-wrap: wrap; row-gap: .45rem; }
  .exam-id { flex: 1 0 100%; }
  .exam-tools { width: 100%; justify-content: space-between; }
}
@media (prefers-reduced-motion: reduce) {
  .calm-btn.playing svg { animation: none; }
}

/* ---------- question reports ---------- */
.report-btn {
  background: none; border: 0; padding: .35rem 0; margin-top: .9rem;
  color: var(--muted); font-size: .8rem; text-decoration: underline;
  text-underline-offset: 3px; align-self: flex-start;
}
.report-btn:hover { color: var(--bad); }
.review-item .report-btn { margin-top: .6rem; }
.report-issues { display: grid; gap: .4rem; margin: .9rem 0; }
.report-issues .pace-btn { text-align: left; justify-content: flex-start; }
.report-comment {
  width: 100%; font: inherit; padding: .7rem .9rem; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  resize: vertical; margin-bottom: .6rem;
}
.report-comment:focus, .report-name:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.report-target { margin: 0 0 .2rem; }
#reportModal .modal-box { max-width: 480px; }
.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  background: var(--text); color: var(--bg); padding: .7rem 1.1rem;
  border-radius: 10px; box-shadow: var(--shadow); z-index: 60;
  font-size: .9rem; max-width: calc(100vw - 40px); text-align: center;
  transition: opacity .5s;
}
.toast.leaving { opacity: 0; }

.rules ul { color: var(--muted); padding-left: 1.1rem; margin: .4rem 0 0; }
.rules li { margin-bottom: .3rem; }
.intro-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.6rem; }

/* ---------- paper layout ---------- */
.exam-layout {
  max-width: 1240px; margin: 0 auto; padding: 1.4rem 20px 3rem;
  display: grid; gap: 1.2rem; grid-template-columns: minmax(0, 1fr) 250px; align-items: start;
}
.question-card { min-height: 340px; }
.q-meta {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: .8rem; margin-bottom: .9rem;
}
.q-number { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); font-weight: 650; flex: none; padding-top: .15rem; }
.q-tags { display: flex; gap: .4rem; flex-wrap: wrap; justify-content: flex-end; min-width: 0; }
.q-tags .chip.section { max-width: 22ch; }
/* The paper's header is cramped, so a lecture name is clipped short there. The
   review card is the full width of the page, so it can show the whole name —
   and knowing the lecture is the point of the tag. It still truncates on a
   narrow screen, where .chip's own max-width takes over. */
.review-item .q-tags .chip.section { max-width: none; }
.passage {
  background: var(--surface-2); border-left: 3px solid var(--accent);
  border-radius: 8px; padding: .8rem 1rem; margin-bottom: 1rem; white-space: pre-wrap;
}
.q-warning {
  display: flex; gap: .55rem; align-items: flex-start;
  background: var(--warn-soft); color: var(--warn);
  border-radius: 10px; padding: .6rem .8rem; margin-bottom: .9rem;
  font-size: .85rem; line-height: 1.45;
}
.q-warning-icon { flex: none; font-size: .95rem; line-height: 1.35; }
.review-item .q-warning { margin: .4rem 0 .8rem; }
.q-stem { font-size: 1.1rem; font-weight: 550; margin-bottom: 1.1rem; white-space: pre-wrap; }
.q-image { max-width: 100%; border-radius: 10px; border: 1px solid var(--line); margin-bottom: 1rem; }
.options { display: grid; gap: .55rem; }
.option {
  display: flex; gap: .75rem; align-items: flex-start; cursor: pointer;
  border: 1px solid var(--line); border-radius: 10px; padding: .8rem .9rem; background: var(--surface);
}
.option:hover { border-color: var(--accent); background: var(--accent-soft); }
.option input { margin: .25rem 0 0; accent-color: var(--accent); flex: none; }
.option.selected { border-color: var(--accent); background: var(--accent-soft); }
.option .letter { font-weight: 700; flex: none; min-width: 1.2em; }
.short-input {
  width: 100%; font: inherit; padding: .7rem .9rem; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
}
.short-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.hint { margin-top: .6rem; }

.question-nav { display: flex; gap: .6rem; margin-top: 1rem; flex-wrap: wrap; }
.question-nav .primary-btn { margin-left: auto; }
.flagged-on { background: var(--warn-soft); color: var(--warn); border-color: var(--warn); }

.palette { position: sticky; top: 84px; }
.palette-title { font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.palette-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: .4rem; margin-bottom: .9rem; }
.palette-grid.sec-label { display: block; }
.pal-section { grid-column: 1 / -1; font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin-top: .5rem; }
.pal-btn {
  padding: .45rem 0; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); font-size: .85rem; justify-content: center;
}
.pal-btn.answered { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 650; }
.pal-btn.flagged { border-color: var(--warn); box-shadow: inset 0 -3px 0 var(--warn); }
.pal-btn.current { outline: 2px solid var(--text); outline-offset: 1px; }
.legend { list-style: none; padding: 0; margin: 0 0 .6rem; display: grid; gap: .3rem; font-size: .8rem; color: var(--muted); }
.legend li { display: flex; align-items: center; gap: .5rem; }
.dot { width: 12px; height: 12px; border-radius: 4px; border: 1px solid var(--line); display: inline-block; }
.dot.answered { background: var(--accent-soft); border-color: var(--accent); }
.dot.flagged { border-color: var(--warn); box-shadow: inset 0 -3px 0 var(--warn); }

/* ---------- results ---------- */
.result-card { text-align: center; }
.score-ring {
  width: 150px; height: 150px; border-radius: 50%; margin: .5rem auto 1rem;
  display: grid; place-items: center; background: conic-gradient(var(--ring-color) var(--ring-deg), var(--surface-2) 0);
}
.score-ring .inner {
  width: 118px; height: 118px; border-radius: 50%; background: var(--surface);
  display: grid; place-items: center; line-height: 1.1;
}
.score-ring .pct { font-size: 2.1rem; font-weight: 700; }
.score-ring .of { font-size: .78rem; color: var(--muted); }
.verdict { font-weight: 700; letter-spacing: .06em; text-transform: uppercase; font-size: .95rem; }
.verdict.pass { color: var(--good); }
.verdict.fail { color: var(--bad); }
.result-stats { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin: 1rem 0; }
.result-actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; }
.review-list { display: grid; gap: .8rem; margin-top: 1.6rem; }
/* Same as the breakdown panel: a grid item will not shrink below its own
   content unless told to, and the lecture tag inside is a long unbroken name. */
.review-item { border-left: 4px solid var(--line); min-width: 0; }
.review-item .q-meta { min-width: 0; }
.review-item.correct { border-left-color: var(--good); }
.review-item.wrong { border-left-color: var(--bad); }
.review-item.blank { border-left-color: var(--muted); }
.tag { border-radius: 999px; padding: .15rem .6rem; font-size: .75rem; font-weight: 650; }
.tag.correct { background: var(--good-soft); color: var(--good); }
.tag.wrong { background: var(--bad-soft); color: var(--bad); }
.tag.blank { background: var(--surface-2); color: var(--muted); }
.answer-line { margin: .35rem 0; }
.answer-line .k { color: var(--muted); font-size: .85rem; margin-right: .35rem; }
.explanation { background: var(--surface-2); border-radius: 10px; padding: .8rem .9rem; margin-top: .7rem; white-space: pre-wrap; }
.opt-review { display: grid; gap: .35rem; margin: .6rem 0; }
.opt-review div { padding: .45rem .7rem; border-radius: 8px; border: 1px solid var(--line); }
.opt-review .is-correct { background: var(--good-soft); border-color: var(--good); }
.opt-review .is-chosen-wrong { background: var(--bad-soft); border-color: var(--bad); }

/* ---------- modal ---------- */
.modal { position: fixed; inset: 0; background: rgba(9, 13, 25, .55); display: grid; place-items: center; z-index: 50; padding: 20px; }
.modal-box { max-width: 420px; width: 100%; }
.modal-actions { display: flex; gap: .6rem; justify-content: flex-end; margin-top: 1.2rem; }

@media (max-width: 860px) {
  .exam-layout { grid-template-columns: minmax(0, 1fr); }
  .palette { position: static; order: -1; }
  .palette.collapsed { display: none; }
  .palette-grid { grid-template-columns: repeat(8, 1fr); }
  h1 { font-size: 1.55rem; }
}
/* The navigator folds away at any width, so the toggle is always offered and
   the question takes the whole width when it is gone. */
.palette.collapsed { display: none; }
/* Wider than the question had with the navigator beside it — hiding it is
   meant to give the question room — but still short of a full-width line of
   text on a big monitor. */
body.palette-off .exam-layout { grid-template-columns: minmax(0, 1fr); max-width: 1080px; }
@media (max-width: 620px) {
  .exam-header-inner { padding: .55rem 14px; gap: .5rem; }
  .exam-sub { display: none; }
  .exam-title { font-size: .95rem; }
  .timer { min-width: 0; padding: .3rem .5rem; font-size: .95rem; }
  .back-link { padding: .05rem .45rem; }
  .exam-tools { gap: .35rem; }
  .exam-tools .ghost-btn.small, .exam-tools .primary-btn.small { padding: .35rem .55rem; font-size: .8rem; }
  .exam-layout, .wrap { padding-left: 14px; padding-right: 14px; }
  .card { padding: 1.1rem; }
  .question-nav .primary-btn { margin-left: 0; width: 100%; justify-content: center; }
}

/* ---------- what people said about a paper ----------
   On the start screen, above the PDF link: the last thing read before deciding
   whether to sit this one. On the results screen, the form for adding to it. */
.notes-panel { margin-top: 1.6rem; padding-top: 1.3rem; border-top: 1px solid var(--line); }
.notes-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; }
.notes-panel h2 { margin: 0 0 .5rem; font-size: 1.02rem; }
.notes-summary { margin: 0 0 .9rem; display: flex; align-items: center; gap: .1rem .35rem; flex-wrap: wrap; }
.notes-summary strong { font-variant-numeric: tabular-nums; }
.notes-verdict::before { content: '· '; }
/* Narrow enough that the verdict drops to its own line, where a leading dot
   would look like the line above got cut off. */
@media (max-width: 560px) {
  .notes-verdict { flex-basis: 100%; }
  .notes-verdict::before { content: ''; }
}

.stars { white-space: nowrap; letter-spacing: .04em; }
.star { color: var(--line); }
.star.on { color: #e0a422; }
:root[data-theme="dark"] .star.on { color: #f0c069; }
.small-stars { font-size: .82rem; }

.note-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .9rem; }
.note { padding: .75rem .85rem; border: 1px solid var(--line); border-radius: 11px; background: var(--surface-2); }
.note-by { margin: 0 0 .3rem; display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap; }
.note-name { font-weight: 600; }
/* Wraps rather than scrolls: a comment is somebody's sentence, and a sentence
   that runs off the side of a phone is not readable. */
.note-body { margin: 0; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
.note-remove { margin-left: auto; font-size: .8rem; }

.notes-form { margin: 0 0 1.4rem; }
.notes-form h2 { margin: 0 0 .3rem; font-size: 1.05rem; }
.note-stars { display: flex; gap: .1rem; margin: .9rem 0 .2rem; }
.star-btn {
  border: 0; background: none; cursor: pointer; padding: .1rem .12rem;
  font-size: 1.85rem; line-height: 1; color: var(--line);
}
.star-btn.on { color: #e0a422; }
:root[data-theme="dark"] .star-btn.on { color: #f0c069; }
.star-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.note-label { margin: .9rem 0 .35rem; color: var(--muted); }
.note-choices { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip-btn {
  padding: .4rem .75rem; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  font: inherit; font-size: .88rem;
}
.chip-btn.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.note-input {
  width: 100%; margin: .9rem 0 .2rem; padding: .6rem .7rem;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-2); color: var(--text); font: inherit;
  /* iOS zooms the page in on any field under 16px when it takes focus, and
     never zooms back out. */
  font-size: 16px;
}
.note-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.note-count { margin: 0 0 .2rem; text-align: right; font-variant-numeric: tabular-nums; }
.note-name-input { margin-top: .5rem; }
.notes-form .primary-btn { margin-top: .9rem; }

/* ---------- the reports page ----------
   A working list, not a display: what somebody said, the question they said it
   about, and a button that takes it off the pile. */
.report-tools {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: .9rem;
  margin-bottom: 1.4rem;
}
.report-filters { display: flex; gap: .4rem; }
.report-paper { margin: 0; min-width: min(320px, 100%); }
.report-paper select {
  width: 100%; padding: .55rem .7rem; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  font: inherit; font-size: 16px;      /* iOS zooms in on anything smaller */
}

.report-list { display: grid; gap: 1rem; padding-bottom: 3rem; }
.report { padding: 1.15rem 1.25rem; }
/* Handled ones stay readable but stop competing for attention. */
.report.done { opacity: .58; }
.report-head { display: flex; align-items: flex-start; gap: .9rem; flex-wrap: wrap; }
.report-where { min-width: 0; flex: 1 1 14rem; }
.report-head h2 { margin: 0 0 .15rem; font-size: 1.02rem; }
.report-head p { margin: 0; }
.report-comment {
  margin: .9rem 0 0; padding: .7rem .85rem; border-radius: 11px;
  background: var(--accent-soft); line-height: 1.55;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.report-stem { margin: .9rem 0 .4rem; line-height: 1.55; overflow-wrap: anywhere; }
.report-options { margin: 0; padding-left: 1.15rem; display: grid; gap: .15rem; }
.report-options li { color: var(--muted); line-height: 1.5; overflow-wrap: anywhere; }
.report-facts { margin-top: .8rem; display: grid; gap: .2rem; }
.report-line { margin: 0; font-size: .9rem; }
.report-label { color: var(--muted); margin-right: .4rem; }
.report-open { display: inline-block; margin-top: .9rem; font-size: .9rem; }

/* The one-press import of the reports that predate this page. Shown only while
   there is nothing at all to show, and only to whoever holds the admin year. */
.seed-wrap { margin-top: 1.4rem; padding-top: 1.2rem; border-top: 1px solid var(--line); max-width: 640px; }
.seed-wrap p { margin: 0 0 .8rem; line-height: 1.55; }
