/*
 * Attend Insight — design tokens.
 *
 * Off-white ground, white cards, pale mint as the supporting fill: panels,
 * table headers, hovers, the active nav item. Chosen from four options as
 * "Mint" — the coolest of the greens on offer.
 *
 * Pale mint cannot carry text at this lightness, so --accent is a deeper
 * version of the same hue held back for links, the primary button and the
 * chart series. That split is the whole scheme: --accent-soft fills, --accent
 * marks.
 *
 * The constraint that pins the hue: green already means "attendance is fine"
 * in the status scale. Mint sits furthest from --st-good of the greens tried,
 * and --accent-soft is cooled deliberately so an active nav chip never reads
 * as a status pill. Warming either toward a fresher green undoes that.
 *
 * Every text/background pair here is measured at 4.5:1 or better in both
 * themes, including --ink-3 on --surface-2, which is where the small mono
 * column labels actually sit and is the pair that fails first.
 *
 * The app does NOT follow the operating system's dark mode. It used to, via
 * prefers-color-scheme, which meant anyone with their Mac in dark mode never
 * saw this palette at all — they got the dark set and the off-white brief was
 * silently overridden by a system setting. Light is the product. The dark
 * tokens are kept below, but only apply when something explicitly stamps
 * data-theme="dark" on <html>, and nothing does today.
 */

:root{
  color-scheme:light;
  --ground:#F4F8F6; --surface:#FFFFFF; --surface-2:#EDF5F1; --sunk:#E0EAE6;
  --ink:#16241F; --ink-2:#4C5F58; --ink-3:#60716A;
  --rule:#D6E4DE; --rule-2:#BCD2CA;
  --accent:#2F7361; --accent-ink:#245A4C; --accent-soft:#D2E9E2;
  --series:#2F7361; --series-soft:#8FBCAF; --context:#A0AEA9; --grid:#E1EDE8;
  --st-good:#17a34a; --st-good-ink:#116b32; --st-good-bg:#dcf0e0;
  --st-warn:#fab219; --st-warn-ink:#7a5300; --st-warn-bg:#f8ecd0;
  --st-serious:#ec835a; --st-serious-ink:#8a3f1c; --st-serious-bg:#f8e3d8;
  --st-crit:#d03b3b; --st-crit-ink:#8f2626; --st-crit-bg:#f6dcdc;
  --font-display:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,serif;
  --font-body:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
}
/* Opt-in only. Nothing sets this attribute yet; it is here so the work is not
   thrown away if a toggle is ever wanted. Do not put it behind a media query. */
:root[data-theme="dark"]{
    color-scheme:dark;
    --ground:#0F1614; --surface:#17201D; --surface-2:#131B19; --sunk:#0A100E;
    --ink:#E4EDE9; --ink-2:#A4B6AF; --ink-3:#7C8D86;
    --rule:#243230; --rule-2:#364844;
    --accent:#6FC0AA; --accent-ink:#9CD8C6; --accent-soft:#16302A;
    --series:#6FC0AA; --series-soft:#437B6C; --context:#6C7F79; --grid:#233230;
    --st-good-ink:#6fd08d; --st-good-bg:#123020;
    --st-warn-ink:#e0b34e; --st-warn-bg:#322813;
    --st-serious-ink:#f0a181; --st-serious-bg:#33211a;
    --st-crit-ink:#ec8181; --st-crit-bg:#331c1c;
}

*{box-sizing:border-box}
body{margin:0;background:var(--ground);color:var(--ink);font-family:var(--font-body);
  font-size:15px;line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:var(--accent);text-underline-offset:.15em}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
.wrap{width:min(1180px,100%);margin-inline:auto;padding:0 1rem}
.narrow{width:min(640px,100%);margin-inline:auto;padding:0 1rem}

/* ---- app bar ---- */
.appbar{background:var(--surface);border-bottom:1px solid var(--rule);position:sticky;top:0;z-index:20}
.appbar .wrap{display:flex;align-items:center;gap:1.1rem;min-height:56px;flex-wrap:wrap}
.brand{font-family:var(--font-display);font-size:1.05rem;font-weight:600;letter-spacing:-.01em;
  white-space:nowrap;text-decoration:none;color:var(--ink)}
