/* CodeGrove v1 (J5, 2026-10-17): the approved Mockup 4 look (mockups/studio.css + studio4.css), made into the real lab.
   His rules: cool blue, 5 px corners on everything, a Files panel that folds into the icon strip, drag lines,
   Input and Output in separate panels, Check with a small results pop-up and a Hint button beside it.
   Page states are classes on <html>, set only by app.js: fail, pass, stale, popopen, free, lang, light, nofiles,
   dragx, dragy, booting, bootfail (boot.js: Python could not start), running, checking, working, histopen (J5b). The page address never becomes a class (a mockup trap).
   Never give a component class a state's name, and never use one class for two different things.
   Code colors come from core/cg_colors.js (editor.js makes the .tk-* rules), so the lab matches paper exactly. */
@font-face{font-family:"JetBrains Mono";src:url("../vendor/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url("../vendor/fonts/jetbrains-mono/JetBrainsMono-Bold.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url("../vendor/fonts/jetbrains-mono/JetBrainsMono-Italic.woff2") format("woff2");font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:"JetBrains Mono";src:url("../vendor/fonts/jetbrains-mono/JetBrainsMono-BoldItalic.woff2") format("woff2");font-weight:700;font-style:italic;font-display:swap}
/* Geist is the UI font (vendor/fonts/geist/, geist 1.7.2, OFL). system-ui is the fallback. */
@font-face{font-family:"Geist";src:url("../vendor/fonts/geist/Geist-Variable.woff2") format("woff2");font-weight:100 900;font-style:normal;font-display:swap}

:root{
  --app:#0A1220;--island:#0F1A2C;--raise:#15223A;--menu:#15223A;--band:#15233A;--border:#1D2C46;
  --text:#DCE6F4;--dim:#98A9C3;--ln:#7A8EAD;--ln-cur:#C9D6EA;
  --accent:#5AA2FF;--chip-tx:#AFCBFF;--btn:#1F6FE5;--soft:rgba(90,162,255,.12);--soft-2:rgba(90,162,255,.22);--sel:rgba(90,162,255,.30);
  --indent:#22334F;--match-bg:rgba(90,162,255,.16);--match-line:#6A8FC4;
  --caret:#AFCBFF;--typed:#4FC1FF;--ok:#4CC38A;--bad:#F48771;--hint:#E8B84A;--hint-band:rgba(232,184,74,.15);
  --handle:#2C3E5E;--shadow:0 10px 28px rgba(0,0,0,.5);--isl-shadow:none;
  --b1:#FFD700;--b2:#DA70D6;--b3:#179FFF;
  --win-bg:rgba(76,195,138,.13);--bad-bg:rgba(244,135,113,.12);
  --ui:"Geist",system-ui,"Segoe UI",Roboto,sans-serif;--mono:"JetBrains Mono",Consolas,monospace;
  color-scheme:dark;
}
html.light{
  --app:#E6EDF6;--island:#FFFFFF;--raise:#F1F5FB;--menu:#FFFFFF;--band:#EDF3FC;--border:#D3DEEB;
  --text:#13223A;--dim:#4F607A;--ln:#5B6473;--ln-cur:#13223A;
  --accent:#1A64D6;--chip-tx:#0451A5;--btn:#1A64D6;--soft:rgba(26,100,214,.08);--soft-2:rgba(26,100,214,.14);--sel:rgba(26,100,214,.20);
  --indent:#DCE4EF;--match-bg:rgba(26,100,214,.09);--match-line:#7E9BC4;
  --caret:#13223A;--typed:#0451A5;--ok:#1A7F45;--bad:#B3261E;--hint:#8A5A00;--hint-band:rgba(232,184,74,.24);
  --handle:#B4C2D6;--shadow:0 10px 28px rgba(20,40,80,.18);--isl-shadow:0 1px 2px rgba(16,34,64,.06);
  --b1:#0431FA;--b2:#217A2B;--b3:#7B3814;
  --win-bg:rgba(26,127,69,.09);--bad-bg:rgba(179,38,30,.07);
  color-scheme:light;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:var(--app);color:var(--text);font:13.5px/1.4 var(--ui);-webkit-font-smoothing:antialiased;overflow-x:clip}
button{font:inherit;color:inherit;background:none;border:0;margin:0;padding:0;cursor:pointer;-webkit-appearance:none;appearance:none;text-align:inherit}
button:focus-visible,.showme:focus-visible,.hint a:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
[hidden]{display:none!important}
svg.i{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
svg.i.fill{fill:currentColor;stroke:none}
code{font-family:var(--mono);font-variant-ligatures:none}

/* the whole screen */
.app{position:relative;width:100%;height:100vh;height:100dvh;display:flex;flex-direction:column;overflow:hidden}
.main{flex:1;display:flex;min-height:0;padding:0 6px 6px 0;position:relative}
.right{width:400px;flex:none;display:flex;flex-direction:column;min-width:0}

/* top bar */
.top{min-height:48px;flex:none;display:flex;align-items:center;gap:12px;padding:0 10px 0 16px;position:relative;z-index:6}
.brand{font-weight:650;font-size:15.5px;letter-spacing:-.01em;white-space:nowrap}
.brand span{color:var(--accent)}
/* The header brand is the page's one <h1> (2026-11-10). .brand already sets its size and weight; this takes away
   the browser's h1 margin so nothing moves. The phone note's brand stays a <div>. */
h1.brand{margin:0}
.vsep{width:1px;height:20px;background:var(--border);flex:none}
.lvl{display:flex;align-items:stretch;height:32px;min-width:0;border:1px solid var(--border);border-radius:5px;background:var(--island);overflow:hidden;box-shadow:var(--isl-shadow)}
.lvl .nav{width:30px;flex:none;display:grid;place-items:center;color:var(--dim)}
.lvl .nav.off{opacity:.4;cursor:default}
.lvl .pick{display:flex;align-items:center;gap:8px;min-width:0;padding:0 9px 0 6px;font-weight:550;border-left:1px solid var(--border);border-right:1px solid var(--border);white-space:nowrap}
.lvl .pick svg{color:var(--dim)}
.lvl .ptitle{min-width:0;overflow:hidden;text-overflow:ellipsis}
.lvl.open .pick{background:var(--soft)}
.lvl.solo .pick{border:0;padding:0 11px 0 5px}
.lvl.solo .pick,.lvl.solo .pick:hover{cursor:default;background:none}   /* FREE1: Free practice is a label, not a menu */
.lvl .chip svg{width:13px;height:13px;color:var(--accent);display:block}
.chip{font:600 12px/1 var(--mono);color:var(--chip-tx);background:var(--soft-2);padding:4px 6px;border-radius:5px;flex:none}
.acts{margin-left:auto;display:flex;align-items:center;gap:8px}
.btn{height:32px;display:inline-flex;align-items:center;gap:7px;padding:0 14px 0 12px;border-radius:5px;border:1px solid var(--border);
  background:var(--island);color:var(--text);font:600 13.5px/1 var(--ui);white-space:nowrap;box-shadow:var(--isl-shadow);flex:none}
.btn svg{width:15px;height:15px}
.btn.run{background:var(--btn);border-color:var(--btn);color:#fff;padding:0 16px 0 13px;min-width:82px;justify-content:center}
.btn.run svg{width:13px;height:13px}
.btn.run .rl{display:inline-flex;align-items:center;gap:7px}
html:not(.working) .btn.run .rl-stop,html.working .btn.run .rl-run{display:none}
html.working .btn.run{background:var(--island);border-color:var(--bad);color:var(--text)}
html.working .btn.run svg{color:var(--bad)}
.btn.pressed{background:var(--soft-2);border-color:var(--match-line)}
.theme{display:flex;height:32px;padding:2px;gap:2px;border:1px solid var(--border);border-radius:5px;background:var(--island);box-shadow:var(--isl-shadow);flex:none}
.theme button{width:28px;display:grid;place-items:center;border-radius:5px;color:var(--dim)}
html:not(.light) .theme .moon,html.light .theme .sun{background:var(--soft-2);color:var(--accent)}
.langbtn{height:32px;display:inline-flex;align-items:center;gap:8px;padding:0 10px 0 7px;border:1px solid var(--border);border-radius:5px;
  background:var(--island);color:var(--text);font:600 13.5px/1 var(--ui);white-space:nowrap;box-shadow:var(--isl-shadow);flex:none}
.langbtn svg{width:14px;height:14px;color:var(--dim)}
.lgo{width:20px;height:20px;flex:none;display:block}

/* icon strip on the far left */
.strip{width:48px;flex:none;display:flex;flex-direction:column;align-items:center;gap:6px;padding:2px 0 0}
.strip .sp{flex:1}
.sb{width:36px;height:36px;display:grid;place-items:center;border-radius:5px;color:var(--dim)}
.sb svg{width:20px;height:20px}
.sb.filesb{background:var(--soft-2);color:var(--accent)}
html.nofiles .sb.filesb,html.histopen .sb.filesb{background:none;color:var(--dim)}
.sb.on{background:var(--soft-2);color:var(--accent)}

/* panels ("islands") and the drag lines between them */
.isl{background:var(--island);border:1px solid var(--border);border-radius:5px;overflow:hidden;display:flex;flex-direction:column;min-width:0;box-shadow:var(--isl-shadow)}
.files{width:206px;flex:none}
.editor{flex:1;min-width:0}
.input{height:150px;flex:none}
.output{flex:1;min-height:0}
.g{flex:none;position:relative}
.gv{width:6px}.gh{height:6px}
.gv.drag::after{content:"";position:absolute;left:1px;top:50%;width:4px;height:40px;margin-top:-20px;border-radius:5px;background:var(--handle)}
.gh.drag::after{content:"";position:absolute;top:1px;left:50%;height:4px;width:40px;margin-left:-20px;border-radius:5px;background:var(--handle)}
html.nofiles .files,html.nofiles:not(.histopen) .g.fg,html.histopen .files,html:not(.histopen) .histp{display:none}
.g.drag{touch-action:none}
.gv.drag{cursor:col-resize}
.gh.drag{cursor:row-resize}
.g.drag:hover::after,html.dragx .gv.drag::after,html.dragy .gh.drag::after{background:var(--accent)}
html.dragx,html.dragx *{cursor:col-resize!important;user-select:none}
html.dragy,html.dragy *{cursor:row-resize!important;user-select:none}

.ihead{height:36px;flex:none;display:flex;align-items:center;gap:8px;padding:0 6px 0 12px;border-bottom:1px solid var(--border);
  font-size:11.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);white-space:nowrap}
.ihead svg{width:15px;height:15px}
.ihead .note{text-transform:none;letter-spacing:0;font-weight:400;font-size:12.5px;overflow:hidden;text-overflow:ellipsis}
.ihead .end{margin-left:auto;display:flex;align-items:center;gap:2px}
.mini{width:26px;height:26px;display:grid;place-items:center;border-radius:5px;color:var(--dim);flex:none}

/* files */
.flist{padding:6px}
.fitem{display:flex;align-items:center;gap:8px;height:30px;padding:0 8px;border-radius:5px;font:500 13.5px/1 var(--ui)}
.fitem.on{background:var(--soft)}
.fitem svg{color:var(--accent)}
/* FP1: Open a file and Download file under the file list, the same rows as a file but quieter until hovered */
.fbtns{margin:0 6px;padding:6px 0;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:2px}
.fbtn{display:flex;align-items:center;gap:8px;height:30px;padding:0 8px;border-radius:5px;font:500 13.5px/1 var(--ui);color:var(--dim);cursor:pointer;user-select:none}
.fbtn svg{width:15px;height:15px}
.fbtn:hover{background:var(--soft);color:var(--text)}
@media (max-width:900px),(pointer:coarse){.fbtn{height:44px}}

/* editor: tab, task line, code */
.tabs{height:36px;flex:none;display:flex;align-items:center;gap:4px;padding:0 6px;border-bottom:1px solid var(--border)}
.tab{height:28px;display:flex;align-items:center;gap:7px;padding:0 11px 0 9px;border-radius:5px;font:500 13px/1 var(--ui);color:var(--dim)}
.tab.on{background:var(--soft);color:var(--text)}
.tab svg{width:15px;height:15px;color:var(--accent)}
.task{flex:none;margin:6px 6px 0;display:block;padding:0 4px 0 10px;border-radius:5px;background:var(--raise);font-size:13px}
.task .row{display:flex;align-items:center;gap:8px;min-height:32px}
.task .row>svg{color:var(--accent)}
.task b{font-weight:650}
.task .tt{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--dim)}
.task .more{display:flex;align-items:center;gap:4px;color:var(--accent);font-weight:550;padding:4px 8px;border-radius:5px;white-space:nowrap}
.task .body{display:none;padding:0 8px 12px 24px;color:var(--text);line-height:1.55;max-height:42vh;overflow:auto}
.task.open .body{display:block}
/* CG85 (C9): a card that scrolls inside itself fades its last 30 px while more is below (app.js taskFade sets .cg-fade) */
.task .body.cg-fade{-webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 30px),transparent);mask-image:linear-gradient(to bottom,#000 calc(100% - 30px),transparent)}
.task.open .tt{visibility:hidden}
.task:not(.open) .t-hide,.task.open .t-show{display:none}
.task .body p{margin:0 0 6px}
.task .body code{font:13px var(--mono);color:var(--typed)}
.exrun{margin:10px 0 2px}
.exhead{margin-bottom:6px;font-size:11.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--dim)}
.exbox{display:flex;flex-wrap:wrap;gap:8px}
.expane{min-width:0;border:1px solid var(--border);border-radius:5px;background:var(--island);overflow:hidden}
.exin{flex:0 1 150px;min-width:110px}
.exout{flex:1 1 260px}
.exlab{display:flex;align-items:center;gap:6px;height:27px;padding:0 10px;border-bottom:1px solid var(--border);
  font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--dim);white-space:nowrap}
