/* rianta.css — the product's stylesheet (design pass, docs/specs/2026-10-28-design-pass-spec.md rev 9).
   Loaded after app.css (which the demo keeps, untouched) and before print.css. It wins by specificity and order:
   every override names a selector at least as specific as the app.css rule it replaces. No !important anywhere.

   Structure (spec §3.3, held by web/tests/design.test.mjs): at the top level of this file there are exactly
     1. the token blocks (light, then dark) — §2.1, §2.2;
     2. the type rules of §2.3 (print sees these on purpose: the printed page is Inter at the same sizes);
     3. one @media print block — the light tokens forced in both themes, and the two rules print needs;
     4. one @media screen block — everything else: layout, fills, edges, marks, the tab bar, sheets, motion.
   Stage 1 of the build (§9): tokens, type, the shell, buttons, chips, inputs, pills, cards, the outcome rows'
   geometry, the element box, the squares' hit box, segmented control, switch rows, banners, tables, toast
   position, My students, sign-in, reset.html, states. Stage 2: Capture's rows and the sticky Save card, To review's
   rows with the photo whole (D8) and its button row, the saved moment (§7). Stage 3: the student page — the header
   grid and its three-colour rule, the "If certified today" rows (M16 took their inline style), the status words'
   colours, the history's trace rail (a dot per row by data-state, M7) and 72 px thumbnails. Stage 4: the admin screens
   on a laptop — the Students, Classes and Staff tables' columns (Staff as a two-line row above 760 px), the Audit log's
   action tiles, Reports' cards, the descriptor sheet's header row and cells. */