.brand span{color:var(--ink-3);font-family:var(--font-mono);font-size:.62rem;letter-spacing:.12em;
  text-transform:uppercase;margin-left:.5rem;font-weight:400}
.nav{display:flex;gap:.15rem;flex-wrap:wrap}
.nav a{padding:.3rem .6rem;border-radius:6px;font-size:.86rem;color:var(--ink-2);text-decoration:none}
.nav a:hover{background:var(--surface-2)}
.nav a[aria-current="page"]{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}
.spacer{flex:1}
.who{font-size:.8rem;color:var(--ink-3);text-align:right;line-height:1.25}
a.who{text-decoration:none;border-radius:6px;padding:.2rem .45rem;margin:-.2rem -.45rem}
a.who:hover{background:var(--surface-2)}
a.who:hover b{color:var(--accent-ink)}
a.who[aria-current="page"] b{color:var(--accent-ink)}
.who b{display:block;color:var(--ink-2);font-weight:600}

select.schoolpick{font:inherit;font-size:.83rem;color:var(--ink);background:var(--surface-2);
  border:1px solid var(--rule);border-radius:5px;padding:.28rem .45rem;max-width:220px}

/* ---- headings ---- */
h1{font-family:var(--font-display);font-size:1.6rem;font-weight:600;letter-spacing:-.01em;margin:1.4rem 0 .2rem}
h2{font-family:var(--font-display);font-size:1.25rem;font-weight:600;margin:1.8rem 0 .5rem}
.lede{color:var(--ink-2);font-size:.92rem;margin:0 0 1.1rem}
.eyebrow{font-family:var(--font-mono);font-size:.63rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3);font-weight:600;margin:0 0 .5rem}

/* ---- cards, kpis ---- */
.card{background:var(--surface);border:1px solid var(--rule);border-radius:9px;padding:1.15rem;
  margin:0 0 1.1rem;box-shadow:0 1px 2px rgb(22 36 31 / .04)}
/* Advisory panel. Mint fill, for guidance rather than content — content
   surfaces stay white so a tinted panel always means "read this". The muted
   ink is too pale to sit on the fill, so this variant steps it up one. */
.card.note{background:var(--accent-soft);border-color:var(--rule-2);box-shadow:none}
.card.note .eyebrow{color:var(--accent-ink)}
.card.note .hint,.card.note p{color:var(--ink-2)}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1px;background:var(--rule);
  border:1px solid var(--rule);border-radius:9px;overflow:hidden;margin:0 0 1.2rem;
  box-shadow:0 1px 2px rgb(22 36 31 / .04)}
.kpi{background:var(--surface);padding:.7rem .85rem}
.kpi .lab{font-family:var(--font-mono);font-size:.61rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);display:block;margin-bottom:.1rem}
.kpi .val{font-size:1.55rem;line-height:1.15;font-weight:600;letter-spacing:-.02em}
.kpi .sub{font-size:.75rem;color:var(--ink-3)}
.kpi.alert .val{color:var(--accent)}

/* ---- tables ---- */
.tablewrap{overflow-x:auto;border:1px solid var(--rule);border-radius:9px;background:var(--surface);
  box-shadow:0 1px 2px rgb(22 36 31 / .04)}
table{border-collapse:separate;border-spacing:0;width:100%;font-size:.84rem}
thead th{text-align:left;font-family:var(--font-mono);font-size:.61rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);font-weight:600;padding:.5rem .7rem;
  background:var(--surface-2);border-bottom:1px solid var(--rule);white-space:nowrap}
tbody td{padding:.55rem .7rem;border-bottom:1px solid var(--rule);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--surface-2)}
td.num{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;font-weight:600}
td.delta{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;font-size:.78rem}
.nm{font-weight:600;white-space:nowrap;text-decoration:none;color:var(--ink)}
.nm:hover{color:var(--accent)}
.cls{font-family:var(--font-mono);font-size:.69rem;color:var(--ink-3);margin-left:.35rem}
.up{color:var(--st-good-ink);font-weight:600}
.dn{color:var(--st-crit-ink);font-weight:600}
.flat{color:var(--ink-3)}
.empty{padding:2.2rem;text-align:center;color:var(--ink-3)}