.exlab svg{width:13px;height:13px}
.expane pre{margin:0;padding:7px 10px 8px;font:13.5px/21px var(--mono);font-variant-ligatures:none;color:var(--text);white-space:pre;overflow-x:auto}
.exout .typed{color:var(--typed);font-weight:700}
.exrnd{flex:1 1 100%}
.exrnd p{margin:0;padding:7px 10px 0;font-size:13.5px;line-height:21px;color:var(--text)}
.exrnd p:last-child{padding-bottom:9px}
.code{flex:1;min-height:0;display:flex}
.code .cm-editor{flex:1;min-width:0;height:100%}
.bk1{color:var(--b1)}.bk2{color:var(--b2)}.bk3{color:var(--b3)}

/* input and output */
.inbox,.con{flex:1;padding:10px 14px;font:14px/22px var(--mono);font-variant-ligatures:none;white-space:pre-wrap;word-break:break-word}
textarea.inbox{display:block;width:100%;min-height:0;margin:0;border:0;outline:0;resize:none;background:transparent;color:var(--text)}
textarea.inbox::placeholder{color:var(--ln);font-family:var(--ui);font-size:13.5px}
.con{overflow:auto;min-height:0;tab-size:8}   /* U2C (2026-11-04): a tab in the Output goes to the next stop of 8 columns, like a terminal. It was 8 by default; this says so. */
.con .typed{color:var(--typed);font-weight:700}
.ph{color:var(--ln);font-family:var(--ui);font-size:13.5px}
.con .done{font:12.5px/1.4 var(--ui);color:var(--dim);display:flex;align-items:center;gap:6px;margin-top:12px;white-space:normal}
.con .done svg{color:var(--ok);width:15px;height:15px}
.con .dn{display:block;margin-top:10px;color:var(--dim);font:13.5px/1.5 var(--ui);white-space:normal}
/* CG41 (C4): the still-running note. It is the calm .dn note ("Python is still loading...") on the soft blue panel of the
   answer box, with more room around it and no red. */
