@font-face{font-family:Overpass;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/overpass-latin-400-normal.woff2) format('woff2');unicode-range:U+0000-00B6,U+00B8-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Overpass;font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/overpass-latin-500-normal.woff2) format('woff2');unicode-range:U+0000-00B6,U+00B8-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Overpass;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/overpass-latin-600-normal.woff2) format('woff2');unicode-range:U+0000-00B6,U+00B8-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Overpass;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/overpass-latin-700-normal.woff2) format('woff2');unicode-range:U+0000-00B6,U+00B8-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Overpass;font-style:normal;font-weight:800;font-display:swap;src:url(../fonts/overpass-latin-800-normal.woff2) format('woff2');unicode-range:U+0000-00B6,U+00B8-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Overpass;font-style:normal;font-weight:900;font-display:swap;src:url(../fonts/overpass-latin-900-normal.woff2) format('woff2');unicode-range:U+0000-00B6,U+00B8-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Overpass;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/overpass-latin-ext-400-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Overpass;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/overpass-latin-ext-600-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Overpass;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/overpass-latin-ext-700-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Overpass;font-style:normal;font-weight:800;font-display:swap;src:url(../fonts/overpass-latin-ext-800-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Overpass;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/overpass-cyrillic-400-normal.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:Overpass;font-style:normal;font-weight:600;font-display:swap;src:url(../fonts/overpass-cyrillic-600-normal.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:Overpass;font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/overpass-cyrillic-700-normal.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:Overpass;font-style:normal;font-weight:800;font-display:swap;src:url(../fonts/overpass-cyrillic-800-normal.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
/* Native Elite Student Platform — design system
   The look borrows from American road signage: guide-sign green for "go on", interstate blue and red
   for stages, warning yellow for things that need attention. One typeface (Overpass, drawn from
   Highway Gothic). Light surfaces throughout. */
:root{
  color-scheme:light;
  --paper:#F2F4F3; --card:#FFFFFF; --ink:#14181B; --ink2:#353E44; --mute:#5A666F; --faint:#5F6C74;
  --line:#DAE0DD; --exit-off:#4E5A63; --line2:#C2CBC6; --soft:#EEF1EF; --soft2:#E4E9E6;
  --green:#0A6B4B; --green2:#0E8660; --green3:#075239; --green-t:#E2F2EB;
  --blue:#12499B; --blue2:#1C5FC4; --blue3:#0C3676; --blue-t:#E5EDF9;
  --red:#D21030; --red2:#B30926; --red-t:#FDECEE;
  --yellow:#FFC629; --yellow2:#E5A800; --yellow-t:#FFF5D1; --yellow-ink:#5E4300;
  --orange:#E8611A; --orange-t:#FDECDF;
  --brown:#6B4A33; --brown-t:#F2EBE4;
  --flap:#1B2024; --flap-ink:#F7F3E3;
  --r:12px; --r-s:8px; --r-sign:16px;
  --ease:cubic-bezier(.2,.8,.2,1); --ease-in:cubic-bezier(.5,0,.9,.4); --spring:cubic-bezier(.34,1.4,.5,1);
  --top:60px; --tab:64px;
  --sat:env(safe-area-inset-top,0px); --sab:env(safe-area-inset-bottom,0px);
  --shadow:0 1px 0 rgba(20,24,27,.04), 0 10px 24px -18px rgba(20,24,27,.35);
  --shadow-up:0 18px 50px -20px rgba(20,24,27,.45), 0 2px 8px rgba(20,24,27,.08);
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font-family:"Overpass",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-size:15.5px;line-height:1.5;-webkit-font-smoothing:antialiased;font-feature-settings:"tnum" 0;
  -webkit-tap-highlight-color:transparent;overscroll-behavior-y:none;min-height:100dvh}
h1,h2,h3,h4,p{margin:0}
h1{font-size:clamp(24px,3.4vw,32px);line-height:1.12;font-weight:800;letter-spacing:-.012em}
h2{font-size:20px;line-height:1.2;font-weight:800;letter-spacing:-.008em}
h3{font-size:16.5px;line-height:1.25;font-weight:700}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;border:0;background:none;padding:0;touch-action:manipulation;-webkit-user-select:none;user-select:none}
a{color:var(--blue2);text-decoration:none}
img,svg{display:block}
[hidden]{display:none!important}
.num{font-variant-numeric:tabular-nums}
.mute{color:var(--mute)} .small{font-size:13px} .b{font-weight:700} .nowrap{white-space:nowrap}
.row{display:flex;align-items:center;gap:10px} .row.wrap{flex-wrap:wrap} .grow{flex:1;min-width:0}
.stack{display:flex;flex-direction:column;gap:12px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
:focus-visible{outline:2.5px solid var(--blue2);outline-offset:2px;border-radius:6px}
.ic{width:20px;height:20px;flex:none;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.ic.s{width:16px;height:16px} .ic.l{width:24px;height:24px} .ic.xl{width:30px;height:30px}

/* ───────── buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:0 18px;border-radius:10px;
  font-weight:700;font-size:15px;line-height:1;white-space:nowrap;background:var(--card);color:var(--ink);
  box-shadow:inset 0 0 0 1.5px var(--line2);transition:transform .16s var(--ease),background .16s,box-shadow .16s,opacity .16s}
.btn:active{transform:scale(.97)}
.btn.go{background:var(--red);color:#fff;box-shadow:inset 0 0 0 2px var(--red),inset 0 0 0 3.5px rgba(255,255,255,.9)}
.btn.stop{background:var(--red);color:#fff;box-shadow:inset 0 0 0 2px var(--red),inset 0 0 0 3.5px rgba(255,255,255,.9)}
.btn.info{background:var(--blue);color:#fff;box-shadow:inset 0 0 0 2px var(--blue),inset 0 0 0 3.5px rgba(255,255,255,.9)}
.btn.warn{background:var(--yellow);color:var(--ink);box-shadow:inset 0 0 0 2px var(--yellow),inset 0 0 0 3.5px var(--ink)}
.btn.white{background:#fff;color:#8E0820;box-shadow:none}
.btn.ghost{box-shadow:none;background:transparent;color:var(--ink2)}
.btn.sm{min-height:36px;padding:0 12px;font-size:13.5px;border-radius:8px}
.btn.lg{min-height:52px;font-size:16.5px;padding:0 24px;border-radius:12px}
.btn.wide{width:100%}
.btn.icon{width:44px;padding:0} .btn.icon.sm{width:36px}
.btn[disabled]{opacity:.45;pointer-events:none}
.btn.busy{pointer-events:none;color:transparent!important;position:relative}
.btn.busy::after{content:"";position:absolute;width:18px;height:18px;border-radius:50%;border:2.5px solid rgba(255,255,255,.5);border-top-color:#fff;animation:spin .7s linear infinite}
.btn.busy:not(.go):not(.stop):not(.info)::after{border-color:var(--line2);border-top-color:var(--ink)}
@media (hover:hover){
  .btn:hover{box-shadow:inset 0 0 0 1.5px var(--ink2)}
  .btn.go:hover{background:#B30926;box-shadow:inset 0 0 0 2px #B30926,inset 0 0 0 3.5px #fff}
  .btn.stop:hover{background:var(--red2);box-shadow:inset 0 0 0 2px var(--red2),inset 0 0 0 3.5px #fff}
  .btn.info:hover{background:var(--blue2);box-shadow:inset 0 0 0 2px var(--blue2),inset 0 0 0 3.5px #fff}
  .btn.ghost:hover{background:var(--soft2);box-shadow:none}
  .btn.white:hover{box-shadow:none;background:#FFF5F6;color:#8E0820}
}
.link{color:var(--blue2);font-weight:700}
@keyframes spin{to{transform:rotate(360deg)}}

/* ───────── forms */
.field{display:flex;flex-direction:column;gap:6px}
.field>label,.label{font-size:13.5px;font-weight:700;color:var(--ink2)}
.input,select.input,textarea.input{width:100%;min-height:48px;padding:0 14px;border-radius:10px;border:1.5px solid var(--line2);background:var(--card);
  font-size:16px;font-weight:500;outline:0;transition:border-color .15s,box-shadow .15s;-webkit-appearance:none;appearance:none}
textarea.input{padding:12px 14px;min-height:110px;line-height:1.5;resize:vertical}
.input:focus{border-color:var(--red);box-shadow:0 0 0 3.5px var(--red-t)}
.input::placeholder{color:var(--faint);font-weight:400}
.input.bad{border-color:var(--red);box-shadow:0 0 0 3.5px var(--red-t)}
select.input{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' stroke='%2364707A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 8 5 5 5-5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:40px}
.help{font-size:13px;color:var(--mute)} .errtext{font-size:13.5px;color:var(--red);font-weight:600}
.phone{display:flex;align-items:stretch;border-radius:10px;border:1.5px solid var(--line2);background:var(--card);overflow:hidden;transition:border-color .15s,box-shadow .15s}
.phone:focus-within{border-color:var(--red);box-shadow:0 0 0 3.5px var(--red-t)}
.phone>span{display:flex;align-items:center;padding:0 12px;background:var(--soft);font-weight:700;color:var(--ink2);border-right:1.5px solid var(--line)}
.phone>input{flex:1;min-width:0;border:0;outline:0;min-height:48px;padding:0 12px;font-size:16px;font-weight:600;letter-spacing:.02em;background:transparent}
.pw{position:relative}.pw .input{padding-right:48px}.pw button{position:absolute;right:4px;top:4px;width:40px;height:40px;display:grid;place-items:center;color:var(--mute);border-radius:8px}
.switch{position:relative;width:46px;height:28px;border-radius:99px;background:var(--line2);transition:background .2s;flex:none}
.switch::after{content:"";position:absolute;left:3px;top:3px;width:22px;height:22px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.25);transition:transform .28s var(--spring)}
.switch[aria-checked="true"]{background:var(--green2)}
.switch[aria-checked="true"]::after{transform:translateX(18px)}
.switch.red[aria-checked="true"]{background:var(--red)}
.check{width:22px;height:22px;border-radius:6px;border:1.75px solid var(--line2);background:var(--card);display:grid;place-items:center;flex:none;transition:.15s;color:transparent}
.check[aria-checked="true"]{background:var(--green);border-color:var(--green);color:#fff}
.check .ic{width:15px;height:15px;stroke-width:3}
.seg{display:inline-flex;padding:3px;border-radius:10px;background:var(--soft2);gap:2px;max-width:100%;overflow-x:auto;scrollbar-width:none}
.seg::-webkit-scrollbar{display:none}
.seg button{min-height:34px;padding:0 13px;border-radius:8px;font-weight:700;font-size:13.5px;color:var(--mute);white-space:nowrap;transition:color .15s,background .15s}
.seg button[aria-pressed="true"]{background:var(--card);color:var(--ink);box-shadow:0 1px 2px rgba(20,24,27,.14)}

/* ───────── plates (status labels) */
.plate{display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 8px;border-radius:6px;font-size:12.5px;font-weight:700;white-space:nowrap;background:var(--soft2);color:var(--ink2)}
.plate.ok{background:var(--green-t);color:var(--green3)} .plate.bad{background:var(--red-t);color:var(--red2)}
.plate.warn{background:var(--yellow-t);color:var(--yellow-ink)} .plate.info{background:var(--blue-t);color:var(--blue3)}
.plate.work{background:var(--orange-t);color:#9A3D0B}
.plate .ic{width:14px;height:14px;stroke-width:2.4}

/* ───────── cards and lists */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r)}
.card.pad{padding:18px}
.card.tap{transition:transform .18s var(--ease),border-color .18s}
.card.tap:active{transform:scale(.985)}
@media (hover:hover){.card.tap:hover{border-color:var(--line2);transform:translateY(-1px)}}
.sec-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:28px 0 12px}
.sec-head:first-child{margin-top:0}
.list{background:var(--card);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.list>*+*{border-top:1px solid var(--line)}
.li{display:flex;align-items:center;gap:12px;padding:12px 14px;width:100%;text-align:left;min-height:56px;transition:background .12s}
button.li:active,a.li:active{background:var(--soft)}
@media (hover:hover){button.li:hover,a.li:hover{background:#F8FAF9}}
.li .t{font-weight:700;line-height:1.25} .li .s{font-size:13px;color:var(--mute);line-height:1.3}
.av{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:14px;color:#fff;background:var(--blue);flex:none;position:relative;letter-spacing:.02em}
.av.sm{width:32px;height:32px;font-size:12px} .av.lg{width:64px;height:64px;font-size:22px}
/* A face is a plate: it carries white type, so it keeps its colour in both
   themes and every one of these holds white above 4.5. */
.av.c0{background:#12499B}.av.c1{background:#0A6B4B}.av.c2{background:#D21030}.av.c3{background:#0C3676}.av.c4{background:#6B4A33}.av.c5{background:#3C4850}
.av .on{position:absolute;right:-1px;bottom:-1px;width:12px;height:12px;border-radius:50%;background:#19B56B;border:2.5px solid #fff}
.empty{padding:36px 20px;text-align:center;color:var(--mute);display:flex;flex-direction:column;align-items:center;gap:10px}
.empty h3{color:var(--ink)} .empty .art{width:120px;height:120px;color:var(--line2)}
.skel{border-radius:10px;background:linear-gradient(90deg,var(--soft2) 0%,#F6F8F7 45%,var(--soft2) 90%);background-size:200% 100%;animation:shim 1.2s linear infinite}
@keyframes shim{to{background-position:-200% 0}}
.meter{height:8px;border-radius:99px;background:var(--soft2);overflow:hidden}
.meter>i{display:block;height:100%;border-radius:99px;background:var(--green2);transform-origin:left;transition:width .6s var(--ease)}

/* ───────── road signs */
.sign{position:relative;border-radius:var(--r-sign);padding:20px;color:#fff;background:var(--red);
  box-shadow:inset 0 0 0 3px var(--red),inset 0 0 0 5px rgba(255,255,255,.92),0 14px 28px -20px var(--red2)}
.sign.blue{background:var(--blue);box-shadow:inset 0 0 0 3px var(--blue),inset 0 0 0 5px rgba(255,255,255,.92),0 14px 28px -20px var(--blue3)}
.sign.brown{background:var(--brown);box-shadow:inset 0 0 0 3px var(--brown),inset 0 0 0 5px rgba(255,255,255,.92),0 14px 28px -20px #3d2a1c}
.sign.red{background:var(--red);box-shadow:inset 0 0 0 3px var(--red),inset 0 0 0 5px rgba(255,255,255,.92),0 14px 28px -20px var(--red2)}
.sign.yellow{background:var(--yellow);color:var(--ink);box-shadow:inset 0 0 0 3px var(--yellow),inset 0 0 0 5px var(--ink),0 14px 28px -20px var(--yellow2)}
.sign .way{font-size:12.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;opacity:.92}
.sign .dest{font-size:clamp(24px,5.6vw,34px);font-weight:800;line-height:1.08;letter-spacing:-.01em;text-wrap:balance}
.exit-tab{position:absolute;right:22px;top:-25px;height:30px;padding:0 12px 0 13px;display:flex;align-items:center;gap:7px;border-radius:9px 9px 0 0;
  background:inherit;color:inherit;font-weight:800;font-size:13px;letter-spacing:.08em;
  box-shadow:inset 0 3px 0 var(--red),inset 3px 0 0 var(--red),inset -3px 0 0 var(--red),inset 0 5px 0 rgba(255,255,255,.92),inset 5px 0 0 rgba(255,255,255,.92),inset -5px 0 0 rgba(255,255,255,.92)}
.sign.blue .exit-tab{box-shadow:inset 0 3px 0 var(--blue),inset 3px 0 0 var(--blue),inset -3px 0 0 var(--blue),inset 0 5px 0 rgba(255,255,255,.92),inset 5px 0 0 rgba(255,255,255,.92),inset -5px 0 0 rgba(255,255,255,.92)}
.exit-tab b{font-size:17px;letter-spacing:0}
.has-tab{margin-top:25px}
.arrow-ne{width:44px;height:44px;flex:none}

/* small exit plaque used in lists */
.exit{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;width:46px;height:46px;border-radius:9px;flex:none;
  background:var(--red);color:#fff;box-shadow:inset 0 0 0 2px var(--red),inset 0 0 0 3.2px rgba(255,255,255,.9);line-height:1}
.exit small{font-size:8.5px;font-weight:800;letter-spacing:.1em;opacity:.9}
.exit b{font-size:19px;font-weight:800;margin-top:1px}
.exit.off{background:var(--soft2);color:var(--exit-off);box-shadow:inset 0 0 0 2px var(--soft2),inset 0 0 0 3.2px #fff}
.exit.done{background:var(--card);color:var(--green3);box-shadow:inset 0 0 0 2.5px var(--green3)}

/* interstate shield */
.shield{width:52px;height:52px;flex:none;position:relative;display:grid;place-items:center}
.shield svg{position:absolute;inset:0;width:100%;height:100%}
.shield b{position:relative;color:#fff;font-weight:900;font-size:22px;line-height:1;margin-top:9px;letter-spacing:-.02em}
.shield.sm{width:38px;height:38px}.shield.sm b{font-size:16px;margin-top:7px}
.shield.lg{width:76px;height:76px}.shield.lg b{font-size:33px;margin-top:14px}
.shield.off{filter:grayscale(1);opacity:.45}

/* ───────── split-flap */
.board{display:inline-flex;gap:14px;flex-wrap:wrap;padding:12px 14px;border-radius:12px;background:#2A3137;box-shadow:inset 0 0 0 1px #3B444B,inset 0 2px 8px rgba(0,0,0,.35)}
.board .col{display:flex;flex-direction:column;gap:6px}
.bcap{font-size:10.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:#9FAAB1}
.flaps{display:flex;gap:2.5px}
.flap{position:relative;width:1.06em;height:1.56em;font-size:24px;font-weight:800;color:var(--flap-ink);perspective:160px;font-variant-numeric:tabular-nums}
.flap.gap{width:.5em;visibility:hidden}
.flap>span{position:absolute;left:0;width:100%;height:50%;overflow:hidden;background:var(--flap);display:block;text-align:center;backface-visibility:hidden}
.flap>span>i{display:block;font-style:normal;height:1.56em;line-height:1.62em}
.flap .t,.flap .ft{top:0;border-radius:4px 4px 0 0;box-shadow:inset 0 -1px 0 rgba(0,0,0,.55)}
.flap .b,.flap .fb{bottom:0;border-radius:0 0 4px 4px;background:#20262B}
.flap .b>i,.flap .fb>i{transform:translateY(-50%)}
.flap .ft{transform-origin:50% 100%;z-index:2}
.flap .fb{transform-origin:50% 0;transform:rotateX(90deg);z-index:2}
.board.sm .flap{font-size:18px}

/* ───────── blueprint panel */
.bp{position:relative;overflow:hidden;border-radius:var(--r-sign);background:var(--blue);color:#fff;
  background-image:linear-gradient(rgba(255,255,255,.11) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.11) 1px,transparent 1px),
    linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:80px 80px,80px 80px,16px 16px,16px 16px;background-position:-1px -1px}
.bp svg.art{color:#fff}
.art .m{stroke-width:1.6} .art .c{stroke-width:.8;opacity:.6;stroke-dasharray:.012 .012}
.art.draw .m,.art.draw .c{stroke-dasharray:1;stroke-dashoffset:1;animation:draw 1.1s var(--ease) forwards;animation-delay:calc(var(--i,0)*28ms)}
.art.draw .c{animation-duration:.7s}
@keyframes draw{to{stroke-dashoffset:0}}
.bp .title-block{position:absolute;right:12px;bottom:12px;padding:6px 10px;border:1px solid rgba(255,255,255,.55);font-size:11.5px;font-weight:700;line-height:1.3;letter-spacing:.04em;text-align:left;background:rgba(18,73,155,.7)}
.bp .title-block span{display:block;font-weight:500;opacity:.8}

/* ───────── kinetic type */
.kin{display:inline-block}
.kin .w{display:inline-block;overflow:hidden;vertical-align:bottom;padding-bottom:.08em;margin-bottom:-.08em}
.kin .w>i{display:inline-block;font-style:normal;transform:translateY(105%) rotate(4deg);transform-origin:0 100%;animation:kin .7s var(--ease) forwards;animation-delay:calc(var(--i)*70ms + var(--d,0ms))}
@keyframes kin{to{transform:none}}
.rise{animation:rise .5s var(--ease) both;animation-delay:calc(var(--i,0)*45ms)}
@keyframes rise{from{opacity:0;transform:translateY(10px)}}
.pop{animation:pop .45s var(--spring) both}
@keyframes pop{from{opacity:0;transform:scale(.9)}}
.shake{animation:shake .4s}
@keyframes shake{20%{transform:translateX(-6px)}40%{transform:translateX(5px)}60%{transform:translateX(-3px)}80%{transform:translateX(2px)}}

/* ───────── overlays */
.scrim{position:fixed;inset:0;z-index:80;background:rgba(20,24,27,.42);opacity:0;transition:opacity .25s;display:flex;align-items:flex-end;justify-content:center}
.scrim.in{opacity:1}
.sheet{width:100%;max-width:560px;max-height:calc(100dvh - 24px - var(--sat));background:var(--card);border-radius:20px 20px 0 0;display:flex;flex-direction:column;
  transform:translateY(100%);transition:transform .38s var(--ease);box-shadow:var(--shadow-up);padding-bottom:var(--sab)}
.scrim.in .sheet{transform:none}
.sheet-head{display:flex;align-items:center;gap:10px;padding:16px 18px 8px}
.sheet-head h2{flex:1;min-width:0}
.sheet-body{padding:8px 18px 20px;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.sheet-foot{padding:12px 18px 16px;border-top:1px solid var(--line);display:flex;gap:10px}
.sheet-foot .btn{flex:1}
@media (min-width:720px){.scrim{align-items:center}.sheet{border-radius:18px;transform:translateY(16px) scale(.98);opacity:0;transition:transform .28s var(--ease),opacity .2s;max-height:min(760px,calc(100dvh - 48px))}.scrim.in .sheet{opacity:1}.sheet.wide{max-width:760px}}
.toasts{position:fixed;left:50%;bottom:calc(var(--tab) + var(--sab) + 14px);z-index:95;transform:translateX(-50%);display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none;width:max-content;max-width:calc(100vw - 24px)}
.toast{display:flex;align-items:center;gap:9px;padding:11px 15px;border-radius:11px;background:var(--ink);color:var(--paper);font-weight:600;font-size:14.5px;box-shadow:var(--shadow-up);animation:toast .35s var(--spring) both}
.toast.out{animation:toastout .25s var(--ease-in) forwards}
.toast.bad{background:var(--red)} .toast .ic{width:18px;height:18px}
@keyframes toast{from{opacity:0;transform:translateY(14px) scale(.96)}} @keyframes toastout{to{opacity:0;transform:translateY(8px)}}
@media (min-width:900px){.toasts{bottom:24px}}
.banner{position:fixed;z-index:90;left:50%;top:calc(var(--sat) + 10px);width:min(440px,calc(100vw - 20px));transform:translate(-50%,-140%);transition:transform .45s var(--spring);
  background:var(--card);border-radius:14px;box-shadow:var(--shadow-up);border:1px solid var(--line);padding:12px 14px;display:flex;gap:12px;align-items:flex-start;text-align:left}
.banner.in{transform:translate(-50%,0)}
.banner .bi{width:40px;height:40px;border-radius:10px;display:grid;place-items:center;flex:none;background:var(--red);color:#fff}
.banner.pay .bi{background:var(--yellow);color:var(--ink)} .banner.lesson .bi{background:var(--green)} .banner.info .bi{background:var(--blue)}
.banner .t{font-weight:800;line-height:1.25} .banner .s{font-size:13.5px;color:var(--ink2);line-height:1.35;margin-top:2px}
.fxlayer{position:fixed;inset:0;z-index:99;pointer-events:none}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;transition-duration:.01ms!important}
  .kin .w>i{transform:none}
}

/* ───── DARK ───── */

/* ─────────────────────────────────────────────────────────────────────────
   Dark. The paper goes to asphalt and the ink comes up out of it.

   A sign is a sign at night too: the green guide sign, the blue banner, the
   red shield and the yellow warning keep their colours and their white type.
   What inverts is the ink — the "3" and "2" variants, which were the darkest
   end on paper and become the lightest end here.
   ───────────────────────────────────────────────────────────────────────── */
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:#0E1113; --card:#171B1E; --ink:#E8EDEE; --ink2:#BFC9CD; --mute:#94A1A7; --faint:#7F8C94;
  --line:#272E32; --line2:#384247; --exit-off:#9AA7AE; --soft:#1B2124; --soft2:#222A2E;

  /* plates keep their hue, lifted just enough to sit on asphalt;
     the ink variants invert */
  --green:#0C7A56; --green2:#109A6E; --green3:#5FD6A6; --green-t:#0C2820;
  --blue:#1A5CBD; --blue2:#7FB2FF; --blue3:#A8CBFF; --blue-t:#122236;
  --red:#C8102E; --red2:#FF7083; --red-t:#2B1217;
  --yellow:#FFC629; --yellow2:#FFD970; --yellow-t:#2C2412; --yellow-ink:#FFE4A3;
  --orange:#E8611A; --orange-t:#2C1810;
  --brown:#8A6448; --brown-t:#241C16;
  --flap:#07090A; --flap-ink:#F7F3E3;

  --shadow:0 1px 0 rgba(0,0,0,.5), 0 10px 26px -18px rgba(0,0,0,.9);
  --shadow-up:0 20px 54px -20px rgba(0,0,0,.95), 0 2px 8px rgba(0,0,0,.6);
}

/* a card lifts off asphalt by light, not by shadow */
:root[data-theme="dark"] .card,:root[data-theme="dark"] .panel,:root[data-theme="dark"] .sheet,
:root[data-theme="dark"] .q-card,:root[data-theme="dark"] .stage-card,:root[data-theme="dark"] .pass,
:root[data-theme="dark"] .tgprev,:root[data-theme="dark"] .notice{
  box-shadow:var(--shadow),inset 0 1px 0 rgba(255,255,255,.05);
}

/* ── the sixteen surfaces that were written as fixed light values ── */
:root[data-theme="dark"] .btn.white:hover{background:#1F2528}
:root[data-theme="dark"] button.li:hover,:root[data-theme="dark"] a.li:hover{background:#1F2528}
:root[data-theme="dark"] .skel{background:#1E2427}
:root[data-theme="dark"] .notice{background:#2C2412;border-color:#4A3D1C}
:root[data-theme="dark"] .notice.bad{background:#2E141A;border-color:#5A2630}
:root[data-theme="dark"] .scene{background:#16202C}
:root[data-theme="dark"] .tf .li.right{background:#0E2A20}
:root[data-theme="dark"] .tf .li.wrong{background:#2E141A}
:root[data-theme="dark"] .chip.in{background:#28435F}
:root[data-theme="dark"] .bitem.right,:root[data-theme="dark"] .sitem.right{background:#0E2A20}
:root[data-theme="dark"] .bitem.wrong,:root[data-theme="dark"] .sitem.wrong{background:#2E141A}
:root[data-theme="dark"] .btn.stopish{background:#4A2028}
:root[data-theme="dark"] .tg-convo{background:#12171A}
:root[data-theme="dark"] .bubble.mine{background:#123B2C}
:root[data-theme="dark"] .trow.sel{background:#102A20}
:root[data-theme="dark"] .tgprev{background:#1A232C}

/* glass bars: a white glass over asphalt is still white, so they are rebuilt dark */
:root[data-theme="dark"] .topbar{background:rgba(14,17,19,.9)}
:root[data-theme="dark"] .tabbar{background:rgba(14,17,19,.94)}
:root[data-theme="dark"] .tg-quick{background:rgba(23,27,30,.8)}

/* the page's own paper texture */
:root[data-theme="dark"] ::selection{background:var(--red);color:#fff}
:root[data-theme="dark"] img:not([src*=".svg"]){filter:brightness(.92)}

/* and the same again for anyone who has never touched the switch */
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
  color-scheme:dark;
  --paper:#0E1113; --card:#171B1E; --ink:#E8EDEE; --ink2:#BFC9CD; --mute:#94A1A7; --faint:#7F8C94;
  --line:#272E32; --line2:#384247; --exit-off:#9AA7AE; --soft:#1B2124; --soft2:#222A2E;

  /* plates keep their hue, lifted just enough to sit on asphalt;
     the ink variants invert */
  --green:#0C7A56; --green2:#109A6E; --green3:#5FD6A6; --green-t:#0C2820;
  --blue:#1A5CBD; --blue2:#7FB2FF; --blue3:#A8CBFF; --blue-t:#122236;
  --red:#C8102E; --red2:#FF7083; --red-t:#2B1217;
  --yellow:#FFC629; --yellow2:#FFD970; --yellow-t:#2C2412; --yellow-ink:#FFE4A3;
  --orange:#E8611A; --orange-t:#2C1810;
  --brown:#8A6448; --brown-t:#241C16;
  --flap:#07090A; --flap-ink:#F7F3E3;

  --shadow:0 1px 0 rgba(0,0,0,.5), 0 10px 26px -18px rgba(0,0,0,.9);
  --shadow-up:0 20px 54px -20px rgba(0,0,0,.95), 0 2px 8px rgba(0,0,0,.6);
}

/* a card lifts off asphalt by light, not by shadow */
:root:not([data-theme="light"]) .card,:root:not([data-theme="light"]) .panel,:root:not([data-theme="light"]) .sheet,
:root:not([data-theme="light"]) .q-card,:root:not([data-theme="light"]) .stage-card,:root:not([data-theme="light"]) .pass,
:root:not([data-theme="light"]) .tgprev,:root:not([data-theme="light"]) .notice{
  box-shadow:var(--shadow),inset 0 1px 0 rgba(255,255,255,.05);
}

/* ── the sixteen surfaces that were written as fixed light values ── */
:root:not([data-theme="light"]) .btn.white:hover{background:#1F2528}
:root:not([data-theme="light"]) button.li:hover,:root:not([data-theme="light"]) a.li:hover{background:#1F2528}
:root:not([data-theme="light"]) .skel{background:#1E2427}
:root:not([data-theme="light"]) .notice{background:#2C2412;border-color:#4A3D1C}
:root:not([data-theme="light"]) .notice.bad{background:#2E141A;border-color:#5A2630}
:root:not([data-theme="light"]) .scene{background:#16202C}
:root:not([data-theme="light"]) .tf .li.right{background:#0E2A20}
:root:not([data-theme="light"]) .tf .li.wrong{background:#2E141A}
:root:not([data-theme="light"]) .chip.in{background:#28435F}
:root:not([data-theme="light"]) .bitem.right,:root:not([data-theme="light"]) .sitem.right{background:#0E2A20}
:root:not([data-theme="light"]) .bitem.wrong,:root:not([data-theme="light"]) .sitem.wrong{background:#2E141A}
:root:not([data-theme="light"]) .btn.stopish{background:#4A2028}
:root:not([data-theme="light"]) .tg-convo{background:#12171A}
:root:not([data-theme="light"]) .bubble.mine{background:#123B2C}
:root:not([data-theme="light"]) .trow.sel{background:#102A20}
:root:not([data-theme="light"]) .tgprev{background:#1A232C}

/* glass bars: a white glass over asphalt is still white, so they are rebuilt dark */
:root:not([data-theme="light"]) .topbar{background:rgba(14,17,19,.9)}
:root:not([data-theme="light"]) .tabbar{background:rgba(14,17,19,.94)}
:root:not([data-theme="light"]) .tg-quick{background:rgba(23,27,30,.8)}

/* the page's own paper texture */
:root:not([data-theme="light"]) ::selection{background:var(--red);color:#fff}
:root:not([data-theme="light"]) img:not([src*=".svg"]){filter:brightness(.92)}

}
/* ───────── shell */
.topbar{position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:14px;height:calc(var(--top) + var(--sat));padding:var(--sat) max(16px,env(safe-area-inset-right)) 0 max(16px,env(safe-area-inset-left));
  background:var(--card);border-bottom:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:10px;color:var(--ink);font-weight:800;font-size:17px;letter-spacing:-.01em;cursor:pointer}
.brand svg{width:34px;height:34px;border-radius:9px}
.role-tag{font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:3px 7px;border-radius:5px;background:var(--red);color:#fff}
.role-tag.teacher{background:var(--blue)} .role-tag.admin{background:var(--red)}
.nav{display:none;gap:4px;margin-left:10px;flex:1}
.nav a{position:relative;display:flex;align-items:center;gap:7px;height:var(--top);padding:0 12px;color:var(--mute);font-weight:700;font-size:14.5px;cursor:pointer;transition:color .15s}
.nav a::after{content:"";position:absolute;left:12px;right:12px;bottom:0;height:4px;border-radius:4px 4px 0 0;background:var(--red);transform:scaleX(0);transition:transform .3s var(--ease)}
.nav a.on{color:var(--ink)} .nav a.on::after{transform:none}
@media (hover:hover){.nav a:hover{color:var(--ink)}}
.top-r{margin-left:auto;display:flex;align-items:center;gap:2px}
.bell{position:relative}
.dot{position:absolute;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--red);color:#fff;font-size:11px;font-weight:800;font-style:normal;display:grid;place-items:center;line-height:1;box-shadow:0 0 0 2px #fff}
.bell .dot{right:3px;top:3px} .nav a .dot{position:static;margin-left:2px;box-shadow:none}
.me-btn{margin-left:6px;border-radius:50%}
#main{display:block;outline:0;padding-bottom:calc(var(--tab) + var(--sab) + 28px)}
#main.enter>.page{animation:rise .35s var(--ease) both}
.page{max-width:1080px;margin:0 auto;padding:22px max(16px,env(safe-area-inset-right)) 0 max(16px,env(safe-area-inset-left))}
.page.narrow{max-width:640px}
.lead{margin:6px 0 20px;max-width:62ch}
.center-page{min-height:100dvh;display:grid;place-items:center;padding:24px 16px}
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:40;display:flex;height:calc(var(--tab) + var(--sab));padding:0 6px var(--sab);background:var(--card);border-top:1px solid var(--line)}
.tabbar a{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;color:var(--mute);font-size:11.5px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}
.tabbar .ti{position:relative;width:54px;height:30px;border-radius:15px;display:grid;place-items:center;transition:background .25s var(--ease),color .2s,transform .2s var(--spring)}
.tabbar a.on{color:var(--red2)} .tabbar a.on .ti{background:var(--red-t);color:var(--red)}
.tabbar a:active .ti{transform:scale(.9)}
.tabbar .dot{right:4px;top:-3px}
body[data-tab="lesson"] .tabbar,body[data-tab="study"] .tabbar,body[data-tab="teach"] .tabbar,body[data-tab="teach"] .topbar{display:none}
body[data-tab="lesson"] #main,body[data-tab="study"] #main{padding-bottom:40px}
body[data-tab="teach"] #main{padding:0}
@media (min-width:900px){
  .nav{display:flex} .tabbar{display:none} #main{padding-bottom:60px} .page{padding-top:30px}
  .toasts{bottom:24px}
}
@media (max-width:899px){.brand .bw{display:none} .hide-s{display:none!important}}

/* ───────── sign-in */
.auth{min-height:100dvh;display:grid;grid-template-rows:minmax(250px,40dvh) 1fr;background:var(--card)}
.auth-art{border-radius:0;display:flex;align-items:flex-end;padding:22px 20px 20px;padding-top:calc(var(--sat) + 22px)}
canvas.torch{position:absolute;inset:0;width:100%;height:100%}
.auth-copy{position:relative;max-width:58%}
.auth-h{font-size:clamp(30px,6.4vw,56px);font-weight:900;line-height:1;letter-spacing:-.02em;text-wrap:balance}
.auth-copy p{margin-top:10px;font-weight:500;opacity:.9;max-width:34ch;line-height:1.4}
.auth-art .title-block{display:none}
.auth-form{display:flex;justify-content:center;padding:26px 20px calc(30px + var(--sab))}
.auth-box{width:100%;max-width:400px}
.auth-brand{display:flex;align-items:center;gap:12px;margin-bottom:22px}
.auth-brand svg{width:46px;height:46px;border-radius:12px}
.auth-brand b{display:block;font-size:19px;font-weight:800;line-height:1.1} .auth-brand span{font-size:13px;color:var(--mute);font-weight:600}
.auth-box .foot,.blocked .foot{margin-top:22px;text-align:center}
@media (min-width:900px){
  .auth{grid-template-rows:none;grid-template-columns:minmax(0,1.15fr) minmax(420px,.85fr)}
  .auth-art{padding:48px} .auth-copy{max-width:46%} .auth-art .title-block{display:block;bottom:48px;right:48px}
  .auth-form{align-items:center;padding:48px}
}
.blocked{width:100%;max-width:460px;display:flex;flex-direction:column;gap:14px}
.blocked .sign p{margin-top:10px;font-weight:500;opacity:.95}

/* account card */
.idcard{border-radius:16px;background:var(--card);border:1px solid var(--line);overflow:hidden;box-shadow:var(--shadow)}
.id-top{display:flex;justify-content:space-between;gap:10px;padding:9px 16px;background:var(--blue);color:#fff;font-size:11.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.id-main{display:flex;align-items:center;gap:14px;padding:18px 16px}
.id-name{font-size:21px;font-weight:800;line-height:1.15} .id-sub{font-size:13.5px;color:var(--mute);margin-top:2px}
.id-stats{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--line)}
.id-stats div{padding:12px 8px;text-align:center} .id-stats div+div{border-left:1px solid var(--line)}
.id-stats b{display:block;font-size:22px;font-weight:800;line-height:1.1} .id-stats span{font-size:12px;color:var(--mute);font-weight:600}
.id-strip{padding:9px 16px;background:var(--soft);border-top:1px solid var(--line);font-size:12.5px;font-weight:600;letter-spacing:.14em;color:var(--mute);white-space:nowrap;overflow:hidden}
.li.notif .ni{width:38px;height:38px;border-radius:10px;display:grid;place-items:center;flex:none;background:var(--blue);color:#fff}
.ni.call{background:var(--red)} .ni.pay{background:var(--yellow);color:var(--ink)} .ni.lesson{background:var(--green)}
.li.notif.read{opacity:.62}

/* ───────── student home */
.hello{margin-bottom:18px} .hello .date{font-size:13.5px;font-weight:700;color:var(--mute);margin-bottom:4px}
.notice{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:var(--r);background:var(--yellow-t);border:1px solid #F1DC96;color:var(--yellow-ink);margin-bottom:14px}
.notice.bad{background:var(--red-t);border-color:#F0BFC6;color:var(--red2)}
.notice .diamond{width:38px;height:38px;flex:none;display:grid;place-items:center;background:var(--yellow);color:var(--ink);border-radius:7px;transform:rotate(45deg);box-shadow:inset 0 0 0 2px var(--yellow),inset 0 0 0 3.2px var(--ink)}
.notice .diamond .ic{transform:rotate(-45deg);width:18px;height:18px}
.notice.bad .diamond{background:var(--red);color:#fff;box-shadow:inset 0 0 0 2px var(--red),inset 0 0 0 3.2px #fff}
.notice .small{color:inherit;opacity:.9}
.home-grid{display:grid;gap:16px;align-items:start}
@media (min-width:900px){.home-grid{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr)}}
.next-sign{display:flex;flex-direction:column;gap:16px;cursor:pointer;transition:transform .2s var(--ease)}
.next-sign:active{transform:scale(.985)}
.next-sign .row.rtop{align-items:flex-start}
.sm-note{font-size:13.5px;font-weight:600;opacity:.92}
.lane{display:flex;gap:6px} .lane i{flex:1;height:8px;border-radius:2px;background:rgba(255,255,255,.28)}
.lane i.on{background:#fff;animation:lanein .5s var(--ease) both;animation-delay:calc(var(--i)*60ms + .25s)}
@keyframes lanein{from{transform:scaleX(0);transform-origin:left}}
.board-wrap{background:var(--card);border:1px solid var(--line);border-radius:var(--r-sign);padding:16px;display:flex;flex-direction:column;gap:12px}
.board-wrap .board{align-self:flex-start;max-width:100%}
a.li,a.rname{color:var(--ink)}
.bw-head h3{flex:1}
.bw-teacher{padding-top:12px;border-top:1px solid var(--line)}
.road{overflow-x:auto;scrollbar-width:none;margin:0 -16px;padding:4px 16px 8px;scroll-snap-type:x proximity}
.road::-webkit-scrollbar{display:none}
.road-in{display:flex;gap:0;position:relative;width:max-content;padding-top:8px}
.road-in::before{content:"";position:absolute;z-index:0;left:0;right:0;top:25px;height:14px;background:#3B444B;border-radius:7px}
.road-in::after{content:"";position:absolute;z-index:0;left:10px;right:10px;top:31px;height:2px;
  background:repeating-linear-gradient(90deg,#FFC629 0 14px,transparent 14px 26px);
  background-size:26px 2px;animation:roadrun 1.1s linear infinite}
/* The dashes run the way the student is travelling, so the road reads as a
   road rather than a drawn line. It is the background that moves, not the
   element, so nothing reflows and the stops stay where they are. */
@keyframes roadrun{from{background-position:0 0}to{background-position:-26px 0}}
@media (prefers-reduced-motion:reduce){.road-in::after{animation:none}}
.rstop{position:relative;z-index:1;width:104px;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;scroll-snap-align:center;cursor:pointer;color:var(--ink)}
.rstop .st{font-size:12px;font-weight:700;line-height:1.25;padding:0 6px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.rstop.off{cursor:default} .rstop.off .st{color:var(--faint)}
.rstop .exit{transition:transform .25s var(--spring)}
.rstop.cur .exit{transform:scale(1.14);box-shadow:inset 0 0 0 2px var(--red),inset 0 0 0 3.2px rgba(255,255,255,.9),0 0 0 4px var(--paper),0 0 0 6px var(--red)}
@media (hover:hover){a.rstop:hover .exit{transform:scale(1.1)}}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.stat{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:14px 12px;color:var(--ink)}
.stat b{display:block;font-size:clamp(24px,6vw,32px);font-weight:800;line-height:1.05;letter-spacing:-.01em} .stat span{font-size:12.5px;font-weight:600;color:var(--mute);line-height:1.25;display:block;margin-top:3px}
.stat.tap{cursor:pointer}

/* ───────── lessons */
.stage-hero,.mat-hero{min-height:210px;display:flex;align-items:flex-end;padding:18px;margin-bottom:16px}
.sh-art{position:absolute;right:-6px;top:6px;bottom:6px;width:min(52%,260px)} .sh-art svg{width:100%;height:100%}
.sh-text{position:relative;display:flex;align-items:center;gap:14px} .sh-text h1,.sh-text h2{color:#fff} .sh-text p{font-weight:600;opacity:.9;font-size:14px}
@media (max-width:639px){.stage-hero,.mat-hero{min-height:236px}.sh-art{width:46%;right:2px}.sh-text{flex-direction:column;align-items:flex-start;gap:10px;max-width:54%}.sh-text .shield.lg{width:60px;height:60px}.sh-text .shield.lg b{font-size:26px;margin-top:11px}}
.bp-back{position:absolute;left:12px;top:12px;background:rgba(255,255,255,.14);color:#fff;box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.5)}
.stage-hero .title-block,.mat-hero .title-block{display:none}
@media (min-width:640px){.stage-hero .title-block,.mat-hero .title-block{display:block;right:auto;left:18px;top:60px;bottom:auto}.mat-hero .title-block{top:18px}.sh-art{right:24px;width:260px}}
.lessons .li{padding:12px 14px} .li.locked{color:var(--faint)} .li.locked .t{color:var(--mute)}
.stage-list{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
.stage-card{display:flex;flex-direction:column;background:var(--card);border:1px solid var(--line);border-radius:var(--r-sign);overflow:hidden;color:var(--ink);cursor:pointer;transition:transform .2s var(--ease),border-color .2s}
.stage-card:active{transform:scale(.98)}
@media (hover:hover){.stage-card:hover{transform:translateY(-2px);border-color:var(--line2)}}
.sc-art{height:150px;border-radius:0;display:grid;place-items:center} .sc-art svg{height:136px;width:136px}
.stage-card.ahead .sc-art{background-color:#7C8A93}
.sc-body{display:flex;align-items:center;gap:12px;padding:12px 14px}
.sc-body .t{font-weight:800;font-size:17px;line-height:1.2} .sc-body .s{font-size:13px;color:var(--mute)}
.stage-card .meter{border-radius:0;height:5px}

/* ───────── lesson book */
.lesson{max-width:820px}
.l-head{display:flex;align-items:center;gap:12px;margin-bottom:16px}
.l-head h1{font-size:clamp(20px,4.6vw,28px)} .l-kicker{font-size:12.5px;font-weight:700;color:var(--mute)}
.l-pct{text-align:right;line-height:1.1} .l-pct b{display:block;font-size:20px;font-weight:800;color:var(--green)} .l-pct span{font-size:12px;color:var(--mute);font-weight:700}
.ptabs{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;margin:0 -16px 18px;padding:2px 16px;position:sticky;top:0;z-index:20;background:linear-gradient(var(--paper) 78%,transparent)}
.ptabs::-webkit-scrollbar{display:none}
.ptabs a{display:flex;align-items:center;gap:7px;height:42px;padding:0 14px;border-radius:10px;background:var(--card);box-shadow:inset 0 0 0 1px var(--line);color:var(--ink2);font-weight:700;font-size:14px;white-space:nowrap;cursor:pointer;transition:background .2s,color .2s,transform .15s}
.ptabs a:active{transform:scale(.96)}
.ptabs a.done .ic{color:var(--green3)}
.ptabs a[aria-selected="true"]{background:var(--ink);color:var(--paper);box-shadow:none} .ptabs a[aria-selected="true"] .ic{color:var(--paper)}
.part{display:block;min-height:40dvh}
.result{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:16px;border-radius:var(--r-sign);background:var(--card);border:1.5px solid var(--line2);margin-top:14px}
.result.good{background:var(--green-t);border-color:#A9D9C4}
.r-score{display:flex;align-items:baseline;gap:4px} .r-score b{font-size:44px;font-weight:900;line-height:1;letter-spacing:-.02em} .r-score span{font-weight:700;color:var(--mute)}
.r-word{font-weight:800;font-size:18px} .r-act{display:flex;gap:8px;margin-left:auto}
/* on a phone the score, the words and two buttons will not share a line: the
   middle column was squeezed to four words wide */
@media (max-width:460px){
  .result>.grow{flex:1 1 100%;order:2}
  .r-act{flex:1 1 100%;order:3;margin-left:0}
  .r-act .btn{flex:1}
}
.done-sheet{display:flex;flex-direction:column;gap:14px;padding-top:26px}
.done-score{margin-top:14px;display:flex;align-items:baseline;gap:10px} .done-score b{font-size:54px;font-weight:900;line-height:1} .done-score span{font-weight:600;opacity:.9}
/* story */
.scene{position:relative;border-radius:var(--r-sign);overflow:hidden;background:#DCE6F0;aspect-ratio:16/9;min-height:180px;border:1px solid var(--line)}
.scene-art{position:absolute;inset:0;cursor:pointer} .scene-art svg{width:100%;height:100%;display:block}
.vsvg *{transform-box:fill-box}
.vsvg .mv{animation:vmv var(--d,2s) var(--e,ease-in-out) var(--t,0s) both}.vsvg .fi{animation:vfi var(--d,.6s) ease var(--t,0s) both}.vsvg .fo{animation:vfo var(--d,.6s) ease var(--t,0s) both}
.vsvg .pp{transform-origin:center;animation:vpp7 .62s linear var(--t,0s) both}.vsvg .shake{transform-origin:center;animation:vshk .1s linear var(--t,0s) var(--n,12) alternate}
.vsvg .jig{animation:vjig .5s ease-in-out infinite alternate;animation-delay:var(--t,0s)}.vsvg .bob{animation:vbob var(--d,.4s) ease-in-out infinite alternate}
.vsvg .spin{transform-box:view-box;transform-origin:0 0;animation:vspin var(--d,2s) linear infinite}.vsvg .draw{stroke-dasharray:var(--len,800);animation:vdraw var(--d,3s) linear var(--t,0s) both}
.vsvg .fall{animation:vfall .7s linear infinite;animation-delay:var(--t,0s)}.vsvg .flash{animation:vflash .9s ease var(--t,0s) both}.vsvg .puff{transform-origin:center;animation:vpuff 1.4s ease-out infinite;animation-delay:var(--t,0s)}
.vsvg .dash{stroke-dasharray:18 14;animation:vdash .8s linear infinite}.vsvg .flo{animation:vflo 2.1s ease-out infinite;animation-delay:var(--t,0s)}
@keyframes vdraw{from{stroke-dashoffset:var(--len,800)}to{stroke-dashoffset:0}}@keyframes vdash{to{stroke-dashoffset:-32}}@keyframes vshk{from{transform:rotate(-12deg)}to{transform:rotate(12deg)}}
@keyframes vpp7{0%{opacity:0;transform:scale(.3)}40%{opacity:1;transform:scale(1.12)}62%{transform:scale(.95)}80%{transform:scale(1.03)}100%{opacity:1;transform:scale(1)}}
@keyframes vfi{from{opacity:0}to{opacity:1}}@keyframes vspin{to{transform:rotate(360deg)}}@keyframes vflo{from{transform:translate(0,0);opacity:0}30%{opacity:1}to{transform:translate(24px,-70px);opacity:0}}
@keyframes vpuff{from{transform:translate(0,0) scale(.4);opacity:.9}to{transform:translate(-40px,-50px) scale(1.6);opacity:0}}@keyframes vmv{from{transform:translate(var(--x0,0px),var(--y0,0px))}to{transform:translate(var(--x1,0px),var(--y1,0px))}}
@keyframes vfall{from{transform:translate(0,-60px);opacity:0}20%{opacity:1}to{transform:translate(-12px,140px);opacity:.2}}@keyframes vflash{0%,100%{opacity:0}15%{opacity:.85}30%{opacity:.1}45%{opacity:.6}}
@keyframes vfo{from{opacity:1}to{opacity:0}}@keyframes vjig{to{transform:translateY(-2px)}}@keyframes vbob{to{transform:translateY(-4px)}}
.scene-tag{position:absolute;left:12px;top:12px;padding:4px 9px;border-radius:6px;background:rgba(20,24,27,.82);color:#fff;font-size:11.5px;font-weight:800;letter-spacing:.08em}
.scene-badge{position:absolute;right:12px;top:12px;padding:6px 10px;border-radius:9px;background:var(--yellow);color:var(--ink);box-shadow:inset 0 0 0 2px var(--yellow),inset 0 0 0 3px var(--ink);line-height:1.15;animation:pop .45s var(--spring) .25s both;max-width:60%}
.scene-badge small{display:block;font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase} .scene-badge b{font-size:15px;font-weight:800}
.scene-bar{position:absolute;left:0;right:0;bottom:0;height:5px;background:rgba(20,24,27,.18)} .scene-bar i{display:block;height:100%;background:var(--red);transition:width .4s var(--ease)}
.cap{font-size:clamp(17px,3.6vw,21px);line-height:1.4;font-weight:500;margin:14px 2px;min-height:3.2em;text-wrap:pretty}
.cap b{font-weight:800;background:var(--hl-bg);background-repeat:var(--hl-rep);background-size:var(--hl-size);background-position:var(--hl-pos)}
.story-ctl{display:flex;align-items:center;gap:10px}
.q-start{margin-top:16px}
.quizwrap{display:flex;flex-direction:column;gap:14px;max-width:620px;margin:0 auto}
.q-prog{display:flex;align-items:center;gap:12px} .q-prog .meter{flex:1}
.q-card h2{font-size:clamp(22px,5vw,28px);margin:2px 0 6px} .q-ctx{font-size:15.5px;color:var(--ink2);margin-bottom:10px;padding:10px 12px;border-radius:10px;background:var(--soft)} .q-ctx b{font-weight:800}
.opts{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.opt{display:flex;align-items:center;gap:10px;min-height:54px;padding:10px 14px;border-radius:11px;background:var(--card);box-shadow:inset 0 0 0 1.5px var(--line2);text-align:left;font-weight:600;line-height:1.3;transition:transform .15s,box-shadow .15s,background .15s}
.opt small{display:block;font-weight:500;color:var(--mute);font-size:13px}
.opt:active{transform:scale(.985)} @media (hover:hover){.opt:not([disabled]):hover{box-shadow:inset 0 0 0 1.5px var(--ink2)}}
.opt.right{background:var(--green-t);box-shadow:inset 0 0 0 2px var(--green2);color:var(--green3)} .opt.wrong{background:var(--red-t);box-shadow:inset 0 0 0 2px var(--red);color:var(--red2);animation:shake .4s} .opt.dim{opacity:.5}
/* words */
.w-actions{margin-bottom:6px} .w-h{font-size:18px;margin:26px 0 12px}
.wgrid{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
.wtile{display:flex;flex-direction:column;gap:3px;padding:12px 14px;border-radius:var(--r);background:var(--card);box-shadow:inset 0 0 0 1px var(--line);text-align:left;animation:rise .45s var(--ease) both;animation-delay:calc(var(--i)*30ms);transition:box-shadow .2s;-webkit-user-select:text;user-select:text}
.wtile.open{box-shadow:inset 0 0 0 2px var(--green)}
.w-top{display:flex;align-items:center;gap:10px;font-size:16.5px;line-height:1.25} .w-top b{font-weight:800}
.w-n{font-size:12px;font-weight:800;color:var(--faint);min-width:22px}
.w-sig{font-size:12.5px;font-weight:700;color:var(--mute)} .w-sig.v{color:var(--blue2)} .w-sig.a{color:var(--orange)} .w-sig.n,.w-sig.u{color:var(--green2)}
.w-say{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;color:var(--blue2);background:var(--blue-t);flex:none;cursor:pointer}
.w-pron{font-size:13px;color:var(--mute);font-weight:600;letter-spacing:.01em;padding-left:32px}
.w-more{display:none;flex-direction:column;gap:3px;padding:6px 0 0 32px} .wtile.open .w-more{display:flex;animation:rise .3s var(--ease) both}
.w-tr{font-weight:800;color:var(--green3)} .w-mean{font-size:14.5px} .w-ex{font-size:14px;color:var(--ink2);font-style:italic}
.wgrid.tight .w-more{padding-left:0}
.li.say .quo{font-size:34px;font-weight:900;line-height:.8;color:var(--red);align-self:flex-start;margin-top:6px} .li .exm{font-style:italic}
.idioms{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.idiom{overflow:hidden;display:flex;flex-direction:column} .idi-pic svg{width:100%;height:auto;display:block} .idi-b{padding:12px 14px;display:flex;flex-direction:column;gap:6px}
.reveal{display:flex;align-items:center;gap:7px;padding:9px 11px;border-radius:9px;background:var(--soft);font-weight:700;font-size:13.5px;color:var(--ink2);text-align:left}
.idi-m b{display:block} .idi-m p{font-size:14px;font-style:italic;color:var(--ink2);margin-top:4px}
.rs-t{font-size:17px;line-height:1.75;margin-top:8px} .rs-t b{color:var(--red);font-weight:800;border-bottom:2px dotted var(--red);cursor:pointer;border-radius:3px} .rs-t b.on{background:var(--red-t)}
.rs-why{margin-top:10px;padding:10px 12px;border-radius:10px;background:var(--yellow-t);font-size:14.5px} .rs details{margin-top:12px;font-size:14.5px;color:var(--ink2)} .rs summary{cursor:pointer;font-weight:700}
/* reading */
.rd{max-width:66ch} .rd h2{font-size:24px;margin:2px 0 12px} .rd-k{font-size:12.5px;font-weight:800;color:var(--red);letter-spacing:.04em}
.rd p+p{margin-top:12px} .rd p{font-size:17px;line-height:1.62} .rd p b{font-weight:700;background:var(--hl-bg);background-repeat:var(--hl-rep);background-size:var(--hl-size);background-position:var(--hl-pos)}
.tf .li{align-items:center;flex-wrap:wrap} .tf .li.right{background:#F3FAF7} .tf .li.wrong{background:#FDF4F5}
.tfb{display:flex;gap:6px;margin-left:auto} .tfb button{height:38px;padding:0 14px;border-radius:9px;font-weight:700;font-size:14px;background:var(--card);box-shadow:inset 0 0 0 1.5px var(--line2);transition:.15s}
.tfb button.on{background:var(--ink);color:var(--paper);box-shadow:none} .tf .right .tfb button.on{background:var(--green)} .tf .wrong .tfb button.on{background:var(--red)}
.reading>.btn{margin-top:14px}
/* practice */
.practice,.writing{display:flex;flex-direction:column;gap:16px}
.ex{padding:16px;display:flex;flex-direction:column;gap:14px;scroll-margin-top:60px}
.ex-head{display:flex;align-items:flex-start;gap:12px}
.ex-l{width:34px;height:34px;border-radius:8px;display:grid;place-items:center;background:var(--ink);color:var(--paper);font-weight:800;flex:none}
.ex>.btn{align-self:flex-start}
.ex-res{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:11px;background:var(--soft);font-weight:600;animation:pop .4s var(--spring) both} .ex-res b{font-size:22px;font-weight:900} .ex-res.good{background:var(--green-t);color:var(--green3)}
.bank,.pool,.built,.chips,.wchips{display:flex;flex-wrap:wrap;gap:7px}
.chip{min-height:38px;padding:0 12px;border-radius:9px;background:var(--card);box-shadow:inset 0 0 0 1.5px var(--line2);font-weight:700;font-size:15px;transition:transform .15s var(--spring),opacity .2s,background .15s}
.chip:active{transform:scale(.93)} .chip.used{opacity:.28} .chip.in{background:var(--blue-t);box-shadow:inset 0 0 0 1.5px #B9CCEB;color:var(--blue3);animation:pop .25s var(--spring)}
.gtext{font-size:17.5px;line-height:2.3}
.gap{display:inline-block;min-width:74px;height:36px;padding:0 10px;margin:0 2px;border-radius:8px;background:var(--soft);box-shadow:inset 0 -2.5px 0 var(--line2);font-weight:800;font-size:16px;vertical-align:middle;line-height:36px;transition:.15s}
.gap.sel{background:var(--yellow-t);box-shadow:inset 0 0 0 2px var(--yellow2)} .gap.full{background:var(--blue-t);box-shadow:none;color:var(--blue3);animation:pop .25s var(--spring)}
.gap.right{background:var(--green-t);color:var(--green3)} .gap.wrong{background:var(--red-t);color:var(--red2);text-decoration:line-through}
.fixed{font-weight:800;color:var(--green3);margin:0 4px;white-space:nowrap}
.bitem,.sitem{display:flex;gap:12px;padding:12px;border-radius:11px;background:var(--soft)} .bn{width:24px;font-weight:800;color:var(--mute);padding-top:7px;flex:none}
.bitem .built{min-height:42px;padding:2px 0 8px;margin-bottom:8px;border-bottom:2px dashed var(--line2);align-items:center} .ph{color:var(--faint);font-size:14px}
.bitem.right,.sitem.right{background:#EAF6F0} .bitem.wrong,.sitem.wrong{background:#FCEEF0}
.fixline{display:flex;align-items:center;gap:6px;font-weight:700;color:var(--green3);margin-top:8px;font-size:15px} .fixline .ic{flex:none}
.swords{line-height:2.2;font-size:17px} .sw{padding:5px 7px;margin:0 -1px;border-radius:7px;font-weight:600;transition:background .15s;-webkit-user-select:none;user-select:none}
@media (hover:hover){.sw:not([disabled]):hover{background:var(--yellow-t)}}
.sw.bad{background:var(--green-t);color:var(--green3);text-decoration:line-through;font-weight:800} .sw.miss{background:var(--red-t);color:var(--red2)}
.match{display:grid;grid-template-columns:1fr 1fr;gap:10px} .mcol{display:flex;flex-direction:column;gap:7px}
.mi{min-height:46px;padding:8px 10px;border-radius:10px;background:var(--card);box-shadow:inset 0 0 0 1.5px var(--line2);font-weight:700;font-size:14.5px;line-height:1.25;text-align:left;transition:.15s}
.mi.sel{background:var(--yellow-t);box-shadow:inset 0 0 0 2px var(--yellow2)} .mi.ok{background:var(--green-t);box-shadow:none;color:var(--green3);opacity:.75} .mi.wrong{background:var(--red-t)}
/* writing */
.dlg{display:flex;flex-direction:column;gap:9px}
.dline{display:flex;gap:9px;align-items:flex-end;max-width:92%} .dline.me{align-self:flex-end;flex-direction:row-reverse}
.dav{width:30px;height:30px;border-radius:50%;background:var(--soft2);display:grid;place-items:center;font-weight:800;font-size:13px;flex:none} .dline.me .dav{background:var(--blue);color:#fff}
.dbub{padding:9px 13px;border-radius:15px 15px 15px 5px;background:var(--soft)} .dline.me .dbub{background:var(--blue-t);border-radius:15px 15px 5px 15px}
.dbub b{font-size:12px;font-weight:800;color:var(--mute)} .dbub p{font-size:16.5px;line-height:1.9} .dbub u{text-decoration:none;font-weight:700}
.gin{height:34px;padding:0 8px;border-radius:8px;border:0;background:var(--card);box-shadow:inset 0 0 0 1.5px var(--line2);font-size:16px;font-weight:700;color:var(--blue3);outline:0;text-align:center;max-width:46vw}
.gin:focus{box-shadow:inset 0 0 0 2px var(--blue2)} .gin.right{background:var(--green-t);box-shadow:none;color:var(--green3)} .gin.wrong{background:var(--red-t);box-shadow:none;color:var(--red2);text-decoration:line-through}
.task{font-size:16.5px} .ideas{margin:0;padding-left:20px;color:var(--ink2);font-size:15px;display:grid;gap:3px}
textarea.essay{min-height:200px;font-size:17px;font-weight:400}
.goals{display:flex;flex-wrap:wrap;gap:8px} .goal{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:9px;background:var(--soft);font-size:13.5px;font-weight:600;color:var(--ink2);transition:.25s}
.goal b{font-weight:800} .goal.on{background:var(--green-t);color:var(--green3)} .goal .ic{width:17px;height:17px}
.wchip{padding:4px 9px;border-radius:7px;background:var(--soft);font-size:13.5px;font-weight:600;color:var(--mute);transition:.25s var(--spring)} .wchip.say{font-style:italic}
.wchip.on{background:var(--green);color:#fff;transform:scale(1.04)}
.model{padding:14px;border-radius:11px;background:var(--soft);font-size:16px;line-height:1.6} .model b{background:var(--hl-bg);background-repeat:var(--hl-rep);background-size:var(--hl-size);background-position:var(--hl-pos)} .model i{color:var(--green3);font-weight:700}

/* ───────── word bank */
.wb-stages{display:flex;gap:10px;overflow-x:auto;scrollbar-width:none;margin:0 -16px 16px;padding:4px 16px}
.wb-stages::-webkit-scrollbar{display:none}
.wb-st{position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;min-width:84px;padding:12px 10px 10px;border-radius:14px;background:var(--card);box-shadow:inset 0 0 0 1px var(--line);color:var(--mute);font-size:13px;font-weight:700;cursor:pointer;transition:transform .2s var(--spring),box-shadow .2s}
.wb-st:active{transform:scale(.95)} .wb-st .shield{transition:transform .3s var(--spring)}
.wb-st[aria-selected="true"]{box-shadow:inset 0 0 0 2.5px var(--ink);color:var(--ink)} .wb-st[aria-selected="true"] .shield{transform:scale(1.1) rotate(-4deg)}
.wb-st em{position:absolute;right:6px;top:6px;font-style:normal;font-size:11px;font-weight:800;background:var(--soft2);color:var(--ink2);padding:1px 6px;border-radius:8px}
.myshield{width:52px;height:52px;border-radius:12px;display:grid;place-items:center;background:var(--blue-t);color:var(--blue2)}
.wb-sum{display:flex;flex-direction:column;gap:14px;margin-bottom:16px} .wb-sum .meter{background:rgba(255,255,255,.25)} .wb-sum .meter i{background:var(--card)}
.wb-sum .btn.white{color:var(--brown)} .mywords-top{display:flex;flex-direction:column;gap:12px;margin-bottom:16px} .mywords-top .btn.white{color:var(--blue3)}
.wb-lessons{display:flex;flex-direction:column;gap:10px} .wb-l{overflow:hidden} .wb-l>.li .ic:last-child{transition:transform .3s var(--ease)} .wb-l.open>.li .ic:last-child{transform:rotate(180deg)}
.wb-words{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;padding:4px 14px 14px}
.wbw{display:flex;flex-direction:column;gap:2px;padding:9px 11px;border-radius:10px;background:var(--soft);text-align:left;line-height:1.25;animation-delay:calc(var(--i)*22ms);transition:transform .15s}
.wbw:active{transform:scale(.96)} .wbw b{font-weight:800;font-size:14.5px} .wbw span{font-size:12.5px;color:var(--mute);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.wbw.known{background:var(--green-t)} .wbw.known b{color:var(--green3)} .wbw.idi{background:var(--brown-t)}
.wb-act{grid-column:1/-1;padding-top:6px} .wdetail{display:flex;flex-direction:column;gap:8px;font-size:16.5px} .wdetail .w-pron{padding:0} .wd-tr{font-size:22px;font-weight:800;color:var(--green3)}
.mw-prev{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
/* study */
.study{max-width:560px} #study{display:flex;flex-direction:column;gap:16px}
.deck{position:relative;height:min(52dvh,420px);perspective:1200px;touch-action:pan-y}
.fc{position:absolute;inset:0;border-radius:20px;transform-style:preserve-3d;transition:transform .5s var(--ease);cursor:pointer;-webkit-user-select:none;user-select:none}
.fc.under{transform:scale(.94) translateY(14px);opacity:.6} .fc.under .fc-face{box-shadow:none}
.fc.flip{transform:rotateY(180deg)}
.fc-face{position:absolute;inset:0;border-radius:20px;background:var(--card);border:1.5px solid var(--line2);box-shadow:var(--shadow-up);backface-visibility:hidden;-webkit-backface-visibility:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:26px;text-align:center}
.fc-face.back{transform:rotateY(180deg);background:var(--red);border-color:var(--red);color:#fff;box-shadow:inset 0 0 0 5px var(--red),inset 0 0 0 7px rgba(255,255,255,.9),var(--shadow-up)}
.fc-w{font-size:clamp(28px,7.5vw,40px);font-weight:900;line-height:1.1;letter-spacing:-.01em;text-wrap:balance} .fc-face .w-pron{padding:0}
.fc-hint{position:absolute;top:16px;left:0;right:0;display:flex;justify-content:center;align-items:center;gap:6px;font-size:12.5px;font-weight:700;color:var(--faint)}
.fc-say{position:absolute;bottom:16px;width:46px;height:46px;border-radius:50%;display:grid;place-items:center;background:var(--blue-t);color:var(--blue2)}
.fc-tr{font-size:clamp(24px,6.4vw,32px);font-weight:900;line-height:1.15} .fc-face.back p{font-size:16px;line-height:1.45;font-weight:500} .fc-face.back .w-ex{color:#fff;opacity:.9}
.stamp{position:absolute;top:18px;padding:5px 12px;border-radius:8px;font-weight:900;font-size:18px;letter-spacing:.04em;text-transform:uppercase;opacity:0;transition:opacity .15s;border:3px solid;background:var(--card);z-index:3}
.stamp.yes{left:18px;color:var(--green3);transform:rotate(-12deg)} .stamp.no{right:18px;color:var(--red2);transform:rotate(12deg)}
.fc.say-yes .stamp.yes,.fc.say-no .stamp.no{opacity:1}
.fc-ctl{display:grid;grid-template-columns:1fr 1fr;gap:12px} .btn.stopish{color:var(--red2);box-shadow:inset 0 0 0 1.5px #EBB9C1}
.center{text-align:center} .study-end{display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center} .study-end .art{width:130px;height:130px;color:var(--blue)}

/* ───────── chat */
.tg{display:flex;flex-direction:column;height:calc(100dvh - var(--top) - var(--sat) - var(--tab) - var(--sab));background:var(--card)}
.tg-list{flex:1}
.tg-convo{flex:1}
.view-chat{padding-bottom:0!important}
.tg-list{display:flex;flex-direction:column;min-height:0;border-right:1px solid var(--line)}
.tg-search{padding:12px 14px;border-bottom:1px solid var(--line)}
.srch{display:flex;align-items:center;gap:8px;height:42px;padding:0 12px;border-radius:10px;background:var(--soft);color:var(--mute);min-width:0}
.srch input{flex:1;min-width:0;border:0;outline:0;background:transparent;font-size:16px;font-weight:500;-webkit-appearance:none}
.srch.big{height:50px;margin-bottom:12px}
.cl{overflow-y:auto;flex:1;overscroll-behavior:contain}
/* Extra's conversation row: a large round face, a name and a time on one line,
   the last words underneath. The rows have to carry the page on their own —
   a chat list is three or four of them on a tall screen — so they are given
   the height to do it. */
.cl-row{display:flex;gap:13px;align-items:center;padding:12px 14px;color:var(--ink);cursor:pointer;transition:background .12s;border-radius:12px}
.cl-row+.cl-row{box-shadow:inset 0 1px 0 var(--line)}
.cl-row.on{background:var(--blue-t)} @media (hover:hover){.cl-row:not(.on):hover{background:var(--soft)}}
.cl-row .av.lg{width:50px;height:50px;font-size:17px;flex:none}
.cl-row .av.lg .ic{width:23px;height:23px}
.cl-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.cl-top,.cl-bot{display:flex;gap:8px;align-items:center} .cl-top b{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:800;font-size:15.5px} .cl-top time{font-size:12px;color:var(--mute);font-weight:600;flex:none}
.cl-row.unread .cl-top b{color:var(--blue2)}
.cl-last{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:14px;color:var(--mute)} .cl-last .ic{display:inline;vertical-align:-3px} .you{color:var(--blue2);font-weight:600}
/* unread: who it is from and how many, not what they said */
.cl-last.held{display:flex;align-items:center;gap:6px}
.cl-who{color:var(--ink);font-weight:700;flex:none}
.cl-new{display:inline-flex;align-items:center;gap:4px;font-style:normal;font-weight:800;color:var(--red2);flex:none}
.cl-new .ic{width:14px;height:14px}
.badge{min-width:22px;height:22px;padding:0 6px;border-radius:11px;background:var(--red);color:#fff;font-size:12px;font-weight:800;font-style:normal;display:grid;place-items:center;flex:none}
.av.grp{background:var(--red)} .av.ne{background:none} .av.ne svg{width:100%;height:100%;border-radius:50%}
.tg-convo{display:none;flex-direction:column;min-height:0;min-width:0;background:#EEF2F0;background-image:radial-gradient(rgba(18,73,155,.07) 1.2px,transparent 1.2px);background-size:22px 22px}
.tg.has-conv .tg-list{display:none} .tg.has-conv .tg-convo{display:flex}
.tg-head{display:flex;align-items:center;gap:10px;padding:8px 12px;background:var(--card);border-bottom:1px solid var(--line);min-height:56px}
.tg-head b{display:block;font-weight:800;line-height:1.2} .tg-sub{font-size:12.5px;color:var(--mute);display:flex;align-items:center;gap:5px}
.live{width:8px;height:8px;border-radius:50%;background:#19B56B;display:inline-block}
.tg-msgs{flex:1;overflow-y:auto;padding:14px 12px 8px;display:flex;flex-direction:column;gap:3px;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.daysep{align-self:center;margin:10px 0 6px} .daysep span{padding:4px 11px;border-radius:12px;background:rgba(20,24,27,.5);color:#fff;font-size:12px;font-weight:700}
.bubble{position:relative;max-width:min(78%,520px);padding:7px 11px 6px;border-radius:16px;background:var(--card);box-shadow:0 1px 1px rgba(20,24,27,.1);align-self:flex-start;cursor:pointer;animation:bub .28s var(--ease) both;word-break:break-word;-webkit-user-select:text;user-select:text}
@keyframes bub{from{opacity:0;transform:translateY(8px) scale(.97)}}
.bubble.first{margin-top:6px} .bubble.theirs{border-bottom-left-radius:5px} .bubble.mine{align-self:flex-end;background:#DDF3E7;border-bottom-right-radius:5px}
.bubble .who{display:block;font-size:12.5px;font-weight:800;color:var(--blue2);margin-bottom:1px} .bubble .who i{font-style:normal;font-weight:600;color:var(--mute);font-size:11.5px}
.bubble .txt{white-space:pre-wrap;font-size:15.5px;line-height:1.38} .bubble .meta{float:right;display:flex;align-items:center;gap:3px;margin:6px 0 -2px 10px;font-size:11px;color:var(--mute);font-weight:600}
.ticks{display:flex;color:var(--mute)} .ticks.seen{color:var(--blue2)} .bubble.gone{opacity:.6;font-style:italic;cursor:default}
.bubble .quote{display:block;padding:3px 8px;margin-bottom:4px;border-left:3px solid var(--blue2);background:rgba(18,73,155,.08);border-radius:4px;font-size:13px;max-height:3.1em;overflow:hidden} .bubble .quote b{display:block;color:var(--blue2)}
.kindline{display:flex;align-items:center;gap:5px;font-size:12px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;margin-bottom:2px}
/* a teacher's feedback, arriving in the chat as feedback */
.fbline{text-decoration:none;color:inherit;flex-wrap:wrap;padding-bottom:5px;margin-bottom:5px;
  border-bottom:1px solid rgba(128,128,128,.25);cursor:pointer}
.fbline em{font-style:normal;margin-left:auto;padding:1px 7px;border-radius:99px;
  background:rgba(128,128,128,.18);letter-spacing:0}
.bubble.call{background:var(--red);color:#fff} .bubble.call .meta,.bubble.call .ticks{color:rgba(255,255,255,.8)} .bubble.pay{background:var(--yellow);color:var(--ink)} .bubble.pay .meta{color:var(--yellow-ink)}
.tg-empty{margin:auto;padding:8px 14px;border-radius:12px;background:rgba(20,24,27,.45);color:#fff;font-size:14px;font-weight:600}
.tg-none{margin:auto} .tg-none .art{color:var(--line2);width:150px;height:150px}
.tg-quick{display:flex;gap:6px;overflow-x:auto;padding:6px 10px;scrollbar-width:none;background:rgba(255,255,255,.7)} .tg-quick::-webkit-scrollbar{display:none}
.tg-quick button{flex:none;padding:7px 11px;border-radius:14px;background:var(--card);box-shadow:inset 0 0 0 1px var(--line2);font-size:13px;font-weight:600;max-width:260px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tg-reply{display:flex;align-items:center;gap:10px;padding:7px 12px;background:var(--card);border-top:1px solid var(--line);color:var(--blue2)} .tg-reply span span{display:block;color:var(--ink2);font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .tg-reply b{font-size:13px}
.tg-input{display:flex;align-items:flex-end;gap:8px;padding:8px 10px calc(8px + var(--sab));background:var(--card);border-top:1px solid var(--line)}
.tg-input textarea{flex:1;min-width:0;min-height:44px;max-height:140px;padding:11px 14px;border-radius:22px;border:0;outline:0;background:var(--soft);resize:none;font-size:16px;line-height:1.35}
.tg-input .btn{border-radius:50%;flex:none}
body[data-tab="chat"] .tg.has-conv .tg-input{padding-bottom:8px}
.tg-menu{position:fixed;z-index:85;min-width:160px;padding:5px;border-radius:12px;background:var(--card);box-shadow:var(--shadow-up);border:1px solid var(--line)}
.tg-menu button{display:flex;align-items:center;gap:9px;width:100%;padding:10px 12px;border-radius:8px;font-weight:700;font-size:14.5px} .tg-menu button.bad{color:var(--red)}
@media (hover:hover){.tg-menu button:hover{background:var(--soft)}}
.tg-convo.insheet{display:flex;height:min(60dvh,520px);border-radius:12px;overflow:hidden;border:1px solid var(--line)}
@media (max-width:899px){body[data-tab="chat"] .tg.has-conv{height:calc(100dvh - var(--sat));position:fixed;inset:var(--sat) 0 0 0;z-index:45}}
/* Extra's scheme: messages are one column at every width. The list is the page,
   and opening a conversation replaces it rather than sitting beside it, so the
   same thing happens on a laptop as on a phone. */
@media (min-width:900px){
  .tg{height:calc(100dvh - var(--top));max-width:720px;margin:0 auto;
      border-left:1px solid var(--line);border-right:1px solid var(--line)}
}
.tg-head-page{padding:18px 16px 10px}
.tg-head-page h1{margin:0 0 2px;font-size:26px}
.tg-head-page p{margin:0}
.tg.has-conv .tg-head-page{display:none}

/* ───────── teacher */
.class-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}
.class{padding:16px;display:flex;flex-direction:column;gap:14px}
.class-top{display:flex;align-items:center;gap:12px} .class-next{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:11px;background:var(--soft)}
.class-next .t{font-weight:700;line-height:1.25} .class-next .s{font-size:13px;color:var(--mute)}
.class-ses{display:flex;flex-direction:column;gap:7px;padding:10px 12px;border-radius:11px;border:1px dashed var(--line2)}
.secbar{display:flex;gap:3px} .secbar i{flex:1;height:8px;border-radius:2px;background:var(--soft2)} .secbar i.on{background:var(--green2)}
.board.big{display:flex;flex-direction:column;gap:8px;margin-bottom:6px;max-width:100%;overflow-x:auto}
.brow{display:grid;grid-template-columns:5.6em 10.9em 2.4em 8.8em;gap:14px;font-size:22px;align-items:center} .brow .flap{font-size:22px} .brow.head{font-size:22px}
@media (max-width:640px){.brow,.brow .flap,.brow.head{font-size:15px}.brow{gap:8px}}
.teach{display:flex;flex-direction:column;height:100dvh}
.teach-bar{display:flex;align-items:center;gap:10px;padding:calc(var(--sat) + 8px) 12px 8px;background:var(--card);border-bottom:1px solid var(--line);min-height:58px}
.teach-bar .tt{display:block;font-weight:800;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .teach-bar .exit{width:38px;height:38px} .teach-bar .exit b{font-size:16px}
.teach-prog{display:flex;align-items:baseline;gap:4px;white-space:nowrap} .teach-prog b{font-size:20px;font-weight:900;color:var(--green)}
.teach-frame{flex:1;position:relative;background:var(--card);min-height:0} .teach-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.teach-load{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;background:var(--blue);color:#fff;font-weight:700} .teach-load .art{width:180px;height:180px}
.head-row{margin-bottom:14px} .head-row .srch{flex:1 1 220px;max-width:340px}
.filters{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:14px;align-items:center} .input.slim{min-height:40px;width:auto;font-size:14.5px;font-weight:600;padding-top:0;padding-bottom:0}
.table{background:var(--card);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.trow{display:flex;align-items:center;gap:12px;padding:8px 12px 8px 14px;min-height:60px;animation:rise .4s var(--ease) both;animation-delay:calc(var(--i)*22ms);transition:background .15s}
.trow+.trow{border-top:1px solid var(--line)} .trow.sel{background:#F1F8F5} .trow.inactive .tmain{opacity:.6}
.tmain{flex:1;min-width:0;display:flex;align-items:center;gap:11px;text-align:left;padding:4px 0}
.tmain .t{display:block;font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .tmain .s{display:block;font-size:12.5px;color:var(--mute);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tcell{flex:none;display:flex;align-items:center;gap:8px} .sw-cell{min-width:46px;justify-content:flex-end} .swl{font-size:12.5px;font-weight:700;color:var(--mute)}
@media (max-width:899px){.sw-cell .swl{display:none}}
.heat{display:inline-grid;place-items:center;min-width:46px;height:28px;padding:0 8px;border-radius:7px;font-weight:800;font-size:13.5px;background:var(--soft2);color:var(--ink2)}
.heat.hi{background:var(--green-t);color:var(--green3)} .heat.md{background:var(--yellow-t);color:var(--yellow-ink)} .heat.lo{background:var(--red-t);color:var(--red2)}
.bulk{position:fixed;z-index:60;left:10px;right:10px;bottom:calc(var(--tab) + var(--sab) + 10px);margin:0 auto;max-width:620px;display:flex;align-items:center;gap:8px;padding:8px 10px 8px 16px;border-radius:14px;background:var(--ink);color:var(--paper);box-shadow:var(--shadow-up)}
.bulk>b{font-size:18px} .bulk .btn{box-shadow:none} .bulk .btn:not(.warn):not(.stop){background:rgba(255,255,255,.14);color:#fff} .bulk>span{font-weight:600}
@media (min-width:900px){.bulk{bottom:24px}}
.tgprev{border-radius:12px;background:#E7EEF5;padding:12px} .tgp-head{display:flex;align-items:center;gap:8px;color:var(--blue2);margin-bottom:8px}
.tgprev pre,.credmsg{margin:0;padding:10px 12px;border-radius:12px 12px 12px 4px;background:var(--card);font-family:inherit;font-size:14px;line-height:1.45;white-space:pre-wrap;word-break:break-word}
.profile{display:flex;flex-direction:column;gap:12px} .chips-row{margin-top:6px;gap:6px}
.p-actions{display:grid;grid-template-columns:repeat(3,1fr);gap:8px} .p-actions .btn{padding:0 8px;font-size:13.5px} .p-h{margin-top:8px}
details.pl>summary{list-style:none;cursor:pointer} details.pl>summary::-webkit-details-marker{display:none}
.pl-body{padding:4px 14px 14px} .ptable{display:flex;flex-direction:column} .pt-row{display:flex;align-items:center;gap:12px;padding:7px 0;font-size:14.5px} .pt-row+.pt-row{border-top:1px solid var(--line)}
.essay-read{margin-top:10px;padding:12px;border-radius:10px;background:var(--soft);font-size:15px;line-height:1.55} .essay-read p{white-space:pre-wrap;margin-top:4px}
.li.mat .t{line-height:1.25}
.rtable-wrap{overflow-x:auto} .rtable{border-collapse:collapse;width:100%} .rtable th,.rtable td{padding:6px 5px;text-align:center;border-bottom:1px solid var(--line)}
.rtable thead th{font-size:12px;color:var(--mute);font-weight:700;padding:10px 5px} .rtable th:first-child{text-align:left;position:sticky;left:0;background:var(--card);padding-left:12px;z-index:1;min-width:150px}
.rtable tr.inactive th{opacity:.55} .rtable tbody tr:last-child th,.rtable tbody tr:last-child td{border-bottom:0}
.rname{display:flex;align-items:center;gap:9px;text-align:left;font-weight:700;font-size:14px;line-height:1.2} .exit.sm{width:30px;height:30px;border-radius:7px;display:inline-flex} .exit.sm b{font-size:14px;margin:0}
.rc{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;width:46px;height:40px;border-radius:8px;font-weight:800;font-size:14px;line-height:1} .rc small{font-size:10px;font-weight:700;opacity:.7;margin-top:2px}
.rc.none{color:var(--faint)} .rc.full{box-shadow:inset 0 0 0 2px currentColor} .legend{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:10px} .legend .heat{height:22px;font-size:11.5px}
.pal{max-height:50dvh;overflow-y:auto}

/* ───────── admin */
.setup{display:flex;flex-direction:column;gap:6px;margin-bottom:18px} .steps{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:8px}
.steps li{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:11px;background:rgba(255,255,255,.12)}
.steps li>span{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;background:var(--card);color:var(--blue);font-weight:900;flex:none} .steps li.done>span{background:var(--green2);color:#fff}
.steps b{display:block;line-height:1.25} .steps small{display:block;font-size:13px;opacity:.88;line-height:1.3} .setup .btn.white{color:var(--blue3)}
.kpis{display:grid;grid-template-columns:repeat(2,1fr);gap:10px} @media (min-width:760px){.kpis{grid-template-columns:repeat(4,1fr)}}
.kpi{display:flex;flex-direction:column;align-items:flex-start;gap:1px;padding:14px;border-radius:var(--r);background:var(--card);border:1px solid var(--line);color:var(--ink);text-align:left;cursor:pointer;border-top:4px solid var(--red);transition:transform .15s}
.kpi:active{transform:scale(.97)} .kpi b{font-size:32px;font-weight:900;line-height:1.05} .kpi span{font-weight:700;font-size:14px} .kpi small{font-size:12.5px;color:var(--mute);font-weight:600}
.kpi.warn{border-top-color:var(--yellow2)} .kpi.bad{border-top-color:var(--red)}
.teach-list{overflow:hidden} .teach-row{display:flex;gap:14px;padding:13px 14px} .teach-row+.teach-row{border-top:1px solid var(--line)}
.tr-time{width:52px;flex:none;font-weight:800;font-size:16px;padding-top:1px} .tr-time.small{font-size:12.5px;color:var(--mute)} .tr-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px} .tr-main .row{flex-wrap:wrap;gap:6px}
details.recent{margin-top:12px} details.recent summary{cursor:pointer;font-weight:700;color:var(--blue2);padding:6px 0;list-style-position:inside} details.recent .card{margin-top:8px}
.nlist{display:flex;flex-direction:column;gap:10px} .card.empty.slim{padding:22px}
.creds{display:grid;grid-template-columns:1fr 1fr;gap:10px} .creds div{padding:12px;border-radius:11px;background:var(--soft)} .creds span{display:block;font-size:12.5px;font-weight:700;color:var(--mute)} .creds b{font-size:19px;font-weight:800} .creds .secret{font-size:24px;letter-spacing:.08em;color:var(--green3)}
.credmsg{background:var(--soft);border-radius:11px}
.daypick{display:flex;gap:6px;flex-wrap:wrap} .daypick label{position:relative;cursor:pointer} .daypick input{position:absolute;opacity:0;inset:0}
.daypick span{display:grid;place-items:center;width:46px;height:42px;border-radius:9px;background:var(--card);box-shadow:inset 0 0 0 1.5px var(--line2);font-weight:700;font-size:14px;transition:.15s} .daypick input:checked+span{background:var(--green);color:#fff;box-shadow:none}
.daypick input:focus-visible+span{outline:2.5px solid var(--blue2);outline-offset:2px}
.li.staff .t{display:flex;flex-wrap:wrap;gap:6px;align-items:center}

/* fixes and additions */
.vsep{display:inline-block;width:1px;height:14px;background:var(--line2);margin:0 10px;vertical-align:-2px}
.hero-bp{display:flex;align-items:flex-end;min-height:150px;padding:20px;margin-bottom:18px}
.hb-art{position:absolute;right:8px;top:8px;bottom:8px;width:min(40%,170px)} .hb-art svg{width:100%;height:100%}
.hb-text{position:relative;max-width:62%} .hb-text h1{color:#fff} .hb-text .date{font-size:13px;font-weight:700;opacity:.85;margin-bottom:4px} .hb-line{margin-top:6px;font-weight:600;opacity:.92;font-size:14.5px}
@media (min-width:900px){.hero-bp{min-height:170px;padding:26px 30px}.hb-art{right:30px;width:200px}}
@media (max-width:640px){.head-row .srch{flex:1 1 100%;max-width:none;order:3}
  .brow{grid-template-columns:5.6em 2.4em 8.8em;gap:10px;font-size:17px}.brow .flap,.brow.head{font-size:17px}.brow>:nth-child(2){display:none}}
.class-grid:has(.class:only-child){grid-template-columns:minmax(0,520px)}
.sc-body .t{white-space:nowrap} .sc-body .plate{flex:none}

/* ── THE STAGE ROAD, READ TOP TO BOTTOM ── */
/* Extra's roadmap scheme — a spine with numbered stops and cards falling
   alternately to either side of it — drawn in the road this app already speaks:
   asphalt down the middle, a dashed yellow centre line, an exit sign at every
   stop. On a phone the road moves to the left margin and the cards line up
   beside it, because a zig-zag needs width to read. */
.rmap{position:relative;margin:16px 0 0;padding:6px 0}
/* The asphalt and the centre line are explicitly the bottom layer, and every
   stop sits above them. They used to share a layer with the exit signs: the
   entrance animation puts a transform on each stop, a transform makes a
   stacking context, and the sign's own z-index was then trapped inside it —
   so the road and the yellow dashes painted straight through the sign and
   "EXIT 3" came out as "EX" on one side and "IT" on the other. */
.rmap::before{content:"";position:absolute;z-index:0;left:50%;top:10px;bottom:10px;width:14px;margin-left:-7px;border-radius:7px;background:#3B444B}
.rmap::after{content:"";position:absolute;z-index:0;left:50%;top:24px;bottom:24px;width:2px;margin-left:-1px;
  background:repeating-linear-gradient(180deg,#FFC629 0 14px,transparent 14px 26px)}
/* The entrance animation lives on the card, not on the stop. A transform on
   the stop makes it a stacking context, which locks the exit sign into the
   same layer as the asphalt however high its z-index is — that is what buried
   the signs in the road. The stop itself now carries no transform, so its
   z-index means what it says. */
.rmap-stop{position:relative;z-index:1;display:flex;align-items:center;gap:12px;width:50%;padding:10px 0;text-decoration:none;color:var(--ink)}
.rmap-txt{animation:rmapIn .45s var(--ease) backwards;animation-delay:calc(var(--i, 0)*45ms)}
@keyframes rmapIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.rmap-stop.l{flex-direction:row-reverse;text-align:right;padding-right:36px}
.rmap-stop.r{margin-left:50%;padding-left:36px}
.rmap-stop>.exit{position:absolute;top:50%;margin-top:-23px;z-index:1}
.rmap-stop.l>.exit{right:-23px}
.rmap-stop.r>.exit{left:-23px}
.rmap-txt{flex:1;min-width:0;background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:11px 13px;box-shadow:var(--shadow);transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.rmap-txt small{display:block;font-size:10.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--mute)}
.rmap-txt b{display:block;font-size:15px;font-weight:800;line-height:1.25;margin:3px 0 2px}
.rmap-txt .sub{display:block;font-size:12.5px;color:var(--mute);line-height:1.3}
.rmap-stop.next>.exit{transform:scale(1.12)}
.rmap-stop.next .rmap-txt{border:2px solid var(--red);box-shadow:0 12px 26px -14px rgba(210,16,48,.5)}
.rmap-stop.next .rmap-txt small{color:var(--red2)}
.rmap-stop.done .rmap-txt small{color:var(--green3)}
/* dim the card, never the sign: a translucent sign lets the centre line
   show straight through it */
.rmap-stop.locked .rmap-txt{opacity:.72}
.rmap-stop>.exit{box-shadow:0 0 0 4px var(--paper)}
@media (hover:hover){.rmap-stop:not(.locked):hover .rmap-txt{transform:translateY(-2px);box-shadow:var(--shadow-up)}}
@media (max-width:620px){
  .rmap::before{left:23px;margin-left:0}
  .rmap::after{left:29px;margin-left:0}
  .rmap-stop,.rmap-stop.l,.rmap-stop.r{width:100%;margin-left:0;flex-direction:row;text-align:left;padding:9px 0 9px 58px}
  .rmap-stop.l>.exit,.rmap-stop.r>.exit{left:0;right:auto}
}
@media (prefers-reduced-motion:reduce){.rmap-stop{animation:none}}

/* ── SIGN-IN, EXTRA'S SCHEME ── */
/* Extra's sign-in, in detail: three blurred orbs and a ruled grid behind
   everything, the mark with its own shadow, the wordmark and badge, the
   academy's promise, a glass card over the wash, and the contacts underneath.
   The colours are this app's — blue, green and the flag red — and each piece
   rises a beat after the one above it. */
.auth2{position:relative;min-height:100dvh;min-height:100vh;display:flex;align-items:flex-start;
  justify-content:center;padding:18px 16px 24px;background:var(--paper);overflow:hidden}
.auth-bg{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none}
.orb{position:absolute;border-radius:50%;filter:blur(60px);opacity:.55;animation:orbFloat 14s ease-in-out infinite}
.orb.o1{width:420px;height:420px;background:#C3D6F2;left:-120px;top:-80px}
.orb.o2{width:360px;height:360px;background:#F2CFD5;right:-120px;top:30%;animation-delay:-5s}
.orb.o3{width:300px;height:300px;background:#C7E3D5;left:30%;bottom:-140px;animation-delay:-9s}
.gridlines{position:absolute;inset:0;
  background-image:linear-gradient(rgba(20,24,27,.05) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(20,24,27,.05) 1px,transparent 1px);
  background-size:40px 40px;
  -webkit-mask-image:radial-gradient(120% 90% at 50% 0%,#000 35%,transparent 78%);
  mask-image:radial-gradient(120% 90% at 50% 0%,#000 35%,transparent 78%)}
@keyframes orbFloat{0%,100%{transform:translate(0,0)}50%{transform:translate(30px,24px)}}

/* the column is the card's width; the contacts are allowed past it so the
   three of them sit on one line the way they do on Extra */
.auth2-in{position:relative;z-index:1;width:100%;max-width:580px;display:flex;flex-direction:column;align-items:center}
.auth2-in>.auth-lang,.auth2-in>.auth-hero,.auth2-in>.auth-card{width:100%;max-width:430px}
.auth2-in>*{animation:rise .7s var(--ease) backwards}
.auth2-in>.auth-card{animation-delay:.12s}
.auth2-in>.auth-contact{animation-delay:.24s}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes popIn{0%{transform:scale(.6);opacity:0}60%{transform:scale(1.08)}100%{transform:scale(1);opacity:1}}

.auth-lang{display:flex;align-items:center;justify-content:center;gap:8px;margin:0 auto 14px;color:var(--mute)}
.auth-lang .i{width:17px;height:17px}
.auth-lang .seg{background:rgba(255,255,255,.75);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);box-shadow:0 0 0 1px var(--line)}
.auth-lang .seg button{padding:6px 11px;font-size:13px}
.auth-theme{background:rgba(255,255,255,.75);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  box-shadow:0 0 0 1px var(--line);border-radius:10px;width:34px;height:34px;flex:none}
:root[data-theme="dark"] .auth-theme{background:rgba(23,27,30,.78)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .auth-theme{background:rgba(23,27,30,.78)}}

.auth-hero{text-align:center;padding:2px 0 4px;display:flex;flex-direction:column;align-items:center}
.auth-logo{display:inline-flex;filter:drop-shadow(0 12px 20px rgba(20,24,27,.26));animation:popIn .7s var(--ease) both}
.auth-logo svg{width:58px;height:58px;border-radius:15px}
.brand-big{display:flex;align-items:center;justify-content:center;gap:9px;font-weight:800;
  letter-spacing:.2em;color:var(--ink);font-size:16px;margin-top:12px}
.brand-big em{font-style:normal;background:var(--red);color:#fff;padding:3px 9px;border-radius:5px;
  font-size:11px;letter-spacing:.18em;text-transform:uppercase}
.motto{font-weight:700;font-size:20px;line-height:1.3;letter-spacing:-.01em;margin:12px auto 0;max-width:340px;color:var(--ink)}

.auth-card{width:100%;margin-top:20px;background:rgba(255,255,255,.92);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border-radius:var(--r-sign);padding:18px;box-shadow:var(--shadow-up);
  border:1px solid rgba(255,255,255,.8);outline:1px solid var(--line);outline-offset:-1px}
.auth-tabs{display:flex;gap:4px;background:var(--soft);border-radius:11px;padding:4px;margin-bottom:16px}
.auth-tabs button{flex:1;padding:10px 8px;border-radius:8px;font-weight:700;font-size:14.5px;color:var(--mute);
  background:transparent;transition:background .2s var(--ease),color .2s var(--ease)}
.auth-tabs button.on{background:var(--card);color:var(--ink);box-shadow:0 1px 3px rgba(20,24,27,.14)}
.auth-card h1{font-size:21px;margin:0 0 2px}
.auth-card .lead{margin:0 0 14px}

.auth-contact{text-align:center;margin:18px 0 6px;color:var(--mute);font-size:13.5px}
.ac-links{display:flex;justify-content:center;gap:8px;flex-wrap:wrap;margin-top:8px}
.ac-links a{display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border-radius:30px;
  background:var(--card);border:1px solid var(--line);color:var(--ink);font-weight:700;
  text-decoration:none;font-size:13.5px;transition:border-color .2s var(--ease),transform .2s var(--ease),box-shadow .2s var(--ease)}
.ac-links a:hover{border-color:var(--blue2);transform:translateY(-1px);box-shadow:var(--shadow)}
.ac-links .i{width:17px;height:17px;color:var(--red)}

@media (max-width:520px){.auth2{padding-top:14px}.auth-logo svg{width:52px;height:52px}.motto{font-size:18px}}
@media (prefers-reduced-motion:reduce){.orb{animation:none}.auth2-in>*,.auth-logo{animation:none}}

/* the same wash after dark: the orbs deepen rather than glow, and the card
   becomes a dark glass so the type on it still holds */
:root[data-theme="dark"] .orb{opacity:.3;filter:blur(72px)}
:root[data-theme="dark"] .orb.o1{background:#1B3A6B}
:root[data-theme="dark"] .orb.o2{background:#5A1526}
:root[data-theme="dark"] .orb.o3{background:#13402F}
:root[data-theme="dark"] .gridlines{background-image:linear-gradient(rgba(190,210,230,.055) 1px,transparent 1px),linear-gradient(90deg,rgba(190,210,230,.055) 1px,transparent 1px)}
:root[data-theme="dark"] .auth-card{background:rgba(23,27,30,.9);border-color:rgba(255,255,255,.07)}
:root[data-theme="dark"] .auth-lang .seg{background:rgba(23,27,30,.78);box-shadow:0 0 0 1px var(--line)}
:root[data-theme="dark"] .auth-logo{filter:drop-shadow(0 12px 22px rgba(0,0,0,.7))}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .orb{opacity:.3;filter:blur(72px)}
  :root:not([data-theme="light"]) .orb.o1{background:#1B3A6B}
  :root:not([data-theme="light"]) .orb.o2{background:#5A1526}
  :root:not([data-theme="light"]) .orb.o3{background:#13402F}
  :root:not([data-theme="light"]) .gridlines{background-image:linear-gradient(rgba(190,210,230,.055) 1px,transparent 1px),linear-gradient(90deg,rgba(190,210,230,.055) 1px,transparent 1px)}
  :root:not([data-theme="light"]) .auth-card{background:rgba(23,27,30,.9);border-color:rgba(255,255,255,.07)}
  :root:not([data-theme="light"]) .auth-lang .seg{background:rgba(23,27,30,.78);box-shadow:0 0 0 1px var(--line)}
  :root:not([data-theme="light"]) .auth-logo{filter:drop-shadow(0 12px 22px rgba(0,0,0,.7))}
}

/* ── THE PROFILE ── */
/* Extra's profile, in this app's dress: a heading that says whose page this is,
   the pass, then the picture and what you have to say about yourself as two
   proper cards rather than a row of links. */
.pf-head{margin:2px 0 14px}
.pf-head .kicker{display:block;font-size:11px;font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:var(--red);margin-bottom:2px}
.pf-head h1{margin:2px 0 2px}
.pf-head .lead{margin:0}
.pf-card{margin-top:14px}
.pf-h{font-size:16px;font-weight:800;margin:0 0 12px}
.pf-pick{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap}
.pf-now{width:84px;height:84px;font-size:27px;flex:none;box-shadow:0 0 0 4px var(--card),0 10px 22px -12px rgba(20,24,27,.4)}
.pf-grid-wrap{flex:1;min-width:210px}
.pf-lab{font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--mute);margin-bottom:9px}
/* five and five, so the set reads as a deliberate block rather than a row
   that happened to wrap */
.pf-grid{display:grid;grid-template-columns:repeat(5,46px);gap:9px;margin-bottom:12px}
.pf-char{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;flex:none;
  background:var(--soft2);color:var(--ink2);border:2px solid transparent;
  transition:transform .18s var(--spring),border-color .18s var(--ease),background .18s var(--ease)}
.pf-char .ch{width:23px;height:23px}
/* Every character you have not picked is one thing, not two — an alternating fill
   reads as a state nobody chose. Only the pick is marked, and it is marked the way
   the picture will actually look: filled, beside the big one it is about to become. */
/* Ten characters, ten colours. Every one is pinned, like the avatar palette, because
   each carries a white glyph: a plate does not invert, and --ink would have turned
   white at night and taken the glyph with it. Deep flag tones, flat — no gradient and
   no orange, which is what this app was asked for.
   The unpicked chips wear the same colour at rest, dimmed, so the row reads as one
   set of choices; the pick comes forward in full and takes the ring. */
.pf-char{opacity:.55}
.pf-char.on{opacity:1;border-color:var(--red);transform:scale(1.06)}
@media (hover:hover){.pf-char:hover{opacity:1}}
.av.ch-star   ,.pf-char.ch-star   {background:#0C3676;color:#fff}
.av.ch-bolt   ,.pf-char.ch-bolt   {background:#D21030;color:#fff}
.av.ch-globe  ,.pf-char.ch-globe  {background:#0F6B74;color:#fff}
.av.ch-crown  ,.pf-char.ch-crown  {background:#12499B;color:#fff}
.av.ch-rocket ,.pf-char.ch-rocket {background:#3B3570;color:#fff}
.av.ch-case   ,.pf-char.ch-case   {background:#6B4A33;color:#fff}
.av.ch-compass,.pf-char.ch-compass{background:#0A6B4B;color:#fff}
.av.ch-mic    ,.pf-char.ch-mic    {background:#3C4850;color:#fff}
.av.ch-heart  ,.pf-char.ch-heart  {background:#8C1F3D;color:#fff}
.av.ch-peak   ,.pf-char.ch-peak   {background:#1D5E8C;color:#fff}
@media (hover:hover){.pf-char:hover{transform:translateY(-2px) scale(1.04)}}
.av.has-ch{overflow:hidden}
.av.has-ch .ch{width:58%;height:58%;color:#fff}
.pf-now.has-ch .ch{width:46px;height:46px}
.pf-card textarea.input{resize:vertical;min-height:84px;font:inherit;line-height:1.45;padding:11px 13px}
@media (max-width:560px){.pf-pick{gap:13px}.pf-now{width:70px;height:70px;font-size:23px}.pf-now.has-ch .ch{width:38px;height:38px}}

/* ── THE DAY AND NIGHT SWITCH ── */
/* The sun and moon swap places rather than cutting: the old one is already gone
   when this runs, so the new one swings in from behind the press and settles.
   Sized to sit with the bell beside it, not above it. */
[data-a="theme"] .ic{width:20px;height:20px;transform-origin:50% 50%}
[data-a="theme"].swap .ic{animation:themeSwap .46s var(--spring) both}
@keyframes themeSwap{
  from{transform:rotate(-140deg) scale(.45);opacity:0}
  60%{opacity:1}
  to{transform:rotate(0) scale(1);opacity:1}
}
@media (hover:hover){[data-a="theme"]:hover .ic{transform:rotate(-12deg)}}
[data-a="theme"] .ic{transition:transform .22s var(--spring)}
@media (prefers-reduced-motion:reduce){
  [data-a="theme"].swap .ic{animation:none}
  [data-a="theme"]:hover .ic{transform:none}
}

/* ── THE VOCABULARY TEST ──
   The gate, then the test itself. While it runs the lists behind it are blurred
   and inert: a test you can read the answers off is not a test. The blur is on a
   wrapper rather than on each card so there is no seam between them, and
   pointer-events go with it so a stray tap cannot open a word. */
.vq-gate{margin-top:22px;text-align:center}
.vq-gate-i{color:var(--red);margin-bottom:4px}
.vq-gate h2{margin:0 0 6px}
.vq-gate p{margin:0 auto 10px;max-width:46ch}
.vq-gate .btn{margin-top:6px}
.words.vq-locked{filter:blur(9px) saturate(.6);opacity:.45;pointer-events:none;user-select:none;
  transform:scale(.985);transition:filter .45s var(--ease),opacity .45s var(--ease),transform .45s var(--ease)}

.vq{margin-bottom:18px}
.vq-bar{height:6px;border-radius:99px;background:var(--soft2);overflow:hidden;margin-bottom:10px}
.vq-bar>i{display:block;height:100%;background:var(--red);transition:width .35s var(--ease)}
.vq-meta{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.vq-meta .num{font-weight:800;color:var(--mute)}
.vq-hintb{margin-left:auto}
.vq-card{text-align:center}
.vq-term{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;margin-bottom:4px}
.vq-term b{font-size:clamp(26px,5.4vw,38px);font-weight:800;letter-spacing:-.015em;line-height:1.1}
.vq-pron{color:var(--mute);font-size:15px}
.vq-cols{display:grid;gap:12px;margin-top:16px}
@media(min-width:560px){.vq-cols:has(.vq-col+.vq-col){grid-template-columns:1fr 1fr}}
.vq-lab{font-size:11.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--faint);margin-bottom:6px}
.vq-opt{display:block;width:100%;margin-bottom:8px;padding:13px 14px;border-radius:var(--r);border:0;cursor:pointer;
  background:var(--card);color:var(--ink);font:inherit;font-weight:700;font-size:15.5px;text-align:center;
  box-shadow:inset 0 0 0 1.5px var(--line);transition:transform .14s var(--spring),box-shadow .14s var(--ease),background .14s var(--ease)}
@media(hover:hover){.vq-opt:not(:disabled):hover{box-shadow:inset 0 0 0 2px var(--ink2);transform:translateY(-1px)}}
.vq-opt:active:not(:disabled){transform:scale(.975)}
/* the verdict: these are plates and carry white type, so they are pinned */
.vq-opt.ok{background:#0A6B4B;color:#fff;box-shadow:inset 0 0 0 2px #0A6B4B,inset 0 0 0 3.4px rgba(255,255,255,.9)}
.vq-opt.bad{background:#D21030;color:#fff;box-shadow:inset 0 0 0 2px #D21030,inset 0 0 0 3.4px rgba(255,255,255,.9)}
.vq-opt.dim{opacity:.4}
.vq-say{margin:14px 0 0;color:var(--red2);font-weight:700}
.vq-mid,.vq-end{text-align:center}
.vq-round{display:inline-block;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);margin-bottom:4px}
.vq-trophy{color:var(--yellow2)}
.vq-end h2{margin:4px 0 4px}
.vq-end .row{justify-content:center;margin-top:12px}

/* ── THE LESSON'S PLAYER ──
   A film, not a slideshow. The artwork drifts for the length of its own scene;
   a flashback is sepia, as it is on the lesson page. */
.vp{margin-bottom:16px}
.vp-stage{position:relative;aspect-ratio:16/9;border-radius:var(--r-sign);overflow:hidden;background:var(--flap);
  box-shadow:var(--shadow);display:grid;place-items:center}
.vp-art{width:100%;height:100%;display:grid;place-items:center}
.vp-art svg{width:100%;height:100%;display:block}
.vp-art.past{filter:sepia(.75) contrast(.92)}
.vp .vp-bar{height:5px;border-radius:99px;background:var(--soft2);overflow:hidden;margin:9px 0 0}
.vp .vp-bar>i{display:block;height:100%;width:0;background:var(--red)}
.vp-cap{margin:11px 0 0;font-size:16.5px;line-height:1.45;min-height:1.45em;text-wrap:balance}
.vp-cap b{background:var(--hl-bg);background-repeat:var(--hl-rep);background-size:var(--hl-size);background-position:var(--hl-pos)}
.vp-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;margin:8px 0 12px}
.vp-head b{font-size:18px;font-weight:800}
.vp-ctl{display:flex;align-items:center;gap:9px}
.vp-ctl .num{flex:none;min-width:52px;text-align:center}
/* the Ken-Burns drifts the lesson picks per scene */
.playing .vp-art.kb0{animation:kb0 var(--kb,9s) linear both}
.playing .vp-art.kb1{animation:kb1 var(--kb,9s) linear both}
.playing .vp-art.kb2{animation:kb2 var(--kb,9s) linear both}
.playing .vp-art.kb3{animation:kb3 var(--kb,9s) linear both}
@keyframes kb0{from{transform:scale(1.02)}to{transform:scale(1.1)}}
@keyframes kb1{from{transform:scale(1.1) translateX(1.5%)}to{transform:scale(1.02) translateX(-1.5%)}}
@keyframes kb2{from{transform:scale(1.04) translateY(1.5%)}to{transform:scale(1.11) translateY(-1.5%)}}
@keyframes kb3{from{transform:scale(1.11) translateX(-1.5%)}to{transform:scale(1.03) translateX(1.5%)}}
@media (prefers-reduced-motion:reduce){.vp-art{animation:none !important}}

/* ── SPEAKING: THE FOUR MOVES ── */
.ap{margin-bottom:18px}
.ap-top{display:flex;align-items:center;gap:10px;margin-bottom:7px}
.ap-label{font-size:11.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--red2)}
.ap-top .num{margin-left:auto}
.ap-stage{position:relative;aspect-ratio:16/9;border-radius:var(--r-sign);overflow:hidden;background:var(--flap);color:#F7F3E3;
  box-shadow:var(--shadow);display:grid;place-items:center;padding:16px}
.ab-sc{display:grid;gap:14px;width:100%;height:100%;align-items:center}
@media(min-width:620px){.ab-sc:has(.ab-art){grid-template-columns:1.1fr 1fr}}
.ab-center{place-items:center;text-align:center;align-content:center}
.ab-big{font-size:clamp(34px,7vw,58px);font-weight:800;letter-spacing:.16em}
.ab-sub{font-size:clamp(15px,2.4vw,20px);opacity:.88}.ab-sub.b{font-weight:800}
.ab-row{display:flex;flex-wrap:wrap;gap:10px;justify-content:center}
.ab-row span{display:flex;gap:6px;align-items:baseline;font-size:13.5px;opacity:.9}
.ab-row b{color:var(--yellow)}
.ab-note{font-size:13px;opacity:.75}
.ab-art{display:grid;place-items:center;height:100%}
.ab-art svg{width:100%;height:100%;max-height:230px}
.ab-h{display:flex;gap:9px;align-items:baseline;font-weight:800;font-size:17px;margin-bottom:6px}
.ab-h b{color:var(--yellow);font-size:22px}
.ab-cap{font-size:14.5px;opacity:.9;margin:2px 0}
.ab-q{margin-top:8px;font-weight:700;color:var(--yellow)}
.ab-vv{margin-top:6px;font-size:12.5px;opacity:.75}
.ab-vv small{font-weight:800;letter-spacing:.08em}
.ap-bar{height:5px;border-radius:99px;background:var(--soft2);overflow:hidden;margin:9px 0}
.ap-bar>i{display:block;height:100%;width:0;background:var(--red)}
.ap-ctl{display:flex;gap:9px;align-items:center}
.ap-how{margin:9px 0 0}
.ab-cards{display:grid;gap:12px}
@media(min-width:720px){.ab-cards{grid-template-columns:1fr 1fr}}
.ab-ch{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.ab-l{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;flex:none;
  background:var(--red);color:#fff;font-weight:800;font-size:18px}
.ab-ch h3{margin:0;font-size:17px}
.ab-st{margin:0 0 10px;padding-left:18px}.ab-st li{margin:3px 0}
.ab-words{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:9px}
.ab-task{margin:0;font-size:14.5px;color:var(--ink2)}
.ab-run{margin-top:14px}
.ab-clock{font-size:24px;font-weight:800;font-variant-numeric:tabular-nums;margin-right:10px}
.cue-cards{display:grid;gap:12px}
@media(min-width:720px){.cue-cards{grid-template-columns:1fr 1fr}}
.cue-card h3{margin:4px 0 8px;font-size:18px}
.cue-say{margin:6px 0 0;padding-left:18px}.cue-say li{margin:3px 0}
.dq .dq-n{width:24px;flex:none;font-weight:800;color:var(--faint)}
.dq-w{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}

/* the listening-speed slider, in the app's own dress rather than the device's */
.rng{-webkit-appearance:none;appearance:none;width:170px;max-width:48vw;height:22px;background:none;cursor:pointer}
.rng::-webkit-slider-runnable-track{height:6px;border-radius:99px;background:var(--soft2)}
.rng::-moz-range-track{height:6px;border-radius:99px;background:var(--soft2)}
.rng::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:22px;height:22px;margin-top:-8px;border-radius:50%;
  background:var(--red);box-shadow:inset 0 0 0 3px rgba(255,255,255,.9),var(--shadow);transition:transform .14s var(--spring)}
.rng::-moz-range-thumb{width:22px;height:22px;border:0;border-radius:50%;background:var(--red);
  box-shadow:inset 0 0 0 3px rgba(255,255,255,.9),var(--shadow)}
.rng:active::-webkit-slider-thumb{transform:scale(1.14)}

/* ── THE APP'S OWN DROPDOWN ──
   The real select stays in the form and keeps working; it is simply never the
   thing anybody sees, so no device ever puts its own wheel over this app. */
select.nsel-real{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;clip-path:inset(50%);overflow:hidden}
.nsel{display:flex;align-items:center;gap:8px;width:100%;min-height:46px;padding:0 12px 0 14px;border:0;cursor:pointer;
  border-radius:var(--r-s);background:var(--card);color:var(--ink);font:inherit;font-weight:700;font-size:15.5px;text-align:left;
  box-shadow:inset 0 0 0 1.5px var(--line);transition:box-shadow .15s var(--ease)}
.nsel.slim{min-height:38px;font-size:14.5px}
.nsel-v{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nsel .ic{color:var(--mute);flex:none}
.nsel:disabled{opacity:.55;cursor:default}
@media(hover:hover){.nsel:not(:disabled):hover{box-shadow:inset 0 0 0 2px var(--ink2)}}
.nsel[aria-expanded="true"]{box-shadow:inset 0 0 0 2px var(--red),0 0 0 3.5px var(--red-t)}
/* It opens unhurriedly and without a bounce. At .15s on a spring it snapped
   open and the overshoot read as the page twitching. */
.nsel-pop{position:fixed;z-index:120;overflow:auto;border-radius:var(--r);background:var(--card);
  box-shadow:var(--shadow-up);padding:5px;opacity:0;transform:translateY(-5px);
  transition:opacity .22s var(--ease),transform .22s var(--ease)}
@media (prefers-reduced-motion:reduce){.nsel-pop{transition:none}}
.nsel-pop.on{opacity:1;transform:none}
.nsel-g{padding:9px 11px 5px;font-size:11.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
.nsel-o{display:block;width:100%;padding:10px 12px;border:0;border-radius:var(--r-s);cursor:pointer;
  background:none;color:var(--ink);font:inherit;font-size:15px;font-weight:600;text-align:left}
@media(hover:hover){.nsel-o:hover{background:var(--soft)}}
.nsel-o[aria-selected="true"]{background:var(--red);color:#fff;font-weight:800}
.nsel-o:disabled{opacity:.45;cursor:default}

/* ── THE PRESS ──
   It gives a little under the finger and comes back. That is all: the ripple
   and the glow that used to follow a tap were weather, not an answer. */
.pressing{transform:scale(.985) !important;transition:transform .08s var(--ease) !important}
/* overflow stays: it is what rounds the blueprint on a stage card */
.btn,.vq-opt,.nsel,.wtile,.pf-char,.stage-card{position:relative;overflow:hidden}
@media (prefers-reduced-motion:reduce){.pressing{transform:none !important}}


/* ── THE HIGHLIGHTER ──
   The marked words are highlighted in four places — the story caption, the
   player caption, the reading and the model answer — and each of those sets a
   different line-height. A gradient with a percentage stop lands somewhere
   different in each, which is why the bar looked detached in one place and
   right in another.

   So the bar is measured in em: a third of the type's own size, sitting just
   under the baseline. It is then the same stroke at every size, in every one of
   the four, and it rides along when the type scales. `clone` keeps it whole
   when a highlighted phrase wraps onto a second line. */
:root{
  --hl-bg:linear-gradient(var(--yellow),var(--yellow));
  --hl-rep:no-repeat;
  --hl-size:100% .34em;
  --hl-pos:0 .96em;
}
.cap b,.rd p b,.model b,.vp-cap b{
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
  padding:0 .06em;margin:0 -.06em;border-radius:1px}

/* ───────────────────────── the microphone
   Three states in one strip, only ever one of them showing: an invitation, a
   live take with its level, and the take that is already with the teacher.
   Recording is the one place in the app that uses a steady pulsing red: it is
   the state a student must never be in by accident. */
.rec{margin-top:12px}
.rec-no{display:flex;gap:7px;align-items:flex-start;margin:10px 0 0}
.rec-no .ic{flex:none;margin-top:1px;color:var(--mute)}
.rec-go{width:100%;justify-content:center}
.rec-live{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:12px;
  background:var(--red-t);box-shadow:inset 0 0 0 1.5px var(--red)}
.rec-dot{width:11px;height:11px;border-radius:50%;background:var(--red);flex:none;animation:recpulse 1.3s var(--ease) infinite}
@keyframes recpulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.78)}}
.rec-t{font-weight:800;color:var(--red2);font-variant-numeric:tabular-nums;min-width:38px}
.rec-meter{flex:1;height:8px;border-radius:99px;background:rgba(210,16,48,.18);overflow:hidden;min-width:40px}
.rec-meter>i{display:block;height:100%;width:100%;border-radius:99px;background:var(--red);
  transform:scaleX(0);transform-origin:left center;transition:transform .07s linear}
.rec-have{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.rec-sent{display:inline-flex;align-items:center;gap:4px;font-size:12.5px;font-weight:700;color:var(--green3)}
.rec-sent .ic{width:15px;height:15px}
.rec-play.on{background:var(--red);color:#fff;box-shadow:inset 0 0 0 2px var(--red)}
@media (prefers-reduced-motion:reduce){.rec-dot{animation:none}}

/* a student's takes, as their teacher sees them */
.tk{display:flex;align-items:center;gap:10px;padding:11px 0}
.tk+.tk{border-top:1px solid var(--line)}
.tk-w{min-width:0;flex:1}
.tk-p{font-weight:700;font-size:14.5px}
.tk-m{color:var(--mute);font-size:12.5px}
.rec-hear.on{background:var(--red);color:#fff;box-shadow:inset 0 0 0 2px var(--red)}

/* ───────────────────────── the profile, after Extra's
   One panel of settings with a steady rhythm, rather than a section heading and
   a card for every single choice. A row is label and control side by side; a row
   that marks itself `.col` puts the control underneath, which is what a segment
   or a slider needs on a phone. */
.settings-list{padding:2px 16px}
.set-row{display:flex;align-items:center;gap:14px;padding:15px 0}
.set-row+.set-row{border-top:1px solid var(--line)}
.set-row>div:first-child{flex:1;min-width:0}
.set-row b{display:block;font-size:15px;font-weight:700}
.set-row small{display:block;color:var(--mute);font-size:12.5px;line-height:1.45;margin-top:2px}
.set-row.col{flex-direction:column;align-items:stretch;gap:10px}
.set-row.col .seg,.set-row.col .rng{width:100%}
.pf-actions{display:flex;flex-direction:column;gap:9px;margin-top:18px}
.pf-actions .btn{justify-content:flex-start;gap:10px}
.btn.danger{color:var(--red2)}
.btn.danger .ic{color:var(--red2)}
@media (hover:hover){.btn.danger:hover{background:var(--red-t);box-shadow:inset 0 0 0 1.5px var(--red)}}

/* a photograph fills the circle it is shown in, at every size */
.av.has-ph{background:var(--soft2);overflow:hidden}
.av.has-ph>img{width:100%;height:100%;object-fit:cover;display:block}
.pf-now.has-ph{overflow:hidden}
.pf-foot{display:flex;flex-wrap:wrap;gap:8px}
.pf-tel{margin-left:auto;font-style:normal;color:var(--mute);font-weight:600;font-size:13px}
/* Removing a photo is a step back, not a third way to choose one, so it sits
   apart from the two that set a picture rather than queuing beside them. */
.pf-foot [data-a="photo-off"]{margin-left:auto}

/* ───────────────────────── E — write the conversation
   The bank is the scoreboard. A word lights the moment it is used, which is why
   there is no Check button on this one: the feedback is the writing itself. */
.tb-bank{margin-bottom:14px}
.tb-bank .chip{transition:background .2s var(--ease),color .2s,box-shadow .2s}
.tb-bank .chip.hit{background:var(--green-t);color:var(--green3);box-shadow:inset 0 0 0 1.5px var(--green2);font-weight:700}
.tb-bank .chip.hit .ic{width:14px;height:14px;margin-right:4px;vertical-align:-2px}
@keyframes tbpop{0%{transform:scale(1)}42%{transform:scale(1.13)}100%{transform:scale(1)}}
.tb-bank .chip.pop{animation:tbpop .34s var(--spring)}
.tb-lines{display:flex;flex-direction:column;gap:9px}
.tb-line{display:flex;align-items:flex-start;gap:9px}
.tb-who{flex:none;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
  font-weight:800;font-size:13px;color:#fff;margin-top:9px}
.tb-who.a{background:var(--blue)} .tb-who.b{background:var(--red)}
.tb-in{flex:1;min-height:52px;padding:11px 12px;line-height:1.45;resize:vertical}
.tb-foot{margin-top:14px;gap:10px;flex-wrap:wrap}
@media (prefers-reduced-motion:reduce){.tb-bank .chip.pop{animation:none}}

/* ───────────────────────── the dictionary
   Every word the academy teaches, in one alphabet. The entries are dense on
   purpose — someone looking a word up is scanning, not reading. */
.dict-head{display:flex;flex-direction:column;gap:10px;margin-bottom:14px}
.dict-find{position:relative;display:flex;align-items:center}
.dict-find>.ic{position:absolute;left:12px;color:var(--mute);pointer-events:none}
.dict-find .input{padding-left:38px;padding-right:40px}
.dict-find .input::-webkit-search-cancel-button{display:none}
.dict-x{position:absolute;right:6px;width:32px;height:32px;display:grid;place-items:center;
  border-radius:8px;color:var(--mute)}
@media (hover:hover){.dict-x:hover{background:var(--soft2);color:var(--ink)}}
.dict-g{margin-bottom:18px}
.dict-l{position:sticky;top:calc(var(--top) + var(--sat));z-index:2;background:var(--paper);
  font-weight:800;font-size:13px;letter-spacing:.1em;color:var(--mute);padding:6px 2px;border-bottom:1.5px solid var(--line)}
.dict-e{background:var(--card);border-radius:var(--r);padding:12px 14px;margin-top:9px;box-shadow:var(--shadow)}
.de-top{display:flex;align-items:center;gap:8px}
.de-top b{font-size:16px}
.de-k{font-style:normal;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--brown);background:var(--brown-t);padding:2px 7px;border-radius:99px}
.de-pr{color:var(--mute);font-size:12.5px;margin-top:1px}
.de-m{font-size:14px;margin-top:5px;line-height:1.45}
.de-tr{font-size:14px;margin-top:3px;color:var(--blue3);font-weight:600}
.de-ex{font-size:13.5px;margin-top:5px;color:var(--ink2);font-style:italic}
.de-at{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.de-at .chip{font-size:11.5px;padding:3px 9px;min-height:0;height:auto;line-height:1.5}

/* ───────────────────────── the notebook
   Pages on a shelf, each showing the drawing that is on it. */
.nb-new{margin-bottom:14px}
.nb-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(146px,1fr));gap:12px}
.nb-card{display:flex;flex-direction:column;align-items:stretch;gap:0;padding:0;overflow:hidden;
  background:var(--card);border-radius:var(--r);box-shadow:var(--shadow);text-align:left}
.nb-thumb{display:block;height:96px;background:var(--soft);border-bottom:1px solid var(--line);
  background-image:linear-gradient(var(--line) 1px,transparent 1px);background-size:100% 18px}
.nb-thumb svg{width:100%;height:100%;display:block}
.nb-t{padding:9px 11px 2px;font-weight:700;font-size:14px;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.nb-d{padding:0 11px 10px;color:var(--mute);font-size:12px}

.nb-edit{display:flex;flex-direction:column;gap:11px}
.nb-title{font-weight:700}
.nb-body{min-height:120px;line-height:1.5;resize:vertical;padding:12px}
.nb-tools{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:8px}
.nb-ink{width:28px;height:28px;border-radius:50%;background:var(--c);flex:none;
  box-shadow:0 0 0 2px var(--card),0 0 0 3px transparent;transition:box-shadow .15s,transform .15s var(--spring)}
.nb-ink.on{box-shadow:0 0 0 2px var(--card),0 0 0 3.5px var(--ink);transform:scale(1.12)}
.nb-pad{position:relative;height:300px;border-radius:var(--r);background:var(--card);
  box-shadow:inset 0 0 0 1.5px var(--line2);overflow:hidden;touch-action:none;cursor:crosshair;
  background-image:linear-gradient(var(--line) 1px,transparent 1px);background-size:100% 25px}
.nb-pad svg{width:100%;height:100%;display:block}
.btn.tool-on{background:var(--ink);color:var(--paper);box-shadow:inset 0 0 0 2px var(--ink)}
.nb-ink{overflow:hidden}
/* the language names are always written in their own language, never translated */
.lang-seg button{font-size:14px}

/* ───────────────────────── seeing how the work was done
   A row per question: what was asked, what they put, and the right answer when
   those differ. Right and wrong are carried by a mark and a rule down the left,
   never by colour alone. */
.pt-row.open{cursor:pointer;user-select:none}
.pt-row.open>.ic{color:var(--mute);transition:transform .2s var(--ease);flex:none}
.pt-row.open.on>.ic{transform:rotate(180deg)}
@media (hover:hover){.pt-row.open:hover{background:var(--soft)}}
.mk{padding:2px 0 10px}
.mk-row{display:flex;align-items:flex-start;gap:9px;padding:7px 10px;border-radius:8px;
  border-left:3px solid var(--line2);background:var(--soft);margin-top:6px;font-size:13.5px;line-height:1.45}
.mk-row.ok{border-left-color:var(--green2)}
.mk-row.no{border-left-color:var(--red)}
.mk-n{flex:none;color:var(--mute);font-size:12px;min-width:16px;padding-top:1px}
.mk-v{flex:none;display:grid;place-items:center;width:20px;height:20px;border-radius:50%}
.mk-v.ok{background:var(--green-t);color:var(--green3)}
.mk-v.no{background:var(--red-t);color:var(--red2)}
.mk-v .ic{width:13px;height:13px}
.mk-fix{display:flex;align-items:center;gap:4px;margin-top:3px;color:var(--green3);font-weight:600}
.mk-fix .ic{width:14px;height:14px;flex:none}
.mk-blank{color:var(--mute);font-style:italic}
.mk-tap{text-decoration-color:var(--red);text-decoration-thickness:2px;text-underline-offset:3px}
.mk-all,.mk-none{color:var(--mute);font-size:13px;padding:8px 10px;margin:6px 0 0;
  background:var(--soft);border-radius:8px}
.mk-text{white-space:pre-wrap;background:var(--soft);border-radius:8px;padding:10px 12px;
  margin-top:6px;font-size:13.5px;line-height:1.5}

/* ───────────────────────── Review
   Native Elite Extra's review system, on this platform's work: a queue the
   teacher filters, then one piece of work on its own page with the exercise
   on the left and the box to write in on the right. */
.list-h{display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:10px 14px 8px;font-size:12.5px;color:var(--mute);font-weight:700;border-bottom:1px solid var(--line)}
.sub-row{display:flex;align-items:center;gap:12px;padding:11px 14px;border-bottom:1px solid var(--line);
  text-decoration:none;color:var(--ink);transition:background .2s}
.sub-row:last-child{border-bottom:0}
@media (hover:hover){.sub-row:hover{background:var(--soft)}}
.sr-i{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;
  background:var(--blue-t);color:var(--blue3);flex:none}
.sr-i .ic{width:19px;height:19px}
.sr-i.p-speaking{background:var(--red-t);color:var(--red2)}
.sr-i.p-writing{background:var(--yellow-t);color:var(--yellow-ink)}
/* listening is neither red nor yellow nor the green of a good score, so the
   tile cannot be misread as the mark the app already gave it */
.sr-i.p-listening{background:var(--brown-t);color:var(--brown)}
/* a listening row carries two things: the app's score and whether a teacher
   has been. Stacked, they stay legible in the narrow end of a phone row. */
.sr-two{display:flex;flex-direction:column;align-items:flex-end;gap:4px}
.sr-main{flex:1;min-width:0}
.sr-main b{display:block;font-weight:700}
.sr-main small{display:block;color:var(--mute);font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sr-end{display:flex;align-items:center;gap:8px;flex:none;flex-wrap:wrap;justify-content:flex-end}
.sr-end small{color:var(--mute);font-size:12.5px}
.rv-badge{display:inline-flex;align-items:baseline;gap:1px;padding:4px 9px;border-radius:99px;
  background:var(--soft2);color:var(--ink2);font-weight:800;font-size:13px;white-space:nowrap}
.rv-badge small{font-weight:700;opacity:.7}
.rv-badge.good{background:var(--green-t);color:var(--green3)}
.rv-badge.mid{background:var(--yellow-t);color:var(--yellow-ink)}
.rv-badge.low{background:var(--red-t);color:var(--red2)}
.rv-badge.lg{font-size:19px;padding:8px 14px}

.view-review .filters .nsel{max-width:260px}
.review-top{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:14px}
.qnav{display:flex;gap:6px}
.rev-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;margin-bottom:16px}
.rev-head h2{font-size:clamp(20px,4.4vw,26px);margin:2px 0 8px}
.kicker{display:block;font-size:11px;font-weight:800;letter-spacing:.12em;color:var(--mute)}
.rev-who{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.rev-grid{display:grid;grid-template-columns:minmax(0,1fr) 350px;gap:16px;align-items:start}
.rv-side.sticky{position:sticky;top:calc(var(--top) + var(--sat) + 12px)}
.rv-side h3{margin:0 0 8px}
.rv-side .btn.wide{margin-top:8px}
.rv-quick{margin:10px 0}
.rv-quick .btn{font-size:12.5px;font-weight:600}
.lbl{font-size:11.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--mute);margin-top:4px}
.score-pick{display:flex;flex-wrap:wrap;gap:5px}
.sp{width:36px;height:36px;border-radius:9px;background:var(--card);box-shadow:inset 0 0 0 1.5px var(--line2);
  font-weight:800;font-size:14.5px;color:var(--ink2);transition:transform .15s,background .2s,color .2s,box-shadow .2s}
@media (hover:hover){.sp:hover{box-shadow:inset 0 0 0 1.5px var(--ink2)}}
.sp.on{background:var(--blue);box-shadow:none;color:#fff;transform:scale(1.07)}
.rv-check{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--ink2);margin:4px 0 2px}
.rv-check input{width:18px;height:18px;flex:none;accent-color:var(--blue)}
.rv-body{min-height:130px;line-height:1.5;resize:vertical;padding:12px}
.rv-prev{background:var(--soft);border-radius:var(--r);padding:11px 13px;margin-bottom:10px}
.rv-prev b{margin-right:8px}
.rv-prev p{margin:6px 0 0;font-size:14px;line-height:1.5;white-space:pre-wrap}
@media (max-width:900px){
  .rev-grid{grid-template-columns:minmax(0,1fr)}
  .rv-side.sticky{position:static}
}

/* what the student sees, above the part it is about — Extra's feedback block */
.feedback{background:var(--blue-t);border-left:4px solid var(--blue);border-radius:var(--r);
  padding:13px 15px;margin-bottom:14px}
.fb-head{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-weight:800;font-size:14.5px}
.fb-head .ic{color:var(--blue3)}
.fb-by{margin-left:auto;font-weight:600}
.rv-got-body{margin:9px 0 0;font-size:14.5px;line-height:1.55;white-space:pre-wrap}
.rv-on::before{content:"\00b7";margin:0 6px;opacity:.6}
.rv-on{font-style:normal;font-weight:600;color:var(--mute)}

/* the student's work, shown as the exercise itself and not to be played with */
.mk-ro{margin-top:8px}
.mk-ro button,.mk-ro input,.mk-ro textarea,.mk-ro select,.mk-ro a{pointer-events:none}
.mk-ro .ex{box-shadow:none;border:1px solid var(--line);margin-bottom:10px}
.mk-ro .practice,.mk-ro .writing{display:flex;flex-direction:column;gap:10px}
.quizwrap-all{display:flex;flex-direction:column;gap:12px}
.quizwrap-all .q-prog{display:none}
.quizwrap-all .q-card{animation:none}
.mk-ro .rise{animation:none}
/* nothing in here can be acted on, so the buttons that invite action go */
.mk-ro [data-a$="-again"],.mk-ro [data-a="story-back"],.mk-ro [data-a="rv-again"],
.mk-ro [data-a="tb-save"],.mk-ro [data-a="e-save"],.mk-ro [data-a="e-model"],
.mk-ro [data-a$="-check"],.mk-ro .rec,.mk-ro .vq-gate{display:none}
/* why a button is not available yet — a disabled control with no reason is the
   same as a broken one to the person pressing it */
.why{margin:7px 0 0}


/* ───────────────────────── Open hours
   A teacher's timetable and the windows a student can take. Rows are the same
   shape on both sides, so a teacher recognises what their students are seeing. */
.hr-who{display:flex;align-items:center;gap:12px}
.hr-switch,.hr-head{display:flex;align-items:center;gap:12px;margin-bottom:10px}
.hr-list{display:flex;flex-direction:column;gap:8px}
.hr-slot{display:flex;align-items:center;gap:12px}
.hr-time{flex:none;width:76px;display:flex;flex-direction:column;line-height:1.2}
.hr-time b{font-size:13px;font-weight:800}
.hr-time span{font-size:19px;font-weight:800;font-variant-numeric:tabular-nums}
.hr-slot .b{font-weight:700}
.hr-slot.mine{box-shadow:inset 0 0 0 2px var(--green);background:var(--green-t)}
.hr-slot.mine .hr-time span{color:var(--green3)}
.hr-slot.taken{background:var(--soft)}
.hr-week{display:flex;flex-direction:column;gap:2px}
.hr-row{display:flex;flex-direction:column;gap:1px;padding:9px 0;border-bottom:1px solid var(--line)}
.hr-row:last-child{border-bottom:0}
.hr-row.on{padding-left:10px;border-left:3px solid var(--blue);margin-left:-13px}
.hr-g{display:flex;align-items:center;gap:8px}
.hr-g em{font-style:normal;font-size:11.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--blue3);background:var(--blue-t);padding:2px 7px;border-radius:99px}
/* the preview of the students' own screen: their layout, nothing pressable */
.hr-prev{padding-bottom:6px}
.hr-prev-h{width:100%;text-align:left;gap:10px;align-items:center;background:none;padding:0}
.hr-prev-h .b{display:block;font-weight:700}
.hr-prev-h .ic{color:var(--mute);flex:none}
.hr-prev-none{margin:10px 0 6px}
.hr-prev-in{margin-top:12px;padding:12px;border-radius:var(--r);background:var(--soft);
  border:1px dashed var(--line2)}
.hr-prev-in>*:first-child{margin-top:0}
.hr-prev-in button,.hr-prev-in a{pointer-events:none}
.hr-prev-in .sec-head h2{font-size:15px}
.hr-prev-in .card{box-shadow:none;border:1px solid var(--line)}

@media (max-width:520px){
  .hr-time{width:66px}
  .hr-time span{font-size:17px}
  .hr-switch,.hr-head,.hr-slot{flex-wrap:wrap}
}


/* ───────────────────────── pointer and selection
   The interface is not a document. Dragging across a card, a tab or a heading
   used to start a text selection and leave the pointer as an I-beam, which
   reads as if the app is a page that half-loaded. Text a person might actually
   want to copy — what they wrote, what their teacher wrote, a word and its
   meaning, a message — keeps selection on. */
.topbar,.tabbar,.nav,.sec-head,.ptabs,.seg,.filters,.board,.board-wrap,.hello,
.l-head,.stats,.lane,.road,.exit,.plate,.kpi,.shield,.hr-time,.rv-badge,.sr-end,
.li,.trow,.class,.stage-card,.sign,.rstop,.ex .eh,.q-prog,.result,.hr-prev-h{
  -webkit-user-select:none;user-select:none}
input,textarea,[contenteditable],
.wtile,.bubble,.w-mean,.w-ex,.de-m,.de-ex,.de-tr,.rv-got-body,.rv-prev p,.mk-text,.fb-b,
.model,.essay-read,.rs,.story-cap,.dq,.cue-card,.nb-body,.tg-msgs{
  -webkit-user-select:text;user-select:text}


/* ───────────────────────── Speaking: kick-off, the big speech, class games */
.warm-q{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:8px;font-size:15.5px;line-height:1.45}
.idea-cards{display:flex;flex-direction:column;gap:8px;margin-top:10px}
.idea summary{display:flex;align-items:baseline;gap:9px;cursor:pointer;list-style:none;font-size:15px}
.idea summary::-webkit-details-marker{display:none}
.idea summary::after{content:"";margin-left:auto;width:8px;height:8px;border-right:2px solid var(--mute);
  border-bottom:2px solid var(--mute);transform:rotate(45deg);transition:transform .2s}
.idea[open] summary::after{transform:rotate(-135deg)}
.idea-q{margin:10px 0 8px;font-size:15.5px;line-height:1.45}
.idea-w{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:9px}
.idea-p{margin:0;padding-left:18px;font-size:14.5px;line-height:1.6;color:var(--ink2)}
.idea-p li{font-style:italic}

.speech .task{margin-bottom:8px}
.sp-clock{margin:14px 0;padding:14px;border-radius:var(--r);background:var(--soft);
  border:1.5px solid var(--line);transition:border-color .25s,background .25s}
.sp-clock.band{background:var(--green-t);border-color:var(--green)}
.sp-time{font-size:34px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums;text-align:center}
.sp-clock.band .sp-time{color:var(--green3)}
.sp-bar{position:relative;height:8px;border-radius:99px;background:var(--line2);margin:12px 0 10px;overflow:hidden}
.sp-bar i{display:block;height:100%;border-radius:99px;background:var(--blue);transition:width .9s linear}
.sp-clock.band .sp-bar i{background:var(--green)}
.sp-mark{position:absolute;top:-3px;width:2px;height:14px;background:var(--ink2);opacity:.55}
.sp-ctl{align-items:center;gap:12px}
.sp-words{margin-top:4px}
.sp-n{font-size:16px;font-weight:800;color:var(--mute)}
.sp-n.on{color:var(--green3)}
.sp-words .wchip{cursor:pointer;transition:background .18s,color .18s,transform .12s}
.sp-words .wchip:active{transform:scale(.95)}
.wchip.pop{animation:wpop .42s var(--ease)}
@keyframes wpop{0%{transform:scale(1)}36%{transform:scale(1.16)}100%{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.wchip.pop{animation:none}}

.games .game{align-items:flex-start;gap:12px}
.games .gi{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;flex:none;
  background:var(--yellow-t);color:var(--yellow-ink)}
.games .s{line-height:1.5;white-space:normal}
@media (max-width:520px){.sp-time{font-size:28px}}

/* ───────── progress: the student's own numbers, and the review section */
/* Three across suits the six-tile boards; a four-tile row says so and gets
   four, so neither is ever left with one tile stranded on a line of its own.
   Two across on a phone for both. */
.kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:14px 0 4px}
.kpis.four,.ht-kpis{grid-template-columns:repeat(4,1fr)}
@media (max-width:860px){.kpis.four,.ht-kpis{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.kpis{grid-template-columns:repeat(2,1fr)}}
.kpi{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:12px 11px 11px;
  box-shadow:var(--shadow);position:relative;overflow:hidden}
.kpi-i{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;background:var(--soft2);color:var(--ink2);margin-bottom:8px}
.kpi-i .ic{width:17px;height:17px}
.kpi b{display:block;font-size:clamp(21px,5.4vw,28px);font-weight:800;line-height:1.05;letter-spacing:-.015em}
.kpi-l{display:block;font-size:12px;font-weight:700;color:var(--ink2);line-height:1.2;margin-top:2px}
.kpi-s{display:block;font-size:11px;font-weight:600;color:var(--mute);line-height:1.25;margin-top:3px}
.kpi.hot .kpi-i{background:var(--orange-t);color:var(--orange)}
.kpi.good .kpi-i{background:var(--green-t);color:var(--green3)}
.kpi.mid .kpi-i{background:var(--yellow-t);color:var(--yellow-ink)}
.kpi.low .kpi-i{background:var(--red-t);color:var(--red2)}
@media (max-width:420px){.kpis{grid-template-columns:repeat(2,1fr)}}

.act{position:relative}
.act-top{display:block;font-size:11px;font-weight:700;color:var(--mute);margin-bottom:4px}
.act-svg{display:block;width:100%;height:128px}
.ac-base{stroke:var(--line2);stroke-width:1}
.ac-bar{fill:var(--green2)}
.ac-bar.today{fill:var(--red)}
.ac-zero{fill:var(--line2)}
.act-x{display:flex;margin-top:6px}
.act-x span{flex:1;text-align:center;font-size:10.5px;font-weight:700;color:var(--mute);white-space:nowrap}
.act-x span.now{color:var(--red2)}

.skills{padding:4px 0}
.skill{display:flex;align-items:center;gap:12px;padding:11px 14px;border-bottom:1px solid var(--line)}
.skill:last-child{border-bottom:0}
.sk-i{width:34px;height:34px;flex:none;border-radius:9px;display:grid;place-items:center;background:var(--blue-t);color:var(--blue3)}
.sk-i .ic{width:19px;height:19px}
.sk-m{flex:1;min-width:0}
.sk-t{display:flex;justify-content:space-between;gap:10px;align-items:baseline;margin-bottom:6px}
.sk-t b{font-weight:700;font-size:14.5px}

.sbars{padding:4px 0}
.sbar{display:flex;align-items:center;gap:12px;padding:9px 14px;border-bottom:1px solid var(--line);
  text-decoration:none;color:var(--ink)}
.sbar:last-child{border-bottom:0}
.sbar .sb-m{flex:1;min-width:0}
.sbar.zero .meter>i{background:var(--line2)}
@media (hover:hover){.sbar:hover{background:var(--soft)}}

.fblist{display:flex;flex-direction:column;gap:10px}
.fbcard{background:var(--card);border:1px solid var(--line);border-left:4px solid var(--line2);
  border-radius:var(--r);padding:12px 14px;box-shadow:var(--shadow)}
.fbcard.new{border-left-color:var(--blue)}
.fb-h{display:flex;align-items:flex-start;gap:10px}
.fb-h b{display:block;font-weight:800;font-size:14.5px}
.fb-h small{display:block;font-size:12.5px;margin-top:1px}
/* .heat is an inline grid, so a score and its "/10" become two rows unless the
   flow is told to run across */
.fb-h .heat{grid-auto-flow:column;gap:1px;align-items:baseline}
.fb-b{margin:9px 0 0;font-size:14.5px;line-height:1.55;white-space:pre-wrap}
.fb-f{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:10px}
/* the byline moves to a line of its own rather than breaking across two */
.fb-f .mute{flex:1 1 150px;white-space:nowrap}

/* the lesson's own progress, on the lesson in the list */
.rm-bar{display:block;margin-top:8px}
.rm-bar .meter{height:5px}
.rm-fb{display:inline-flex;align-items:center;gap:3px;font-style:normal;color:var(--blue2)}
.rm-fb::before{content:"\00b7";margin:0 5px;color:var(--mute)}
.rm-fb .ic{width:12px;height:12px}

/* ───────── the word quiz: stopping, and what was missed */
.qz-back{text-align:center}
.qz-back .art{max-width:160px;margin:0 auto 10px}
.qz-back h2{margin:0 0 4px}
.qz-back .row{justify-content:center;margin-top:14px}
.qz-leave{margin-top:12px}
.qz-clean{display:flex;align-items:center;gap:14px;margin-top:14px}
.qz-clean .ic{color:var(--green2);flex:none}
.qz-clean b{font-size:15.5px}
.qz-clean p{margin:2px 0 0}
.qz-miss .li .s b{color:var(--green3)}
.qz-said{display:block;font-style:normal;margin-top:1px;color:var(--mute)}
.qz-miss-act{margin-top:12px}

/* ───────── voice messages */
.tg-rec{display:flex;align-items:center;gap:10px;padding:10px 12px calc(10px + var(--sab));
  background:var(--card);border-top:1px solid var(--line)}
body[data-tab="chat"] .tg.has-conv .tg-rec{padding-bottom:10px}
.tg-rec .rec-meter{min-width:50px}
.tg-mic{background:var(--soft);color:var(--ink2)}
@media (hover:hover){.tg-mic:hover{background:var(--soft2)}}

.vmsg{display:flex;align-items:center;gap:9px;min-width:170px;padding:2px 0 1px}
.vm-play{flex:none;background:var(--green2);color:#fff;border:0}
.vm-play.on,.vm-play:disabled{opacity:1}
@media (hover:hover){.vm-play:hover{background:var(--green)}}
.vm-wave{flex:1;display:flex;align-items:center;gap:2px;height:24px;min-width:60px}
.vm-wave>i{flex:1;min-width:2px;border-radius:99px;background:var(--line2)}
.bubble.mine .vm-wave>i{background:rgba(10,107,75,.42)}
:root[data-theme="dark"] .vm-wave>i{background:#4A565C}
:root[data-theme="dark"] .bubble.mine .vm-wave>i{background:rgba(255,255,255,.34)}
.vm-t{flex:none;font-size:12.5px;font-weight:700;color:var(--mute);font-variant-numeric:tabular-nums}
.vmsg.sending{color:var(--mute);gap:6px}
.vmsg.sending .ic{color:var(--mute)}

/* ───────── the notification sheet, split into new and read */
.nf-h{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin:14px 2px 7px;font-size:12px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:var(--mute)}
.nf-h:first-child{margin-top:2px}
.nf-h .btn{letter-spacing:0;text-transform:none}

/* ───────── work a teacher has set */
.asg{margin-top:10px;padding-top:10px;border-top:1px solid var(--line)}
.asg-h{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:8px}
.asg-h b{font-size:13.5px}
.asg-chips{gap:6px}
.asg-c{border:1.5px solid var(--line2);background:transparent;color:var(--ink2)}
.asg-c.set{background:var(--green-t);border-color:var(--green2);color:var(--green3)}
.asg-c.must{background:var(--red-t);border-color:var(--red);color:var(--red2);font-weight:800}
.asg-key{margin:8px 0 10px}
.asg-shut{display:flex;align-items:center;gap:6px;margin:10px 0 0;padding-top:10px;border-top:1px solid var(--line)}
.asg-list .li.col{display:block}
.asg-list .li.col .row{display:flex;align-items:center;gap:12px}

/* the tab of a part that has been set */
.ptabs a .tab-asg{position:absolute;top:5px;right:7px;width:7px;height:7px;border-radius:50%;background:var(--green2)}
.ptabs a.must .tab-asg{background:var(--red)}
.ptabs a{position:relative}

.hw .li{align-items:center}
.hw-i{width:30px;height:30px;flex:none;border-radius:9px;display:grid;place-items:center;background:var(--green-t);color:var(--green3)}
.hw-i.must{background:var(--red-t);color:var(--red2)}
.hw-i .ic{width:17px;height:17px}
.hw-must{font-style:normal;font-size:11px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  color:var(--red2);background:var(--red-t);border-radius:5px;padding:1px 5px;margin-left:6px}

/* ───────── looking a word up outside the course */
.dol-ask,.dol-out{margin-top:14px}
.dol-h{display:flex;align-items:flex-start;gap:11px}
.dol-h>.ic{flex:none;color:var(--blue2);width:24px;height:24px;margin-top:1px}
.dol-h b{display:block;font-size:15.5px;font-weight:800}
.dol-h .grow>span{display:block;margin-top:2px}
.dol-h .de-pr{margin-top:2px}
.dol-note{margin:10px 0 12px;line-height:1.45}
.dol-tr{display:flex;align-items:baseline;gap:9px;margin:12px 0 4px;padding:9px 12px;
  background:var(--green-t);border-radius:var(--r);flex-wrap:wrap}
.dol-tr b{font-size:16px;color:var(--green3)}
.dol-lbl{font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--green3);opacity:.8}
.dol-p{margin-top:12px}
.dol-p ol{margin:6px 0 0;padding-left:20px}
.dol-p li{margin-bottom:6px;line-height:1.5}
.dol-ex{display:block;font-style:italic;color:var(--mute);margin-top:2px}
.dol-out .btn.ghost{margin-top:2px}

/* ───────── a word from the stage ahead */
.peek{margin-top:16px}
.peek-h{display:flex;align-items:flex-start;gap:11px}
.peek-h b{display:block;font-size:15px;font-weight:800}
.peek-h .grow>span{display:block;margin-top:2px}
.peek-score{flex:none;font-weight:800;color:var(--mute);font-size:13.5px}
.peek-w{margin:14px 0 12px;text-align:center;font-size:clamp(22px,6vw,28px);font-weight:800;letter-spacing:-.015em}
.peek-w em{display:block;font-style:normal;font-size:14px;font-weight:600;color:var(--mute);margin-top:3px}
.peek-o{gap:8px}
.peek-end{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px}
.peek-end .grow{font-size:14px;line-height:1.45;min-width:140px}
.peek-end .grow.ok{color:var(--green3);font-weight:700}

/* ───────── thumbs
   A few controls are smaller than a fingertip: a text link in a section
   heading, the lesson chips under a dictionary entry, a selection box in a
   list. Making them visually bigger would be wrong — a link that looks like a
   button is a button — so each keeps its size and grows an invisible area
   around it instead. Nothing here moves anything on the page.

   The words in "spot the mistake" are deliberately left alone: they sit in a
   paragraph two lines apart, and an area tall enough to help would reach into
   the line above and take taps meant for the word there. A short word being a
   short word is how reading works. */
.sec-head .link,.de-at .chip.sm,.check{position:relative}
.sec-head .link::after,.de-at .chip.sm::after,.check::after{
  content:"";position:absolute;left:0;right:0;top:50%;height:34px;transform:translateY(-50%)}
/* only the selection box is narrow as well as short */
.check::after{left:-7px;right:-7px}

/* ───────── reviews gathered by lesson */
.fbl{background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden}
.fbl.new{border-left:4px solid var(--blue)}
.fbl>summary{display:flex;align-items:center;gap:12px;padding:11px 13px;cursor:pointer;list-style:none}
.fbl>summary::-webkit-details-marker{display:none}
.fbl>summary b{display:block;font-weight:800;font-size:14.5px}
.fbl>summary small{display:block;font-size:12.5px;margin-top:1px}
.fbl>summary .ic{flex:none;color:var(--mute);transition:transform .2s var(--ease)}
.fbl[open]>summary .ic{transform:rotate(180deg)}
.fbl[open]>summary{border-bottom:1px solid var(--line)}
@media (hover:hover){.fbl>summary:hover{background:var(--soft)}}
.fbl-body{padding:12px 13px;display:flex;flex-direction:column;gap:10px;background:var(--soft)}
.fbl-body .fbcard{box-shadow:none}
/* a score and its "/10" are one thing: .heat is an inline grid, so without
   this they stack into two rows */
.fbl>summary .heat{grid-auto-flow:column;gap:1px;align-items:baseline;flex:none}
/* the switch sits beside the heading on a wide screen and under it on a
   narrow one, rather than squeezing the words into two lines */
.page .sec-head{flex-wrap:wrap}
.page .sec-head .seg{flex:none}
@media (max-width:460px){.page .sec-head .seg{flex:1 1 100%;margin-top:6px}}

/* a mark kept from before answers were stored */
.ex-old{display:flex;align-items:flex-start;gap:7px;margin:0 0 12px;padding:9px 11px;
  background:var(--yellow-t);border-radius:var(--r-s);color:var(--yellow-ink);
  font-size:13px;line-height:1.45}
.ex-old .ic{flex:none;margin-top:1px}
/* the home banner is a thing you tap, so it should not select like text */
.notice{-webkit-user-select:none;user-select:none}

/* ───────── listening */
.ls-top h3{margin:0 0 2px;font-size:17px}
.ls-how{margin:12px 0;font-size:14px;line-height:1.5;color:var(--ink2)}
.ls-player{margin:4px 0 12px}

/* ── THE APP'S OWN AUDIO PLAYER ──
   The real <audio> is in the page doing the decoding; nothing of the device's
   own control strip is ever drawn. Same reasoning as the dropdown and the
   speed slider: one app, the same on every phone. */
.au{display:flex;align-items:center;gap:13px;padding:12px 14px;border-radius:var(--r-s);
  background:var(--soft);box-shadow:inset 0 0 0 1.5px var(--line)}
.au-el{display:none}
.au-play{flex:none;width:50px;height:50px;border:0;border-radius:50%;cursor:pointer;
  display:grid;place-items:center;background:var(--red);color:#fff;box-shadow:var(--shadow);
  transition:transform .16s var(--spring),filter .16s var(--ease)}
.au-play .ic{width:25px;height:25px;margin-left:2px}      /* the triangle sits right of centre */
.au.on .au-play .ic{margin-left:0}
@media (hover:hover){.au-play:hover{filter:brightness(1.08)}}
.au-play:active{transform:scale(.93)}
.au-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}

/* the bar, wearing the same dress as the speed slider */
.au-seek{-webkit-appearance:none;appearance:none;width:100%;height:20px;background:none;cursor:pointer;display:block}
.au-seek::-webkit-slider-runnable-track{height:6px;border-radius:99px;
  background:linear-gradient(to right,var(--red) var(--p,0%),var(--soft2) var(--p,0%))}
.au-seek::-moz-range-track{height:6px;border-radius:99px;background:var(--soft2)}
.au-seek::-moz-range-progress{height:6px;border-radius:99px;background:var(--red)}
.au-seek::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;margin-top:-5px;
  border-radius:50%;background:var(--red);box-shadow:inset 0 0 0 3px rgba(255,255,255,.92),var(--shadow);
  transition:transform .14s var(--spring)}
.au-seek::-moz-range-thumb{width:16px;height:16px;border:0;border-radius:50%;background:var(--red);
  box-shadow:inset 0 0 0 3px rgba(255,255,255,.92),var(--shadow)}
.au-seek:active::-webkit-slider-thumb{transform:scale(1.2)}
.au-seek:focus-visible{outline:2px solid var(--red);outline-offset:3px;border-radius:99px}

.au-row{display:flex;align-items:center;gap:3px}
.au-t{font-size:13px;color:var(--mute);font-variant-numeric:tabular-nums;white-space:nowrap}
.au-t b{color:var(--ink);font-weight:800}
.au-b{flex:none;min-width:32px;height:32px;padding:0 7px;border:0;border-radius:9px;cursor:pointer;
  display:grid;place-items:center;background:none;color:var(--mute);
  font:inherit;font-size:12.5px;font-weight:800;transition:background .15s var(--ease),color .15s var(--ease)}
.au-b .ic{width:19px;height:19px}
@media (hover:hover){.au-b:hover{background:var(--soft2);color:var(--ink)}}
.au-b:active{background:var(--soft2)}
.au-rate{letter-spacing:.01em}
.au-rate.on{background:var(--red-t);color:var(--red2)}   /* anything but normal speed says so */

/* the teacher's review page gives it less room */
.mk-ro .au,.rev-grid .au{padding:10px 12px;gap:11px}
.mk-ro .au-play,.rev-grid .au-play{width:44px;height:44px}
.mk-ro .au-play .ic,.rev-grid .au-play .ic{width:22px;height:22px}
/* …and it is the one control there that is not read-only */
.mk-ro .au button,.mk-ro .au input{pointer-events:auto}
.ls-read{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.ls-ctl{margin-top:2px}
.ls-script{margin-top:12px;display:flex;flex-direction:column;gap:12px;transition:filter .25s var(--ease)}
/* "listen first" is the point of the exercise: the script starts hidden and
   the gaps stay usable, so a student can type what they hear before reading */
.ls-script.blur{-webkit-user-select:none;user-select:none}
/* one blurred layer for the whole script rather than one per line: the
   gaps are lifted back out of it so they stay sharp and typeable */
.ls-script.blur .ls-line p{filter:blur(4.5px)}
.ls-script.blur .ls-line p .lsg{filter:blur(0)}
.ls-script.blur .lsg{filter:none}
.ls-line{display:flex;gap:10px;align-items:flex-start}
.ls-who{flex:none;min-width:74px;font-size:11px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;
  color:var(--blue2);padding-top:4px}
.ls-line.b .ls-who{color:var(--red2)}
.ls-line p{margin:0;flex:1;min-width:0;font-size:15.5px;line-height:2}
/* the listening gap. NOT `lg`: that is the size modifier `av lg`,
   `shield lg` and `rv-badge lg` have carried for far longer, and taking
   the name knocked every large avatar and stage shield out of centre. */
.lsg{display:inline-flex;align-items:baseline;gap:5px}
.lsg-in{font:inherit;font-weight:700;color:var(--ink);background:var(--soft);border:0;
  border-bottom:2px solid var(--line2);border-radius:6px 6px 0 0;padding:1px 6px;min-width:5ch;outline:0}
.lsg-in:focus{background:var(--blue-t);border-bottom-color:var(--blue2)}
.lsg.ok .lsg-in{background:var(--green-t);border-bottom-color:var(--green2);color:var(--green3)}
.lsg.bad .lsg-in{background:var(--red-t);border-bottom-color:var(--red);color:var(--red2);text-decoration:line-through}
.lsg-a{font-style:normal;font-weight:800;color:var(--green3);font-size:14px}
.ls-foot{margin-top:14px}
.listening .ex-res{margin-top:14px}
@media (max-width:520px){
  .ls-line{flex-direction:column;gap:2px}
  .ls-who{padding-top:0}
  .ls-line p{line-height:2.1}
}

/* ─────────────────────────────────────────────────────────────────────────
   Long pages, on a phone.

   The dictionary is the worst of them: for a student four stages in it is six
   hundred entries, nine thousand elements and a page a hundred and eighteen
   thousand pixels tall; for a teacher it is three times that. The browser was
   laying out and painting every one of them on every scroll frame, which is
   what the stutter was.

   content-visibility lets it skip everything outside the viewport entirely.
   The paired intrinsic size is what each item is roughly worth, so the
   scrollbar and the page height stay honest instead of jumping about as
   entries come into view. A browser that does not know the property ignores
   both lines and renders exactly as before.
   ───────────────────────────────────────────────────────────────────────── */
.dict-e{content-visibility:auto;contain-intrinsic-size:auto 132px}
.idiom{content-visibility:auto;contain-intrinsic-size:auto 300px}
.wtile{content-visibility:auto;contain-intrinsic-size:auto 86px}
.ls-line{content-visibility:auto;contain-intrinsic-size:auto 78px}
.fbcard{content-visibility:auto;contain-intrinsic-size:auto 150px}
/* Not the roadmap. content-visibility brings paint containment with it, which
   clips a child to its parent's box — and the exit sign hangs 23px outside
   its stop, straddling the road on purpose. Containment sliced every sign in
   half, which is why the numbers looked welded into the asphalt. A stage has
   twelve stops; it was never what made scrolling heavy anyway. */
/* a blurred script must stay blurred while it is skipped, so the gaps above
   are the only part lifted out of it */
.ls-script.blur .ls-line{content-visibility:visible}
.dict-more{margin-top:14px}

/* ───────── THE STUDENT'S OWN PAGE (stu.js)
   A page, not a sheet: a teacher reads it on a phone between classes, so it
   is one column of plain cards and nothing scrolls inside anything else. */
.page-stu .back-link{margin-bottom:12px}
.stu-head{display:flex;flex-direction:column;gap:14px}
.stu-top{display:flex;align-items:center;gap:14px}
.stu-top h1{margin:0 0 5px;font-size:clamp(21px,5vw,27px);line-height:1.15}
.stu-top .chips-row{gap:6px}
.stu-acts{display:flex;flex-wrap:wrap;gap:8px}
.stu-acts .btn{flex:1 1 auto;min-width:fit-content}
@media (max-width:520px){.stu-acts .btn{flex:1 1 calc(50% - 4px)}}

/* the facts a teacher would otherwise ring the office for */
.stu-facts-card{margin-top:12px}
.facts-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px 14px}
@media (min-width:720px){.facts-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media (max-width:400px){.facts-grid{grid-template-columns:1fr}}
.fact-cell{display:flex;align-items:center;gap:9px;padding:9px 0;min-width:0;border-bottom:1px solid var(--line)}
.facts-grid .fact-cell:last-child,.facts-grid .fact-cell:nth-last-child(2){border-bottom:0}
@media (max-width:400px){.facts-grid .fact-cell:nth-last-child(2){border-bottom:1px solid var(--line)}}
.fact-cell > .ic{color:var(--mute);flex:none}
.fact-cell > div{min-width:0;flex:1}
.fact-cell small{display:block;font-size:11.5px;font-weight:700;color:var(--mute);letter-spacing:.01em}
.fact-cell b{display:block;font-size:14.5px;font-weight:700;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fact-cell b a{color:inherit;text-decoration:none}
@media (hover:hover){.fact-cell b a:hover{text-decoration:underline}}
.stu-active-row{margin-top:12px}
.page-stu .p-h{margin:22px 0 10px;font-size:18px}
.page-stu .sec-head{margin-top:18px}
/* the board is the student's own, so it keeps its own top margin in check here */
.page-stu .kpis{margin-top:4px}

/* ───────── a review row has two destinations
   The student, and the work. One row, two targets, so neither has to guess
   which one a tap meant. */
.rv-row{display:flex;align-items:stretch;gap:0;padding:0}
.rv-who-btn{flex:1;min-width:0;display:flex;align-items:center;gap:12px;padding:11px 4px 11px 14px;
  border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;border-radius:var(--r-s)}
.rv-open{flex:none;display:flex;align-items:center;gap:4px;padding:11px 12px 11px 6px;
  text-decoration:none;color:inherit;border-radius:var(--r-s)}
.rv-open .ic{color:var(--mute);flex:none}
@media (hover:hover){.rv-who-btn:hover,.rv-open:hover{background:var(--soft)}}
.rv-who-btn:active,.rv-open:active{background:var(--soft2)}
.rv-rows .rv-row{border-bottom:1px solid var(--line)}
.rv-rows .rv-row:last-child{border-bottom:0}

/* the same on the marking page: the name is a way back to the person */
button.rev-who{display:flex;align-items:center;gap:9px;flex-wrap:wrap;border:0;background:none;
  font:inherit;color:inherit;text-align:left;cursor:pointer;padding:6px 8px;margin:4px -8px 0;border-radius:var(--r-s)}
@media (hover:hover){button.rev-who:hover{background:var(--soft)}}
button.rev-who .ic{color:var(--mute)}

/* the dashboard's waiting-for-review block */
.wait-clear{display:flex;align-items:center;gap:12px}
.wait-clear > .ic{color:var(--green3);flex:none}
.wait-old{display:flex;align-items:center;gap:6px;margin:-4px 0 8px;color:var(--red2)}
.wait-old .ic{flex:none}

/* ───────── a mark arriving in the chat
   The one message a student waits for, so it is a card with the score drawn
   in a ring rather than a grey line that reads like a system notice. */
.bubble .fbmsg{display:flex;flex-direction:column;gap:9px;min-width:210px;margin:-2px 0 2px}
.fb-head{display:flex;align-items:center;gap:5px;font-size:11.5px;font-weight:800;
  letter-spacing:.04em;text-transform:uppercase;opacity:.78}
.fb-head .ic{flex:none}
.fb-body{display:flex;align-items:center;gap:12px}
.fb-what{min-width:0;display:flex;flex-direction:column;gap:1px}
.fb-what b{font-size:15px;font-weight:800;line-height:1.2}
.fb-what small{font-size:12.5px;opacity:.72;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.fb-ring{position:relative;width:52px;height:52px;flex:none;display:grid;place-items:center}
.fb-ring svg{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg)}
.fb-ring circle{fill:none;stroke-width:4;stroke-linecap:round}
.fb-trk{stroke:currentColor;opacity:.2}
.fb-arc{stroke:currentColor;transition:stroke-dashoffset 1.05s cubic-bezier(.22,1,.36,1) .12s}
/* one item in the middle of the ring, so a two-digit score sits where a
   one-digit score does */
.fb-n{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;line-height:1}
.fb-ring b{font-size:18px;font-weight:900;line-height:1;letter-spacing:-.02em}
.fb-ring small{font-size:9px;font-weight:800;opacity:.68;line-height:1;margin-top:1px}
.fb-ring.good{color:var(--green3)} .fb-ring.mid{color:var(--yellow-ink)} .fb-ring.low{color:var(--red2)}
/* in the student's own outgoing bubble the ring sits on a dark ground */
.bubble.mine .fb-ring.good,.bubble.mine .fb-ring.mid,.bubble.mine .fb-ring.low{color:#fff}
.fb-ring.pop b{animation:fbpop .5s var(--spring) .3s both}
@keyframes fbpop{0%{transform:scale(.6);opacity:0}60%{transform:scale(1.14)}100%{transform:scale(1);opacity:1}}

.fb-go{display:flex;align-items:center;gap:5px;text-decoration:none;color:inherit;
  font-size:13.5px;font-weight:800;padding:7px 10px;border-radius:9px;
  background:rgba(127,127,127,.14);transition:background .15s var(--ease)}
.fb-go .ic{flex:none} .fb-go .ic:last-child{margin-left:auto}
@media (hover:hover){.fb-go:hover{background:rgba(127,127,127,.24)}}
.fb-go:active{background:rgba(127,127,127,.3)}
.fbmsg.noscore .fb-body{display:none}
@media (prefers-reduced-motion:reduce){.fb-arc{transition:none}.fb-ring.pop b{animation:none}}

/* a statistic you can open: same tile, plus a chevron and something to press */
.kpi-go{cursor:pointer;text-align:left;font:inherit;position:relative;width:100%;
  border:1px solid transparent;transition:border-color .15s var(--ease),transform .15s var(--ease)}
.kpi-go>.ic:last-child{position:absolute;right:10px;top:12px;color:var(--faint)}
@media (hover:hover){.kpi-go:hover{border-color:var(--line2);transform:translateY(-1px)}
  .kpi-go:hover>.ic:last-child{color:var(--mute)}}

/* ───────── THE WEEK AS A WALL CHART (hours.js)
   Days across, hours down, classes as blocks. What a teacher is really
   looking for is the space between the blocks, so the empty cells are the
   quietest thing here and every one of them is a button. */
/* The week is a panel, not a disclosure: it is open, and it has the three
   states a window has — normal, minimised to its own bar, and maximised over
   the page. Everything that acts on the week sits in its header. */
.tt-card{margin-bottom:14px;overflow:hidden}
.tt-top{display:flex;align-items:center;gap:10px;width:100%;padding:11px 10px 11px 14px;
  font:inherit;color:inherit;text-align:left;flex-wrap:wrap}
.tt-top b{font-size:16px;font-weight:800}
.tt-top .ic{color:var(--mute);flex:none}
.tt-sum{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tt-tools{display:flex;align-items:center;gap:6px;flex:none;margin-left:auto}
.tt-card.tt-min{padding-bottom:0}
/* maximised: its own surface over the page, with the chart taking the room */
.tt-card.tt-max{position:fixed;inset:10px;z-index:140;margin:0;display:flex;flex-direction:column;
  box-shadow:var(--shadow-up)}
.tt-card.tt-max .tt-scroll{flex:1;max-height:none}
.tt-card.tt-max .tt{min-width:760px}
.tt-key{display:flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700;color:var(--mute);padding:0 14px 8px}
.tt-key i{width:10px;height:10px;border-radius:3px;display:inline-block;margin-left:7px}
.tt-key i:first-child{margin-left:0}
.k-class{background:var(--blue3)} .k-booked{background:var(--red)}
.k-free{background:var(--card);box-shadow:inset 0 0 0 1.5px var(--yellow2)}
/* The whole day is drawn and you move around inside it, both ways. The day
   names stay put at the top and the hours down the left, or you lose your
   place the moment you scroll into the evening. */
.tt-scroll{overflow:auto;-webkit-overflow-scrolling:touch;padding:0 14px 4px;max-height:430px;overscroll-behavior:contain}
.tt{display:grid;grid-template-columns:42px repeat(7,minmax(74px,1fr));gap:0;min-width:600px;position:relative}
.tt-corner{grid-column:1;grid-row:1;position:sticky;left:0;top:0;z-index:4;background:var(--card)}
.tt-d{grid-row:1;display:grid;place-items:center;font-size:12px;font-weight:800;color:var(--mute);
  padding-bottom:5px;border-bottom:1.5px solid var(--line);position:sticky;top:0;z-index:3;background:var(--card)}
.tt-d.today{color:var(--red2)}
.tt-h{grid-column:1;display:flex;align-items:flex-start;justify-content:flex-end;padding-right:7px;
  font-size:10.5px;font-weight:700;color:var(--mute);font-variant-numeric:tabular-nums;
  position:sticky;left:0;z-index:2;background:var(--card)}
.tt-cell{border:0;background:none;padding:0;margin:0;cursor:pointer;
  border-top:1px solid var(--line);border-left:1px solid var(--line);border-radius:0}
.tt-cell:nth-child(7n){border-right:1px solid var(--line)}
.tt-cell.today{background:var(--soft)}
@media (hover:hover){.tt-cell:hover{background:var(--blue-t);box-shadow:inset 0 0 0 1.5px var(--blue2)}}
.tt-cell:active{background:var(--blue-t)}

.tt-b{margin:1px 2px;padding:3px 6px;border-radius:6px;overflow:hidden;pointer-events:none;
  display:flex;flex-direction:column;justify-content:center;min-width:0;z-index:1}
.tt-b b{font-size:11.5px;font-weight:800;line-height:1.15;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tt-b small{font-size:10px;font-weight:600;opacity:.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tt-class{background:var(--blue3);color:#fff}
.tt-booked{background:var(--red);color:#fff}
.tt-free{background:var(--card);color:var(--yellow-ink);box-shadow:inset 0 0 0 1.5px var(--yellow2)}
.tt-foot{padding:2px 14px 12px;margin:0}
.tt-none{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.tt-none > .ic{color:var(--mute);flex:none}

/* ───────── THE GROUP CARD (group.js)
   One loud thing — the action a teacher came to press. Each fact said once.
   The whole top is a door into the group. */
.gcard{padding:0;overflow:hidden;display:flex;flex-direction:column}
.gcard-top{display:flex;align-items:center;gap:12px;padding:14px;text-decoration:none;color:inherit}
.gcard-top > span.grow{min-width:0;display:flex;flex-direction:column;gap:1px}
.gcard-top b{font-size:16.5px;font-weight:800;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gcard-top small{font-size:12.5px;color:var(--mute);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gcard-top > .ic{color:var(--mute);flex:none}
@media (hover:hover){.gcard-top:hover{background:var(--soft)}}

.gcard-next{display:flex;align-items:center;gap:11px;margin:0 14px;padding:10px 12px;border-radius:11px;background:var(--soft)}
.gn-l{flex:none;font-size:10px;font-weight:900;letter-spacing:.09em;text-transform:uppercase;color:var(--mute)}
.gcard-next > span.grow{min-width:0;display:flex;flex-direction:column;gap:0}
.gcard-next b{font-size:14px;font-weight:800;line-height:1.2}
.gcard-next small{font-size:12px;color:var(--mute);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gn-n{flex:none;display:flex;align-items:baseline;gap:3px}
.gn-n b{font-size:17px;font-weight:900} .gn-n small{font-size:11px;color:var(--mute);font-weight:700}

.gcard-wait{display:flex;align-items:center;gap:7px;margin:10px 14px 0;padding:8px 11px;border-radius:10px;
  background:var(--red-t);color:var(--red2);text-decoration:none;font-size:13px;font-weight:800}
.gcard-wait .ic{flex:none}
@media (hover:hover){.gcard-wait:hover{filter:brightness(.97)}}
.gcard-act{display:flex;gap:8px;padding:12px 14px 14px;margin-top:auto}
.gcard-act .btn.icon{flex:none}

/* ───────── THE GROUP PAGE */
.page-grp .back-link{margin-bottom:12px}
.grp-head{display:flex;flex-direction:column;gap:14px}
.grp-top{display:flex;align-items:center;gap:13px}
.grp-top h1{margin:0 0 3px;font-size:clamp(20px,4.6vw,26px);line-height:1.15}
.grp-acts{display:flex;flex-wrap:wrap;gap:8px}
.grp-acts .btn{flex:1 1 auto}
.btn.warn{background:var(--red-t);color:var(--red2)}
.grp-kpis{grid-template-columns:repeat(2,1fr);margin-top:14px}
@media (min-width:720px){.grp-kpis{grid-template-columns:repeat(4,1fr)}}
.grp-stu{width:100%;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;
  display:flex;align-items:center;gap:12px;padding:11px 14px}
.grp-stu > .ic{color:var(--mute);flex:none}
.grp-stu b i{font-style:normal;font-weight:600;font-size:12px}
@media (hover:hover){.grp-stu:hover{background:var(--soft)}}
.grp-tabs{display:flex;flex-direction:column;gap:2px;padding:4px 0}
.grp-tab{display:flex;align-items:center;gap:11px;padding:7px 2px}

/* ───────── hover physics on the statistics
   The tiles lift and the meters brighten under a pointer; a touch gets the
   press instead, since a finger has no hover to give. */
.kpi{transition:transform .22s var(--spring),box-shadow .22s var(--ease),border-color .2s var(--ease)}
@media (hover:hover){
  .kpi:hover{transform:translateY(-3px);box-shadow:0 10px 24px -12px rgba(0,0,0,.3),var(--shadow);border-color:var(--line2)}
  .kpi:hover .kpi-i{transform:scale(1.1) rotate(-5deg)}
  .skill:hover .meter > i,.sbar:hover .meter > i{filter:saturate(1.25) brightness(1.06)}
  .sbar:hover{background:var(--soft)}
  .sbar:hover .shield{transform:scale(1.07) rotate(-3deg)}
}
.kpi:active{transform:translateY(-1px) scale(.985)}
.kpi-i{transition:transform .22s var(--spring)}
.skill .meter > i,.sbar .meter > i{transition:filter .2s var(--ease),width .6s var(--spring)}
.sbar,.sbar .shield{transition:background .18s var(--ease),transform .22s var(--spring)}
@media (prefers-reduced-motion:reduce){
  .kpi,.kpi-i,.sbar,.sbar .shield,.skill .meter > i,.sbar .meter > i{transition:none}
  .kpi:hover,.kpi:active{transform:none}
}
.facts-h{margin:-2px 0 6px}
.facts-h b{font-size:14px;font-weight:800}

/* ───────── choosing several pieces of work at once */
.rv-bar{margin:10px 0 8px;align-items:center;gap:8px}
.rv-tick{flex:none;width:40px;display:grid;place-items:center;border:0;background:none;cursor:pointer;color:var(--mute);padding:0}
.rv-tick.off{width:40px}
.rv-tick .ic{width:21px;height:21px}
@media (hover:hover){.rv-tick:hover{color:var(--ink)}}
.rv-row.on{background:var(--blue-t)}
.rv-row.on .rv-tick{color:var(--blue3)}
.rv-rows .rv-row.on + .rv-row.on{border-top-color:transparent}
.rv-bulk{position:sticky;bottom:calc(var(--tabbar,64px) + 10px);z-index:30;margin-top:12px}
.rv-bulk-in{display:flex;align-items:center;gap:9px;padding:10px 12px;border-radius:var(--r);
  background:var(--ink);color:var(--card);box-shadow:0 12px 30px -10px rgba(0,0,0,.5)}
.rv-bulk-in b{font-size:17px;font-weight:900}
.rv-bulk-in .btn{background:rgba(255,255,255,.14);color:inherit;border:0}
.rv-bulk-in .btn.go{background:var(--red);color:#fff}
@media (hover:hover){.rv-bulk-in .btn:hover{background:rgba(255,255,255,.24)}.rv-bulk-in .btn.go:hover{filter:brightness(1.08)}}

/* ───────── PHONE: the things a finger notices
   Measured on a 390px viewport with touch, not guessed. */

/* iOS zooms the whole page in when a text field it focuses is under 16px.
   A listening has thirty of these, so every single answer yanked the page
   about. 16px exactly, which is the same size it looked before. */
.lsg-in{font-size:16px}

/* 44px is the size of a fingertip. These were all under it. */
.me-btn{width:40px;height:40px;display:grid;place-items:center}
.me-btn .av{width:34px;height:34px;font-size:13px}
.au-b{min-width:40px;height:40px;border-radius:11px}
.au-b .ic{width:20px;height:20px}
.wchip{min-height:38px;padding-top:7px;padding-bottom:7px}
.chip.sm,a.chip.sm{min-height:32px;display:inline-flex;align-items:center}
/* the exit badge's kicker — still a stylised label, just readable */
.exit small{font-size:9.5px}

/* A tap should never leave a grey box behind on a phone, and a long press on
   a control should not offer to select its label. Text the student is meant
   to read and copy from is left alone. */
button,.btn,.nsel,.tabbar a,.nav a,[data-a],[data-go]{-webkit-tap-highlight-color:transparent}
button,.btn,.tabbar a,.nav a{-webkit-touch-callout:none}

/* Momentum scrolling inside the few places that scroll on their own. */
.tt-scroll,.rtable-wrap,.tg-msgs,.wb-stages,.ptabs,.filters,.chips{-webkit-overflow-scrolling:touch}

/* ───────── THE HEAD TEACHER (head.js) */
.ht-kpis{grid-template-columns:repeat(2,1fr)}
@media (min-width:760px){.ht-kpis{grid-template-columns:repeat(4,1fr)}}
.ht-one-kpis{grid-template-columns:repeat(2,1fr)}
@media (min-width:760px){.ht-one-kpis{grid-template-columns:repeat(3,1fr)}}
.ht-row{display:flex;align-items:center;gap:12px;padding:11px 14px;text-decoration:none;color:inherit}
.ht-row > .ic{color:var(--mute);flex:none}
.ht-row b i{font-style:normal;font-weight:600;font-size:12px}
@media (hover:hover){.ht-row:hover{background:var(--soft)}}
.ht-nums{display:flex;align-items:center;gap:12px;flex:none}
.ht-n{display:flex;flex-direction:column;align-items:center;line-height:1.1}
.ht-n b{font-size:15px;font-weight:800} .ht-n b.bad{color:var(--red2)}
.ht-n small{font-size:10px;font-weight:700;color:var(--mute)}
@media (max-width:620px){.ht-nums .ht-n:nth-child(2){display:none}}
@media (max-width:460px){.ht-nums .plate{display:none}}
.page-ht .back-link{margin-bottom:12px}
.ht-head{display:flex;flex-direction:column;gap:14px}

.task-row{display:flex;align-items:flex-start;gap:11px;padding:11px 14px}
.task-row.done .sr-main b{text-decoration:line-through;opacity:.6}
.task-tick{flex:none;width:30px;display:grid;place-items:center;border:0;background:none;cursor:pointer;color:var(--mute);padding:2px 0 0}
.task-tick .ic{width:21px;height:21px}
@media (hover:hover){.task-tick:hover{color:var(--ink)}}
.task-row.late .sr-i,.task-row.late .task-tick{color:var(--red2)}
.task-body{display:block;margin-top:3px;white-space:pre-wrap}
.sr-i.p-ok{background:var(--green-t);color:var(--green3)}
.sr-i.p-late{background:var(--red-t);color:var(--red2)}
.sr-i.p-urgent{background:var(--red-t);color:var(--red2)}
.task-none{display:flex;align-items:center;gap:12px}
.task-none > .ic{color:var(--green3);flex:none}

.hp-row{display:flex;align-items:flex-start;gap:11px;padding:12px 14px;flex-wrap:wrap}
.hp-row.closed{opacity:.6}
.hp-body{display:block;margin-top:3px;white-space:pre-wrap}
.hp-act{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-left:auto}
.grant-row{margin-bottom:0}
.warn-seg{width:100%}

/* ───────── A WARNING
   Over everything, blurred behind. The sign breathes rather than flashes:
   a flashing red square reads as an error, and this is not an error — it is
   a person being spoken to. The button arrives only when the seconds are up,
   because the seconds are the whole point. */
#app.warn-blurred{filter:blur(7px) saturate(.7);pointer-events:none;transition:filter .45s var(--ease)}
.warnwrap{position:fixed;inset:0;z-index:9000;display:grid;place-items:center;padding:24px;
  background:rgba(8,6,14,.55);opacity:0;transition:opacity .26s var(--ease)}
.warnwrap.in{opacity:1}
.warnbox{width:min(440px,100%);text-align:center;padding:30px 24px 24px;border-radius:22px;
  background:var(--card);box-shadow:0 30px 80px -20px rgba(0,0,0,.6);
  transform:translateY(14px) scale(.97);transition:transform .32s var(--spring)}
.warnwrap.in .warnbox{transform:none}
.warnsign{width:84px;height:84px;margin:0 auto 16px;border-radius:50%;display:grid;place-items:center;
  background:var(--red-t);color:var(--red);animation:warnbreathe 2.4s ease-in-out infinite}
.warnsign .ic{width:46px;height:46px;stroke-width:2.1}
@keyframes warnbreathe{
  0%,100%{box-shadow:0 0 0 0 rgba(210,16,48,.42),0 0 26px 2px rgba(210,16,48,.3);transform:scale(1)}
  50%    {box-shadow:0 0 0 16px rgba(210,16,48,0),0 0 46px 8px rgba(210,16,48,.5);transform:scale(1.045)}}
.warnwrap.final .warnsign{background:var(--red);color:#fff}
.warnwrap.note .warnsign{background:var(--yellow-t);color:var(--yellow-ink);animation-duration:3.4s}
.warnkick{font-size:12px;font-weight:900;letter-spacing:.11em;text-transform:uppercase;color:var(--red2)}
.warnwrap.note .warnkick{color:var(--yellow-ink)}
.warnmsg{margin:9px 0 22px;font-size:17.5px;font-weight:600;line-height:1.45;color:var(--ink);white-space:pre-wrap}
.warngo{min-height:50px;font-size:16px}
.warngo:disabled{opacity:1;background:var(--soft2);color:var(--mute);cursor:default}
.warngo .warncount{font-variant-numeric:tabular-nums}
.warngo.ready{animation:warnpop .34s var(--spring)}
@keyframes warnpop{0%{transform:scale(.92);opacity:.5}100%{transform:scale(1);opacity:1}}
@media (prefers-reduced-motion:reduce){
  .warnsign{animation:none;box-shadow:0 0 0 6px rgba(210,16,48,.25)}
  .warnbox,.warngo.ready{transition:none;animation:none;transform:none}}