/* ---- pills, tags ---- */
.pill{display:inline-flex;align-items:center;gap:.3rem;font-size:.7rem;font-weight:600;
  padding:.14rem .45rem;border-radius:4px;white-space:nowrap}
.pill .dot{width:7px;height:7px;border-radius:50%;flex:none}
.p-good{background:var(--st-good-bg);color:var(--st-good-ink)}    .p-good .dot{background:var(--st-good)}
.p-warn{background:var(--st-warn-bg);color:var(--st-warn-ink)}    .p-warn .dot{background:var(--st-warn)}
.p-serious{background:var(--st-serious-bg);color:var(--st-serious-ink)} .p-serious .dot{background:var(--st-serious)}
.p-crit{background:var(--st-crit-bg);color:var(--st-crit-ink)}    .p-crit .dot{background:var(--st-crit)}
.tag{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.05em;background:var(--sunk);
  color:var(--ink-2);border-radius:3px;padding:.1rem .3rem;white-space:nowrap;display:inline-block}
.tags{display:flex;gap:.25rem;flex-wrap:wrap}
.stage{font-family:var(--font-mono);font-size:.68rem;border:1px solid var(--rule-2);border-radius:4px;
  padding:.12rem .4rem;color:var(--ink-2);white-space:nowrap}
.await{color:var(--accent-ink);font-weight:600;font-size:.78rem}
.restricted{font-family:var(--font-mono);font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;
  background:var(--accent-soft);color:var(--accent-ink);border-radius:3px;padding:.1rem .32rem;font-weight:600}

/* ---- filters ---- */
.filters{display:flex;gap:.4rem;align-items:center;flex-wrap:wrap;margin:0 0 .75rem}
.chip{font-size:.78rem;padding:.28rem .6rem;border:1px solid var(--rule);border-radius:99px;
  background:var(--surface);color:var(--ink-2);white-space:nowrap;text-decoration:none;display:inline-block}
.chip[aria-current="true"]{background:var(--accent-soft);border-color:var(--accent);
  color:var(--accent-ink);font-weight:600}
.chip .n{font-family:var(--font-mono);font-size:.7rem;opacity:.75;margin-left:.25rem}

/* ---- forms ---- */
label{display:block;font-size:.77rem;color:var(--ink-3);margin:.6rem 0 .2rem}
input[type=text],input[type=email],input[type=password],input[type=date],input[type=number],
input[type=search],select,textarea{
  width:100%;font:inherit;font-size:.86rem;color:var(--ink);background:var(--surface);
  border:1px solid var(--rule-2);border-radius:5px;padding:.4rem .5rem}
textarea{resize:vertical;min-height:90px}
textarea.paste{font-family:var(--font-mono);font-size:.79rem;line-height:1.6;min-height:190px;
  background:var(--surface-2);border-style:dashed}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:.7rem}
.row3{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:.7rem}
.check{display:flex;gap:.45rem;align-items:flex-start;margin:.6rem 0 0;font-size:.85rem;color:var(--ink-2)}
.check input{margin-top:.25rem}
.hint{font-size:.76rem;color:var(--ink-3);margin:.25rem 0 0}

.btn{border:1px solid var(--rule-2);border-radius:6px;padding:.34rem .7rem;font-size:.82rem;
  background:var(--surface-2);color:var(--ink-2);white-space:nowrap;display:inline-block;text-decoration:none}
.btn:hover{border-color:var(--accent);color:var(--accent-ink)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--ground);font-weight:600}
.btn.lg{padding:.45rem 1rem;font-size:.88rem}
.btn.danger{color:var(--st-crit-ink);border-color:var(--st-crit-bg)}
.actions{display:flex;gap:.5rem;align-items:center;margin-top:.9rem;flex-wrap:wrap}