.con .dn.still{margin-top:16px;padding:10px 14px;border-radius:6px;background:var(--soft);font-size:14px;line-height:1.55}
.con .err{display:flex;align-items:flex-start;gap:8px;margin-top:8px;padding:8px 10px;border-radius:5px;background:var(--bad-bg);
  color:var(--text);font:13.5px/1.5 var(--ui);white-space:normal}
.con .err svg{width:16px;height:16px;color:var(--bad);margin-top:2px}
.con .err code{font:13px var(--mono)}
.con .err .py{display:block;margin-top:4px;color:var(--dim);font-size:12.5px}
.con .err .py code{font-size:12.5px;color:var(--dim);word-break:break-word}
.con .err .showme{margin-top:6px}
.askwrap{white-space:normal}
.con .ask{display:inline-block;width:16ch;max-width:100%;margin:0;padding:0 4px;border:0;border-bottom:2px solid var(--accent);border-radius:3px 3px 0 0;
  outline:0;background:var(--soft);color:var(--typed);font:700 14px/22px var(--mono);font-variant-ligatures:none;vertical-align:top}
.con .askhelp{display:block;margin-top:6px;font:12.5px/1.4 var(--ui);color:var(--dim)}
/* first load: a bar and a plain message while Python loads */
.boot{flex:none;margin:12px 12px 0;padding:12px 14px;border:1px solid var(--border);border-radius:5px;background:var(--raise);font:13.5px/1.5 var(--ui)}
.boot b{display:block;font-weight:650;margin-bottom:8px}
.boot p{margin:6px 0 0;color:var(--dim)}
.bar{height:8px;border-radius:5px;background:var(--soft-2);overflow:hidden}
.bar span{display:block;height:100%;width:2%;background:var(--accent);border-radius:5px;transition:width .3s}
html:not(.booting) .boot:not(.bad){display:none}
.boot.bad b{color:var(--bad)}
.boot.bad .bar{display:none}
html.bootfail .con .ph{display:none}   /* Python could not start: the card says what to do, so "Press Run" would only confuse */

/* status bar */
.status{height:24px;flex:none;display:flex;align-items:center;gap:18px;padding:0 14px;font-size:12px;color:var(--dim);white-space:nowrap;overflow:hidden}
.status span{display:flex;align-items:center;gap:6px}
.status svg{width:14px;height:14px}
.status .r{margin-left:auto}

