:root{--bg:#141a2e;--bg2:#25335f;--panel:#1f2a44;--panel2:#26335a;--line:rgba(255,255,255,.12);--hi:#f4f1e8;--lo:#a9b1c9;--gold:#e0a93b;--gold-hi:#f3c765;--r:14px}
/* KeepDeck's Home board shares js/drawdeck-engine.js + css/drawdeck-engine.css with TeachersDeck's DrawDeck
   (tools/check_shared.py keeps both byte-identical to teachersdeck/js/drawdeck.js and css/drawdeck.css).
   The engine's CSS never defines these itself — it only reads them — so each deck supplies its own palette;
   these map to ParentDeck's own --bg/--panel/--panel2/--bg2/--hi/--lo/--gold/--gold-hi scale above. --danger,
   --radius-chip, --shadow-panel and --teal have no ParentDeck equivalent, so they keep DrawDeck's own values. */
:root{--amber:var(--gold);--amber-hi:var(--gold-hi);--danger:#E06565;--ink-0:var(--bg);--ink-1:var(--panel);--ink-2:var(--panel2);--ink-3:var(--bg2);--radius-chip:10px;--shadow-panel:0 12px 30px rgba(0,0,0,0.35),0 2px 6px rgba(0,0,0,0.25);--teal:#47C9B6;--text-hi:var(--hi);--text-lo:var(--lo)}
*{box-sizing:border-box}
html,body{height:100%;margin:0}
body{font:14px/1.4 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--hi);background:radial-gradient(1200px 700px at 20% 0%,var(--bg2) 0%,var(--bg) 60%);overflow:hidden}
.top{position:fixed;top:0;left:0;right:0;height:44px;display:flex;align-items:center;gap:16px;padding:0 16px;z-index:5}
.brand{font-weight:800;font-size:17px;white-space:nowrap}.mark{color:var(--gold)}
.ver{color:var(--lo);font-size:11px}
#wall{position:fixed;top:44px;left:0;right:0;bottom:0;overflow:hidden}   /* --dock-clear is measured from the real dock in js/app.js (syncDockClearance) */
.widget{position:absolute;min-width:220px;min-height:140px;display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:0 10px 30px rgba(0,0,0,.35)}
.widget.min{min-height:0;height:auto!important}.widget.min .body,.widget.min .grip{display:none}
.head{display:flex;align-items:center;gap:8px;padding:8px 8px 8px 12px;cursor:grab;touch-action:none;user-select:none;border-bottom:1px solid var(--line)}
.head:active{cursor:grabbing}.widget.min .head{border-bottom:0}
.title{flex:1;font-weight:700}
.hbtn{width:26px;height:26px;border:0;border-radius:8px;background:transparent;color:var(--lo);font-size:16px;line-height:1;cursor:pointer}
.hbtn:hover{background:rgba(255,255,255,.1);color:var(--hi)}
.body{flex:1;overflow:auto;padding:12px}
.grip{position:absolute;right:2px;bottom:2px;width:18px;height:18px;cursor:nwse-resize;opacity:.45;touch-action:none;background:linear-gradient(135deg,transparent 55%,var(--lo) 55% 62%,transparent 62% 76%,var(--lo) 76% 83%,transparent 83%)}
.grip:hover{opacity:1}
.btn,.chip{font:inherit;border:1px solid var(--line);background:var(--panel2);color:var(--hi);border-radius:10px;padding:7px 12px;cursor:pointer}
.btn:hover,.chip:hover{border-color:var(--gold)}.btn.primary{background:var(--gold);border-color:var(--gold);color:#231604;font-weight:700}
.chip.on{background:rgba(224,169,59,.2);border-color:var(--gold);color:var(--gold-hi)}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:8px 0}.center{justify-content:center}
input[type=text]{font:inherit;color:var(--hi);background:rgba(0,0,0,.25);border:1px solid var(--line);border-radius:10px;padding:7px 10px;min-width:0;flex:1}
input:focus,button:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
.muted{color:var(--lo);font-size:12px}
#toast{position:fixed;left:50%;top:54px;transform:translateX(-50%);max-width:min(440px,92vw);background:var(--panel2);border:1px solid var(--gold);padding:9px 14px;border-radius:12px;z-index:50;opacity:0;pointer-events:none;transition:opacity .2s}
#toast.show{opacity:1}
.tiles{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:10px 0}.tile{background:rgba(0,0,0,.2);border:1px solid var(--line);border-radius:10px;padding:8px 10px}
.tile b{display:block;font-size:17px;color:var(--gold-hi)}.tile span{font-size:11px;color:var(--lo)}
.srow{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:5px 0;border-bottom:1px solid var(--line);font-size:12px}
.lvl{display:flex;align-items:center;gap:12px;margin-bottom:8px}.lvl .big{font-size:30px;font-weight:800;color:var(--gold-hi)}
.big{font-weight:800}
.xpbar{display:inline-block;width:70px;height:7px;border-radius:5px;background:rgba(255,255,255,.15);overflow:hidden}.xpbar.wide{display:block;width:100%;height:10px}
.xpbar i{display:block;height:100%;background:var(--gold);border-radius:5px;transition:width .4s}
h4{margin:14px 0 6px;font-size:13px}
.x{border:0;background:transparent;color:var(--lo);font-size:18px;cursor:pointer}.x:hover{color:#ff8b8b}

/* ---- ParentDeck-specific: header kid switcher + account ---- */
.hright{margin-left:auto;display:flex;align-items:center;gap:14px}
.kids{display:flex;gap:6px;overflow-x:auto;max-width:44vw}
.chip.kid{padding:5px 12px;font-size:12px;white-space:nowrap}
.acctbtn{display:flex;align-items:center;gap:8px;font:inherit;font-size:12px;color:var(--hi);background:rgba(255,255,255,.06);border:1px solid var(--line);border-radius:999px;padding:4px 12px 4px 4px;cursor:pointer}
.acctbtn:hover{border-color:var(--gold)}
.avatar{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--gold);color:#231604;font-weight:800;font-size:11px}
.sev{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:2px}
.sev-low{background:#f3c765}.sev-medium{background:#e8863a}.sev-high{background:#e05353}

/* ---- KeepDeck's own tab shell (js/keepdeck.js): .body gets .kd-body added once KeepDeck mounts, which
   establishes the flex-column chain .kd-pane fills — whatever's mounted inside it (DrawDeck's .dd-root for
   the Home board, or keepdeck-scrap.js's own markup for Scrapbook) sizes against .kd-pane the same way it
   would size against a full widget .body. ---- */
.kd-body{ display:flex; flex-direction:column; padding:0; overflow:hidden; }
.kd-tabs{ display:flex; gap:8px; padding:10px 12px; flex:0 0 auto; border-bottom:1px solid var(--line); }
.kd-tab{ font:inherit; border:1px solid var(--line); background:var(--panel2); color:var(--hi); border-radius:10px; padding:6px 14px; cursor:pointer; }
.kd-tab:hover{ border-color:var(--gold); }
.kd-tab.on{ background:var(--gold); border-color:var(--gold); color:#231604; font-weight:700; }
.kd-pane{ flex:1; min-height:0; position:relative; display:flex; flex-direction:column; overflow:hidden; }

/* ---- KeepDeck's Scrapbook tab (js/keepdeck-scrap.js) ---- */
.kd-scrap-bar{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; padding:8px 10px; border-bottom:1px solid var(--line); flex:0 0 auto; }
.kd-scrap-bar select{ font:inherit; border:1px solid var(--line); background:var(--panel2); color:var(--hi); border-radius:10px; padding:6px 10px; max-width:160px; }
.kd-scrap-sp{ flex:1 1 auto; }
.kd-scrap-wrap{ flex:1; min-height:0; overflow:auto; display:flex; align-items:flex-start; justify-content:center; padding:12px; }
.kd-scrap-page{ position:relative; transform-origin:top center; flex:none; border-radius:8px; box-shadow:0 10px 30px rgba(0,0,0,.35); overflow:hidden; }
.kd-scrap-empty{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; text-align:center; padding:40px; pointer-events:none; }
.kd-scrap-it{ position:absolute; display:flex; align-items:center; justify-content:center; cursor:grab; overflow:hidden; outline:none; }
.kd-scrap-it.picked{ outline:2px dashed var(--gold); outline-offset:2px; }
.kd-scrap-it img{ width:100%; height:100%; object-fit:cover; display:block; pointer-events:none; }
.kd-scrap-it.kd-scrap-photo.kd-scrap-f-polaroid{ background:#fff; padding:10px 10px 28px; box-shadow:0 4px 14px rgba(0,0,0,.3); }
.kd-scrap-it.kd-scrap-sticker{ font-size:48px; line-height:1; background:none; }
.kd-scrap-it.kd-scrap-text{ white-space:pre-wrap; word-break:break-word; cursor:text; background:none; }
.kd-scrap-it.kd-scrap-shape svg{ width:100%; height:100%; }
.kd-scrap-handles{ position:absolute; pointer-events:none; outline:1px solid var(--gold); }
.kd-scrap-h{ position:absolute; width:14px; height:14px; margin:-7px; border-radius:50%; background:var(--gold); border:2px solid #231604; pointer-events:all; cursor:pointer; }
.kd-scrap-h-nw{ left:0; top:0; cursor:nwse-resize; } .kd-scrap-h-se{ left:100%; top:100%; cursor:nwse-resize; }
.kd-scrap-h-ne{ left:100%; top:0; cursor:nesw-resize; } .kd-scrap-h-sw{ left:0; top:100%; cursor:nesw-resize; }
.kd-scrap-h-rot{ left:50%; top:-28px; cursor:grab; background:var(--panel2); }
.kd-scrap-menu{ position:fixed; z-index:9999; display:grid; grid-template-columns:repeat(6,1fr); gap:2px; background:var(--panel); border:1px solid var(--line); border-radius:10px; box-shadow:0 12px 30px rgba(0,0,0,.4); padding:6px; max-width:260px; }
.kd-scrap-menu button{ border:none; background:none; font-size:22px; padding:6px; cursor:pointer; border-radius:8px; }
.kd-scrap-menu button:hover{ background:var(--panel2); }
.kd-scrap-yearwrap{ flex:1; min-height:0; overflow:auto; padding:14px; }
.kd-scrap-yearwrap h4{ margin:14px 0 8px; }
.kd-scrap-year{ display:grid; grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); gap:10px; }
.kd-scrap-cover{ font:inherit; text-align:left; border:1px solid var(--line); background:var(--panel2); color:var(--hi); border-radius:10px; padding:14px 10px; cursor:pointer; aspect-ratio:3/2; display:flex; flex-direction:column; justify-content:flex-end; gap:4px; }
.kd-scrap-cover:hover{ border-color:var(--gold); }
.kd-scrap-cover span{ font-size:12px; color:var(--lo); }

/* ---- KeepDeck's parent-unlock challenge (js/keepdeck.js) — its own overlay, separate from .modal above,
   since it must sit on top of DrawDeck's own full-screen widget and that widget's own internal modal. ---- */
.kd-unlock-ov{position:fixed;inset:0;background:rgba(10,13,24,.7);display:flex;align-items:center;justify-content:center;z-index:9999}
.kd-unlock-card{width:min(320px,92vw);background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:0 20px 50px rgba(0,0,0,.5);padding:18px;text-align:center}
.kd-unlock-card h3{margin:0 0 8px;font-size:15px}
.kd-unlock-card p{margin:0 0 10px}
.kd-unlock-input{width:100%;box-sizing:border-box;font-size:20px;text-align:center;padding:8px;border-radius:10px;border:1px solid var(--line);background:var(--bg);color:var(--hi);margin-bottom:10px}
.kd-unlock-err{color:#e06565}
.kd-unlock-btns{display:flex;gap:8px;justify-content:center}

/* ---- Modal (account / link-a-child) ---- */
.modal{position:fixed;inset:0;background:rgba(10,13,24,.6);display:flex;align-items:center;justify-content:center;z-index:60}
.modal[hidden]{display:none}
.mcard{width:min(420px,92vw);max-height:80vh;overflow:auto;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:0 20px 50px rgba(0,0,0,.5)}
.mhead{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border-bottom:1px solid var(--line);font-weight:700}
.mbody{padding:14px}

/* ---- Trends widget: bar / line / pie, all hand-rolled to match the rest of the shell ---- */
select{font:inherit;font-size:12px;color:var(--hi);background:rgba(0,0,0,.25);border:1px solid var(--line);border-radius:10px;padding:6px 8px}
.cols{display:flex;gap:5px;align-items:flex-end;height:110px;margin:8px 0}
.col{flex:1;height:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;font-size:9px;color:var(--lo);gap:2px}
.col i{display:block;width:100%;background:var(--gold);border-radius:4px 4px 0 0;min-height:2px}
.col em{font-style:normal;color:var(--hi);font-size:10px}
.linechart{width:100%;height:110px;display:block;margin:8px 0}
.linechart polyline{fill:none;stroke:var(--gold);stroke-width:2}
.linechart circle{fill:var(--gold-hi)}
.linechart text{fill:var(--lo);font-size:8px}
.pie{width:120px;height:120px;border-radius:50%;margin:10px auto;flex:none}
.legend{display:flex;flex-direction:column;gap:5px;font-size:12px}
.legend .sw{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:6px;vertical-align:middle}
.delta{display:flex;align-items:center;gap:8px;margin-top:10px;padding:9px 10px;background:rgba(0,0,0,.2);border-radius:10px;font-size:13px}
.delta.up{color:#9be89b}.delta.down{color:var(--gold-hi)}.delta.flat{color:var(--lo)}

/* ---- Theme presets widget ---- */
.theme-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:6px}
.theme-swatch{display:flex;flex-direction:column;align-items:center;gap:6px;padding:10px 8px;border:2px solid var(--line);border-radius:12px;background:rgba(0,0,0,.15);cursor:pointer;font:inherit;color:var(--hi)}
.theme-swatch:hover{border-color:var(--gold)}
.theme-swatch.on{border-color:var(--gold);background:rgba(224,169,59,.12)}
.theme-swatch-dot{width:34px;height:34px;border-radius:50%;box-shadow:inset 0 0 0 2px rgba(255,255,255,.2)}
.theme-swatch span{font-size:11.5px}

/* ---- Language toggle pill (header) ---- */
.langpill{display:flex;border:1px solid var(--line);border-radius:999px;overflow:hidden;flex:none}
.langpill button{font:inherit;font-size:11px;font-weight:700;border:0;background:transparent;color:var(--lo);padding:6px 11px;cursor:pointer}
.langpill button.on{background:var(--gold);color:#231604}
.langpill button:not(.on):hover{background:rgba(255,255,255,.08);color:var(--hi)}

/* ---- Settings header shortcut ("bar") ---- */
.iconbtn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--line);border-radius:10px;background:rgba(255,255,255,.05);color:var(--lo);cursor:pointer;flex:none}
.iconbtn:hover{border-color:var(--gold);color:var(--hi)}
.iconbtn svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.settings-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 0;border-bottom:1px solid var(--line)}
.settings-row:last-child{border-bottom:0}

/* ---- Header XP pill (StudentDeck style: level + bar + total; opens Trends) ---- */
.xp{position:relative;display:flex;align-items:center;gap:8px;font:inherit;font-size:12px;color:var(--hi);background:rgba(255,255,255,.06);border:1px solid var(--line);border-radius:999px;padding:4px 12px;cursor:pointer;flex:none}
.xp:hover{border-color:var(--gold)}.xp b{color:var(--gold-hi)}
.xp[hidden]{display:none}

/* ---- Nested "widget in a widget" chrome (Class Ranking / Behaviour Log inside Student Summary) ---- */
.subwidget{border:1px solid var(--line);border-radius:10px;margin:10px 0;background:rgba(0,0,0,.15);overflow:hidden}
.subhead{display:flex;align-items:center;gap:8px;padding:7px 10px;font-weight:700;font-size:12.5px}
.subwidget:has(.subbody) .subhead{border-bottom:1px solid var(--line)}
.subtitle{flex:1}
.subbody{padding:10px}

/* ---- Full-screen widget (Student Summary): fills the wall, sits under the floating widgets, no drag/resize ---- */
.widget.full{left:0!important;top:0!important;width:100%!important;height:100%!important;min-width:0;border-radius:0;border-width:0;box-shadow:none;z-index:1}
.widget.full.min{height:auto!important}
.widget.full .head{cursor:default;touch-action:auto}.widget.full .grip{display:none}
.widget.full .body{padding:14px clamp(12px,2.5vw,28px) 20px}
.sgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr));gap:12px;align-items:start}
.sgrid>div{min-width:0}.sgrid .subwidget{margin:0}
.sgrid .sm-wide{grid-column:1/-1}
.sm-tiles{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));margin:8px 0 12px}
.bar{display:grid;grid-template-columns:minmax(80px,38%) 1fr auto;align-items:center;gap:8px;padding:4px 0;font-size:12px}
.bar>div{height:8px;border-radius:5px;background:rgba(255,255,255,.12);overflow:hidden}.bar>div i{display:block;height:100%;background:var(--gold);border-radius:5px}
.bar b{color:var(--gold-hi);white-space:nowrap}