/* ---- messages ---- */
.flash{border-radius:7px;padding:.6rem .8rem;margin:0 0 1rem;font-size:.87rem}
.flash.ok{background:var(--st-good-bg);color:var(--st-good-ink)}
.flash.warn{background:var(--st-warn-bg);color:var(--st-warn-ink)}
.flash.bad{background:var(--st-crit-bg);color:var(--st-crit-ink)}
.errors{background:var(--st-crit-bg);color:var(--st-crit-ink);border-radius:5px;padding:.6rem .8rem;
  margin:0 0 1rem;font-size:.85rem}
.errors ul{margin:.3rem 0 0;padding-left:1.1rem}

/* ---- guest pages ---- */
.guest{min-height:100vh;display:grid;place-items:center;padding:2rem 1rem}
.guest .box{width:min(420px,100%);background:var(--surface);border:1px solid var(--rule);
  border-radius:11px;padding:1.7rem;box-shadow:0 2px 10px rgb(29 40 35 / .05)}
.guest h1{margin:0 0 .2rem;font-size:1.35rem}
.guest .lede{font-size:.87rem}
.guest .foot{margin-top:1.1rem;font-size:.78rem;color:var(--ink-3);text-align:center}

/* ---- timeline ---- */
.tl{list-style:none;margin:0;padding:0;border-left:2px solid var(--rule);margin-left:.3rem}
.tl li{position:relative;padding:0 0 1rem 1rem}
.tl li::before{content:"";position:absolute;left:-5px;top:.42em;width:8px;height:8px;border-radius:50%;
  background:var(--rule-2);border:2px solid var(--surface)}
.tl li.now::before{background:var(--accent)}
.tl .t{font-size:.87rem;font-weight:600}
.tl .m{font-family:var(--font-mono);font-size:.68rem;color:var(--ink-3)}
.tl .b{font-size:.85rem;color:var(--ink-2);margin-top:.25rem;white-space:pre-line}

/* ---- misc ---- */
.mono{font-family:var(--font-mono);font-size:.8rem}
.muted{color:var(--ink-3)}
/* A link that exists once and has to leave this page with somebody. */
.copyrow{display:flex;gap:.4rem;align-items:stretch;margin:.5rem 0 0}
.copyrow__link{flex:1;min-width:0;font-family:var(--font-mono);font-size:.78rem;
  background:var(--surface);border:1px solid var(--rule-2);border-radius:5px;padding:.55rem .7rem}
.copyrow .btn{white-space:nowrap}

.tokenbox{font-family:var(--font-mono);font-size:.78rem;background:var(--sunk);border-radius:5px;
  padding:.55rem .7rem;word-break:break-all;margin:.5rem 0 0}
.codes{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:.4rem;margin:.7rem 0}
.codes code{font-family:var(--font-mono);font-size:.85rem;background:var(--sunk);border-radius:4px;
  padding:.35rem .5rem;text-align:center;letter-spacing:.04em}
.pagination{display:flex;gap:.25rem;margin:0;font-size:.82rem;flex-wrap:wrap;align-items:center}
.pagination a,.pagination span{min-width:1.9rem;padding:.22rem .5rem;border:1px solid var(--rule);
  border-radius:5px;text-decoration:none;color:var(--ink-2);text-align:center;
  font-variant-numeric:tabular-nums;line-height:1.4}
.pagination a:hover{border-color:var(--accent);color:var(--accent-ink)}
.pagination [aria-current="page"]{background:var(--accent-soft);border-color:var(--rule-2);
  color:var(--accent-ink);font-weight:600}
/* The gap markers Laravel emits between page ranges, and the dead arrows at
   either end: present for alignment, but not pretending to be pressable.
   No opacity — faded to .6 these came out at 2.32:1, under the 3:1 a control
   needs to be discernible at all. The missing border is what says "dead". */
.pagination [aria-disabled="true"],.pagination [aria-hidden="true"]{
  color:var(--ink-3);border-color:transparent;cursor:default}
@media (prefers-reduced-motion: reduce){*{transition:none!important;animation:none!important}}

/* Development-only warning bar. See config/tr.php. */
.devbanner{background:var(--st-crit);color:#fff;text-align:center;padding:.45rem .8rem;
  font-size:.82rem;font-weight:600;letter-spacing:.01em}