/* menus and pop-ups */
.menu{position:absolute;background:var(--menu);border:1px solid var(--border);border-radius:5px;box-shadow:var(--shadow);padding:6px;z-index:7;white-space:normal;font-family:var(--ui)}
.mhead{padding:6px 8px 8px;font-size:11.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--dim)}
.mrow{display:flex;align-items:center;gap:10px;width:100%;min-height:34px;padding:0 8px;border-radius:5px;font-size:13.5px;white-space:nowrap}
.mrow .mt{min-width:0;overflow:hidden;text-overflow:ellipsis}
.mrow .sc{margin-left:auto;padding-left:10px;font-size:12.5px;color:var(--dim)}
.mrow .sc.ok{color:var(--ok);font-weight:600}
.mrow.on .sc:not(.ok){color:var(--text)}
.mrow svg.done{color:var(--ok)}
.mrow svg.now{color:var(--accent)}
.mrow svg.todo{color:var(--ln)}
.msep{height:1px;background:var(--border);margin:6px 2px}
.mrow.tall{height:auto;padding:9px 10px;align-items:flex-start;white-space:normal}
.mrow.tall svg{margin-top:2px;color:var(--accent)}
.mrow.tall b{display:block;font-weight:600}
.mrow.tall small{display:block;font-size:12.5px;color:var(--dim);margin-top:2px}
.lvlmenu{width:340px;max-height:calc(100vh - 80px);overflow:auto}
.sharem{width:340px}
.linkbox{padding:4px 10px 8px}
.linkbox input{width:100%;height:30px;padding:0 8px;border:1px solid var(--border);border-radius:5px;background:var(--island);color:var(--text);font:12.5px var(--mono)}
.linkbox small{display:block;margin-top:4px;color:var(--dim);font-size:12.5px}
.tipm{display:flex;align-items:center;gap:7px;padding:8px 11px;font-size:13px;white-space:nowrap}
.tipm svg{width:14px;height:14px;color:var(--dim)}
.helpm{width:340px;padding:6px 14px 10px}
.helpm .mhead{padding:6px 0 4px}
.helpm p{margin:8px 0 0;font-size:13.5px;line-height:1.5}
.helpm code{font-size:12.5px;color:var(--typed)}

/* things you can press */
.btn,.sb,.mini,.theme button,.task .more,.lvl .nav,.lvl .pick,.mrow,.showme,.more3,.hint a,.langbtn{cursor:pointer;user-select:none}
.btn:hover,.langbtn:hover{border-color:var(--match-line)}
.btn.run:hover{border-color:var(--btn);filter:brightness(1.1)}
html.working .btn.run:hover{border-color:var(--bad);filter:none}
.btn:active,.langbtn:active{transform:translateY(1px)}
.sb:hover{background:var(--soft);color:var(--text)}
html:not(.nofiles):not(.histopen) .sb.filesb:hover{background:var(--soft-2);color:var(--accent)}
.mini:hover,.task .more:hover,.showme:hover{background:var(--soft);color:var(--text)}
.theme button:hover{color:var(--text)}
.lvl .nav:not(.off):hover,.lvl .pick:hover{background:var(--soft)}
.mrow:hover{background:var(--soft)}
.mrow.on,.mrow.on:hover{background:var(--soft-2)}
.more3:hover{border-color:var(--match-line);color:var(--text)}

/* state switches: "only-x" shows only in state x; "not-x" hides in state x; "only-none" = no Check yet */
html.fail .only-none,html.pass .only-none,html.free .only-none,
html:not(.fail) .only-fail,html:not(.pass) .only-pass,html:not(.free) .only-free,html:not(.lang) .only-lang,
html:not(.stale) .only-stale,
html.free .not-free,html.pass .not-pass{display:none!important}

/* Check shows the last result (gray circle, red X, green check); Hint sits right next to it */
.cpair{position:relative;display:flex;align-items:center;gap:8px}
.cpair>.pop{right:0;top:calc(100% + 7px)}
.btn.check svg{color:var(--ln);stroke-width:2}
.btn.check svg.fail{color:var(--bad)}
.btn.check svg.pass{color:var(--ok)}
html.stale .btn.check svg.fail,html.stale .btn.check svg.pass{display:none!important}
html.stale .btn.check svg.only-none{display:block!important}
html.popopen .btn.check{background:var(--soft-2);border-color:var(--match-line)}
.btn.check .spin{display:none;width:15px;height:15px;flex:none;border:2px solid var(--soft-2);border-top-color:var(--accent);border-radius:50%}
html.checking .btn.check .spin{display:block}
html.checking .btn.check svg{display:none!important}
/* The Hint button is .hintbtn, not .hint (the hint boxes). When all tests pass, only its colors dim. */
.btn.hintbtn svg{color:var(--hint)}
html.pass:not(.stale) .btn.hintbtn{color:var(--dim)}
html.pass:not(.stale) .btn.hintbtn svg{color:var(--ln)}
@media (prefers-reduced-motion:no-preference){
  .btn.check.ck svg{animation:ckpop .32s cubic-bezier(.2,1.6,.45,1)}
  .cpair>.pop{animation:popin .14s ease-out}
  .pop.rerun .cl,.pop.rerun .win,.pop.rerun .score{animation:rerun .3s ease-out}
  html.checking .btn.check .spin{animation:spin .8s linear infinite}
  .code .cm-editor{animation:cgin .18s ease-out}   /* FREE2: the editor fades in once, when it is made, instead of popping in */
}
@keyframes cgin{from{opacity:0}to{opacity:1}}
@keyframes ckpop{0%{transform:scale(.35);opacity:0}100%{transform:scale(1);opacity:1}}
@keyframes popin{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@keyframes rerun{from{opacity:.2}to{opacity:1}}
@keyframes spin{to{transform:rotate(360deg)}}

/* Check pop-up */
.pop{width:420px;padding:0;max-height:calc(100vh - 70px);overflow:hidden;display:flex;flex-direction:column}
/* CG9: the header, the banner and the footer stay in view, and only the result list scrolls */
.pop>*{flex:none}
.pop>.cl{flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain}
.phead{display:flex;align-items:center;gap:10px;height:44px;padding:0 8px 0 14px;border-bottom:1px solid var(--border)}
.phead b{font-weight:650;font-size:14px}
.phead .score{margin-left:auto;font-size:12.5px;font-weight:600;color:var(--text);background:var(--raise);padding:4px 8px;border-radius:5px}
.stalebar{display:flex;align-items:center;gap:8px;margin:8px 8px 0;padding:8px 10px;border-radius:5px;background:var(--raise);font-size:13px;line-height:1.4}
.stalebar svg{width:15px;height:15px;color:var(--accent)}
html.stale .pop .crow,html.stale .pop .score,html.stale .pop .chead{opacity:.55}
.cl{padding:8px 8px 4px}
/* the Code check rows sit under this small heading, below the test rows that "N of M pass" counts */
.chead{margin:10px 6px 4px;padding-top:12px;border-top:1px solid var(--border);font-size:11.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--dim)}
.crow{display:flex;align-items:center;gap:10px;min-height:30px;padding:0 6px;font-size:13.5px}
.crow svg{width:18px;height:18px}
.crow.ok svg{color:var(--ok)}
.crow.bad svg{color:var(--bad)}
.crow.bad{font-weight:600}
/* U8C (2026-11-06), C7: a team level's still-shipped file (its rows don't count yet) */
.crow.gray{color:var(--dim)}
.crow.gray svg{color:var(--dim)}
.con .dn.ran{margin:0 0 6px}
/* CG9: the passed tests fold into one line that opens (the Check pop-up and Grade a whole class) */
.cfold{width:100%;border-radius:5px;text-align:left}
.cfold:hover{background:var(--raise)}
.crow.cfold .cfnote{display:inline-flex;align-items:center;gap:4px;margin-left:auto;font-size:13px;font-weight:600;color:var(--accent)}
.crow.cfold .cfnote svg{width:14px;height:14px;margin:0;color:var(--accent)}
.cfold[aria-expanded="true"] .cfnote svg{transform:rotate(180deg)}
.cfoldlist{margin:2px 0 4px 15px;padding-left:6px;border-left:2px solid var(--border)}
.cgap{position:relative;margin-top:9px}
.cgap::before{content:"";position:absolute;left:6px;right:6px;top:-5px;border-top:1px solid var(--border)}
.fix{margin:2px 6px 6px 34px}
.why{font-size:13px;color:var(--dim);margin:0 0 8px}
.why code,.hint code{font:13px var(--mono);color:var(--text)}
/* U2FIX (2026-11-04, A07): the program's printed line and the expected line, quoted in a Check message (the Check panel and the
   grade page). Only this text keeps every space; the sentence around it wraps as before. */