/* ================================================================ 1. tokens — light (the default, by attribute: D5) */
:root, :root:not([data-theme]), :root[data-theme="light"] {
  color-scheme: light;
  --ground: #F7F3EA;      /* the page (D1) */
  --surface: #FFFFFF;     /* cards, sheets, inputs, the tab bar, the rail */
  --surface-2: #F7F3EA;   /* a field inside a card, a disabled fill, the PLU tile */
  --line: #E6DFD0;        /* card edges, rules */
  --line-2: #8A8272;      /* input and secondary-button edges: 3.44:1 on beige, 3.81:1 on white */
  --ink: #0B2D4B;         /* navy: text, icons, primary buttons, selected chips, the focus ring */
  --ink-2: #5B6B7C;       /* secondary text: 5.47:1 white, 4.94:1 beige */
  --on-ink: #FFFFFF;
  --brand-navy: #0B2D4B;  /* constant in both themes: text on a teal or yellow fill, the toast's ground */
  --on-brand-navy: #FFFFFF;
  --teal: #20B09B;        /* marks and fills only (brand-navy on teal 5.19:1) */
  --yellow: #F4B400;      /* marks and fills only (brand-navy on yellow 7.63:1) */
  --ok-ink: #0F6D5F;      /* the word "Achieved": 6.23:1 white, 5.62:1 beige */
  --ok-tint: #E7F4F0;
  --amber-ink: #8A6200;   /* "Not yet achieved" with progress, "Still needed", "needs more" */
  --amber-tint: #FBF0D2;
  --alert-ink: #A43137;   /* real errors only */
  --alert-tint: #FFF1EF;
  --sel-tint: #EEF3F7;    /* a selected suggestion's or row's fill */
  --pri: var(--ink);      /* the primary button's fill */
  --scrim: rgba(11, 45, 75, .5);
  --shadow: 0 14px 30px -26px rgba(11, 45, 75, .35);
  --shadow-btn: 0 10px 24px -12px rgba(11, 45, 75, .55);
  --r: 20px; --r-s: 14px; --r-pill: 999px;
  /* app.css's legacy names, so the inline styles in the views follow */
  --acc: var(--ink); --acc-2: var(--ink); --acc-dim: var(--sel-tint); --on-acc: var(--on-ink);
  --ok: var(--ok-ink); --ok-dim: var(--ok-tint); --mid: var(--amber-ink); --mid-dim: var(--amber-tint);
  --bad: var(--alert-ink); --bad-dim: var(--alert-tint); --alert: var(--alert-ink);
  --ink-3: var(--ink-2); --surface-3: var(--surface-2); --glass: transparent; --line-soft: var(--line);
  --f-dis: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --f-ui: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --f-mono: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ================================================================ 1. tokens — dark */
:root[data-theme="dark"] {
  color-scheme: dark;
  --ground: #102536; --surface: #183448; --surface-2: #224359;
  --line: #2C4C63; --line-2: #829CAB;
  --ink: #F4F7F6; --ink-2: #B8C9D4; --on-ink: #0B2D4B;
  --brand-navy: #0B2D4B; --on-brand-navy: #FFFFFF; --teal: #20B09B; --yellow: #F4B400;
  --ok-ink: #83E0C9; --ok-tint: #1E4A44; --amber-ink: #F2C14E; --amber-tint: #3E3620;
  --alert-ink: #FFB6B5; --alert-tint: #40282F; --sel-tint: #224359;
  --pri: #EAF1F3;
  --scrim: rgba(0, 0, 0, .6);
  --shadow: none; --shadow-btn: none;
  --r: 20px; --r-s: 14px; --r-pill: 999px;
  --acc: var(--ink); --acc-2: var(--ink); --acc-dim: var(--sel-tint); --on-acc: var(--on-ink);
  --ok: var(--ok-ink); --ok-dim: var(--ok-tint); --mid: var(--amber-ink); --mid-dim: var(--amber-tint);
  --bad: var(--alert-ink); --bad-dim: var(--alert-tint); --alert: var(--alert-ink);
  --ink-3: var(--ink-2); --surface-3: var(--surface-2); --glass: transparent; --line-soft: var(--line);
  --f-dis: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --f-ui: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --f-mono: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ================================================================ 2. type (§2.3) — phone sizes; the laptop deltas are in the screen block */
body { font-family: Inter, "Segoe UI", system-ui, -apple-system, sans-serif; font-size: 16px; line-height: 24px; }
h1, h2, h3, h4 { font-family: inherit; font-weight: 800; letter-spacing: -.02em; font-variation-settings: normal; }
#stHead h2 { font-size: 30px; line-height: 34px; letter-spacing: -.025em; }
.top h1 { font-size: 26px; line-height: 32px; }
.card-h h3, .sheet .card-h h3 { font-size: 17px; line-height: 24px; letter-spacing: -.01em; }
.sugg, .rowitem { font-size: 16px; line-height: 24px; }
.cov-list .lo-row { font-size: 15px; line-height: 21px; }
.cov-list .lo-row .txt { font-size: 15px; line-height: 21px; font-weight: 400; }
.cov-list .lo-row .code, .sugg b, .chip b { font-family: inherit; font-size: 14px; line-height: 21px; font-weight: 700; }
.elgrp .en { font-size: 15px; line-height: 21px; font-weight: 600; }
.elgrp .en .frac, .cov-list .en .frac { font-family: inherit; font-size: 13px; line-height: 19px; font-weight: 700; }
.btn { font-size: 16px; line-height: 20px; font-weight: 600; }
.btn.pri { font-size: 17px; }
.btn.sm { font-size: 15px; }
.chip { font-size: 15px; line-height: 20px; font-weight: 500; }
.chip.on { font-weight: 600; }
.lab, label { font-family: inherit; font-size: 14px; line-height: 20px; font-weight: 600; text-transform: none; letter-spacing: 0; }
.tiny, .muted, .top .sub, .state { font-family: inherit; font-size: 13px; line-height: 19px; font-weight: 400; letter-spacing: 0; }
.pill, .cov-list .lo-row .st { font-size: 13px; line-height: 19px; font-weight: 700; letter-spacing: 0; }
.nav { font-size: 12px; line-height: 14px; font-weight: 600; }
.nav[aria-current="true"] { font-weight: 700; }
.nav .count { font-family: inherit; font-size: 12px; line-height: 16px; font-weight: 700; }
.av, #accountName .ini { font-family: inherit; font-size: 13px; line-height: 36px; font-weight: 700; letter-spacing: 0; }
.brand b { font-family: inherit; font-size: 18px; line-height: 22px; font-weight: 800; letter-spacing: -.01em; }
.brand small { font-size: 12px; line-height: 16px; font-weight: 500; letter-spacing: 0; }
table, td { font-size: 15px; line-height: 22px; }
th { font-family: inherit; font-size: 13px; line-height: 19px; font-weight: 700; text-transform: none; letter-spacing: 0; }
.pw { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 22px; line-height: 28px; font-weight: 500; letter-spacing: .04em; }
.mono { font-family: inherit; font-size: 1em; }
input[type=text], input[type=email], input[type=password], input[type=search], input[type=date], textarea, select { font-size: 16px; line-height: 24px; }
.seg button { font-size: 15px; line-height: 20px; font-weight: 600; }
#jgCard .seg > button { font-size: 15px; font-weight: 600; }
.cov-list .lo-fold > summary { font-size: 15px; line-height: 20px; font-weight: 600; }
.banner { font-size: 16px; line-height: 24px; }
.switchrow b { font-size: 16px; line-height: 24px; font-weight: 600; }
.cov-list .plu-fold > summary b { font-size: 16px; line-height: 24px; font-weight: 700; }

/* ================================================================ 3. print (§3.3): light tokens in both themes, and the two rules print needs */
@media print {
  :root, :root:not([data-theme]), :root[data-theme="light"], :root[data-theme="dark"] {
    color-scheme: light;
    --ground: #FFFFFF; --surface: #FFFFFF; --surface-2: #FFFFFF; --line: #CCCCCC; --line-2: #8A8272;
    --ink: #0B2D4B; --ink-2: #5B6B7C; --on-ink: #FFFFFF; --brand-navy: #0B2D4B; --on-brand-navy: #FFFFFF;
    --teal: #20B09B; --yellow: #F4B400; --ok-ink: #0F6D5F; --ok-tint: #E7F4F0; --amber-ink: #8A6200; --amber-tint: #FBF0D2;
    --alert-ink: #A43137; --alert-tint: #FFF1EF; --sel-tint: #EEF3F7; --pri: #0B2D4B;
    --shadow: none; --shadow-btn: none;
  }
  .cov-list .lo-row.achieved { opacity: 1; }
  /* the "If certified today" rows keep today's look in print once §8 M16 removes their inline style (stage 3) */
  #stHead + .card > .card-b.grid > .row { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid var(--line); }
}

/* ================================================================ 4. screen: everything else */
@media screen {
  /* ---- base ---- */
  body { background: var(--ground); color: var(--ink); }
  body::before { content: none; }                               /* app.css's ambient gradients */
  ::selection { background: var(--ink); color: var(--on-ink); }
  .muted { color: var(--ink-2); }
  #view a, #sheet a, #reset a { color: var(--ink); text-underline-offset: 3px; }   /* navy is the only text colour (D2): no browser blue */
  .lab, label { color: var(--ink); }
  .top .sub { color: var(--ink-2); margin-top: 2px; }
  .state { color: var(--ink-2); }
  .grid { gap: 12px; }
  .card .grid { gap: 10px; }
  .chips { gap: 8px; }
  #view details > summary { min-height: 44px; cursor: pointer; }
  .wrap > * { animation: rianta-up .24s cubic-bezier(.2, .7, .3, 1) both; }
  @keyframes rianta-up { from { opacity: 0; transform: translateY(6px); } }

  /* ---- focus (§4): one ring, navy, on every control ---- */
  :focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
  .btn:focus-visible { border-radius: var(--r-s); }
  .chip:focus-visible, .pill:focus-visible { border-radius: var(--r-pill); }
  .nav:focus-visible { border-radius: 8px; outline-offset: -4px; }
  .btn.pri:focus-visible, .chip.on:focus-visible, .segb.on:focus-visible, .seg [aria-pressed="true"]:focus-visible { box-shadow: 0 0 0 2px var(--surface); }
  input[type]:focus-visible, textarea:focus-visible, select:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; box-shadow: none; border-color: var(--ink); }
  input[type]:focus:not(:focus-visible), textarea:focus:not(:focus-visible), select:focus:not(:focus-visible) { outline: 0; border-color: var(--ink); box-shadow: none; }

  /* ---- shell: the laptop rail (§3.2) ---- */
  .app { grid-template-columns: 240px 1fr; }
  .side { background: var(--surface); border-right: 1px solid var(--line); padding: 16px 12px; gap: 2px; }
  .brand { padding: 4px 8px 20px; gap: 12px; }
  .brand .mark { width: 32px; height: 32px; border-radius: 0; background: url(brand/rianta-r.svg) center / contain no-repeat; color: transparent; box-shadow: none; }
  :root[data-theme="dark"] .brand .mark { background-image: url(brand/rianta-r-navy.svg); border-radius: 8px; }
  .brand small { color: var(--ink-2); }
  .nav { position: relative; min-height: 48px; padding: 0 12px; gap: 12px; border-radius: 10px; color: var(--ink-2); font-size: 15px; line-height: 20px; }
  .nav:hover { background: var(--surface-2); color: var(--ink); }
  .nav[aria-current="true"] { background: var(--surface-2); color: var(--ink); box-shadow: inset 3px 0 0 var(--ink); }
  .nav .ic { font-size: 0; width: 20px; height: 20px; opacity: 1; flex: none; background: currentColor; -webkit-mask: url(icons/camera.svg) center / contain no-repeat; mask: url(icons/camera.svg) center / contain no-repeat; }
  .nav[data-go="mine"] .ic, .nav[data-go="students"] .ic { -webkit-mask-image: url(icons/students.svg); mask-image: url(icons/students.svg); }
  .nav[data-go="review"] .ic { -webkit-mask-image: url(icons/inbox.svg); mask-image: url(icons/inbox.svg); }
  .nav[data-go="classes"] .ic { -webkit-mask-image: url(icons/classes.svg); mask-image: url(icons/classes.svg); }
  .nav[data-go="staff"] .ic { -webkit-mask-image: url(icons/staff.svg); mask-image: url(icons/staff.svg); }
  .nav[data-go="settings"] .ic { -webkit-mask-image: url(icons/settings.svg); mask-image: url(icons/settings.svg); }
  .nav[data-go="audit"] .ic { -webkit-mask-image: url(icons/audit.svg); mask-image: url(icons/audit.svg); }
  .nav[data-go="reports"] .ic { -webkit-mask-image: url(icons/reports.svg); mask-image: url(icons/reports.svg); }
  .nav .count { margin: 0 0 0 auto; opacity: 1; min-width: 18px; height: 18px; padding: 0 6px; border-radius: var(--r-pill); background: var(--yellow); color: var(--brand-navy); display: inline-flex; align-items: center; justify-content: center; }
  .nav .count:empty { display: none; }
  .side-foot { color: var(--ink-2); font-size: 13px; line-height: 19px; padding: 14px 8px 2px; border-top: 1px solid var(--line); }

  /* ---- shell: the header and the account strip ---- */
  .top { gap: 10px 14px; padding: 16px 40px; background: color-mix(in srgb, var(--ground) 88%, transparent); border-bottom: 1px solid var(--line); flex-wrap: nowrap; }
  .top > div:first-child { flex: 1 1 0; min-width: 120px; }                    /* one row, never wrapping: the title block takes what the strip leaves (its sub-line wraps) */
  .top .sub { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
  .top h1 { font-size: 28px; line-height: 34px; }
  #account { gap: 10px; flex-wrap: nowrap; min-height: 44px; }
  #envPill { position: relative; padding-left: 24px; }
  #envPill::before { content: ""; position: absolute; left: 10px; top: 50%; width: 8px; height: 8px; margin-top: -4px; border-radius: 50%; background: var(--yellow); }
  #accountName { flex: none; color: var(--ink); }
  #accountName b { font-weight: 600; }
  .side-tools { display: flex; gap: 0; padding: 0; flex: none; }
  .side-tools .btn, #themeBtn { width: 44px; min-height: 44px; padding: 0; border-radius: 50%; justify-content: center; font-size: 18px; }
  #account[hidden] ~ .side-tools { margin-left: auto; }
  .wrap { max-width: 960px; padding: 24px 40px 72px; }
  #view :is(button, input, select, textarea, summary, a, [tabindex]) { scroll-margin-top: 150px; scroll-margin-bottom: 24px; }   /* clears the sticky header, even one whose title wraps on a narrow laptop; the strip always shows the role (the block 3 runner reads it at 1200) */

  /* ---- cards (§4) ---- */
  .card { border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow); transition: none; }
  .card::before { content: none; }
  .card:hover { border-color: var(--line); }
  .card-h { padding: 16px 18px; gap: 10px; border-bottom: 1px solid var(--line); }
  .card-b { padding: 16px 18px; }
  body[data-screen="mine"] .card-h { border-bottom: 0; padding-bottom: 6px; }

  /* ---- buttons (§4) ---- */
  .btn { min-height: 44px; padding: 10px 16px; gap: 8px; border: 1.5px solid var(--line-2); border-radius: var(--r-s); background: var(--surface); color: var(--ink); text-decoration: none; box-shadow: none; }
  .btn:hover { background: var(--surface-2); border-color: var(--line-2); }
  .btn.pri { min-height: 52px; padding: 12px 20px; background: var(--pri); color: var(--on-ink); border-color: var(--pri); box-shadow: var(--shadow-btn); }
  .btn.pri:hover { background: var(--pri); box-shadow: var(--shadow-btn); }
  .btn.sm { min-height: 44px; padding: 0 14px; }
  .btn:disabled, .sugg[disabled], .chip[disabled], .segb[disabled], .seg button:disabled, #covMode button:disabled { opacity: 1; background: var(--surface-2); color: var(--ink-2); border-color: var(--line); box-shadow: none; cursor: not-allowed; }
  .btn:disabled:hover, .btn.pri:disabled:hover { background: var(--surface-2); color: var(--ink-2); border-color: var(--line); box-shadow: none; }
  #selected .chip[data-unsel][aria-disabled="true"] { color: var(--ink-2); cursor: default; }
  #selected .chip[data-unsel][aria-disabled="true"]::after { content: none; }

  /* ---- chips (§4) ---- */
  button.chip { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 14px; border: 1.5px solid var(--line-2); border-radius: var(--r-pill); background: var(--surface); color: var(--ink); }
  button.chip.on { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
  .chip .mark { display: inline-block; vertical-align: middle; font-size: 0; width: 16px; height: 16px; opacity: 1; background: currentColor; -webkit-mask: url(icons/lock.svg) center / contain no-repeat; mask: url(icons/lock.svg) center / contain no-repeat; }
  .chip.dim { opacity: 1; color: var(--ink); border-style: dashed; }
  span.chip.on { display: inline; background: var(--sel-tint); color: var(--ink); border: 0; border-radius: 4px; padding: 2px 6px; font-size: 15px; font-weight: 500; line-height: 1.6; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
  .chip b { font-weight: 700; }
  #selected .chip[data-unsel] { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 10px; margin: 2px 0; cursor: pointer; line-height: 20px; }
  #selected .chip[data-unsel]::after { content: ""; width: 16px; height: 16px; flex: none; background: currentColor; -webkit-mask: url(icons/cross.svg) center / contain no-repeat; mask: url(icons/cross.svg) center / contain no-repeat; }

  /* ---- inputs (§4) ---- */
  input[type=text], input[type=email], input[type=password], input[type=search], input[type=date], textarea, select { min-height: 48px; padding: 10px 14px; background: var(--surface); border: 1.5px solid var(--line-2); border-radius: var(--r-s); color: var(--ink); box-shadow: none; }
  textarea { min-height: 72px; line-height: 24px; }
  ::placeholder { color: var(--ink-2); }
  .field { gap: 6px; }

  /* ---- status pills (§4, D3): a word and a mark ---- */
  .pill { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 10px 0 8px; border: 0; border-radius: var(--r-pill); white-space: nowrap; }
  .pill::before { content: ""; width: 12px; height: 12px; flex: none; box-sizing: border-box; border-radius: 3px; border: 1.5px solid transparent; }
  .p-ok { background: var(--ok-tint); color: var(--ok-ink); }
  .p-ok::before { background: var(--yellow); border-color: var(--yellow); }
  .p-warn { background: var(--amber-tint); color: var(--amber-ink); }
  .p-warn::before { background: var(--teal); border-color: var(--teal); }
  .p-none { background: var(--surface-2); color: var(--ink-2); }
  .p-none::before { border-color: var(--line-2); }
  .p-alert { background: var(--amber-tint); color: var(--amber-ink); }
  .p-alert::before { border-color: var(--amber-ink); }
  .p-acc { background: var(--teal); color: var(--brand-navy); padding-left: 10px; }
  .p-acc::before { content: none; }
  .warn { color: var(--amber-ink); }
  .rowitem .tiny.warn { color: var(--amber-ink); }

  /* ---- tables (§4) ---- */
  th { color: var(--ink-2); padding: 10px 12px; border-bottom: 2px solid var(--ink); }
  td { padding: 12px; height: 56px; border-bottom: 1px solid var(--line); }
  tbody tr:hover { background: none; }
  .av { width: 36px; height: 36px; border-radius: 50%; background: var(--surface-2); color: var(--ink); }
  td a[data-open] { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); }
  td.row { display: table-cell; min-width: 300px; }                               /* a flex cell loses its row height; the 44 px buttons wrap inside the cell instead */
  td.row .btn { margin: 3px 6px 3px 0; }

  /* ---- the outcome row (§4), normal: a <button> with .code, .txt, .st and a mark in column 1 ---- */
  .cov-list .lo-row { display: grid; grid-template-columns: 20px auto 1fr auto; gap: 8px 10px; align-items: baseline; min-height: 48px; padding: 8px 4px; border: 0; border-top: 1px solid var(--line); border-radius: 0; background: none; color: var(--ink); text-align: left; width: 100%; }
  .cov-list .lo-row::before { content: ""; width: 14px; height: 14px; box-sizing: border-box; border-radius: 4px; border: 1.5px solid var(--line-2); align-self: start; margin-top: 4px; }
  .cov-list .lo-row.achieved::before { background: var(--yellow); border-color: var(--yellow); }
  .cov-list .lo-row.working::before { background: var(--teal); border-color: var(--teal); }
  .cov-list .lo-row:hover, .cov-list .lo-row.on { background: var(--sel-tint); border-top-color: var(--line); }
  .cov-list .lo-row.achieved { opacity: 1; background: none; }
  .cov-list .lo-row.achieved:hover { background: var(--sel-tint); }
  .cov-list .lo-row .code { grid-column: 2; color: var(--ink); }
  .cov-list .lo-row .txt { grid-column: 3; min-width: 0; }
  .cov-list .lo-row .st { grid-column: 4; min-width: 0; text-align: right; white-space: nowrap; }
  .cov-list .st.ok { color: var(--ok-ink); }
  .cov-list .st.mid { color: var(--ink); }
  .cov-list .st.alert { color: var(--ink-2); }
  /* selecting (Mark achieved): a <div> whose first child is the tick box or an empty span; no mark */
  .cov-list .lo-row.selecting { grid-template-columns: 24px auto 1fr auto; cursor: pointer; }
  .cov-list .lo-row.selecting[aria-disabled="true"] { cursor: default; }
  .cov-list .lo-row.selecting::before { content: none; }
  .cov-list .lo-row.selecting > input, .cov-list .lo-row.selecting > span:first-child { grid-column: 1; align-self: start; }
  .cov-list .lo-row.selecting input[type=checkbox] { width: 24px; height: 24px; margin: 0; accent-color: var(--ink); }
  /* the element box, the folds, the labels */
  .elgrp, .elgrp.fail { background: none; }
  .elgrp { gap: 8px; padding: 12px; border: 1px solid var(--line); border-radius: 14px; }
  .elgrp.fail { border-color: var(--amber-ink); }
  .elgrp .en { color: var(--ink); gap: 10px; }
  .elgrp .en .frac, .cov-list .en .frac { color: var(--ink-2); }
  .cov-list .lab.alert { color: var(--amber-ink); }
  .cov-list .lab.ok { color: var(--ok-ink); }
  .cov-list .ok { color: var(--ok-ink); }
  .cov-list .plu-fold > summary { min-height: 48px; padding: 4px 0; gap: 10px; }
  #selBar { padding: 12px 18px 0; }                                               /* the Mark-achieved bar sits between the card header and the list */
  .cov-list .plu-fold > summary::before, .cov-list .plu-fold[open] > summary::before { content: ""; font-size: 0; width: 20px; height: 20px; flex: none; color: var(--ink); background: currentColor; -webkit-mask: url(icons/chevron-down.svg) center / contain no-repeat; mask: url(icons/chevron-down.svg) center / contain no-repeat; transform: rotate(-90deg); }
  .cov-list .plu-fold[open] > summary::before { transform: none; }
  .cov-list .lo-fold > summary { display: flex; align-items: center; min-height: 44px; padding: 0 12px; border-radius: 12px; color: var(--ok-ink); border: 1px dashed var(--line-2); }
  /* the squares: real buttons that open the outcome, so a 44 px hit box around a 24 px mark */
  .hm { gap: 0; }
  .hm .cell { width: 44px; height: 44px; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; display: grid; place-items: center; transition: none; }
  .hm .cell::before { content: ""; width: 24px; height: 24px; box-sizing: border-box; border-radius: 6px; border: 1.5px solid transparent; transition: transform .1s; }
  .hm .c-ok::before { background: var(--yellow); border-color: var(--yellow); }
  .hm .c-warn::before { background: var(--teal); border-color: var(--teal); }
  .hm .c-none::before { background: var(--surface); border-color: var(--line-2); }
  .hm .cell:hover { transform: none; box-shadow: none; z-index: auto; }
  .hm .cell:hover::before { transform: scale(1.15); }

  /* ---- the student page (§5, stage 3): the header — a grid: the name; class, the programme pill, year; the no-photos
     line; the back link and Print on their own row below; a 3 px navy/teal/yellow rule. The back link's label already
     carries "← " (copy, D7), so it takes no chevron mask. Every item is placed by area, since the no-photos and
     left-the-roll lines are conditional; an empty area row is 0 px tall and the row gap is 0 (the items carry margins) */
  #stHead { display: grid; grid-template-columns: minmax(0, max-content) max-content minmax(0, 1fr); grid-template-areas: "name name name" "class prog year" "warn warn warn" "left left left" "back back print" "rule rule rule"; gap: 0 10px; align-items: center; padding: 4px 0 0; }
  #stHead h2 { grid-area: name; font-size: 32px; line-height: 38px; }
  #stHead > h2 + .tiny { grid-area: class; }
  #stHead > .pill { grid-area: prog; justify-self: start; }
  #stHead > .pill + .tiny { grid-area: year; justify-self: start; }
  #stHead > h2 + .tiny, #stHead > .pill + .tiny { margin-top: 8px; font-size: 15px; line-height: 22px; color: var(--ink-2); }
  #stHead > .pill { margin-top: 8px; }
  #stHead > .warn { grid-area: warn; }
  #stHead > .pill + .tiny + .tiny, #stHead > .warn + .tiny { grid-area: left; }
  #stHead > .warn, #stHead > .pill + .tiny + .tiny, #stHead > .warn + .tiny { margin-top: 6px; font-size: 14px; line-height: 20px; }
  #stHead > [data-go2] { grid-area: back; justify-self: start; min-height: 44px; margin-top: 10px; padding: 0 8px 0 0; background: none; border: 0; box-shadow: none; font-size: 15px; font-weight: 600; color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
  #stHead > [data-go2]:hover { background: none; }
  #stHead > #printBtn { grid-area: print; justify-self: end; min-height: 44px; margin-top: 10px; padding: 0 14px; gap: 8px; }
  #stHead > #printBtn::before { content: ""; width: 20px; height: 20px; flex: none; background: currentColor; -webkit-mask: url(icons/print.svg) center / contain no-repeat; mask: url(icons/print.svg) center / contain no-repeat; }
  #stHead::after { content: ""; grid-area: rule; height: 3px; margin-top: 14px; border-radius: 2px; background: linear-gradient(to right, var(--ink) 0 50%, var(--teal) 50% 80%, var(--yellow) 80% 100%); }

  /* ---- the student page: "If certified today" (§5) — scoped to that card; M16 removed the rows' inline style and the
     print block restores it. The PLU number is a small tile; the pill and the count sit on a second line, never wrapping */
  #stHead + .card > .card-b.grid > .row { display: grid; grid-template-columns: 1fr; gap: 6px; align-items: start; padding: 10px 0; border-bottom: 1px solid var(--line); }
  #stHead + .card > .card-b.grid > .row > span:first-child { font-size: 16px; line-height: 24px; font-weight: 600; color: var(--ink); }
  #stHead + .card > .card-b.grid > .row > span:first-child > .mono { display: inline-block; padding: 2px 8px; margin-right: 8px; border-radius: 6px; background: var(--surface-2); color: var(--ink-2); font-size: 12px; line-height: 16px; font-weight: 800; vertical-align: 2px; }
  #stHead + .card > .card-b.grid > .row > span:last-child { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

  /* ---- the outcome row's status word (§4, D3): a colour beside the mark, never red — app.css's .cov-list .st.alert is
     the error red at 0,3,0 */
  .cov-list .lo-row .st.ok { color: var(--ok-ink); }
  .cov-list .lo-row .st.mid { color: var(--ink); }
  .cov-list .lo-row .st.alert { color: var(--ink-2); }

  /* ---- the student page: the evidence history (§4) — each row a grid of a 72 px thumbnail and the rest; a trace rail
     drawn by the rows themselves (so an empty history has none) with a 12 px dot per row coloured by data-state (M7):
     signed_off yellow, filed teal, pending outlined, needs_more amber. The media slot spans the content rows; the row
     gap is 0 and the content items carry margins, so the empty spanned rows add no height */
  #stHistory .rowitem.col[data-row] { position: relative; display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 0 12px; align-items: start; margin-left: 22px; padding: 14px 0; }
  #stHistory .rowitem.col[data-row] > .rv-media { grid-column: 1; grid-row: 1 / span 8; width: 72px; min-height: 72px; border-radius: 10px; background: var(--surface-2); display: grid; place-items: center; text-align: center; overflow: hidden; }
  #stHistory .rowitem.col[data-row] > .rv-media > .tiny { font-size: 12px; line-height: 15px; padding: 4px; }
  #stHistory .rowitem.col[data-row] > .rv-media [data-retry] { width: 72px; min-height: 72px; padding: 4px; border: 0; border-radius: 10px; background: var(--surface-2); font-size: 12px; line-height: 15px; white-space: normal; }
  #stHistory .rv-media img, #stHistory .rv-media video { display: block; width: 72px; height: 72px; max-width: none; max-height: none; object-fit: cover; border-radius: 10px; }
  #stHistory .rv-media video { pointer-events: none; }                            /* the row's tap opens the evidence sheet, where the video plays at full size */
  #stHistory .rowitem.col[data-row] > :not(.rv-media) { grid-column: 2; margin-top: 4px; }
  #stHistory .rowitem.col[data-row] > .rv-media + * { margin-top: 0; }
  #stHistory .rowitem.col[data-row] > .rv-media + .tiny + div:not(.tiny):not(.chips) { font-size: 16px; line-height: 22px; font-weight: 600; }
  #stHistory .rowitem.col[data-row] > div > i { font-weight: 400; }
  #stHistory .rowitem.col[data-row]::before { content: ""; position: absolute; left: -22px; top: 18px; width: 12px; height: 12px; box-sizing: border-box; border-radius: 50%; border: 2px solid var(--line-2); background: var(--surface); z-index: 1; }
  #stHistory .rowitem.col[data-state="signed_off"]::before { background: var(--yellow); border-color: var(--yellow); }
  #stHistory .rowitem.col[data-state="filed"]::before { background: var(--teal); border-color: var(--teal); }
  #stHistory .rowitem.col[data-state="needs_more"]::before { background: var(--amber-ink); border-color: var(--amber-ink); }
  #stHistory .rowitem.col[data-row]::after { content: ""; position: absolute; left: -17px; top: 0; bottom: -1px; width: 2px; background: var(--line); }
  #stHistory .rowitem.col[data-row]:first-child::after, #stHistory > .tiny + .rowitem.col[data-row]::after { top: 24px; }
  #stHistory .rowitem.col[data-row]:last-child::after { bottom: calc(100% - 24px); }
  /* the inline "Review" links in the history and the evidence sheet (§4): a 44 px hit area without moving the text */
  #stHistory a[href="#review"], #sheet a[href="#review"] { display: inline-block; min-height: 44px; box-sizing: border-box; padding: 12px 6px; margin: -12px -6px; text-decoration: underline; text-underline-offset: 3px; }

  /* ---- segmented control (§4) ---- */
  .seg { border: 1.5px solid var(--line-2); border-radius: var(--r-s); background: var(--surface); }
  .seg button { min-height: 44px; padding: 0 14px; color: var(--ink); background: none; border-right: 1px solid var(--line); }
  .seg button:hover { background: var(--surface-2); }
  .seg button[aria-pressed="true"], .seg .segb.on { background: var(--ink); color: var(--on-ink); }
  #jgCard .seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; width: 100%; }
  #jgCard .seg > button { min-height: 52px; white-space: normal; text-align: center; }

  /* ---- switch rows (§4) ---- */
  .switchrow { min-height: 56px; gap: 12px; padding: 12px 0; }
  .switchrow input[type=checkbox] { width: 24px; height: 24px; margin: 0; flex: none; accent-color: var(--ink); }
  .switchrow .tiny { color: var(--ink-2); }

  /* ---- banners (§4) ---- */
  .banner { gap: 12px; padding: 12px 14px; border: 0; border-radius: 12px; align-items: flex-start; }
  .banner > span:first-child { width: 24px; height: 24px; flex: none; display: grid; place-items: center; border-radius: 50%; border: 1.5px solid currentColor; font-size: 14px; font-weight: 800; line-height: 1; }
  .b-alert { background: var(--alert-tint); color: var(--alert-ink); }
  .b-warn { background: var(--amber-tint); color: var(--amber-ink); }
  .b-ok { background: var(--ok-tint); color: var(--ok-ink); }
  .banner b { color: inherit; }

  /* ---- states (§6) ---- */
  #view .card-b.tiny.muted { font-size: 16px; line-height: 24px; color: var(--ink-2); padding: 24px 18px; }
  #siMsg, #stMsg, #capSaveMsg, [data-msg] { font-size: 15px; line-height: 21px; color: var(--ink); }
  #siMsg:empty, #stMsg:empty, #capSaveMsg:empty, [data-msg]:empty { display: none; }
  .pw { background: var(--surface-2); border: 1.5px solid var(--line-2); border-radius: var(--r-s); color: var(--ink); }

  /* ---- My students (§4) ---- */
  .card-b > ul { list-style: none; padding: 0; margin: 0; }
  .card-b > ul > li { border-top: 1px solid var(--line); }
  .card-b > ul > li:first-child { border-top: 0; }
  .card-b > ul > li > a { display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 2px; color: var(--ink); text-decoration: none; font-size: 17px; font-weight: 600; border-radius: 8px; }
  .card-b > ul > li > a::after { content: ""; margin-left: auto; width: 20px; height: 20px; flex: none; color: var(--ink-2); background: currentColor; -webkit-mask: url(icons/chevron-left.svg) center / contain no-repeat; mask: url(icons/chevron-left.svg) center / contain no-repeat; transform: rotate(180deg); }
  .card-b > ul > li > a:hover, .card-b > ul > li > a:active { background: var(--sel-tint); }

  /* ---- the admin screens (§4 tables, §5; stage 4) — what a principal walks on a laptop: Students, Classes, Staff &
     access, Settings, Reports, the descriptor sheet, Audit. The tables keep their markup; these rules place the columns
     and size the type, each scoped by body[data-screen] (M8) so no other screen's table moves. The column placement
     lives in the laptop block below (> 760 px); the phone keeps today's wrapping and sideways-scrolling tables (§5) ---- */
  th { white-space: nowrap; }
  body[data-screen="students"] #view .card-h > .tiny.muted { font-size: 15px; line-height: 22px; }   /* a class's count beside its name */
  /* Students: the row itself opens the editor, so it shows a pointer and a fill under it; "Open record" is a text link
     beside the name (44 px tall since stage 1) */
  body[data-screen="students"] #view td { padding: 10px 12px; }
  body[data-screen="students"] #view td:first-child b { font-size: 16px; }
  body[data-screen="students"] #view td.tiny { font-size: 15px; color: var(--ink); }
  body[data-screen="students"] #view td a[data-open] { font-size: 14px; font-weight: 500; margin-left: 6px; padding: 0 2px; text-decoration: underline; text-underline-offset: 3px; }
  body[data-screen="students"] #view tbody tr[data-id] { cursor: pointer; }
  body[data-screen="students"] #view tbody tr[data-id]:hover { background: var(--sel-tint); }
  body[data-screen="students"] #view td .pill + .pill { margin-left: 6px; }
  /* Classes: the year is data, not a note */
  body[data-screen="classes"] #view td.tiny { font-size: 15px; color: var(--ink); }
  body[data-screen="classes"] #view td:first-child .pill { margin-left: 6px; vertical-align: 1px; }
  /* Staff & access: a name stays whole; the email is 14 px (on the laptop it wraps at any point before it widens the row) */
  body[data-screen="staff"] #view td.tiny { font-size: 14px; color: var(--ink); }
  body[data-screen="staff"] #view td > .row b { white-space: nowrap; }
  /* Audit: an action's name is a name, not a status — a plain tile, no mark (D3 is for statuses); the time in tabular
     figures; the detail in the secondary ink */
  #auditBody .pill { background: var(--surface-2); color: var(--ink); font-weight: 600; min-height: 26px; padding: 0 8px; border-radius: 6px; white-space: nowrap; }
  #auditBody .pill::before { content: none; }
  #auditBody td { padding: 10px 12px; height: 52px; }
  #auditBody td.tiny { font-size: 14px; line-height: 20px; color: var(--ink); }
  #auditBody td.tiny.muted { color: var(--ink-2); }
  #auditBody td.mono { font-variant-numeric: tabular-nums; }
  body[data-screen="audit"] #view .card-h input[type=text] { min-height: 44px; padding: 8px 14px; }
  /* Reports: each card's sentence in the body's type; the run's own lines likewise */
  #rpRoot .card-b.grid > .tiny { font-size: 15px; line-height: 22px; color: var(--ink); }
  #rpRoot .card-b.grid > .row .btn { white-space: nowrap; }
  #rpRoot #rpArchiveBody:empty, #rpRoot #rpStudentBody:empty { display: none; }
  #rpRoot #rpArchiveBody .tiny, #rpRoot #rpStudentBody .tiny { font-size: 15px; line-height: 22px; }
  /* the descriptor sheet: the descriptor cells in 14 px with the count under each; the column titles under the PLU
     number in the secondary ink; the sheet's sentences 14 px */
  body[data-screen="descriptors"] #view .card-b.grid > .tiny.muted { font-size: 14px; line-height: 20px; }
  body[data-screen="descriptors"] #view table, body[data-screen="descriptors"] #view td { font-size: 14px; line-height: 20px; }
  body[data-screen="descriptors"] #view th { vertical-align: bottom; padding: 8px 10px; white-space: normal; }
  body[data-screen="descriptors"] #view th .tiny.muted { font-size: 12px; line-height: 16px; font-weight: 400; margin-top: 2px; }
  body[data-screen="descriptors"] #view td { vertical-align: top; padding: 12px 10px; height: auto; }
  body[data-screen="descriptors"] #view td .tiny.muted { font-size: 12px; line-height: 16px; }
  /* Settings: the switch rows read as a list in the card */
  body[data-screen="settings"] #view .switchrow { padding: 14px 0; }
  body[data-screen="settings"] #view .switchrow .tiny { margin-top: 2px; }

  /* ================================================================ laptop and up (> 760 px): the admin tables' columns.
     Students: the name takes the room, the programme, year and permission columns hug the right edge in one rhythm.
     Classes: Edit at the right edge. Staff & access as a two-line row — the person, role, email, state and counts on one
     line and the four actions on a second, so nothing is clipped or scrolled sideways (the table was 1071 px wide in an
     878 px card); the phone keeps the scrolling table with the actions in a 2 × 2 block (td.row, above). Reports: each
     card's sentence beside its button (the student card stacks: its row holds the picker and the button). The descriptor
     sheet: one header row — the school, the class filter at its own width, Print, Download CSV, ← Reports; the student,
     class, programme and year cells never wrap; its column is capped at 1300 px, not 960 (ten columns) */
  @media (min-width: 761px) {
    body[data-screen="students"] #view td:first-child { width: auto; }
    body[data-screen="students"] #view td:not(:first-child) { width: 1%; white-space: nowrap; padding-left: 20px; }
    body[data-screen="classes"] #view td:last-child, body[data-screen="classes"] #view th:last-child { width: 1%; text-align: right; }
    body[data-screen="staff"] #view table, body[data-screen="staff"] #view thead, body[data-screen="staff"] #view tbody { display: block; width: 100%; }
    body[data-screen="staff"] #view tr { display: grid; grid-template-columns: minmax(190px, 1.3fr) 96px minmax(170px, 1.7fr) 124px 78px 86px; align-items: center; border-bottom: 1px solid var(--line); }
    body[data-screen="staff"] #view thead tr { border-bottom: 2px solid var(--ink); }
    body[data-screen="staff"] #view tbody tr:last-child { border-bottom: 0; }
    body[data-screen="staff"] #view th, body[data-screen="staff"] #view td { display: block; border-bottom: 0; height: auto; }
    body[data-screen="staff"] #view thead th:last-child { display: none; }
    body[data-screen="staff"] #view td { padding: 14px 12px 6px; }
    body[data-screen="staff"] #view td.row { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; padding: 4px 12px 14px 60px; }
    body[data-screen="staff"] #view td.row .btn { margin: 0; }
    body[data-screen="staff"] #view td.tiny { overflow-wrap: anywhere; }
    #rpRoot .card-b.grid { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px 24px; align-items: center; }
    #rpRoot [data-card="student"] .card-b.grid { grid-template-columns: minmax(0, 1fr); }
    #rpRoot .card-b.grid > .row { justify-self: end; flex-wrap: nowrap; }
    #rpRoot [data-card="student"] .card-b.grid > .row { justify-self: stretch; flex-wrap: wrap; }
    #rpRoot #rpPick { flex: 1 1 260px; width: auto; min-width: 0; }
    #rpRoot #rpArchiveBody, #rpRoot #rpStudentBody { grid-column: 1 / -1; }
    body[data-screen="descriptors"] .wrap { max-width: 1300px; }                   /* app.css's own cap: ten columns need the room */
    body[data-screen="descriptors"] #view .card-h { gap: 10px; }
    body[data-screen="descriptors"] #view .card-h h3 { flex: 1 1 auto; }
    body[data-screen="descriptors"] #view .card-h .spacer { display: none; }
    body[data-screen="descriptors"] #view #dsClass { flex: 0 1 auto; width: auto; min-width: 180px; max-width: 280px; min-height: 44px; padding: 8px 36px 8px 14px; font-size: 15px; }
    body[data-screen="descriptors"] #view th:nth-child(-n+4), body[data-screen="descriptors"] #view td:nth-child(-n+4) { white-space: nowrap; }
    body[data-screen="descriptors"] #view th:nth-child(n+5), body[data-screen="descriptors"] #view td:nth-child(n+5) { min-width: 88px; padding-left: 8px; padding-right: 8px; }
  }

  /* ---- Capture (§4, stage 2) ---- */
  /* the view's root grid is a column flex on this route, so the sticky Save card has travel (a grid item's containing
     block is its own grid area, so sticky on it never moves — F-06); the nested .card-b.grids are untouched */
  body[data-screen="capture"] #view > .grid { display: flex; flex-direction: column; gap: 12px; }
  /* the media options: Take a photo full width, the others a two-column grid of outlined pills (D7a: full labels, wrapping) */
  #capButtons { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  #capButtons .btn { min-height: 44px; white-space: normal; text-align: center; justify-content: center; border-radius: var(--r-pill); }
  #capButtons .btn.pri { grid-column: 1 / -1; min-height: 52px; border-radius: var(--r-s); }
  #capPreview img, #capPreview video, #camView { width: 100%; max-height: 360px; object-fit: contain; background: var(--surface-2); border-radius: 12px; margin-bottom: 10px; }
  #camStage .row, #capPreview .row { gap: 10px; }
  /* "Everyone else" and a group's "Note about …": a 44 px summary with a chevron, no UA marker */
  body[data-screen="capture"] #view details > summary { display: flex; align-items: center; gap: 10px; min-height: 44px; list-style: none; font-size: 15px; font-weight: 600; color: var(--ink); }
  body[data-screen="capture"] #view details > summary::-webkit-details-marker { display: none; }
  body[data-screen="capture"] #view details > summary::before { content: ""; width: 20px; height: 20px; flex: none; background: currentColor; -webkit-mask: url(icons/chevron-down.svg) center / contain no-repeat; mask: url(icons/chevron-down.svg) center / contain no-repeat; transform: rotate(-90deg); }
  body[data-screen="capture"] #view details[open] > summary::before { transform: none; }
  body[data-screen="capture"] #view details > #chipSearch { margin: 4px 0 10px; }
  #ocrChips > .tiny.muted, #targetChips > .lab { margin-bottom: 6px; }
  /* the suggestion card is not a nested card (F-14): a small secondary heading over a list of 48 px rows */
  #suggest .card { border: 0; box-shadow: none; padding: 0; border-radius: 0; background: none; }
  #suggest .card-h { padding: 0 0 6px; border-bottom: 0; }
  #suggest .card-b { padding: 0; }
  #suggest .card-h h3 { font-size: 14px; line-height: 20px; font-weight: 600; letter-spacing: 0; color: var(--ink-2); }
  /* a suggestion (here, in the outcome browser and in To review's "Change this child's outcomes" sheet): a row with a
     24 px tick box at the right — outlined, filled with a check when chosen */
  .sugg { position: relative; display: block; min-height: 48px; margin: 6px 0; padding: 11px 48px 11px 12px; border: 1.5px solid var(--line-2); border-radius: var(--r-s); background: var(--surface); color: var(--ink); }
  .sugg:hover { background: var(--surface-2); }
  .sugg::after { content: ""; position: absolute; right: 12px; top: 50%; width: 24px; height: 24px; margin-top: -12px; box-sizing: border-box; border: 1.5px solid var(--line-2); border-radius: 6px; background: var(--surface); }
  .sugg.on { background: var(--sel-tint); border-color: var(--ink); }
  .sugg.on::after { background: var(--ink); border-color: var(--ink); }
  .sugg.on::before { content: ""; position: absolute; right: 12px; top: 50%; width: 24px; height: 24px; margin-top: -12px; z-index: 1; background: var(--on-ink); -webkit-mask: url(icons/check.svg) center / 18px no-repeat; mask: url(icons/check.svg) center / 18px no-repeat; }
  .sugg .tiny.muted { display: block; margin-top: 2px; color: var(--ink-2); }
  .sugg[disabled]::after { background: var(--surface-2); border-color: var(--line); }
  .sugg.on[disabled]::after { background: var(--ink-2); border-color: var(--ink-2); }
  #browseFw { background: none; border: 0; box-shadow: none; padding: 0 6px; text-decoration: underline; text-underline-offset: 3px; font-size: 15px; font-weight: 600; color: var(--ink); }
  #browseFw:hover { background: none; }
  /* the Save card: sticky at the foot of the viewport (above the phone's tab bar), fading into the ground above it;
     `:has` is in every pilot browser and this is its one use in the stylesheet */
  body[data-screen="capture"] #view > .grid > .card:has(#capSave) { position: sticky; bottom: 16px; z-index: 5; border: 0; box-shadow: none; border-radius: 0; padding-top: 20px; background: linear-gradient(to bottom, transparent, var(--ground) 28%); }
  body[data-screen="capture"] #view > .grid > .card:has(#capSave) > .card-b { padding: 0; }
  body[data-screen="capture"] #view > .grid > .card:has(#capSave) .row { gap: 10px; }
  #capSave { flex: 1 1 100%; width: 100%; justify-content: center; }
  #frozenRow .btn { flex: 1 1 auto; justify-content: center; }
  #confirmLine:empty { display: none; }
  #confirmLine { margin-bottom: 8px; }
  #capSaveMsg { margin-top: 8px; }
  @media (max-height: 560px) { body[data-screen="capture"] #view > .grid > .card:has(#capSave) { position: static; } }   /* a short viewport keeps the whole page */
  body[data-screen="capture"] #view :is(button, input, select, textarea, summary, a, [tabindex]) { scroll-margin-bottom: 140px; }   /* a control scrolled into view clears the sticky card */
  /* Recent: 48 px rows, the time in bold, the status word small */
  #recent .rowitem { min-height: 48px; gap: 6px 12px; padding: 8px 0; flex-wrap: wrap; }
  #recent .rowitem > div:first-child { flex: 1 1 auto; min-width: 0; }
  #recent .rowitem b { font-weight: 700; }
  #recent .rowitem .tiny { font-size: 13px; line-height: 19px; display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  #recent > .tiny.muted { font-size: 16px; line-height: 24px; color: var(--ink-2); }
  #recentHint { margin-bottom: 8px; }

  /* ---- To review (§4, stage 2) ---- */
  /* the photo whole (D8): the card's full width, uncropped, up to 320 px tall; the student history's thumbnails are stage 3 */
  body[data-screen="review"] #view .rv-media img, body[data-screen="review"] #view .rv-media video { width: 100%; max-height: 320px; object-fit: contain; background: var(--surface-2); border-radius: 12px; }
  body[data-screen="review"] #view .rowitem.col { gap: 10px; padding: 14px 0; }
  body[data-screen="review"] #view .card-h h3 a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; color: var(--ink); text-decoration: none; }
  body[data-screen="review"] #view .card-h h3 a::after { content: ""; width: 20px; height: 20px; flex: none; color: var(--ink-2); background: currentColor; -webkit-mask: url(icons/chevron-left.svg) center / contain no-repeat; mask: url(icons/chevron-left.svg) center / contain no-repeat; transform: rotate(180deg); }
  body[data-screen="review"] #view .rowitem.col > .tiny > b { font-size: 14px; font-weight: 600; }
  /* the buttons: Accept full width with a check; Working towards and Achieved side by side; Needs more and Change
     this child's outcomes as underlined text buttons on one row */
  body[data-screen="review"] #view .rowitem.col > .row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  body[data-screen="review"] #view .rowitem.col > .row .btn { white-space: normal; text-align: center; justify-content: center; min-height: 44px; }
  body[data-screen="review"] #view .rowitem.col > .row [data-act="accept"] { grid-column: 1 / -1; min-height: 52px; }
  body[data-screen="review"] #view .rowitem.col > .row [data-act="accept"]::before { content: ""; width: 20px; height: 20px; flex: none; background: currentColor; -webkit-mask: url(icons/check.svg) center / contain no-repeat; mask: url(icons/check.svg) center / contain no-repeat; }
  body[data-screen="review"] #view .rowitem.col > .row [data-act="working"] { grid-column: 1; }
  body[data-screen="review"] #view .rowitem.col > .row [data-act="achieved"] { grid-column: 2; }
  body[data-screen="review"] #view .rowitem.col > .row [data-act="needs_more"], body[data-screen="review"] #view .rowitem.col > .row [data-change] { background: none; border: 0; box-shadow: none; padding: 0 6px; text-decoration: underline; text-underline-offset: 3px; font-size: 15px; font-weight: 600; color: var(--ink); }
  body[data-screen="review"] #view .rowitem.col > .row [data-act="needs_more"] { grid-column: 1; justify-self: start; }
  body[data-screen="review"] #view .rowitem.col > .row [data-change] { grid-column: 2; justify-self: end; text-align: right; }
  body[data-screen="review"] #view .rowitem.col > .row [data-act="needs_more"]:hover, body[data-screen="review"] #view .rowitem.col > .row [data-change]:hover { background: none; }

  /* ---- toast (§4, §7) ---- */
  .toast { bottom: 26px; gap: 0; background: var(--brand-navy); color: var(--on-brand-navy); padding: 12px 18px; border-radius: 12px; font-size: 15px; font-weight: 600; box-shadow: var(--shadow); }
  /* the saved moment (§7, D4): the navy app tile's R — white outer stroke, invisible against the navy toast until
     revealed — draws itself left to right once beside "Saved"; only toast("Saved", "saved") adds the class (M10) */
  #toast.saved::before { content: ""; width: 28px; height: 28px; flex: none; margin-right: 10px; border-radius: 6px; background: url(brand/rianta-r-navy.svg) center / contain no-repeat; animation: rianta-draw .45s ease-out both; }
  @keyframes rianta-draw { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0); } }

  /* ---- sheets (§3.1, §3.2, §7) ---- */
  .modal { background: var(--scrim); backdrop-filter: none; padding: 20px; }
  .modal.on { animation: rianta-fade .18s both; }
  .sheet { border: 1px solid var(--line); border-radius: 20px; max-width: 640px; max-height: 87vh; box-shadow: var(--shadow); animation: rianta-rise .32s cubic-bezier(.2, .9, .3, 1.15) both; }
  .sheet.wide { max-width: 980px; }
  .sheet .card-h { position: sticky; top: 0; z-index: 1; background: var(--surface); }
  @keyframes rianta-rise { from { transform: translateY(24px); opacity: 0; } }
  @keyframes rianta-fade { from { opacity: 0; } }

  /* ---- sign-in (§5) ---- */
  #signin { max-width: 420px; margin: 0 auto; padding-top: 24px; display: flex; flex-direction: column; gap: 20px; }
  #signin .wordmark { display: block; width: 196px; height: auto; margin: 0 auto; }
  #signin .wordmark-dark { display: none; }
  :root[data-theme="dark"] #signin .wordmark { display: none; }
  :root[data-theme="dark"] #signin .wordmark-dark { display: block; box-sizing: content-box; padding: 20px; border-radius: 20px; background: var(--brand-navy); }
  #signin .card { border-radius: 22px; }
  #signin .card-b { padding: 20px 18px; }
  #signin input { min-height: 52px; }
  #signinForm > .row { flex-direction: column; align-items: stretch; gap: 6px; }
  #siBtn { width: 100%; }
  #siForgot { background: none; border: 0; justify-content: center; text-decoration: underline; text-underline-offset: 3px; font-size: 15px; font-weight: 500; color: var(--ink); box-shadow: none; }
  #siForgot:hover { background: none; }
  #siSandbox { text-align: center; color: var(--ink-2); }
  body[data-screen="signin"] #view .wrap > * { animation: none; }

  /* ---- reset.html (§5): a single card on the ground ---- */
  #reset input { min-height: 52px; }
  #reset .btn { margin-top: 4px; }
  #reset p { margin: 0 0 12px; }

  /* ---- motion (§7, D4): controls only ---- */
  .btn, .chip, .nav, .cov-list .lo-row, .sugg, .card-b > ul > li > a { transition: background-color .14s, border-color .14s, color .14s, transform .1s; }
  .btn:active, .chip:active { transform: translateY(1px); }

  /* ================================================================ up to 1100 px (a phone, an iPad, a narrow laptop window): the two-row header */
  @media (max-width: 1100px) {
    /* the header: not sticky; two rows — the account strip and the theme button, then the title (F-30: every row-1 item
       has a zero basis or a fixed size, so the line is chosen before anything shrinks) */
    .top { position: static; backdrop-filter: none; background: none; border-bottom: 0; gap: 10px; padding: 10px 40px 6px; flex-wrap: wrap; }
    .top > div:first-child { order: 0; flex: 0 0 100%; min-width: 0; }
    .top .spacer { display: none; }
    #account { order: -1; flex: 1 1 0; min-width: 0; min-height: 44px; }
    #envPill { display: block; flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 28px; padding: 0 12px 0 24px; }
    #signOutBtn { flex: none; }
    .side-tools { order: -1; flex: none; padding: 0; gap: 0; flex-wrap: nowrap; }
    #view :is(button, input, select, textarea, summary, a, [tabindex]) { scroll-margin-top: 12px; }
  }

  /* ================================================================ phone (≤ 760 px, §3.1) */
  @media (max-width: 760px) {
    /* the tab bar: a fixed row of 56 px tabs; each <nav>'s buttons are the flex items (display: contents) */
    .app { grid-template-columns: 1fr; }
    .side { position: fixed; inset: auto 0 0 0; z-index: 30; display: flex; flex-direction: row; align-items: stretch; gap: 0; height: calc(56px + env(safe-area-inset-bottom)); padding: 0 0 env(safe-area-inset-bottom); background: var(--surface); border-top: 1px solid var(--line); border-right: 0; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity; }
    .side nav { display: contents; }
    .nav { flex: 1 0 25%; min-width: max-content; width: auto; height: 56px; min-height: 56px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; padding: 0 10px; margin: 0; border-radius: 0; font-size: 12px; line-height: 14px; white-space: nowrap; scroll-snap-align: start; color: var(--ink-2); }
    .nav:hover { background: none; }
    .nav[aria-current="true"] { background: none; color: var(--ink); box-shadow: none; }
    .nav .ic { width: 22px; height: 22px; }
    .nav .count { position: absolute; top: 3px; left: 50%; margin: 0 0 0 4px; }
    body[data-screen="signin"] .side, body:not([data-screen]) .side { display: none; }   /* no bar on sign-in, nor before the first route has drawn one */
    .main { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
    #view :is(button, input, select, textarea, summary, a, [tabindex]) { scroll-margin-top: 12px; scroll-margin-bottom: 80px; }
    .top { padding: 10px 16px 6px; }
    .top h1 { font-size: 26px; line-height: 32px; }
    #accountName .ini { display: inline-flex; width: 36px; height: 36px; align-items: center; justify-content: center; border-radius: 50%; background: var(--surface); border: 1px solid var(--line); }
    .wrap { padding: 10px 16px 16px; }
    .card-h { padding: 14px 16px; }
    .card-b { padding: 16px; }
    #view .card-b.tiny.muted { padding: 24px 16px; }
    /* the outcome row at phone width: three columns, the status under the wording. The insets are tighter than the
       laptop's so the selecting row's wording column is 266 px: Inter sets L1LP 3.2 (64 characters) in two lines
       only from 261 px (the geometry measure, web/tests/design-geometry.mjs) */
    .elgrp { padding: 12px 10px; }
    .cov-list .lo-row { grid-template-columns: 20px auto 1fr; gap: 8px; padding: 8px 2px; }
    .cov-list .lo-row .st { grid-column: 3; margin-top: 0; text-align: left; font-size: 13px; }
    .cov-list .lo-row.selecting { grid-template-columns: 24px 1fr; }
    .cov-list .lo-row.selecting > input, .cov-list .lo-row.selecting > span:first-child { grid-column: 1; grid-row: 1 / 4; align-self: start; }
    .cov-list .lo-row.selecting > .code, .cov-list .lo-row.selecting > .txt, .cov-list .lo-row.selecting > .st { grid-column: 2; }
    .cov-list .plu-fold > summary b { flex: 1 1 calc(100% - 30px); }               /* app.css reserves 22 px for its glyph; the chevron is 20 px + the 10 px gap */
    #stHead h2 { font-size: 30px; line-height: 34px; }
    #selBar { padding: 12px 16px 0; }
    /* the bottom sheet */
    .modal { padding: 0; }
    .modal.on { display: flex; align-items: flex-end; justify-content: center; }
    .sheet { width: 100%; max-width: none; max-height: calc(100vh - 20px); max-height: calc(100dvh - 20px); border: 0; border-top: 1px solid var(--line); border-radius: 20px 20px 0 0; box-shadow: none; }
    .sheet.wide { max-width: none; max-height: 96vh; max-height: 96dvh; }
    .sheet .card-b { padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
    .toast { bottom: calc(84px + env(safe-area-inset-bottom)); }
    #signin { padding-top: 8px; }
    /* Capture on the phone (stage 2): the Save card sits above the tab bar; the suggestion's element path (six
       repeats) is hidden; a control scrolled into view clears the sticky card as well as the bar */
    body[data-screen="capture"] #view > .grid > .card:has(#capSave) { bottom: calc(64px + env(safe-area-inset-bottom)); }
    .sugg .tiny.muted { display: none; }
    body[data-screen="capture"] #view :is(button, input, select, textarea, summary, a, [tabindex]) { scroll-margin-bottom: 180px; }
    body[data-screen="staff"] #view td.tiny { white-space: nowrap; }                    /* the admin's phone table scrolls sideways (§11); an email never breaks mid-word */
  }

  /* ================================================================ reduced motion (§7) */
  @media (prefers-reduced-motion: reduce) {
    .wrap > *, .modal.on, .sheet { animation: none; }
    #toast.saved::before { animation: none; }                                       /* the R shown complete */
    .btn, .chip, .nav, .cov-list .lo-row, .sugg, .card-b > ul > li > a, .hm .cell::before, .toast { transition: none; }
  }
}