/* ---- school picker ----
   Grows in flow when opened. Deliberately not an absolutely positioned
   dropdown: those get clipped by any scrolling ancestor, and this one has to
   work inside cards and next to tables. */
.picker{border:1px solid var(--rule-2);border-radius:6px;background:var(--surface);max-width:26rem}
.picker>summary{cursor:pointer;padding:.34rem .7rem;font-size:.82rem;color:var(--ink-2);
  list-style:none;display:flex;align-items:center;gap:.4rem}
.picker>summary::-webkit-details-marker{display:none}
.picker>summary::after{content:"";margin-left:auto;width:.45rem;height:.45rem;flex:none;
  border-right:1.5px solid var(--ink-3);border-bottom:1.5px solid var(--ink-3);
  transform:rotate(45deg) translate(-2px,-2px)}
.picker[open]>summary::after{transform:rotate(225deg) translate(-1px,-1px)}
.picker[open]>summary{border-bottom:1px solid var(--rule);background:var(--surface-2);
  border-radius:5px 5px 0 0}
.picker__panel{padding:.5rem}
.picker__bar{display:flex;gap:.35rem;align-items:center;margin-bottom:.4rem}
.picker__filter{flex:1;font-size:.8rem;padding:.28rem .45rem}
.picker__list{max-height:15rem;overflow-y:auto;display:flex;flex-direction:column;gap:.05rem}
.picker__opt{display:flex;gap:.5rem;align-items:center;font-size:.83rem;color:var(--ink-2);
  padding:.22rem .35rem;border-radius:4px;margin:0;cursor:pointer}
.picker__opt:hover{background:var(--surface-2)}
.picker__opt input{margin:0;flex:none}
.picker__opt[hidden]{display:none}

/* ---- sortable column headings ---- */
.sortlink{color:inherit;text-decoration:none;display:inline-flex;align-items:baseline;gap:.25rem;
  white-space:nowrap;border-radius:3px}
.sortlink:hover{color:var(--accent-ink)}
.sortlink.on{color:var(--accent-ink)}
.sortlink__mark{font-size:.8em;line-height:1}
th[aria-sort]:not([aria-sort="none"]){background:var(--accent-soft)}

/* ---- foldable section ----
   For a block that is worth having but not worth meeting first: the full
   import table behind a summary of what it holds. */
.foldable{border:1px solid var(--rule);border-radius:9px;background:var(--surface);
  margin:0 0 1rem;box-shadow:0 1px 2px rgb(22 36 31 / .04)}
.foldable>summary{cursor:pointer;padding:.6rem .9rem;font-size:.86rem;font-weight:600;
  color:var(--ink-2);list-style:none;display:flex;align-items:center;gap:.4rem}
.foldable>summary::-webkit-details-marker{display:none}
.foldable>summary::after{content:"";margin-left:auto;width:.45rem;height:.45rem;flex:none;
  border-right:1.5px solid var(--ink-3);border-bottom:1.5px solid var(--ink-3);
  transform:rotate(45deg) translate(-2px,-2px)}
.foldable[open]>summary::after{transform:rotate(225deg) translate(-1px,-1px)}
.foldable[open]>summary{border-bottom:1px solid var(--rule)}
.foldable>summary:hover{color:var(--accent-ink)}
/* The table inside supplies its own frame; drop the duplicate. */
.foldable .tablewrap{border:0;border-radius:0;box-shadow:none}

/* ---- bulk selection bar ----
   Appears only when something is ticked, so it never sits there offering to
   act on nobody. Mint fill, like the other "read this" surfaces. */
.bulkbar{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;
  background:var(--accent-soft);border:1px solid var(--rule-2);border-radius:9px;
  padding:.6rem .8rem;margin:0 0 .7rem;font-size:.86rem}
.bulkbar[hidden]{display:none}
.bulkbar select,.bulkbar input{width:auto;font-size:.83rem;padding:.3rem .45rem}
.bulkbar strong{white-space:nowrap;color:var(--accent-ink)}

/* ---- undo panel ----
   A disclosure rather than a browser confirm(): the sentence explaining what
   is about to happen has to be readable, and confirm() cannot show one. */