.said{font:13px var(--mono);font-variant-ligatures:none;color:var(--text);white-space:pre-wrap;overflow-wrap:anywhere}
.hint{display:flex;gap:9px;align-items:flex-start;padding:8px 10px;margin-bottom:6px;border-radius:5px;background:var(--raise);font-size:13px;line-height:1.5}
.hint svg{color:var(--hint);margin-top:2px}
.hint .hn{display:block;font-size:11.5px;font-weight:650;letter-spacing:.06em;text-transform:uppercase;color:var(--hint)}
.hint a{color:var(--accent);font-weight:600;text-decoration:underline;text-underline-offset:2px}
.showme{display:inline-flex;align-items:center;gap:4px;margin-top:6px;padding:3px 8px;border-radius:5px;border:1px solid var(--border);color:var(--accent);font-weight:600;font-size:12.5px}
.showme svg{width:13px;height:13px;color:var(--accent);margin:0}
.more3{display:flex;width:100%;align-items:center;justify-content:center;gap:6px;height:32px;border-radius:5px;border:1px dashed var(--border);color:var(--dim);font-size:13px;font-weight:550}
.more3 svg{color:var(--hint)}
.win{display:flex;align-items:center;gap:10px;margin:4px 14px 12px;padding:8px 8px 8px 12px;border-radius:5px;background:var(--win-bg);font-size:13.5px;font-weight:600}
.win>svg{color:var(--ok);width:18px;height:18px}
.win .btn{margin-left:auto;height:30px;padding:0 10px 0 12px;box-shadow:none}
.win .btn svg{width:14px;height:14px}
.pfoot{display:flex;flex-wrap:wrap;gap:6px 16px;padding:10px 14px;border-top:1px solid var(--border);font-size:12.5px;color:var(--dim)}
.pfoot b{color:var(--text);font-weight:600}
.pfoot .pnote{margin-left:auto}

/* language picker: tiles like OneCompiler's, a logo above the name */
.scrim{position:absolute;inset:0;z-index:8;display:grid;place-items:center;background:rgba(3,7,14,.62)}
html.light .scrim{background:rgba(19,34,58,.30)}
.picker{width:min(766px,calc(100vw - 24px));background:var(--menu);border:1px solid var(--border);border-radius:5px;box-shadow:var(--shadow)}
.pk-head{display:flex;align-items:center;gap:12px;padding:16px 12px 0 22px}
.pk-head h3{margin:0;font-size:18px;font-weight:650;letter-spacing:-.01em}
.pk-head .mini{margin-left:auto}
.lgrid{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;padding:16px 22px 4px}
.ltile{display:flex;flex-direction:column;align-items:center;gap:9px;padding:18px 6px 14px;border:1px solid var(--border);border-radius:5px;
  background:var(--island);color:var(--text);text-align:center}
.ltile:hover{border-color:var(--match-line)}
.ltile.on{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent);background:var(--soft)}
.lg{width:44px;height:44px;flex:none;display:grid;place-items:center}
.lg img{width:44px;height:44px;object-fit:contain;display:block}
.lg img.sq{width:38px;height:38px}
.lg.ico{border-radius:5px;background:var(--soft-2);color:var(--accent)}
.lg.ico svg{width:26px;height:26px;stroke-width:1.7}
.ltile b{font-size:14.5px;font-weight:650;white-space:nowrap}
.tag{padding:3px 7px;border-radius:5px;background:var(--raise);color:var(--dim);font-size:11.5px;font-weight:600;white-space:nowrap}
.tag.ready{background:var(--win-bg);color:var(--ok)}
.pk-foot{padding:14px 22px 18px;color:var(--dim);font-size:13px}
.ltile.nudge{animation:nudge .38s ease}
@keyframes nudge{20%{transform:translateX(-4px)}40%{transform:translateX(4px)}60%{transform:translateX(-3px)}80%{transform:translateX(2px)}}

/* a short note at the bottom of the screen */
.toast{position:absolute;left:50%;bottom:40px;z-index:20;transform:translate(-50%,6px);max-width:calc(100% - 32px);padding:9px 14px;border-radius:5px;background:var(--menu);
  border:1px solid var(--border);box-shadow:var(--shadow);font-size:13.5px;text-align:center;opacity:0;pointer-events:none;transition:opacity .18s,transform .18s}
.toast.on{opacity:1;transform:translate(-50%,0)}
/* CG85 (C2): while the History panel is open (a 48 or 52 px strip, then a panel up to 360 px wide), the toast sits to the right
   of it, so it never covers the panel's last lines (the centered toast did, at 768 and at 1280). */
html.histopen .toast{left:calc(60px + min(360px,100vw - 72px));max-width:calc(100% - min(360px,100vw - 72px) - 68px);transform:translate(0,6px);text-align:left}
html.histopen .toast.on{transform:translate(0,0)}