/* Month calendar (nested inside the Homework Assignments widget) — ported from
   TeachersDeck's canonical .cal-* calendar CSS, variable names mapped to this app's
   palette (--line/--hi/--lo/--gold/--gold-hi in place of TD's --line/--text-hi/--text-lo/
   --amber/--amber-hi). Read-only here: no manage/edit states. */
.cal-head{display:flex;align-items:center;gap:6px;margin-bottom:8px}
.cal-nav{width:26px;height:26px;border-radius:8px;border:1px solid var(--line);background:rgba(255,255,255,.03);color:var(--hi);display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0}
.cal-nav:hover{background:rgba(255,255,255,.08)}
.cal-month{flex:1;text-align:center;font-weight:700;font-size:13px}
.cal-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;font-size:10px;color:var(--lo);text-align:center;margin-bottom:4px}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:10px}
.cal-cell{aspect-ratio:1;border:none;border-radius:8px;background:transparent;color:var(--hi);font-size:11.5px;cursor:pointer;position:relative;display:flex;align-items:center;justify-content:center}
.cal-cell:hover:not(.empty){background:rgba(255,255,255,.06)}
.cal-cell.empty{cursor:default}
.cal-cell.today{font-weight:700;color:var(--gold-hi)}
.cal-cell.selected{background:var(--gold);color:#231604;font-weight:700}
.cal-dot{position:absolute;bottom:2px;left:4px;width:4px;height:4px;border-radius:50%;background:#47c9b6}
.cal-cell.selected .cal-dot{background:#231604}
.cal-day-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.cal-day-label{font-weight:600;font-size:12px;color:var(--lo)}
.cal-ev-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px;max-height:120px;overflow-y:auto}
.cal-ev-row{display:flex;align-items:center;gap:7px;font-size:12px;background:rgba(255,255,255,.03);border-radius:8px;padding:6px 8px}
.cal-ev-time{font-weight:600;color:var(--gold-hi);font-size:11px;flex-shrink:0}
.cal-ev-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---- v0.9.0: Notes Home ---- */
.note-card{display:block;width:100%;text-align:left;margin:0 0 8px;padding:10px 12px;border-radius:12px;border:1px solid var(--line);background:rgba(255,255,255,.03);color:var(--hi);font:inherit;cursor:pointer}
.note-card.unread{border-color:var(--gold);background:rgba(224,169,59,.10)}
.note-card.frowny{border-left:4px solid #7aa7d9}
.note-card.smiley{border-left:4px solid #9be89b}
.note-card.unread .note-top b{color:var(--gold-hi)}
.note-top{display:flex;align-items:center;gap:8px;font-size:12.5px}
.note-top .muted{margin-left:auto;font-size:11px}
.note-dot{width:9px;height:9px;border-radius:50%;background:var(--gold)}
.note-text{display:block;margin-top:6px;font-size:14px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}
#toast.soft{background:#1d2a3d;border:1px solid #7aa7d9;color:#e9f1fb}
#toast.good{background:linear-gradient(135deg,#3b2f10,#27304f);border-color:var(--gold-hi);color:#fff6dc;box-shadow:0 0 22px rgba(243,199,101,.38)}
#toast.show{animation:toastPop .5s cubic-bezier(.2,1.5,.4,1)}
@keyframes toastPop{0%{transform:translateX(-50%) translateY(-14px) scale(.88)}100%{transform:translateX(-50%) translateY(0) scale(1)}}


/* ============================================================
   v0.9.1 — app tray + Tier 1 widgets (identical in the v0.9.3 and v0.10.0 lines)
   ============================================================ */
.warn{color:var(--gold-hi)}
.pill{display:inline-block;padding:2px 9px;border-radius:999px;font-size:11px;white-space:nowrap;background:rgba(255,255,255,.1);color:var(--lo)}
.pill.ok{background:rgba(155,232,155,.16);color:#9be89b}
.pill.warn{background:rgba(224,169,59,.18);color:var(--gold-hi)}
.tiles3{grid-template-columns:repeat(3,1fr)}
.tiles3 .tile b{font-size:14px}
input[type=number].numin{font:inherit;color:var(--hi);background:rgba(0,0,0,.25);border:1px solid var(--line);border-radius:10px;padding:6px 8px;width:84px}

/* app tray */

/* 1 Family Overview */
.famgrid{display:grid;gap:10px}
.famcard{display:flex;flex-direction:column;gap:8px;text-align:left;font:inherit;color:var(--hi);padding:10px 12px;border:1px solid var(--line);border-radius:12px;background:rgba(0,0,0,.18);cursor:pointer}
.famcard:hover{border-color:var(--gold)}.famcard.on{border-color:var(--gold);background:rgba(224,169,59,.1)}
.famhead{display:flex;justify-content:space-between;gap:8px;align-items:baseline}
.famlv{display:flex;align-items:center;gap:8px}.famlv b{color:var(--gold-hi);white-space:nowrap}.famlv .xpbar{flex:1}
.famrows{display:flex;flex-wrap:wrap;gap:4px 14px;font-size:12px}
.famopen{align-self:flex-end;font-size:11px;color:var(--gold-hi)}

/* 3 Homework Completion */
.hbar{display:grid;grid-template-columns:96px 1fr 40px;gap:8px;align-items:center;font-size:12px;margin:6px 0}
.hbar .track{height:8px;border-radius:5px;background:rgba(255,255,255,.12);overflow:hidden}
.hbar .track i{display:block;height:100%;background:var(--gold)}
.hbar b{text-align:right}

/* 4 Rewards Wishlist */
.wishrow,.wishgoal{padding:9px 10px;margin:8px 0;border:1px solid var(--line);border-radius:12px;background:rgba(0,0,0,.16)}
.wishgoal{border-color:var(--gold);background:rgba(224,169,59,.1)}
.wishmain{display:flex;flex-wrap:wrap;justify-content:space-between;gap:2px 8px;margin-bottom:6px}
.wishdesc{flex-basis:100%}
.wishfoot{display:flex;justify-content:space-between;align-items:center;margin-top:6px}
.pinbtn{padding:3px 10px;font-size:11px}

/* 5 Goals & Streaks */
.gcal{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin:6px 0 4px}
.gday{display:flex;align-items:center;justify-content:center;aspect-ratio:1;border-radius:7px;font-size:10px;color:var(--lo);background:rgba(255,255,255,.06)}
.gday.on{background:var(--gold);color:#231604;font-weight:700}
.gday.today{outline:2px solid var(--gold-hi);outline-offset:1px}
.rings{display:flex;flex-wrap:wrap;gap:12px;margin:8px 0}
.ring{position:relative;width:88px;text-align:center;font-size:11px}
.ring svg{width:64px;height:64px;display:block;margin:0 auto}
.ring circle{fill:none;stroke-width:5}
.ring .rbg{stroke:rgba(255,255,255,.12)}.ring .rfg{stroke:var(--gold);stroke-linecap:round}.ring.full .rfg{stroke:#9be89b}
.ring b{position:absolute;left:0;right:0;top:20px;font-size:15px;color:var(--hi)}
.ring span{color:var(--lo)}.ring em{display:block;font-style:normal;color:var(--lo);font-size:10px;margin-top:1px}
.goaledit{display:grid;gap:8px;margin:8px 0}
.goaledit label{display:flex;justify-content:space-between;align-items:center;gap:10px;font-size:12px}

/* 6 Conversation Starters */
.starters{list-style:none;margin:0 0 6px;padding:0;display:grid;gap:10px}
.starters li{padding:11px 12px 11px 34px;border:1px solid var(--line);border-radius:12px;background:rgba(0,0,0,.18);line-height:1.45;position:relative}
.starters li::before{content:'“';position:absolute;left:11px;top:2px;font-size:30px;color:var(--gold);font-family:Georgia,serif}

/* 7 Weekly Digest */
.digest{border:1px solid var(--line);border-radius:12px;padding:10px 12px;background:rgba(0,0,0,.16)}
.dghead{display:flex;flex-direction:column;gap:1px;margin-bottom:6px}.dghead b{font-size:16px;color:var(--gold-hi)}
label.nochrome{cursor:pointer}

@media print{
  body.print-digest{background:#fff!important;overflow:visible!important;height:auto}
  body.print-digest .top,body.print-digest .dock-wrap,body.print-digest .edge-dock,body.print-digest #toast,body.print-digest .app-tray-backdrop,body.print-digest .modal,body.print-digest .nochrome,
  body.print-digest .print-target .head,body.print-digest .print-target .grip{display:none!important}
  body.print-digest .widget:not(.print-target){display:none!important}
  body.print-digest #wall{position:static;overflow:visible}
  body.print-digest .widget.print-target{position:static!important;width:auto!important;height:auto!important;box-shadow:none;border:0;background:#fff}
  body.print-digest .print-target .body{overflow:visible}
  body.print-digest .print-target,body.print-digest .print-target *{color:#111!important;border-color:#ccc!important;background:transparent!important}
}

/* v0.9.2 — Progress Reports */
.prrep{border:1px solid var(--line);border-radius:12px;background:rgba(0,0,0,.16);margin:8px 0;overflow:hidden}
.prrep.on{border-color:var(--gold)}
.prline{display:flex;justify-content:space-between;align-items:center;gap:8px;width:100%;padding:10px 12px;border:0;background:transparent;color:var(--hi);font:inherit;text-align:left;cursor:pointer}
.prline b{color:var(--gold-hi);font-size:16px}
.prbody{padding:0 12px 10px}
.prbody h4{margin:10px 0 4px}
.prlist{margin:0;padding-left:18px;display:grid;gap:3px;font-size:13px}

/* v0.9.3 — demo mode */
.demobar{position:fixed;left:8px;bottom:84px;z-index:60;display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.demotab{padding:6px 12px;border:1px solid var(--gold);border-radius:999px;background:rgba(224,169,59,.2);color:var(--gold-hi);font:inherit;font-size:12px;cursor:pointer}
.demopanel{width:min(300px,calc(100vw - 16px));padding:10px 12px;border:1px solid var(--line);border-radius:14px;background:var(--panel);box-shadow:0 10px 30px rgba(0,0,0,.45)}
.demopanel[hidden]{display:none}

/* ============================================================
   v0.12.0 — layout modes, docks and the app tray (ported from StudentDeck v0.9.0, which ported them from TeachersDeck v0.14.1),
   the 3-column Stats & XP section, and the Teacher Notes widget
   ============================================================ */
.dock-wrap{position:fixed;left:50%;bottom:16px;transform:translateX(-50%);z-index:5;display:flex;flex-direction:column;align-items:center;max-width:calc(100vw - 40px)}
.dock{z-index:5;display:flex;gap:4px;padding:8px 10px;background:rgba(20,26,46,.78);border:1px solid var(--line);border-radius:16px;backdrop-filter:blur(12px);box-shadow:0 12px 30px rgba(0,0,0,.35),0 2px 6px rgba(0,0,0,.25);max-width:100%;overflow-x:auto;scrollbar-width:thin}
.dock-item{display:flex;flex-direction:column;align-items:center;gap:5px;width:88px;flex:none;padding:8px 4px 6px;cursor:pointer;border:none;background:rgba(255,255,255,.03);color:var(--lo);font:inherit;font-weight:600;font-size:10.5px;line-height:1.2;text-align:center;transition:background .15s ease,color .15s ease,transform .12s ease;position:relative;border-radius:12px;margin:0 1px}
.dock-item>span:last-child,.app-tray-item>span:last-child{max-width:100%;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;white-space:normal;overflow-wrap:break-word}
.dock-item:hover{background:rgba(255,255,255,.08);color:var(--hi);z-index:2;transform:translateY(-2px)}
.dock-item.active{background:rgba(224,169,59,.14);color:var(--gold-hi);z-index:3}
.dock-item.active .dock-ic{background:rgba(224,169,59,.16);color:var(--gold-hi)}
.dock-ic{width:34px;height:34px;border-radius:10px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.04);color:inherit}
.dock-ic svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
/* unread Notes Home count on the launchers that open the notes */
.dock-item .badge,.app-tray-item .badge{position:absolute;top:2px;right:8px;min-width:17px;height:17px;padding:0 4px;border-radius:9px;background:#e05353;color:#fff;font:700 10.5px/17px system-ui,sans-serif;font-style:normal;text-align:center}
/* tab on the dock's top edge + the sheet that slides up */
.app-tray-tab{z-index:6;width:46px;height:20px;padding:0;flex:none;border-radius:12px 12px 4px 4px;border:1px solid var(--line);border-bottom:none;background:rgba(20,26,46,.78);color:var(--lo);cursor:pointer;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(12px);box-shadow:0 12px 30px rgba(0,0,0,.35);transition:background .15s ease;margin-bottom:-1px}
.app-tray-tab:hover{background:rgba(255,255,255,.1)}
.app-tray-tab-line{display:block;width:22px;height:4px;border-radius:2px;background:var(--lo);transition:background .15s ease}
.app-tray-tab:hover .app-tray-tab-line{background:var(--hi)}
.app-tray-tab.open .app-tray-tab-line{background:var(--gold-hi)}
.app-tray-backdrop{position:fixed;inset:0;z-index:45;background:rgba(6,9,14,.55);display:flex;align-items:flex-end;justify-content:center}
.app-tray-backdrop[hidden]{display:none}
.app-tray{width:100%;max-width:760px;max-height:72vh;overflow-y:auto;background:var(--panel);border:1px solid var(--line);border-bottom:none;border-radius:20px 20px 0 0;box-shadow:0 -16px 40px rgba(0,0,0,.45);padding:8px 18px 24px;animation:traysheetup .2s ease}
@keyframes traysheetup{from{transform:translateY(28px);opacity:0}to{transform:none;opacity:1}}
.app-tray-handle{display:block;width:44px;height:5px;border-radius:3px;margin:6px auto 14px;background:var(--line);border:none;cursor:pointer;padding:0}
.app-tray-title{font-weight:700;font-size:12.5px;letter-spacing:.4px;color:var(--lo);text-align:center;margin:0 0 14px}
.app-tray-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(100px,1fr));gap:8px}
.app-tray-cat{grid-column:1/-1;margin:8px 0 0;font-size:11px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:var(--lo)}
.app-tray-item{position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;padding:10px 4px 8px;cursor:pointer;border:none;background:rgba(255,255,255,.03);color:var(--lo);font:inherit;font-weight:600;font-size:10.5px;line-height:1.2;text-align:center;border-radius:14px;transition:background .15s ease,color .15s ease,transform .12s ease}
.app-tray-item .dock-ic{width:38px;height:38px}
.app-tray-item:hover{background:rgba(255,255,255,.08);color:var(--hi);transform:translateY(-2px)}
.app-tray-item.active{background:rgba(224,169,59,.14);color:var(--gold-hi)}
.app-tray-item.active .dock-ic{background:rgba(224,169,59,.16);color:var(--gold-hi)}
/* side drawers */
.edge-dock{position:fixed;z-index:6;background:rgba(20,26,46,.78);border:1px solid var(--line);backdrop-filter:blur(12px);box-shadow:0 12px 30px rgba(0,0,0,.35);transition:transform .22s ease}
.edge-dock[hidden]{display:none}
.edge-dock-items{display:flex;flex-direction:column;gap:4px}
.edge-dock-left,.edge-dock-right{top:50%;transform:translateY(-50%);border-radius:14px;padding:10px 6px}
.edge-dock-left{left:12px}.edge-dock-right{right:12px}
.edge-dock-left .dock-item,.edge-dock-right .dock-item{width:88px;margin:1px 0}
.edge-dock-left .dock-item:hover{transform:translateX(2px)}.edge-dock-right .dock-item:hover{transform:translateX(-2px)}
@media (max-width:680px){.edge-dock-left,.edge-dock-right{display:none}}
/* hide-the-dock option: the dock + tab unit slides down until only the tab shows; hover the tab (or Tab to a button) to bring it back */
.dock-wrap.auto-hide{bottom:0;padding-bottom:16px;transform:translateX(-50%) translateY(calc(100% - 20px));transition:transform .22s ease .35s}
.dock-wrap.auto-hide:hover,.dock-wrap.auto-hide:has(:focus-visible){transform:translateX(-50%);transition-delay:0s}
body.dock-auto #wall{bottom:0}
/* the full-screen Student Summary must never hide under a side drawer; the wall itself ends above the dock (v0.21.1) */
.widget.full .body{padding-bottom:calc(var(--dock-clear,132px) + 8px)}   /* the wall is full height again, so the full-screen Summary keeps its last section clear of the floating dock */
body.dock-auto .widget.full .body{padding-bottom:40px}   /* dock hidden: only the tab peeks above the bottom edge */
body.dl .widget.full .body{padding-left:128px}
body.dr .widget.full .body{padding-right:128px}
@media (max-width:680px){body.dl .widget.full .body{padding-left:clamp(12px,2.5vw,28px)}body.dr .widget.full .body{padding-right:clamp(12px,2.5vw,28px)}}

/* Layout section of the Settings widget */
.layout-mode-grid{display:flex;flex-direction:column;gap:8px;margin-bottom:4px}
.layout-mode-opt{display:flex;flex-direction:column;align-items:flex-start;gap:3px;width:100%;text-align:left;padding:10px 12px;border-radius:10px;border:1px solid var(--line);background:transparent;color:var(--hi);font:inherit;cursor:pointer;transition:border-color .15s ease,background .15s ease}
.layout-mode-opt:hover{background:rgba(255,255,255,.03)}
.layout-mode-opt.active{border-color:var(--gold);background:rgba(224,169,59,.08)}
.layout-mode-name{font-weight:700;font-size:12.5px}
.layout-mode-desc{font-size:11px;color:var(--lo);line-height:1.4}
.switch-row{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12.5px;color:var(--lo);margin-top:6px}
.switch-row input{accent-color:var(--gold);width:16px;height:16px;flex:none}
.switch-row.locked,.dock-vis-row.locked{opacity:.45}
.lock-hint{margin:4px 0 8px}
.dock-vis-list{display:grid;grid-template-columns:1fr;gap:6px;margin:6px 0;max-height:240px;overflow-y:auto;padding-right:2px}
.dock-vis-row{display:flex;align-items:center;gap:8px;font-size:12.5px;padding:6px 8px;border-radius:8px;border:1px solid var(--line);background:rgba(255,255,255,.02)}
.dock-vis-row span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.placement-row select{flex:none;width:122px;padding:4px}
.placement-row select option{color:#222}
.st-section{margin-top:14px;padding-top:6px;border-top:1px solid var(--line)}

/* Student Stats and XP inside Student Summary: three columns wide, not long. A container query, so it follows the SECTION'S width, not the window's. */
#sm-stats .subbody{container-type:inline-size;container-name:stats}

/* Teacher Notes widget (the Notes Home inbox, all children) */
.nfilters{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 10px}
.nfilters .chip{padding:4px 11px;font-size:12px}
.nfilters .chip i{font-style:normal;margin-left:5px;color:var(--gold-hi);font-weight:700}
.note-card .note-who{font-weight:700;color:var(--hi);font-size:12px}

/* ============================================================
   v0.13.0 — Student Stats and XP as a horizontal dashboard, with motion
   Layout follows the SECTION'S width (container queries). Motion: an entrance (class .s3-in, present only for the first couple of
   seconds after a draw or a range change) and a per-panel hover that replays that panel's own graph. The hover rules use differently
   NAMED keyframes (…H) because a CSS animation only restarts when its name changes — same name = no replay. Reduced motion turns all of it off.
   ============================================================ */
.s3{display:block}
.s3top{display:grid;grid-template-columns:auto minmax(200px,1.5fr) minmax(190px,1.1fr) minmax(240px,1.3fr);gap:14px 26px;align-items:center}
.s3tiles{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px;margin:16px 0}
.s3panels{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;align-items:stretch}
.s3foot{margin:12px 0 0}
@container stats (max-width:1059px){.s3panels{grid-template-columns:repeat(3,minmax(0,1fr))}.s3panels>.s3p:last-child{grid-column:span 2}.s3tiles{grid-template-columns:repeat(3,minmax(0,1fr))}}
@container stats (max-width:899px){.s3top{grid-template-columns:auto minmax(0,1fr)}.s3streak,.s3ctl{grid-column:1/-1}}
@container stats (max-width:759px){.s3panels{grid-template-columns:repeat(2,minmax(0,1fr))}.s3panels>.s3p:last-child{grid-column:span 2}}
@container stats (max-width:559px){.s3panels{grid-template-columns:1fr}.s3panels>.s3p:last-child{grid-column:auto}.s3tiles{grid-template-columns:repeat(2,minmax(0,1fr))}.s3top{grid-template-columns:1fr;justify-items:start}}

/* level ring */
.s3ring{position:relative;width:84px;height:84px;padding:0;border:0;background:none;cursor:pointer;color:inherit;flex:none}
.s3ring svg{width:100%;height:100%;display:block;filter:drop-shadow(0 0 8px rgba(224,169,59,.25))}
.s3ring circle{fill:none;stroke-width:6}
.s3ring .rg-bg{stroke:rgba(255,255,255,.13)}
.s3ring .rg-fg{stroke:var(--gold);stroke-linecap:round}
.s3lv{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;line-height:1}
.s3lv small{font-size:10px;letter-spacing:.8px;color:var(--lo);text-transform:uppercase}
.s3lv b{font-size:28px;font-weight:800;color:var(--gold-hi)}
.s3ring:hover svg{filter:drop-shadow(0 0 12px rgba(243,199,101,.55))}
.s3ring:focus-visible{outline:2px solid var(--gold-hi);outline-offset:3px;border-radius:50%}
.s3almost{display:inline-block;margin-top:7px;padding:2px 10px;border-radius:999px;font-size:11px;font-weight:700;color:var(--gold-hi);background:rgba(224,169,59,.14);border:1px solid rgba(224,169,59,.4);animation:s3pulse 1.9s ease-in-out infinite}
.s3streak{display:flex;align-items:center;gap:12px}
.s3streak b{font-size:17px;color:var(--gold-hi)}
.s3next{font-size:11px;margin-top:2px}
.flame{font-size:30px;line-height:1;display:inline-block;transform-origin:50% 90%;animation:s3flame 1.7s ease-in-out infinite}
.flame.off{animation:none;filter:grayscale(.6);opacity:.8}
.s3ctl{display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.s3ctl .row{margin:0}

/* tiles */
.s3tiles .tile{margin:0;padding:10px 12px;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}
.s3tiles .tile b{font-size:17px;font-variant-numeric:tabular-nums}
.s3tiles .tile em{font-style:normal}
.s3tiles .tile:hover{transform:translateY(-3px) scale(1.025);border-color:rgba(224,169,59,.55);box-shadow:0 8px 20px rgba(224,169,59,.14)}

/* panels */
.s3p{min-width:0;padding:10px 12px 12px;border:1px solid var(--line);border-radius:12px;background:rgba(0,0,0,.18);transition:transform .2s ease,border-color .2s ease,box-shadow .2s ease}
.s3p>h4{margin:0 0 8px;font-size:12.5px}
.s3p:hover{transform:translateY(-3px);border-color:rgba(224,169,59,.5);box-shadow:0 10px 26px rgba(224,169,59,.12)}
.s3 .bar{grid-template-columns:minmax(64px,40%) 1fr auto}
.s3 .bar>div i{transform-origin:left center;background:linear-gradient(90deg,var(--gold),var(--gold-hi))}
.s3 .bar:hover>div i{filter:brightness(1.15)}
.s3 .cols{height:128px;margin:6px 0 0}
.s3 .col i{transform-origin:bottom center;background:linear-gradient(180deg,var(--gold-hi),var(--gold));transition:filter .15s ease}
.s3 .col:hover i{filter:brightness(1.2)}
.s3 .col.today span{color:var(--gold-hi);font-weight:700}
.s3 .col.today i{box-shadow:0 0 0 2px rgba(243,199,101,.55)}
.s3 .col.best{position:relative}
.s3 .col.best::before{content:'⭐';position:absolute;top:-15px;font-size:11px}

/* entrance (only while .s3-in is on) */
.s3-in .tile{animation:s3pop .55s cubic-bezier(.2,1.3,.4,1) both;animation-delay:calc(var(--i,0) * 60ms)}
.s3-in .s3p{animation:s3rise .6s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(var(--p,0) * 90ms + 180ms)}
.s3-in .bar>div i{animation:s3grow .9s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(var(--i,0) * 70ms + 300ms)}
.s3-in .col i{animation:s3up .85s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(var(--i,0) * 80ms + 350ms)}
.s3-in .col em{animation:s3pop .45s ease both;animation-delay:calc(var(--i,0) * 80ms + 900ms)}
.s3-in .xpbar i{animation:s3grow 1s cubic-bezier(.2,.8,.2,1) both;animation-delay:.15s;transform-origin:left center}
.s3-in .rg-fg{animation:s3ring 1.1s cubic-bezier(.2,.8,.2,1) both;animation-delay:.1s}
/* hover: replay THIS panel's graph */
.s3p:hover .bar>div i{animation:s3growH .8s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(var(--i,0) * 70ms)}
.s3p:hover .col i{animation:s3upH .75s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(var(--i,0) * 70ms)}
.s3p:hover .col em{animation:s3popH .4s ease both;animation-delay:calc(var(--i,0) * 70ms + 420ms)}
.s3ring:hover .rg-fg{animation:s3ringH .9s cubic-bezier(.2,.8,.2,1) both}
.s3p:hover .srow{animation:s3slideH .45s ease both}

@keyframes s3rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes s3pop{0%{opacity:0;transform:scale(.6)}70%{transform:scale(1.07)}100%{opacity:1;transform:scale(1)}}
@keyframes s3popH{0%{opacity:0;transform:scale(.6)}70%{transform:scale(1.07)}100%{opacity:1;transform:scale(1)}}
@keyframes s3grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes s3growH{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes s3up{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes s3upH{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes s3ring{from{stroke-dasharray:0 188.5}to{stroke-dasharray:var(--arc) 188.5}}
@keyframes s3ringH{from{stroke-dasharray:0 188.5}to{stroke-dasharray:var(--arc) 188.5}}
@keyframes s3slideH{from{opacity:.3;transform:translateX(-8px)}to{opacity:1;transform:none}}
@keyframes s3flame{0%,100%{transform:rotate(-4deg) scale(1)}25%{transform:rotate(3deg) scale(1.1)}50%{transform:rotate(-2deg) scale(.95)}75%{transform:rotate(4deg) scale(1.12)}}
@keyframes s3pulse{0%,100%{box-shadow:0 0 0 0 rgba(243,199,101,.5)}50%{box-shadow:0 0 0 8px rgba(243,199,101,0)}}

/* confetti (opening good news) and sparkles (tap the level ring) */
.confetti{position:fixed;inset:0;pointer-events:none;z-index:70;overflow:hidden}
.confetti i{position:absolute;border-radius:2px;opacity:0;animation:confettiFall var(--d,1400ms) cubic-bezier(.2,.7,.3,1) forwards}
@keyframes confettiFall{0%{opacity:1;transform:translate(0,0) rotate(0)}15%{opacity:1}100%{opacity:0;transform:translate(var(--dx),var(--dy)) rotate(var(--r))}}
.spark{position:fixed;pointer-events:none;z-index:70;transform:translate(-50%,-50%);animation:sparkFly .9s ease-out forwards}
@keyframes sparkFly{0%{opacity:1;transform:translate(-50%,-50%) scale(.4)}60%{opacity:1}100%{opacity:0;transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(1.15)}}

@media (prefers-reduced-motion:reduce){
  .s3 *,.s3 *::before,#toast,#toast.show,.confetti i,.spark,.sm-anim>*,.sm-in *,.tr-in *{animation:none!important;transition:none!important}
}

/* ---- v0.14.0: Student Summary status at a glance (On track / Needs monitoring / Off track) ---- */
.status-card{border:1px solid var(--line);border-left:5px solid var(--lo);border-radius:12px;padding:14px;background:rgba(0,0,0,.18);margin:0 0 14px}
.status-card.ov-good{border-left-color:#9be89b}.status-card.ov-watch{border-left-color:var(--gold-hi)}.status-card.ov-off{border-left-color:#ff8a80}
.st-head{display:flex;align-items:center;gap:12px;margin-bottom:12px}.st-icon{font-size:30px;line-height:1}
.st-title{margin:0;font-size:20px;font-weight:800;color:var(--hi)}.st-sub{margin:2px 0 0;color:var(--lo)}
.st-items{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:8px}
.st-item{background:rgba(0,0,0,.2);border:1px solid var(--line);border-radius:10px;padding:9px 11px}
.st-top{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap}.st-label{font-weight:700}
.st-pill{font-size:11px;font-weight:700;padding:2px 8px;border-radius:999px;white-space:nowrap;background:rgba(255,255,255,.1);color:var(--lo)}
.lv-good .st-pill{background:rgba(155,232,155,.16);color:#9be89b}.lv-watch .st-pill{background:rgba(224,169,59,.18);color:var(--gold-hi)}.lv-off .st-pill{background:rgba(255,138,128,.16);color:#ff9d94}
.st-val{margin-top:5px}.st-hint{margin-top:2px;font-size:11.5px}.st-cap{margin:10px 0 0;font-size:11.5px}
.st-how{margin-top:6px;font-size:12px;color:var(--lo)}.st-how summary{cursor:pointer;width:max-content}.st-how p{margin:5px 0 0}
.sm-detail-h{margin:6px 0 0;font-size:12.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--lo)}
.sgrid .sm-tiles{margin:0}

/* ==============================================================================================================================   v0.15.0 — Badge Display Case (js/badges.js): the medal (same look as StudentDeck's), the full-screen trophy cabinet and the detail card.
   ===================================================================================================================================== */
@keyframes bcSpin{0%{transform:rotateY(0)}100%{transform:rotateY(360deg)}}
@keyframes bcShine{from{background-position:-130% 0}to{background-position:230% 0}}
@keyframes bcPop{0%{transform:scale(.4);opacity:0}60%{transform:scale(1.15);opacity:1}100%{transform:scale(1)}}
@keyframes bcStar{0%,100%{transform:scale(1) rotate(0);opacity:1}50%{transform:scale(1.5) rotate(25deg);opacity:.55}}
@keyframes bcBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}

.medal{--m1:#cd7f32;--m2:#8a4f1d;position:relative;display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:50%;flex-shrink:0;
  background:conic-gradient(from 210deg,var(--m1),var(--m2),var(--m1),var(--m2),var(--m1));box-shadow:0 3px 14px rgba(0,0,0,.45),0 0 14px color-mix(in srgb,var(--m1) 55%,transparent)}
.medal.t2{--m1:#e2e6ee;--m2:#8e97a8}.medal.t3{--m1:#ffe27a;--m2:#c48a12}.medal.t4{--m1:#9ff0ff;--m2:#4a8bff}
.medal .mi{width:42px;height:42px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:23px;background:radial-gradient(circle at 35% 30%,#2e3b63,#171f3a);box-shadow:inset 0 2px 6px rgba(0,0,0,.55)}
.medal::after{content:'';position:absolute;inset:0;border-radius:50%;background:linear-gradient(110deg,transparent 0,rgba(255,255,255,.7) 48%,transparent 62%);background-size:55% 100%;background-repeat:no-repeat;background-position:-130% 0}

.bc{max-width:1100px;margin:0 auto;display:flex;flex-direction:column;gap:14px}
.bc-hero{display:flex;align-items:center;gap:22px;flex-wrap:wrap;padding:18px 22px;border:1px solid rgba(224,169,59,.35);border-radius:18px;
  background:radial-gradient(520px 200px at 12% 0%,rgba(224,169,59,.22),transparent 70%),linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.02))}
.bc-spot{font:inherit;border:0;background:none;padding:0;cursor:pointer;perspective:600px;animation:bcBob 4s ease-in-out infinite}
.bc-spot .medal{width:128px;height:128px}.bc-spot .medal .mi{width:98px;height:98px;font-size:54px}
.bc-spot:hover .medal::after,.bc-item:hover .medal::after{animation:bcShine .9s ease-out}
.bc-spot.fresh .medal{animation:bcSpin 1.3s ease-in-out both}
.bc-spot.empty{width:96px;height:96px;display:flex;align-items:center;justify-content:center;font-size:48px;border-radius:50%;border:2px dashed var(--line);opacity:.6;animation:none;cursor:default}
.bc-hero-t{flex:1;min-width:220px}.bc-hero-t h2{margin:0 0 4px;font-size:clamp(20px,3.2vw,30px)}
.bc-count{margin:0 0 6px;font-size:clamp(15px,2vw,19px);color:var(--gold-hi)}.bc-last{margin:8px 0 0}
.bc-chips{display:flex;flex-wrap:wrap;gap:6px}
.bc-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 11px 3px 8px;border-radius:999px;font-size:12px;background:rgba(255,255,255,.07);border:1px solid var(--line)}
.bc-chip i{width:12px;height:12px;border-radius:50%;background:conic-gradient(var(--m1,#cd7f32),var(--m2,#8a4f1d),var(--m1,#cd7f32))}
.bc-chip.t1 i,.bc-shelf.t1{--m1:#cd7f32;--m2:#8a4f1d}.bc-chip.t2 i,.bc-shelf.t2{--m1:#e2e6ee;--m2:#8e97a8}.bc-chip.t3 i,.bc-shelf.t3{--m1:#ffe27a;--m2:#c48a12}.bc-chip.t4 i,.bc-shelf.t4{--m1:#9ff0ff;--m2:#4a8bff}
.bc-bar{display:flex;gap:8px}

/* the cabinet: a dark wood frame, a lit back wall, and glass shelves */
.bc-cabinet{padding:10px 18px 4px;border-radius:18px;border:7px solid #4a3620;box-shadow:inset 0 0 0 2px #6b4e2c,inset 0 14px 40px rgba(0,0,0,.45),0 12px 30px rgba(0,0,0,.35);
  background:radial-gradient(700px 260px at 50% -10%,rgba(255,236,170,.16),transparent 70%),linear-gradient(180deg,#1b2442,#121830)}
.bc-bare{padding:30px 18px}.bc-empty{margin:0;text-align:center;color:var(--lo);font-size:15px}
.bc-shelf{padding-top:12px}
.bc-shelf h3{margin:0 0 4px;font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--m1,var(--gold-hi))}
.bc-shelf h3 span{margin-left:6px;padding:1px 8px;border-radius:999px;background:rgba(255,255,255,.1);color:var(--lo);letter-spacing:0}
.bc-row{display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:8px 6px;align-items:end;padding:6px 2px 0}
.bc-item{position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;padding:8px 4px 10px;border:0;border-radius:14px;background:none;color:inherit;font:inherit;text-align:center;cursor:pointer;perspective:500px;transition:transform .2s ease,background .2s ease}
.bc-item:hover,.bc-item:focus-visible{transform:translateY(-6px);background:rgba(255,255,255,.05);outline:none}
.bc-item:focus-visible{box-shadow:0 0 0 2px var(--gold)}
.bc-item .medal{width:84px;height:84px}.bc-item .medal .mi{width:64px;height:64px;font-size:35px}
.bc-item b{font-size:12.5px;line-height:1.25}.bc-item small{font-size:11px;color:var(--lo)}
.bc-item.fresh .medal{animation:bcPop .7s both}
.bc-new{position:absolute;top:2px;right:6px;padding:1px 7px;border-radius:999px;font-style:normal;font-size:10px;font-weight:800;background:var(--gold);color:#231604;animation:bcStar 1.4s ease-in-out 4}
.bc-ledge{height:12px;margin:0 -14px;border-radius:3px;background:linear-gradient(180deg,rgba(190,225,255,.5),rgba(120,170,230,.18) 55%,rgba(0,0,0,.25));box-shadow:0 6px 12px rgba(0,0,0,.4),inset 0 1px 0 rgba(255,255,255,.5)}

.bc-prizes{padding:14px 18px 16px;border:1px solid var(--line);border-radius:18px;background:rgba(255,255,255,.03)}
.bc-prizes h3{margin:0 0 10px;font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--gold-hi)}
.bc-prizes h3 span{margin-left:6px;padding:1px 8px;border-radius:999px;background:rgba(255,255,255,.1);color:var(--lo);letter-spacing:0}
.bc-prow{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:10px}
.bc-prize{display:flex;flex-direction:column;gap:2px;padding:12px 14px;border-radius:14px;border:1px dashed rgba(224,169,59,.5);background:linear-gradient(135deg,rgba(224,169,59,.14),rgba(224,169,59,.04))}
.bc-gift{font-size:24px}.bc-prize b{font-size:13.5px}.bc-prize small{font-size:11px;color:var(--lo)}.bc-pdesc{font-style:italic}
.bc-foot{text-align:center;margin:2px 0 0}

/* the detail card */
.bc-back{position:fixed;inset:0;z-index:1100;display:flex;align-items:center;justify-content:center;padding:16px;background:rgba(10,13,24,.72)}
.bc-card{position:relative;width:min(380px,100%);max-height:92vh;overflow:auto;padding:26px 22px 20px;text-align:center;background:var(--panel);border:1px solid var(--gold);border-radius:20px;box-shadow:0 20px 60px rgba(0,0,0,.6),0 0 40px rgba(224,169,59,.25)}
.bc-x{position:absolute;top:8px;right:8px;width:30px;height:30px;border:0;border-radius:9px;background:transparent;color:var(--lo);font-size:20px;line-height:1;cursor:pointer}.bc-x:hover{background:rgba(255,255,255,.1);color:var(--hi)}
.bc-bigmedal{display:flex;justify-content:center;margin-bottom:10px;perspective:600px}
.bc-bigmedal .medal{width:168px;height:168px;animation:bcSpin 1.2s .1s ease-in-out both}.bc-bigmedal .medal .mi{width:128px;height:128px;font-size:72px}
.bc-bigmedal .medal::after{animation:bcShine 1.3s .55s ease-out both}
.bc-tier{display:block;font-size:10.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--gold-hi)}
.bc-card h3{margin:4px 0 6px;font-size:22px}.bc-card p{margin:0 0 8px;color:var(--lo)}.bc-card em{display:block;font-style:normal;font-size:12px;color:var(--lo)}
.bc-nav{margin-top:14px;justify-content:center}

@media (max-width:560px){.bc-hero{justify-content:center;text-align:center}.bc-chips{justify-content:center}.bc-spot .medal{width:104px;height:104px}.bc-spot .medal .mi{width:78px;height:78px;font-size:42px}.bc-row{grid-template-columns:repeat(auto-fill,minmax(96px,1fr))}}
@media (prefers-reduced-motion:reduce){.bc-spot,.bc-item,.bc-new,.bc-bigmedal .medal,.bc-bigmedal .medal::after,.bc-spot.fresh .medal,.bc-item.fresh .medal{animation:none!important;transition:none!important}.bc-item:hover{transform:none}}
/* ---- v0.15.0: Calendar widget (month grid + Week Ahead tab) ---- */
.cal-tabs{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:10px;flex-wrap:wrap}
.cal-tabs .chip{padding:4px 11px;font-size:12px}
.cal-sys{display:flex;align-items:center;gap:6px;font-size:11px}
.cal-sys[hidden]{display:none}
.cal-sys select{font:inherit;font-size:11px;background:var(--panel2);color:var(--hi);border:1px solid var(--line);border-radius:8px;padding:3px 6px}
.cal-lunar-day{position:absolute;bottom:1px;right:2px;font-size:6.5px;line-height:1;color:var(--lo)}
.cal-cell.selected .cal-lunar-day{color:rgba(35,22,4,.75)}
.cal-cell.today .cal-lunar-day{color:var(--gold-hi)}
.cal-ev-gcal{flex-shrink:0;text-decoration:none;font-size:12px;opacity:.7}
.cal-ev-gcal:hover{opacity:1}
/* ---- v0.15.0: Class Pulse + Attendance ---- */
.pulse-row{padding:10px 0;border-bottom:1px solid var(--line)}
.pulse-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:13px}
.pulse-val{font-size:17px;font-weight:700;color:var(--gold-hi);font-variant-numeric:tabular-nums}
.pulse-bar{position:relative;height:12px;margin:8px 0 6px;border-radius:7px;background:rgba(255,255,255,.07)}
.pulse-band{position:absolute;top:0;bottom:0;border-radius:7px;background:rgba(155,232,155,.28);border:1px solid rgba(155,232,155,.45);box-sizing:border-box}
.pulse-me{position:absolute;top:-3px;width:6px;height:18px;margin-left:-3px;border-radius:3px;background:var(--gold);box-shadow:0 0 0 2px rgba(0,0,0,.35)}
.pulse-me.in{background:#9be89b}
.pulse-sub{display:flex;justify-content:space-between;gap:8px;flex-wrap:wrap;font-size:11px}
.pulse-verdict{color:var(--hi)}
.pulse-intro p{font-size:13px;line-height:1.5}
.att-nav{display:flex;align-items:center;justify-content:space-between;gap:8px}
.att-nav .btn{padding:4px 12px}.att-nav .btn:disabled{opacity:.35;cursor:default}
.att-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin:8px 0 6px}
.att-h{text-align:center;font-size:10px;color:var(--lo)}
.att-day{position:relative;display:flex;align-items:center;justify-content:center;aspect-ratio:1;border-radius:8px;font-size:10px;color:var(--lo);background:rgba(255,255,255,.05);border:1px solid transparent}
.att-day i{position:absolute;top:2px;left:4px;font-style:normal;font-size:9px;opacity:.8}
.att-day b{font-size:14px;line-height:1}
.att-day.wknd{opacity:.45}.att-day.fut{opacity:.35}
.att-day.ok{background:rgba(74,222,128,.18);border-color:rgba(74,222,128,.55);color:#4ade80}
.att-day.late{background:rgba(250,204,21,.18);border-color:rgba(250,204,21,.6);color:#facc15}
.att-day.abs{background:rgba(248,113,113,.2);border-color:rgba(248,113,113,.6);color:#f87171}
.att-day b{font-weight:800}
.att-day.other{border-color:var(--line)}
.att-day.today{outline:2px solid var(--gold-hi);outline-offset:1px}
.att-legend{display:flex;gap:12px;flex-wrap:wrap;font-size:11px}
.att-key.ok{color:#4ade80}.att-key.late{color:#facc15}.att-key.abs{color:#f87171}

/* ==============================================================================================================================
   v0.17.0 — motion for the rest of Student Summary (Student Stats and XP already had it, above).
   Same rules as that section: an entrance that plays on the first draw (and when a chart choice changes), never on a live
   update — JS puts .sm-in / .tr-in on a host only for the draw that should animate. Section blocks rise in one after another.
   Reduced motion turns every bit of it off (see the media query above).
   ============================================================================================================================== */
@keyframes smRise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes smSlide{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:none}}
@keyframes smDraw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
@keyframes smSpin{from{opacity:0;transform:rotate(-120deg) scale(.55)}to{opacity:1;transform:none}}

/* the blocks of the Summary: heading, header tiles and each sub-widget rise in turn */
.sm-anim>*{animation:smRise .55s cubic-bezier(.2,.8,.2,1) backwards}
.sm-anim>:nth-child(1){animation-delay:.05s}.sm-anim>:nth-child(2){animation-delay:.12s}.sm-anim>:nth-child(3){animation-delay:.19s}
.sm-anim>:nth-child(4){animation-delay:.26s}.sm-anim>:nth-child(5){animation-delay:.33s}.sm-anim>:nth-child(6){animation-delay:.4s}

/* status card */
.sm-in .status-card{animation:smRise .5s cubic-bezier(.2,.8,.2,1) backwards}
.sm-in .st-icon{display:inline-block;animation:s3pop .7s cubic-bezier(.2,1.3,.4,1) backwards .15s}
.sm-in .st-title{animation:smSlide .5s ease backwards .2s}.sm-in .st-sub{animation:smSlide .5s ease backwards .3s}
.sm-in .st-item{animation:s3pop .5s cubic-bezier(.2,1.3,.4,1) backwards;animation-delay:calc(var(--i,0) * 70ms + 260ms)}
.sm-in .st-pill{animation:s3pop .4s ease backwards;animation-delay:calc(var(--i,0) * 70ms + 520ms)}
.st-item,.sm-tiles .tile{transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}
.st-item:hover,.sm-tiles .tile:hover{transform:translateY(-3px);border-color:rgba(224,169,59,.55);box-shadow:0 8px 20px rgba(224,169,59,.14)}

/* "this week" tiles */
.sm-in .tile{animation:s3pop .55s cubic-bezier(.2,1.3,.4,1) backwards;animation-delay:calc(var(--i,0) * 60ms + 120ms)}
.sm-tiles .tile b{font-variant-numeric:tabular-nums}

/* notes, reward points, class ranking */
.sm-in .note-card{animation:smRise .5s cubic-bezier(.2,.8,.2,1) backwards;animation-delay:calc(var(--i,0) * 80ms + 120ms)}
.sm-in .lvl .big{animation:s3pop .6s cubic-bezier(.2,1.3,.4,1) backwards}
.sm-in .srow{animation:smSlide .4s ease backwards;animation-delay:calc(var(--i,0) * 50ms + 280ms)}
.sm-in .xpbar i{transform-origin:left center;animation:s3grow 1s cubic-bezier(.2,.8,.2,1) backwards .2s}
.sm-in .big{animation:s3pop .6s cubic-bezier(.2,1.3,.4,1) backwards}

/* practice trends: bars grow, the line draws itself, the pie spins in */
.tr-in .col i{transform-origin:bottom center;animation:s3up .85s cubic-bezier(.2,.8,.2,1) backwards;animation-delay:calc(var(--i,0) * 80ms + 120ms)}
.tr-in .col em{animation:s3pop .45s ease backwards;animation-delay:calc(var(--i,0) * 80ms + 700ms)}
.tr-in .linechart polyline{stroke-dasharray:1;animation:smDraw 1.1s cubic-bezier(.3,.7,.2,1) backwards .1s}
.tr-in .linechart circle{transform-box:fill-box;transform-origin:center;animation:s3pop .4s ease backwards;animation-delay:calc(var(--i,0) * 70ms + 500ms)}
.tr-in .pie{animation:smSpin .9s cubic-bezier(.2,.8,.2,1) backwards}
.tr-in .legend>div{animation:smSlide .4s ease backwards;animation-delay:.45s}
.tr-in .delta{animation:smRise .5s ease backwards .6s}
.col i{transition:filter .15s ease}.col:hover i{filter:brightness(1.2)}

/* v0.18.0: Goals & Streaks inside Student Summary — rings sweep, streak tiles pop, the 28 day squares ripple in */
@keyframes smRing{from{stroke-dasharray:0 113.1}}
.sm-in .rfg{animation:smRing 1s cubic-bezier(.2,.8,.2,1) backwards .25s}
.sm-in .ring{animation:s3pop .5s cubic-bezier(.2,1.3,.4,1) backwards .15s}
.sm-in .gday{animation:s3pop .35s ease backwards;animation-delay:calc(var(--i,0) * 16ms + 150ms)}

/* ==============================================================================================================================
   v0.19.0 — Reward Points / Goals & Streaks / Class Ranking as one block: Points and Ranking stacked on the left, Goals on the right
   (a single column in the order Points, Goals, Ranking on a narrow screen), and motion for the Class Ranking section.
   ============================================================================================================================== */
.sm-duo{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:auto 1fr;grid-template-areas:"pts goals" "rank goals";gap:12px;align-items:start}
.sm-duo>div{min-width:0}
.sm-duo #sm-points{grid-area:pts}.sm-duo #sm-goals{grid-area:goals}.sm-duo #sm-ranking{grid-area:rank}
@media (max-width:780px){.sm-duo{grid-template-columns:minmax(0,1fr);grid-template-rows:none;grid-template-areas:"pts" "goals" "rank"}}
.sm-anim>.sm-duo{animation:none}                      /* the three sections rise in turn instead of the block as a whole */
.sm-duo>*{animation:smRise .55s cubic-bezier(.2,.8,.2,1) backwards}
.sm-duo>:nth-child(1){animation-delay:.26s}.sm-duo>:nth-child(2){animation-delay:.34s}.sm-duo>:nth-child(3){animation-delay:.42s}

@keyframes smPulse{0%,100%{opacity:.45}50%{opacity:1}}
.sm-in .rk-btn{animation:s3pop .5s cubic-bezier(.2,1.3,.4,1) backwards .25s}
.sm-in #rk-out>p{animation:smRise .5s ease backwards .4s}
.rk-btn{transition:transform .15s ease,box-shadow .15s ease}
.rk-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 16px rgba(224,169,59,.2)}
.rk-btn.busy{animation:smPulse .9s ease-in-out infinite}
.rk-loading>p{animation:smPulse 1.1s ease-in-out infinite}
.rk-fade{animation:smRise .4s ease backwards}
.rk-medal{display:inline-block;margin-right:6px;animation:s3pop .7s cubic-bezier(.2,1.3,.4,1) backwards .35s}
@media (prefers-reduced-motion:reduce){.sm-duo>*,.rk-btn,.rk-btn.busy,.rk-loading>p,.rk-fade,.rk-medal{animation:none!important;transition:none!important}}

/* ==============================================================================================================================
   v0.20.0 — sparkle (the way StudentDeck's Stats & XP does it) for Notes Home, Reward Points, Goals & Streaks and Practice trends.
   Entrance as before; now also hover: every section glows and twinkles, tiles lift and count up again, the level badge pulses and throws
   stars, rows cascade, the 28 day squares twinkle, goal rings re-sweep (and a met goal glows), bars re-grow with a glint and a value
   tooltip, the best bar wears a star, and note cards lift (unread ones shimmer). All of it is off under reduced motion.
   The hover rules use differently NAMED keyframes (…H) — a CSS animation only restarts when its name changes.
   ============================================================================================================================== */
@keyframes spStar{0%{opacity:0;transform:scale(0) rotate(0)}45%{opacity:1;transform:scale(1.25) rotate(100deg)}100%{opacity:0;transform:scale(0) rotate(200deg)}}
@keyframes spTwinkle{0%,100%{transform:scale(1);filter:brightness(1);box-shadow:0 0 0 0 rgba(255,214,102,0)}35%{transform:scale(1.5);filter:brightness(1.9);box-shadow:0 0 9px 3px rgba(255,214,102,.75)}70%{transform:scale(.8);filter:brightness(.75);box-shadow:0 0 0 0 rgba(255,214,102,0)}}
@keyframes spSpark{0%{opacity:1;transform:translate(-50%,-50%) scale(1) rotate(0)}100%{opacity:0;transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(.2) rotate(240deg)}}
@keyframes spPulse{0%,100%{text-shadow:0 0 0 rgba(255,214,102,0)}50%{text-shadow:0 0 18px rgba(255,214,102,.9)}}
@keyframes spGlint{from{background-position:-120% 0}to{background-position:220% 0}}
@keyframes spWave{0%,100%{transform:translateY(0) scale(1)}40%{transform:translateY(-9px) scale(1.25)}}
@keyframes spSlideH{from{opacity:0;transform:translateX(-14px)}to{opacity:1;transform:none}}
@keyframes spGrowYH{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes spPopH{0%{transform:scale(.55);opacity:0}60%{transform:scale(1.18);opacity:1}100%{transform:scale(1);opacity:1}}
@keyframes spRingH{from{stroke-dasharray:0 113.1}}
@keyframes spDrawH{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
@keyframes spDot{0%,100%{box-shadow:0 0 0 0 rgba(243,199,101,.6)}50%{box-shadow:0 0 0 6px rgba(243,199,101,0)}}

.sp-spark{position:absolute;pointer-events:none;color:#ffe08a;text-shadow:0 0 6px var(--gold);line-height:1;z-index:5;animation:spSpark 1.1s ease-out both}
.subbody{position:relative}

/* every section: a soft glow and two twinkling stars while the pointer is on it (Student Stats and XP has its own panels) */
.sgrid .subwidget{position:relative;transition:box-shadow .25s ease,border-color .25s ease}
.sgrid .subwidget:not(#sm-stats)::before,.sgrid .subwidget:not(#sm-stats)::after{position:absolute;pointer-events:none;color:var(--gold-hi);opacity:0;text-shadow:0 0 6px var(--gold);z-index:4}
.sgrid .subwidget:not(#sm-stats)::after{content:'\2726';top:9px;right:46px;font-size:14px}
.sgrid .subwidget:not(#sm-stats)::before{content:'\2727';top:24px;right:62px;font-size:11px}
.sgrid .subwidget:not(#sm-stats):hover{border-color:rgba(224,169,59,.6);box-shadow:0 10px 28px rgba(0,0,0,.38),0 0 0 1px rgba(224,169,59,.22),0 0 24px rgba(224,169,59,.14)}
.sgrid .subwidget:not(#sm-stats):hover::after{animation:spStar 1.7s ease-in-out infinite}
.sgrid .subwidget:not(#sm-stats):hover::before{animation:spStar 1.7s .85s ease-in-out infinite}

/* tiles (Goals & Streaks): lift, glow and count up again */
.subwidget .tile{transition:transform .2s ease,box-shadow .2s ease,background .2s ease,border-color .2s ease}
.subwidget .tile:hover{transform:translateY(-4px) scale(1.05);background:rgba(224,169,59,.13);border-color:var(--gold);box-shadow:0 8px 18px rgba(0,0,0,.35),0 0 16px rgba(224,169,59,.3)}
.subwidget .tile:hover b{animation:spPopH .45s both}
.tile .flame{font-size:inherit;vertical-align:-1px}

/* Reward Points: the level badge pulses, the rows cascade in again and light up */
.lvl .big{display:inline-block;transition:transform .2s ease}
.lvl:hover .big{animation:spPulse 1.2s ease-in-out;transform:scale(1.07)}
.subwidget .srow{transition:background .15s ease}
.subwidget .srow:hover{background:rgba(224,169,59,.09)}
.subwidget .srow:hover b{animation:spPopH .4s both;color:var(--gold-hi)}
.subwidget:hover .srow{animation:spSlideH .45s ease-out both;animation-delay:calc(var(--i,0) * 38ms)}

/* Goals & Streaks: the day squares twinkle, rings re-sweep, a met goal glows and carries a star */
.gday{position:relative;transition:transform .15s ease}
#sm-goals:hover .gday.on{animation:spTwinkle 1.9s ease-in-out infinite;animation-delay:var(--d,0s)}
.gday:hover{animation:spTwinkle .55s ease-out !important;z-index:3}
.gday:hover::after{content:'\2726';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-size:12px;color:#fff;text-shadow:0 0 5px var(--gold-hi)}
.ring{transition:transform .2s ease}
.ring:hover{transform:scale(1.1)}
.ring:hover svg{filter:drop-shadow(0 0 8px rgba(224,169,59,.55))}
.ring:hover .rfg{animation:spRingH .9s cubic-bezier(.2,.8,.2,1) both}
.ring.full svg{filter:drop-shadow(0 0 6px rgba(155,232,155,.5))}
.ring.full::after{content:'\2726';position:absolute;top:-4px;right:10px;font-size:13px;color:#fff;text-shadow:0 0 6px #9be89b;opacity:0;animation:spStar 2.4s ease-in-out infinite}

/* Practice trends: bars glint and glow, show their value, re-grow when the section is hovered; the best one wears a star */
#sm-trends .col{position:relative;transition:transform .2s ease}
#sm-trends .col i{position:relative;overflow:hidden;transition:filter .2s ease,box-shadow .2s ease}
#sm-trends .col i::after{content:'';position:absolute;inset:0;background:linear-gradient(100deg,transparent 0,rgba(255,255,255,.8) 50%,transparent 100%);background-size:60% 100%;background-repeat:no-repeat;background-position:-120% 0}
#sm-trends .tr-in .col i::after{animation:spGlint 1.2s .9s ease-out both}
#sm-trends .col:hover{transform:translateY(-3px)}
#sm-trends .col:hover i{filter:brightness(1.45);box-shadow:0 0 14px var(--gold-hi)}
#sm-trends .col:hover i::after{animation:spGlint .9s ease-out}
#sm-trends .col:hover::after{content:attr(data-v);position:absolute;top:-4px;left:50%;transform:translate(-50%,-100%);background:var(--gold);color:#231604;font-weight:700;font-size:11px;padding:2px 6px;border-radius:6px;white-space:nowrap;z-index:4;animation:spPopH .3s both}
#sm-trends:hover .col i{animation:spGrowYH .8s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(var(--i,0) * 28ms)}
#sm-trends .col.best::before{content:'⭐';position:absolute;top:-16px;font-size:11px;animation:spPopH .5s .9s both}
#sm-trends .linechart circle{transition:filter .15s ease}
#sm-trends .linechart circle:hover{filter:drop-shadow(0 0 4px var(--gold-hi));r:4.5}
#sm-trends:hover .linechart polyline{stroke-dasharray:1;animation:spDrawH 1s cubic-bezier(.3,.7,.2,1) both}
.pie{transition:transform .4s cubic-bezier(.2,.8,.2,1),filter .3s ease}
.pie:hover{transform:rotate(14deg) scale(1.07);filter:drop-shadow(0 0 10px rgba(224,169,59,.4))}
.legend>div{transition:transform .15s ease}.legend>div:hover{transform:translateX(4px)}
.delta{transition:transform .2s ease,background .2s ease}.delta:hover{transform:translateY(-2px);background:rgba(224,169,59,.12)}

/* Notes Home (the widget and the Summary section): cards lift, glow and twinkle; unread ones shimmer and their dot pulses */
.note-card{position:relative;overflow:hidden;transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.note-card:hover{transform:translateY(-3px);border-color:rgba(224,169,59,.6);box-shadow:0 8px 20px rgba(0,0,0,.35),0 0 18px rgba(224,169,59,.16)}
.note-card::after{content:'\2726';position:absolute;bottom:7px;right:14px;font-size:14px;color:var(--gold-hi);text-shadow:0 0 6px var(--gold);opacity:0;pointer-events:none}
.note-card:hover::after{animation:spStar 1.7s ease-in-out infinite}
.note-card.unread::before{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(100deg,transparent 0,rgba(255,224,138,.22) 50%,transparent 100%);background-size:45% 100%;background-repeat:no-repeat;background-position:-120% 0;animation:spGlint 3.8s ease-in-out infinite}
.note-card .note-mood{display:inline-block}
.note-card:hover .note-mood{animation:spWave .8s ease-in-out}
.note-card .note-dot{animation:spDot 1.8s ease-out infinite}

@media (prefers-reduced-motion:reduce){
  .sgrid *,.sgrid *::before,.sgrid *::after,.note-card,.note-card *,.note-card::before,.note-card::after,.sp-spark,.pie,.ring,.gday{animation:none!important;transition:none!important}
  .sgrid .gday:hover{animation:none!important}
  .note-card:hover,#sm-trends .col:hover,.ring:hover,.pie:hover,.subwidget .tile:hover,.gday:hover{transform:none!important}
}
.note-card .note-dot{flex:none;min-width:10px;min-height:10px}

/* =====================================================================================================================================
   v0.21.0 — stoplight colours on the Student Summary's top boxes, in the style of AdminDeck's School Stats cards: green = on track,
   yellow = needs monitoring, red = off track. A solid 2px box in the full colour, a strong tint, a glow, and ONE colour for all of its text; a shape
   (● / ▲ / ■) comes with it so colour is never the only signal. Boxes with no verdict keep the plain gold look.
   ===================================================================================================================================== */
:root{ --st-good:#2EE66B; --st-watch:#FFE600; --st-bad:#FF3B3B;
       --st-good-bg:rgba(46,230,107,.22); --st-watch-bg:rgba(255,230,0,.20); --st-bad-bg:rgba(255,59,59,.24); }
.st-item.lv-good,.sm-tiles .tile[data-st="good"],.sl-key[data-st="good"]{ --c:var(--st-good); --bg:var(--st-good-bg); --rgb:46,230,107; }
.st-item.lv-watch,.sm-tiles .tile[data-st="watch"],.sl-key[data-st="watch"]{ --c:var(--st-watch); --bg:var(--st-watch-bg); --rgb:255,230,0; }
.st-item.lv-off,.sm-tiles .tile[data-st="bad"],.sl-key[data-st="bad"]{ --c:var(--st-bad); --bg:var(--st-bad-bg); --rgb:255,59,59; }

/* the four status boxes at the very top */
.st-item.lv-good,.st-item.lv-watch,.st-item.lv-off{ border:2px solid var(--c); background:var(--bg); color:var(--c); box-shadow:0 0 0 1px rgba(var(--rgb),.25),0 0 18px rgba(var(--rgb),.30); }
.st-item.lv-good .st-label,.st-item.lv-watch .st-label,.st-item.lv-off .st-label,
.st-item.lv-good .st-val,.st-item.lv-watch .st-val,.st-item.lv-off .st-val,
.st-item.lv-good .st-hint,.st-item.lv-watch .st-hint,.st-item.lv-off .st-hint{ color:inherit; }
.st-item.lv-good .st-pill,.st-item.lv-watch .st-pill,.st-item.lv-off .st-pill{ color:var(--c); background:var(--bg); border:1.5px solid currentColor; }
.st-item.lv-good .st-hint,.st-item.lv-watch .st-hint,.st-item.lv-off .st-hint{ opacity:.9; }
.st-item.lv-good:hover,.st-item.lv-watch:hover,.st-item.lv-off:hover{ border-color:var(--c); box-shadow:0 0 0 1px rgba(var(--rgb),.4),0 8px 26px rgba(var(--rgb),.42); }
/* red is lower-luminance than green/yellow, so the shared formula above reads weaker for it — boosted to match, same baseline as AdminDeck's School Stats */
.st-item.lv-off{ box-shadow:0 0 0 1.5px rgba(255,59,59,.55), 0 0 28px rgba(255,59,59,.6), 0 0 46px rgba(255,59,59,.22); }
.st-item.lv-off:hover{ box-shadow:0 0 0 1.5px rgba(255,59,59,.7), 0 10px 32px rgba(255,59,59,.65), 0 0 50px rgba(255,59,59,.28); }
.status-card.ov-good{ border-left-color:var(--st-good); }.status-card.ov-watch{ border-left-color:var(--st-watch); }.status-card.ov-off{ border-left-color:var(--st-bad); }

/* the four "this week" tiles: centred stat cards like School Stats' top row (gold when there is no verdict) */
.sm-tiles{ grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:10px; }
.sm-tiles .tile{ position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; padding:13px 15px; border:2px solid rgba(255,203,92,.28); background:rgba(255,203,92,.05); }
.sm-tiles .tile b{ width:100%; font-size:30px; line-height:1.1; font-weight:700; color:#FFCB5C; font-variant-numeric:tabular-nums; }
.sm-tiles .tile b span{ display:inline; font-size:inherit; color:inherit; font-weight:inherit; }       /* the count-up number (was drawn as a small grey label) */
.sm-tiles .tile b small.sl-u{ font-size:.5em; font-weight:600; margin:0 .12em 0 .06em; }
.sm-tiles .tile > span{ width:100%; margin-top:6px; font-size:13.5px; font-weight:600; color:#F6DDA6; }
.sm-tiles .tile:hover{ border-color:rgba(255,203,92,.75); box-shadow:0 8px 20px rgba(255,203,92,.18); }
.sm-tiles .tile[data-st]{ border-color:var(--c); background:var(--bg); color:var(--c); box-shadow:0 0 0 1px rgba(var(--rgb),.25),0 0 18px rgba(var(--rgb),.30); }
.sm-tiles .tile[data-st] b,.sm-tiles .tile[data-st] > span,.sm-tiles .tile[data-st] b small.sl-u{ color:inherit; }
.sm-tiles .tile[data-st]:hover{ border-color:var(--c); box-shadow:0 0 0 1px rgba(var(--rgb),.4),0 8px 26px rgba(var(--rgb),.45); }
.sm-tiles .tile[data-st="bad"]{ box-shadow:0 0 0 1.5px rgba(255,59,59,.55), 0 0 28px rgba(255,59,59,.6), 0 0 46px rgba(255,59,59,.22); }
.sm-tiles .tile[data-st="bad"]:hover{ box-shadow:0 0 0 1.5px rgba(255,59,59,.7), 0 10px 32px rgba(255,59,59,.65), 0 0 50px rgba(255,59,59,.28); }
.sm-tiles .tile[data-st]::after{ position:absolute; top:8px; right:11px; font-size:16px; line-height:1; color:var(--c); }
.sm-tiles .tile[data-st="good"]::after{ content:'●'; }.sm-tiles .tile[data-st="watch"]::after{ content:'▲'; }.sm-tiles .tile[data-st="bad"]::after{ content:'■'; }

/* the colour key above the tiles */
.sl-legend{ display:flex; flex-wrap:wrap; align-items:flex-start; gap:6px 12px; margin:8px 0 10px; font-size:13px; font-weight:600; }
.sl-key{ display:inline-block; padding:1px 9px; border-radius:999px; border:1.5px solid var(--c); color:var(--c); background:var(--bg); line-height:1.5; }
.sl-key::before{ font-size:.7em; margin-right:5px; vertical-align:.1em; }
.sl-key[data-st="good"]::before{ content:'●'; }.sl-key[data-st="watch"]::before{ content:'▲'; }.sl-key[data-st="bad"]::before{ content:'■'; }
.sl-legend details{ flex:1 1 260px; color:var(--lo); font-weight:500; font-size:12.5px; margin-left:6px; }
.sl-legend summary{ cursor:pointer; width:max-content; padding-top:3px; }
.sl-legend details p{ margin:5px 0 0; }

/* v0.21.3: "class code instead" fallback in Link a child */
details.join-classcode{margin:6px 0 4px}
details.join-classcode summary{cursor:pointer;color:var(--muted, #aab);font-size:.9em}

/* Pro gate: a locked widget (js/progate.js) */
.pg-lock{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:8px;height:100%;min-height:140px;padding:18px}
.pg-lock .pg-star{font-size:34px;filter:drop-shadow(0 0 8px rgba(255,203,92,.6))}
.pg-lock b{font-size:16px}.pg-lock p{margin:0;max-width:34ch;opacity:.85;line-height:1.4}
.pg-lock .pg-cta{margin-top:4px;padding:8px 16px;border-radius:999px;border:0;cursor:pointer;font-weight:600;background:linear-gradient(135deg,#ffcb5c,#f59e0b);color:#3b2600}
.pg-lock .pg-note{font-size:12px;opacity:.6}
.pro-on{color:var(--gold-hi, #ffcb5c);font-weight:600}

/* anti-theft: shown only in a copy running under a different extension ID */
.unofficial-build{position:fixed;top:0;left:0;right:0;z-index:2147483647;padding:8px 14px;background:#b91c1c;color:#fff;font:600 13px/1.3 system-ui,sans-serif;text-align:center}

/* v0.22.0 (backend v2.8.0) — Scrapbook (Scrapdeck sharing, M3) */
.sb-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px}
.sb-card{display:flex;flex-direction:column;text-align:left;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:none;cursor:pointer;padding:0;color:inherit}
.sb-card img{width:100%;aspect-ratio:3/2;object-fit:cover;display:block;background:rgba(0,0,0,.2)}
.sb-cap{padding:6px 8px;font-size:12px;line-height:1.3}
.sb-modal{position:fixed;inset:0;background:rgba(10,14,24,.6);display:flex;align-items:center;justify-content:center;z-index:50;padding:16px}
.sb-mcard{background:var(--panel2,#1b2434);border-radius:14px;padding:14px;max-width:min(520px,100%);max-height:85vh;overflow:auto;display:flex;flex-direction:column;gap:10px;align-items:center}
.sb-mcard img{max-width:100%;max-height:70vh;border-radius:8px}