.revert{display:inline-block;position:relative}
.revert>summary{list-style:none;cursor:pointer}
.revert>summary::-webkit-details-marker{display:none}
.revert__panel{position:absolute;right:0;z-index:30;width:min(24rem,80vw);text-align:left;
  background:var(--surface);border:1px solid var(--rule-2);border-radius:9px;
  padding:.85rem;margin-top:.35rem;box-shadow:0 6px 20px rgb(22 36 31 / .16)}
.revert__panel .check{font-size:.83rem;margin:.3rem 0 0}
.revert__panel .actions{margin-top:.7rem}
.btn[disabled]{opacity:.55;cursor:not-allowed}

/* ---- pupil chart ---------------------------------------------------------
   The span buttons are the only control on the page that changes what a
   graph shows rather than what the record says, so they are quiet: a segmented
   strip, not a row of buttons competing with the actions below. */
.chart__head{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;margin-bottom:.5rem}
.chart__legend{display:flex;gap:1rem;font-size:.76rem;color:var(--ink-2);flex-wrap:wrap}
.chart__legend span{display:inline-flex;align-items:center;gap:.35rem}
.k-line{display:inline-block;width:14px;height:2px;border-radius:2px}
.k-pupil{background:var(--series)}
.k-school{background:var(--context)}
.k-target{height:0;border-top:2px dashed var(--ink-3);border-radius:0}

.chart__spans{display:flex;gap:.15rem;margin-left:auto;background:var(--sunk);padding:.15rem;border-radius:7px}
.chart__spans button{
  font:inherit;font-size:.72rem;border:0;background:transparent;color:var(--ink-2);
  padding:.2rem .5rem;border-radius:5px;cursor:pointer;font-variant-numeric:tabular-nums;
}
.chart__spans button:hover{color:var(--ink)}
.chart__spans button[aria-pressed="true"]{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px rgb(22 36 31 / .1)}
.chart__spans button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* The plot is the positioning context for the hover readout. */
.chart__plot{position:relative}

.chart__tip{
  position:absolute;left:0;top:0;transform:translate(-50%,calc(-100% - 12px));
  background:var(--surface);border:1px solid var(--rule-2);border-radius:8px;
  padding:.4rem .6rem;box-shadow:0 2px 10px rgb(22 36 31 / .16);
  display:flex;flex-direction:column;gap:.05rem;white-space:nowrap;
  pointer-events:none;opacity:0;visibility:hidden;transition:opacity .09s ease;
  z-index:2;
}
.chart__tip.is-on{opacity:1;visibility:visible}
.chart__tip-when{font-size:.68rem;color:var(--ink-3);font-family:var(--font-mono)}
.chart__tip-pc{font-size:1.05rem;color:var(--ink);font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums}
.chart__tip-band{font-size:.7rem;font-weight:600}

/* The dot grows on hover; the invisible circle over it is what catches the
   pointer, so the target is comfortable without the dot being fat. */
.chart__dot{transition:r .09s ease}
.chart__dot.is-lit{r:6}
.chart__hit{cursor:pointer;outline:none}
.chart__hit:focus-visible{outline:2px solid var(--accent);outline-offset:1px;border-radius:50%}

@media (prefers-reduced-motion: reduce){
  .chart__tip,.chart__dot{transition:none}
}

.chart__summary{margin:.55rem 0 0;font-size:.82rem;color:var(--ink-2)}
.chart__summary b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.chart__summary .sep{margin:0 .4rem;color:var(--rule-2)}

.chart__foot{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;margin-top:.45rem;font-size:.72rem}
.chart__dots{display:flex;gap:.8rem;flex-wrap:wrap;color:var(--ink-2)}
.chart__dots span{display:inline-flex;align-items:center;gap:.3rem}
.k-dot{display:inline-block;width:8px;height:8px;border-radius:50%}
.k-good{background:var(--st-good)}
.k-warn{background:var(--st-warn)}
.k-serious{background:var(--st-serious)}
.k-crit{background:var(--st-crit)}
.chart__foot .muted{margin-left:auto;font-size:.72rem}

/* A dot is a week somebody recorded; it earns a cursor that says so. */
.chart circle{cursor:help}