/* phones: a short notice instead of the lab */
.phone-note{display:none}

/* touch screens and narrow windows: the buttons are big enough for a finger (at least 44 px tall). An iPad on its side is
   1024 px wide, so touch is found by (pointer:coarse) as well as by width (J12g, G1). Mouse screens keep the small sizes. */
@media (max-width:900px),(pointer:coarse){
  .btn,.langbtn,.lvl,.theme{height:44px}
  .btn{padding:0 18px 0 14px;font-size:14.5px}
  .btn.run{min-width:96px}
  .btn svg{width:17px;height:17px}
  .lvl .nav{width:44px}
  .lvl .ptitle{max-width:none}                          /* CG85 (C7): the whole title; a full row ends it with ... */
  .theme button{width:40px}
  .sb{width:44px;height:44px}
  .mini{width:40px;height:40px}
  .task .row{min-height:44px}
  .task .more{padding:0 12px;min-height:44px}
  .mrow{min-height:44px}
}
/* CG85 (C7): a touch screen 901 to 1240 wide (a tablet sideways, 1024 x 768) has a single top row with no room for the level
   title ("Ask and A..."). It wraps to the tablet's two rows: the title row, then Run, Check, Hint and Share. */
@media (min-width:901px) and (max-width:1240px) and (pointer:coarse){
  .top{flex-wrap:wrap;row-gap:8px;padding:8px 10px 8px 14px}
  .acts{order:5;width:100%;margin-left:0;gap:10px}
  .acts #sharebtn{margin-left:auto}
}
/* tablets (768 x 1024 portrait): the panels stack */
@media (max-width:900px){
  .top{flex-wrap:wrap;row-gap:8px;padding:8px 10px 8px 14px}
  .acts{order:5;width:100%;margin-left:0;gap:10px}
  .acts #sharebtn{margin-left:auto}
  .main{display:grid;grid-template-columns:52px minmax(0,1fr);grid-template-rows:minmax(0,1fr) 8px 42%;padding:0 8px 8px 0}
  .strip{grid-column:1;grid-row:1/4;width:52px}
  .editor{grid-column:2;grid-row:1}
  .gv.drag{grid-column:2;grid-row:2;width:auto;height:8px;cursor:default}
  .gv.drag::after{display:none}
  .right{grid-column:2;grid-row:3;width:auto!important;min-height:0}
  .input{height:112px}
  .gh{height:8px}
  .files{position:absolute;left:52px;top:0;bottom:8px;z-index:4;box-shadow:var(--shadow)}
  .g.fg{display:none}
  .cpair>.pop{left:0;right:auto;width:min(420px,calc(100vw - 130px));max-height:calc(100vh - 140px)}
  .lgrid{grid-template-columns:repeat(3,1fr)}
  .exin{flex-basis:130px}
}
@media (max-width:699px),(max-height:419px) and (pointer:coarse){
  .app{display:none!important}
  .phone-note{display:grid;place-items:center;min-height:100vh;padding:24px;text-align:center;font-size:15px;line-height:1.5}
  .phone-note .brand{font-size:24px;margin-bottom:12px}
  .phone-note>div{max-width:420px}
}

/* J5b: Share > Download file and Open a file, the name dialog, the drop note, and the History panel.
   The History panel takes the Files panel's place (html.histopen), like a second page of the icon strip. */
.btn.pri{background:var(--btn);border-color:var(--btn);color:#fff}
.btn.pri:hover{border-color:var(--btn);filter:brightness(1.1)}
.longbox{margin:2px 4px 6px;padding:9px 10px;border-radius:5px;background:var(--bad-bg);font-size:13px;line-height:1.45}
.longbox p{margin:0 0 8px}
/* CG85 (C1): while the pink note shows (the code is too long for a link), its Download file button is the only one. */
.longbox:not([hidden]) ~ [data-act=download]{display:none}
.namebox{width:min(420px,calc(100vw - 24px))}
.nb-body{padding:12px 22px 0}
.nb-body>p{margin:0 0 14px;font-size:13.5px;line-height:1.5}
.fld{display:block;margin:0 0 12px}
.fld span{display:block;margin-bottom:5px;font-size:13px;font-weight:600}
.fld input{width:100%;height:36px;padding:0 10px;border:1px solid var(--border);border-radius:5px;background:var(--island);color:var(--text);font:14px var(--ui)}
.fld input:focus{outline:2px solid var(--accent);outline-offset:-1px}
.nb-body .nb-err{margin:-2px 0 12px;color:var(--bad);font-size:13px;font-weight:600}
.nb-body .nb-err:empty{display:none}
.nb-body .nb-keep{display:flex;align-items:center;gap:7px;margin:0;color:var(--dim);font-size:12.5px}
.nb-keep svg{width:15px;height:15px}
.nb-foot{display:flex;justify-content:flex-end;gap:8px;padding:18px 22px 18px}
.dropzone{position:absolute;inset:0;z-index:9;display:grid;place-items:center;background:rgba(3,7,14,.62);pointer-events:none}
html.light .dropzone{background:rgba(19,34,58,.30)}
.dropzone>div{display:flex;flex-direction:column;align-items:center;gap:6px;padding:28px 40px;border:2px dashed var(--accent);border-radius:5px;background:var(--menu);box-shadow:var(--shadow);text-align:center}
.dropzone svg{width:30px;height:30px;color:var(--accent)}
.dropzone b{font-size:15px;font-weight:650}
.dropzone small{color:var(--dim);font-size:13px}
.con .opened{display:block;color:var(--dim);font:13.5px/1.5 var(--ui);white-space:normal}
.con .opened b{color:var(--text);font-weight:600}
.histp{width:360px;flex:none}
.hfor{flex:none;padding:8px 12px 2px;font-size:12.5px;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hlist{flex:1 1 auto;min-height:88px;overflow:auto;padding:4px 6px 6px}
.histp.viewing .hlist{flex:0 1 38%}
.hrow{display:flex;align-items:flex-start;gap:10px;width:100%;padding:7px 8px;border-radius:5px;text-align:left;cursor:pointer;user-select:none}
.hrow:hover{background:var(--soft)}
.hrow.on,.hrow.on:hover{background:var(--soft-2)}
.hrow svg{margin-top:2px;color:var(--accent)}
.hrow b{display:block;font-weight:600}
.hrow small{display:block;margin-top:1px;font-size:12.5px;color:var(--dim)}
.hempty{margin:6px;color:var(--dim);font-size:13px;line-height:1.5}
.hview{flex:1 1 62%;min-height:150px;display:flex;flex-direction:column;border-top:1px solid var(--border)}
/* CG73 (C3): the note box with Save version, the saved-version rows, the view's title and two buttons, and Show changes.
   The green and red fill the whole row. There is never a colored stripe or border on one side. */
.hsave{flex:none;display:flex;flex-direction:column;gap:8px;padding:8px 10px 12px}
.hnote{width:100%;height:36px;padding:0 10px;border:1px solid var(--border);border-radius:5px;background:var(--island);color:var(--text);font:14px var(--ui)}
.hnote::placeholder{color:var(--dim);opacity:1}
.hnote:focus{outline:2px solid var(--accent);outline-offset:-1px}
.hsave .btn{width:100%;justify-content:center}
.hmsg{margin:0;color:var(--bad);font-size:13px;font-weight:600;line-height:1.45}
.hrow b{overflow-wrap:anywhere}
.hrow.ver svg{color:var(--hint)}
.hview{--add-bg:rgba(76,195,138,.22);--del-bg:rgba(244,135,113,.22)}
html.light .hview{--add-bg:rgba(26,127,69,.16);--del-bg:rgba(179,38,30,.13)}
.hvhead{flex:none;display:flex;align-items:flex-start;gap:8px;padding:10px 6px 8px 12px;font-size:13px}
.hvt{min-width:0;display:flex;flex-direction:column;gap:3px}
.hvt b{font-weight:600;line-height:1.4;overflow-wrap:anywhere}
.hvt small{font-size:12.5px;color:var(--dim)}
.hvhead .mini{margin-left:auto}
.hdnote{flex:none;margin:0 8px 10px;padding:0 4px;font-size:12.5px;line-height:1.9;color:var(--text)}
.hdnote .dadd,.hdnote .ddel{padding:2px 6px;border-radius:3px;font-weight:600;white-space:nowrap}
.hdnote .dadd{background:var(--add-bg)}
.hdnote .ddel{background:var(--del-bg)}
.hcode{flex:1;min-height:96px;margin:0 8px;padding:8px 10px;overflow:auto;border:1px solid var(--border);border-radius:5px;background:var(--raise);
  font:12.5px/19px var(--mono);font-variant-ligatures:none;white-space:pre-wrap;overflow-wrap:anywhere;tab-size:4}
.hcode.diff{padding:8px 0}
.dl{display:flex;min-height:19px}
.dm{flex:none;width:24px;text-align:center;font-weight:700;user-select:none}
.dc{flex:1 1 auto;min-width:0;padding-right:10px}
.dl.add{background:var(--add-bg)}
.dl.del{background:var(--del-bg)}
.dl.add .dm{color:var(--ok)}
.dl.del .dm{color:var(--bad)}
.hvfoot{flex:none;display:flex;flex-direction:column;gap:10px;padding:12px 8px 12px}
.hvbtns{display:flex;gap:8px}
.hvbtns .btn{flex:1 1 0;justify-content:center}
.hvfoot span{padding:0 4px;font-size:12px;line-height:1.45;color:var(--dim)}
/* While a copy is open, the note box and the two small lines step aside, so the list shows all its rows and the code box has room.
   Press the X to bring them back. */
#hist.viewing #histfor,#hist.viewing .hsave,#hist.viewing .hkeep{display:none}
#hist.viewing #hlist{flex:0 1 auto;min-height:112px}
#hist.viewing #hview{flex:1 1 0;min-height:min(410px,54vh);overflow:auto}
.hkeep{flex:none;padding:8px 12px 10px;border-top:1px solid var(--border);font-size:12px;line-height:1.4;color:var(--dim)}
@media (max-width:900px){
  /* END2 (2026-11-06), item 3: the drawer starts below the file tab row (36 px and a 1 px border), so it never covers the tabs */
  .histp{position:absolute;left:52px;top:42px;bottom:8px;z-index:4;box-shadow:var(--shadow);width:min(360px,calc(100vw - 72px))}
}
@media (max-width:900px),(pointer:coarse){
  .hrow{min-height:48px;align-items:center}
  .hnote{height:44px;font-size:15px}
  .fld input{height:44px;font-size:15px}
}
/* J5c: Share > Grade a whole class is a link that looks like the menu rows around it. */
a.mrow{color:inherit;text-decoration:none}
a.mrow:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
/* CG3 (2026-10-18): the bug ticket on a fix-the-bug task's card, under the task's sentence. It is one box in the card's
   own style (the border and background of the Example panes and the robot task's Tests rows), with no colored stripe.
   "The screen showed" uses the Output panel's code box and its error style, without the friendly sentence. */
.tkbox{display:flex;flex-direction:column;gap:4px;padding:8px 10px 10px;border:1px solid var(--border);border-radius:5px;
  background:var(--island);font-size:13px;line-height:1.45}
.tkout{margin-top:2px;padding:7px 10px 8px;border:1px solid var(--border);border-radius:5px;background:var(--island);
  font:13.5px/21px var(--mono);font-variant-ligatures:none;color:var(--text);white-space:pre-wrap;word-break:break-word}
.tkout .typed{color:var(--typed);font-weight:700}
.tkout .err{display:flex;align-items:flex-start;gap:8px;margin-top:8px;padding:8px 10px;border-radius:5px;background:var(--bad-bg);
  color:var(--text);font:13.5px/1.5 var(--ui);white-space:normal}
.tkout .err:first-child{margin-top:0}
.tkout .err svg{flex:none;width:16px;height:16px;color:var(--bad);margin-top:2px}
.tkout .err .py{display:block;margin-top:4px;color:var(--dim);font-size:12.5px}
.tkout .err .py code{font:12.5px var(--mono);color:var(--dim);word-break:break-word}
/* On a tablet the panels stack under the code, so a card with a ticket scrolls inside a shorter box. At 768 x 1024
   at least 8 lines of code still show under it. */
@media (max-width:900px){
  .task .body:has(> .tkrun){max-height:max(140px,calc(42vh - 240px))}
}
/* CG6 (2026-10-18): a build task's Task card is tall, because its Example shows a whole story. On a tablet (768 x 1024) it
   left only 4 lines of code. As in a robot room, the code keeps room for at least 8 lines (200 px; a line is 23 px). The
   Task card gives up space first: it shrinks, and its words and the whole Example scroll inside it. Only build tasks have
   html.bdmode (app.js). */
@media (max-width:900px){
  html.bdmode #code{flex:1 0 200px}
  html.bdmode .task{flex:0 1 auto;min-height:0;display:flex;flex-direction:column}
  html.bdmode .task .row{flex:none}
  html.bdmode .task .body{flex:1 1 auto;min-height:0;max-height:none}
}

/* CG45 (2026-10-23): the task card as a lead, numbered steps and a tip (a level's "steps" and "tip"). A card with no steps is
   drawn exactly as before. Each step has its number in a round badge; the number is drawn here, so a step's code spans keep
   their line. The tip is one line after the steps. The one-line Task bar (#tt) keeps the lead's code spans. On a wide screen a
   card with steps may be taller, so its Example does not hide under a scroll bar. */
.task .body p.lead{margin:0 0 8px;font-weight:600}
.task .body ol.steps{list-style:none;margin:0 0 8px;padding:0;counter-reset:step}
.task .body ol.steps li{position:relative;margin:0 0 6px;padding-left:32px;counter-increment:step}
.task .body ol.steps li:last-child{margin-bottom:0}
.task .body ol.steps li::before{content:counter(step);position:absolute;left:0;top:-1px;width:22px;height:22px;border-radius:50%;background:var(--soft-2);color:var(--chip-tx);font:700 12px/22px var(--ui);text-align:center}
.task .body p.tip{margin:8px 0 0}
.task .body p.tip b{font-weight:650;color:var(--chip-tx)}
.task .tt code{font:12.5px var(--mono);color:var(--typed)}
@media (min-width:901px){
  .task .body:has(> ol.steps){max-height:calc(100vh - 340px)}
}

/* CGM (2026-10-23): on a computer (a wide screen), a robot task's card drops its Tests list, so the code box gets taller.
   The list stays in the page's code, and a tablet (900 px wide or less) still shows it. Check still runs every test, its
   pop-up still lists them, and the Room panel keeps its test buttons. */
@media (min-width:901px){
  html.rbmode #taskbody > .exrun:has(> .tlist){display:none}
}
/* U5CB (2026-11-05), C2: data files. A task with data files shows them in tabs after main.py (a lock on a shipped file, a
   tag on a file the program wrote) and in the Files panel; the open file shows in .fview in place of the code. A task with
   no data files keeps its one main.py tab, exactly as before (none of these classes are used then). */
.tabs.ftabs{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin}
.tabs.ftabs .tab{flex:none;white-space:nowrap}
.tabs.ftabs .tab:not(.on):hover{background:var(--soft);color:var(--text)}
.tab .tlock{width:13px;height:13px;color:var(--dim);margin-left:-2px}
.ttag{font:600 11.5px/1 var(--ui);color:var(--chip-tx);background:var(--soft-2);padding:4px 7px;border-radius:4px;margin-left:1px}
button.fitem{width:100%;color:var(--dim)}
button.fitem.on{color:var(--text)}
button.fitem:not(.on):hover{background:var(--soft);color:var(--text)}
.fitem .fname{display:flex;flex-direction:column;gap:4px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fitem .fname small{font:500 11.5px/1 var(--ui);color:var(--chip-tx)}

.fitem .flock{width:13px;height:13px;flex:none;margin-left:auto;color:var(--dim)}
.editor.fon .code{display:none}
.fview{flex:1;min-height:0;display:flex;flex-direction:column}
.fview[hidden]{display:none}
.fnote{flex:none;display:flex;align-items:center;gap:9px;margin:10px 12px 2px;padding:9px 12px;border-radius:5px;background:var(--soft);
  font:500 13.5px/1.45 var(--ui);color:var(--text)}
.fnote svg{width:15px;height:15px;flex:none;color:var(--accent)}
.fscroll{flex:1;min-height:0;overflow:auto;padding:8px 0 16px}
.fbody{display:flex;min-width:max-content}
.fnum{margin:0;padding:0 12px 0 14px;min-width:54px;text-align:right;font:13.5px/23px var(--mono);color:var(--ln);user-select:none}
.ftext{margin:0;padding:0 20px 0 8px;font:15px/23px var(--mono);font-variant-ligatures:none;color:var(--text);white-space:pre}
.fmore{margin:10px 0 0 62px;font:500 13.5px/1.4 var(--ui);color:var(--dim)}
.fedit{flex:1;min-height:0;margin:8px 12px 12px;padding:8px 12px;border:1px solid var(--border);border-radius:5px;background:var(--island);
  color:var(--text);font:15px/23px var(--mono);font-variant-ligatures:none;white-space:pre;overflow:auto;resize:none;outline:0}
.fedit:focus{border-color:var(--accent)}
.ftext mark.fbad{background:var(--bad-bg);color:inherit;box-shadow:inset 3px 0 0 var(--bad)}   /* U7C (2026-11-05), C4: an error's line in a file */
@media (max-width:900px),(pointer:coarse){.tabs.ftabs .tab{height:34px}}
/* U5CI (2026-11-05): a colored icon for each file type in the file tabs and the Files panel (icons.js fileIcon), the same
   size as before (15 px in a tab, 16 px in the panel). Each color reads at 4.2:1 or more on the tab backgrounds in both themes. */
:root{--ft-csv:#3FB950;--ft-json:#F2B544;--ft-java:#F26B5B;--ft-html:#F0743E;--ft-css:#4F8EF7;--ft-gray:#8E9AAD;--ft-txtc:#8FA8CC;
  --ft-jsbox:#F7DF1E;--ft-jsedge:#F7DF1E;--ft-jstx:#1B1B1B}
html.light{--ft-csv:#1D7A44;--ft-json:#A86400;--ft-java:#C42B2B;--ft-html:#CC3F1A;--ft-css:#1F5FD1;--ft-gray:#687384;--ft-txtc:#56709A;
  --ft-jsedge:#8C7B00}
svg.i.ft{stroke:none}
svg.ft.ft-csv{color:var(--ft-csv)}svg.ft.ft-json{color:var(--ft-json)}svg.ft.ft-java{color:var(--ft-java)}svg.ft.ft-html{color:var(--ft-html)}
svg.ft.ft-css{color:var(--ft-css)}svg.ft.ft-gray{color:var(--ft-gray)}svg.ft.ft-txtc{color:var(--ft-txtc)}
img.ft{width:16px;height:16px;flex:none;display:block}
.tab img.ft{width:15px;height:15px}