/* ---- attendance plan ------------------------------------------------------
   A screen that gets turned round to face a parent, so it is bigger and
   quieter than the rest of the application: three fields, one answer, and a
   sentence somebody can say out loud. */
.calc__three{display:grid;grid-template-columns:repeat(3,1fr) auto;gap:.9rem;align-items:end}
.calc__three > div{display:flex;flex-direction:column;gap:.3rem}
.calc__three label{font-size:.85rem;color:var(--ink-2);font-weight:500}
.calc__three input{font-family:var(--font-mono);font-size:1.15rem;padding:.5rem .6rem;
  font-variant-numeric:tabular-nums}
.calc__three small{font-size:.72rem;color:var(--ink-3)}
.calc__go{justify-content:flex-end}
@media (max-width:680px){.calc__three{grid-template-columns:1fr 1fr}.calc__go{grid-column:1/-1}}

/* The two questions an officer is asked within a minute of each other, so
   both are answered at once rather than one hiding behind a field change. */
.answers{display:grid;grid-template-columns:1fr 1fr;gap:.8rem;margin-bottom:.9rem}
@media (max-width:640px){.answers{grid-template-columns:1fr}}
.answer{background:var(--surface);border:1px solid var(--rule);border-radius:12px;padding:1rem 1.1rem}
.answer__q{font-size:.82rem;color:var(--ink-2);margin-bottom:.35rem}
.answer__a{font-family:var(--font-mono);font-size:2.3rem;font-weight:700;line-height:1;
  letter-spacing:-.02em;color:var(--ink);font-variant-numeric:tabular-nums}
.answer__a span{font-size:1rem;font-weight:500;color:var(--ink-3);letter-spacing:0}
.answer__a--no{font-size:1.5rem;color:var(--st-crit-ink)}
.answer__note{font-size:.78rem;color:var(--ink-3);margin-top:.4rem}

.plan{border-radius:12px;padding:1.2rem 1.3rem;margin:0 0 .9rem;border:1px solid transparent}
.plan--yes{background:var(--st-good-bg);border-color:var(--st-good);color:var(--st-good-ink)}
.plan--no{background:var(--st-crit-bg);border-color:var(--st-crit);color:var(--st-crit-ink)}
/* Short of the target but not impossible — a different answer from either. */
.plan--short{background:var(--st-warn-bg);border-color:var(--st-warn);color:var(--st-warn-ink)}
.plan__lead{font-family:var(--font-display);font-size:1.45rem;line-height:1.25;font-weight:600}
.plan__sub{margin:.5rem 0 0;font-size:.95rem;opacity:.92}
.plan__swap{margin-top:.9rem;display:flex;gap:.7rem;align-items:center;flex-wrap:wrap;font-size:.9rem}
.plan__swap .btn{border-color:currentColor;color:inherit;background:transparent}
.plan__swap .btn:hover{background:color-mix(in srgb,currentColor 12%,transparent)}

/* One square per remaining school day. "Four of these" is something a parent
   can hold; "you need 80%" is not. */
.daygrid{display:flex;flex-wrap:wrap;gap:3px;margin:.2rem 0 .6rem}
.daygrid i{width:15px;height:15px;border-radius:3px;background:var(--accent-soft);
  border:1px solid transparent;display:block}
.daygrid i.spare{background:var(--st-crit-bg);border-color:var(--st-crit)}
.daygrid i.taken{background:var(--st-warn-bg);border-color:var(--st-warn)}
.daykey{display:flex;gap:1.1rem;flex-wrap:wrap;font-size:.76rem;color:var(--ink-2)}
.daykey span{display:inline-flex;align-items:center;gap:.35rem}
.daykey i{width:11px;height:11px;border-radius:3px;background:var(--accent-soft);
  border:1px solid transparent;display:block}
.daykey i.spare{background:var(--st-crit-bg);border-color:var(--st-crit)}
.daykey i.taken{background:var(--st-warn-bg);border-color:var(--st-warn)}

.saying{background:var(--surface-2);border-radius:10px;padding:1rem 1.1rem;
  font-family:var(--font-display);font-size:1.08rem;line-height:1.5;color:var(--ink)}

