/* ============================================================
   KitsArt 3D — the frame.

   One window, six workspaces, and the two panels that never move: the scene on
   the left, whatever is selected on the right. The rule the layout is trying to
   hold is that only the middle bar changes when you switch workspace — the
   shape of the window does not, so nothing has to be re-found.
   ============================================================ */
*{box-sizing:border-box}
html,body{margin:0;height:100%;overflow:hidden}
body{background:var(--bg);color:var(--text);
  font:13px/1.45 var(--ui, system-ui, -apple-system, "Segoe UI", sans-serif)}

#app{height:100%;display:grid;
  --left:222px;--right:300px;
  grid-template-columns:var(--left) minmax(0,1fr) var(--right);
  grid-template-rows:34px 34px 36px minmax(0,1fr) 24px;
  grid-template-areas:"menu menu menu" "ws ws ws" "opt opt opt" "left stage right" "status status status"}

/* ---------- menu bar ---------- */
.menubar{grid-area:menu;display:flex;align-items:center;gap:2px;padding:0 8px;
  background:var(--s1);border-bottom:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:7px;font-weight:660;letter-spacing:-.012em;font-size:13px;padding-inline-end:6px}
.brand b{color:var(--cat);font-weight:700}
.mark{width:15px;height:15px;border-radius:4px;background:var(--cat);flex:none}
.menu{position:relative}
.menu-t{padding:4px 9px;border-radius:6px;border:0;background:none;color:var(--t2);font:inherit;font-size:12.5px;cursor:pointer}
.menu-t:hover,.menu.on .menu-t{background:var(--s2);color:var(--text)}
.menu-d{position:absolute;top:100%;inset-inline-start:0;z-index:200;min-width:240px;padding:5px;
  border-radius:10px;border:1px solid var(--line2);background:var(--popbg,var(--s1));
  box-shadow:0 22px 50px -20px rgba(0,0,0,.72);display:none}
.menu.on .menu-d{display:block}
.menu-d .mi{display:flex;align-items:center;gap:10px;width:100%;padding:6px 9px;border:0;border-radius:6px;
  background:none;color:var(--text);font:inherit;font-size:12.5px;text-align:start;cursor:pointer}
.menu-d .mi:hover{background:var(--s3)}
.menu-d .mi .k{margin-inline-start:auto;color:var(--t3);font-size:11px}
.menu-d .msep{height:1px;background:var(--line);margin:4px 3px}
.menubar-r{margin-inline-start:auto;display:flex;align-items:center;gap:8px}
.backend{cursor:pointer;font:inherit;font-size:10.5px;font-weight:640;letter-spacing:.04em;padding:2px 7px;border-radius:999px;
  border:1px solid color-mix(in srgb,var(--cat) 38%,var(--line));color:var(--cat);
  background:color-mix(in srgb,var(--cat) 12%,transparent)}

/* ---------- workspaces ---------- */
.wsbar{grid-area:ws;display:flex;align-items:stretch;gap:2px;padding:3px 8px;background:var(--s2);
  border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none}
.wsbar::-webkit-scrollbar{display:none}
.wstab{display:inline-flex;align-items:center;gap:7px;padding:0 12px;border-radius:8px;border:1px solid transparent;
  background:none;color:var(--t3);font:inherit;font-size:12.3px;font-weight:560;cursor:pointer;white-space:nowrap;flex:none}
.wstab svg{width:15px;height:15px}
.wstab:hover{background:var(--s1);color:var(--t2)}
.wstab.on{background:var(--s1);color:var(--text);border-color:var(--line);box-shadow:inset 0 -2px 0 var(--cat)}
.wstab .soon{font-size:9.5px;letter-spacing:.05em;text-transform:uppercase;opacity:.6}

/* ---------- the workspace's own tools ---------- */
.optbar{grid-area:opt;display:flex;align-items:center;gap:5px;padding:0 9px;background:var(--s1);
  border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none}
.optbar::-webkit-scrollbar{display:none}
.obsep{width:1px;height:18px;background:var(--line);margin:0 4px;flex:none}
.oblab{font-size:11px;color:var(--t3);flex:none}
.btn{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 11px;border-radius:7px;
  border:1px solid var(--line);background:var(--s2);color:var(--text);font:inherit;font-size:12px;cursor:pointer;flex:none}
.btn:hover{background:var(--s3)}
.btn-p{background:var(--btnp-bg,var(--cat));border-color:transparent;color:var(--btnp-fg,#fff);font-weight:600}
.btn-p:hover{filter:brightness(1.08)}
.tb{display:inline-flex;align-items:center;gap:5px;height:25px;padding:0 9px;border-radius:7px;border:1px solid transparent;
  background:none;color:var(--t2);font:inherit;font-size:12px;cursor:pointer;flex:none}
.tb:hover{background:var(--s2);color:var(--text)}
.tb.on{background:color-mix(in srgb,var(--cat) 22%,var(--s2));color:var(--text);
  border-color:color-mix(in srgb,var(--cat) 45%,transparent)}
.optbar-r{margin-inline-start:auto;display:flex;align-items:center;gap:6px}
.optbar input[type=range]{accent-color:var(--cat)}

/* ---------- the two panes ---------- */
.pane{position:relative;background:var(--s1);display:flex;flex-direction:column;min-height:0}
.pane-l{grid-area:left;border-inline-end:1px solid var(--line)}
.pane-r{grid-area:right;border-inline-start:1px solid var(--line)}
.ptabs{flex:none;display:flex;border-bottom:1px solid var(--line);background:var(--s2)}
.ptab{padding:6px 11px;border:0;background:none;color:var(--t3);font:inherit;font-size:11.8px;cursor:pointer}
.ptab:hover{color:var(--t2)}
.ptab.on{color:var(--text);background:var(--s1);box-shadow:inset 0 -2px 0 var(--cat)}
.pbody{display:none;flex:1;flex-direction:column;min-height:0}
.pbody.on{display:flex}
.phead{flex:none;display:flex;align-items:center;gap:7px;padding:7px 10px;font-size:10.5px;font-weight:650;
  letter-spacing:.06em;text-transform:uppercase;color:var(--t3);border-bottom:1px solid var(--line)}
.phead .n{margin-inline-start:auto;font-size:11px}
.pfoot{flex:none;padding:7px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:5px}
.rowbtn{width:100%;padding:6px 9px;border-radius:7px;border:1px solid var(--line);background:var(--s2);
  color:var(--t2);font:inherit;font-size:12px;cursor:pointer;text-align:start}
.rowbtn:hover{background:var(--s3);color:var(--text)}
.rowbtn[disabled]{opacity:.45;cursor:default}
.rowbtn[disabled]:hover{background:var(--s2);color:var(--t2)}
.rowbtn .k{float:inline-end;color:var(--t3);font-size:11px}
.gedit{display:flex;align-items:center;gap:6px}
.gedit .glab{flex:1;min-width:0;font-size:11.5px;color:var(--t2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gedit input[type=color]{width:26px;height:22px;flex:none;padding:0;border:1px solid var(--line);
  border-radius:5px;background:none;cursor:pointer}
.foothint{font-size:10.5px;line-height:1.45;color:var(--t3)}

/* ---------- the hierarchy ---------- */
.tree{flex:1;overflow-y:auto;padding:5px}
.tree .empty,.props .empty,.matlist .empty{padding:22px 12px;color:var(--t3);font-size:12px;text-align:center;line-height:1.75}
.tgroup{margin-bottom:3px}
.tgroup>.th{display:flex;align-items:center;gap:6px;padding:4px 7px;font-size:10.5px;font-weight:650;
  letter-spacing:.05em;text-transform:uppercase;color:var(--t3)}
.tgroup>.th .n{margin-inline-start:auto;opacity:.8}
.trow{display:flex;align-items:center;gap:7px;padding:5px 8px;border-radius:7px;cursor:pointer;
  border:1px solid transparent}
.trow:hover{background:var(--s2)}
.trow.sel{background:color-mix(in srgb,var(--cat) 18%,var(--s2));border-color:color-mix(in srgb,var(--cat) 42%,transparent)}
/* The icon is the switch. It is a button, it is on the left, and it looks
   pressed when the thing is on — the same shape as every other toggle here. */
.trow .ic{width:22px;height:20px;flex:none;color:var(--t3);display:grid;place-items:center;
  border:1px solid transparent;border-radius:5px;background:none;cursor:pointer;padding:0}
.trow .ic:hover{background:var(--s3);color:var(--text);border-color:var(--line)}
.trow.sel .ic{color:var(--cat)}
.trow.off .ic{opacity:.4}
.trow .ic svg{width:13px;height:13px}
.trow .nm{cursor:default}
.trow .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.3px}
.trow.off .nm{opacity:.42}
.trow .sw{width:11px;height:11px;border-radius:3px;flex:none;border:1px solid rgba(255,255,255,.14)}

/* ---------- materials ---------- */
.matlist{flex:1;overflow-y:auto;padding:5px}
.mrow{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:7px;cursor:pointer;border:1px solid transparent}
.mrow:hover{background:var(--s2)}
.mrow.sel{background:color-mix(in srgb,var(--cat) 18%,var(--s2));border-color:color-mix(in srgb,var(--cat) 42%,transparent)}
.mrow .sw{width:20px;height:20px;border-radius:6px;flex:none;border:1px solid rgba(255,255,255,.14)}
.mrow .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.3px}
.mrow .use{font-size:10.5px;color:var(--t3)}

/* ---------- properties ---------- */
.props{flex:1;overflow-y:auto;padding:10px}
.sec{margin-bottom:14px}
.sec>h4{margin:0 0 8px;font-size:10.5px;font-weight:650;letter-spacing:.06em;text-transform:uppercase;color:var(--t3);
  display:flex;align-items:center;gap:7px}
.sec>h4 .rt{margin-inline-start:auto;font-size:10px;font-weight:600;text-transform:none;letter-spacing:0;color:var(--t3)}
.row{display:flex;align-items:center;gap:9px;margin-bottom:7px}
.row>label{flex:none;width:82px;color:var(--t3);font-size:11.6px}
.row>.f{flex:1;display:flex;align-items:center;gap:7px;min-width:0}
.row input[type=range]{flex:1;min-width:0;accent-color:var(--cat)}
.row input[type=number],.row input[type=text]{width:100%;min-width:0;background:var(--s2);border:1px solid var(--line);
  border-radius:6px;color:var(--text);padding:4px 7px;font:inherit;font-size:12px}
.row input[type=color]{width:32px;height:24px;padding:0;border:1px solid var(--line);border-radius:6px;background:none;flex:none}
.row select{flex:1;min-width:0;background:var(--s2);border:1px solid var(--line);border-radius:6px;
  color:var(--text);padding:4px 7px;font:inherit;font-size:12px}
.row .v{flex:none;min-width:48px;text-align:end;color:var(--t2);font-size:11.4px;font-variant-numeric:tabular-nums}
.xyz{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-bottom:7px}
.xyz label{display:flex;align-items:center;gap:4px;font-size:10.5px;color:var(--t3)}
.xyz input{width:100%;min-width:0;background:var(--s2);border:1px solid var(--line);border-radius:6px;
  color:var(--text);padding:4px 5px;font:inherit;font-size:11.6px}
.chips{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:8px}
.chip{padding:4px 9px;border-radius:999px;border:1px solid var(--line);background:var(--s2);color:var(--t2);
  font:inherit;font-size:11.5px;cursor:pointer}
.chip:hover{color:var(--text);border-color:var(--t3)}
.chip.on{background:var(--cat);border-color:transparent;color:#fff}
.note{color:var(--t3);font-size:11.3px;line-height:1.6;margin:6px 0 2px}
.stat{display:flex;justify-content:space-between;gap:10px;padding:4px 0;font-size:12px;border-bottom:1px solid var(--line)}
.stat b{font-weight:600;font-variant-numeric:tabular-nums}
.stat.warn b{color:var(--warn,#e2a03f)}
.stat.bad b{color:var(--bad,#e5484d)}
.stat.ok b{color:var(--ok,#46a758)}

/* ---------- a material channel ----------
   The switch, the value and the map in one row each, because a channel is one
   idea and splitting it across a panel makes it three. */
.chan{border:1px solid var(--line);border-radius:9px;padding:8px 9px;margin-bottom:7px;background:var(--s2)}
.chan.doing{border-color:color-mix(in srgb,var(--cat) 45%,var(--line))}
.chan-h{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.chan-h b{font-size:11.8px;font-weight:600;flex:1}
.chan-h .sw2{width:26px;height:15px;border-radius:999px;border:1px solid var(--line);background:var(--s1);
  position:relative;cursor:pointer;flex:none;padding:0}
.chan-h .sw2 i{position:absolute;top:1px;inset-inline-start:1px;width:11px;height:11px;border-radius:50%;
  background:var(--t3);transition:transform .16s,background .16s}
.chan-h .sw2.on{background:color-mix(in srgb,var(--cat) 40%,var(--s1));border-color:var(--cat)}
.chan-h .sw2.on i{background:var(--cat);transform:translateX(11px)}
.chan .mapbar{display:flex;align-items:center;gap:6px;margin-top:6px}
.chan .mapbar .name{flex:1;font-size:11px;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chan .mini{padding:3px 8px;border-radius:6px;border:1px solid var(--line);background:var(--s1);color:var(--t2);
  font:inherit;font-size:11px;cursor:pointer}
.chan .mini:hover{color:var(--text);background:var(--s3)}
.chan .thumb{width:26px;height:26px;border-radius:5px;flex:none;border:1px solid var(--line);
  background-size:cover;background-position:center}

/* ---------- the stage ---------- */
.stage{grid-area:stage;position:relative;overflow:hidden;background:var(--stagebg,#1a1917)}
.viewport{position:absolute;inset:0}
.viewport canvas{display:block;width:100%;height:100%;touch-action:none}
.dz{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;z-index:5;
  background:color-mix(in srgb,var(--stagebg,#1a1917) 74%,transparent)}
/* `hidden` hides by setting display:none, and the rule above sets display:grid
   — an author rule beats the browser's default every time, so the attribute was
   being set correctly and having no effect. The overlay stayed over the model. */
.dz[hidden]{display:none}
.dz.over{background:color-mix(in srgb,var(--cat) 22%,var(--stagebg,#1a1917))}
.dzi{text-align:center;color:var(--stage-fg2,#9a938b);max-width:340px}
.dzi h3{margin:0 0 6px;font-size:15px;font-weight:620;color:var(--stage-fg,#e8e2da)}
.dzi p{margin:0;font-size:12.5px;line-height:1.6}
/* The right panel's own two tabs. A different class from the left panel's
   Scene/Materials pair, which is `.ptab` and has its own handler — sharing the
   class would have each strip toggling the other. */
.rtabs{display:flex;align-items:center;gap:2px;padding:5px 8px;border-block-end:1px solid var(--line)}
.rtab{border:0;background:none;cursor:pointer;font:inherit;font-size:11.5px;font-weight:640;
  color:var(--t3);padding:4px 9px;border-radius:7px}
.rtab:hover{background:var(--s3);color:var(--text)}
.rtab.on{background:color-mix(in srgb,var(--cat) 16%,transparent);color:var(--cat)}
.rtab[disabled]{opacity:.4;cursor:default}
.rtab[disabled]:hover{background:none;color:var(--t3)}
.phead-what{margin-inline-start:auto;color:var(--t3);font-size:11px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:45%}

/* ---------- the material and light sheet ----------
   One row per control: name, number, slider, texture. The layout every surface
   shader's interface has, because it is the layout the questions come in. */
.msheet{padding:0 0 8px}
.mgrp{border-block-start:1px solid var(--line)}
.mgh{display:flex;align-items:center;gap:6px;width:100%;padding:7px 10px;border:0;background:none;
  color:var(--t2);font:inherit;font-size:11.5px;font-weight:640;letter-spacing:.02em;
  cursor:pointer;text-align:start}
.mgh.static{cursor:default}
.mgh:hover{color:var(--text)}
.mgh .caret{display:grid;place-items:center;width:13px;height:13px;transition:transform .14s ease}
.mgh .caret svg{width:11px;height:11px}
.mgrp .mgh .caret{transform:rotate(90deg)}
.mgrp.shut .mgh .caret{transform:rotate(0)}
.mgrp.shut .mgb{display:none}
.mgb{padding:1px 10px 8px}

.mrow2{display:flex;align-items:center;gap:7px;padding:2.5px 0;min-height:24px}
.mrow2.muted{opacity:.42}
.mrow2 .mlab{flex:0 0 96px;font-size:11.5px;color:var(--t2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mrow2 .mctl{flex:1;display:flex;align-items:center;gap:6px;min-width:0}
.mnum{width:52px;flex:none;background:var(--s2);border:1px solid var(--line);border-radius:5px;
  color:var(--text);font:inherit;font-size:11px;padding:2px 5px;font-variant-numeric:tabular-nums}
.mnum:focus{outline:0;border-color:var(--cat)}
.msl{flex:1;min-width:0;accent-color:var(--cat);height:16px}
.msl:disabled{opacity:.25}
.mcol{width:34px;height:20px;flex:none;padding:0;border:1px solid var(--line);border-radius:5px;
  background:none;cursor:pointer}
.munit{flex:0 0 20px;font-size:10px;color:var(--t3)}
.mmap{flex:none;width:22px;height:22px;border-radius:5px;border:1px solid var(--line);
  background:var(--s2);cursor:pointer;color:var(--t3);display:grid;place-items:center;padding:0;
  overflow:hidden}
.mmap:hover{border-color:var(--cat);color:var(--text)}
.mmap.on{border-color:var(--cat);box-shadow:0 0 0 1px color-mix(in srgb,var(--cat) 55%,transparent)}
.mmap .thumb{width:100%;height:100%;background-size:cover;background-position:center}
.mmap .plus{font-size:13px;line-height:1}
.mmini{flex:none;height:20px;padding:0 5px;border-radius:5px;border:1px solid var(--line);
  background:var(--s2);color:var(--t3);font:inherit;font-size:10px;cursor:pointer}
.mmini:hover{color:var(--text);border-color:var(--line2)}
.mrow2.mapped .mlab{color:var(--cat)}
.mvec{padding:2px 0 4px}
.mvec > .mlab{display:block;font-size:11px;color:var(--t3);margin-block-end:2px}
.mrow2.axis .mlab{flex:0 0 14px;text-align:center;font-weight:700;font-size:10.5px}
.mrow2.axis .ax0{color:#e5675c}
.mrow2.axis .ax1{color:#7fc95a}
.mrow2.axis .ax2{color:#5a9ce5}

/* ---------- groups in the outliner ---------- */
.tgroup.grp .gh{display:flex;align-items:center;gap:6px;cursor:default}
.tgroup.grp .gh.sel{background:color-mix(in srgb,var(--cat) 18%,transparent);border-radius:6px}
.caret{width:16px;height:16px;padding:0;border:0;background:none;cursor:pointer;color:var(--t3);
  display:grid;place-items:center;flex:none;transition:transform .15s ease}
.caret svg{width:12px;height:12px}
.tgroup.grp .caret{transform:rotate(90deg)}
.tgroup.grp.shut .caret{transform:rotate(0deg)}
.tgroup.grp.shut .gbody{display:none}
.gsw{width:11px;height:11px;border-radius:3px;flex:none;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.35)}
.trow.kid{padding-inline-start:20px}

/* ---------- panels you can move ---------- */
.movable{position:absolute}
.pgrip{position:absolute;top:2px;left:50%;transform:translateX(-50%);width:26px;height:11px;
  border:0;background:none;padding:0;cursor:grab;color:var(--stage-fg2,#9a938b);opacity:.5;
  display:grid;place-items:center;touch-action:none;z-index:2}
.pgrip:hover{opacity:1}
.pgrip svg{width:18px;height:11px;fill:currentColor}
.moving{cursor:grabbing;box-shadow:0 10px 30px -8px rgba(0,0,0,.7)}
.moving .pgrip{cursor:grabbing}
/* A vertical panel wears its grip on the top edge and gets room for it. */
.vshelf.movable,.brushbar.movable{padding-block-start:14px}
.vbar.movable{padding-inline-start:16px}
.vbar.movable .pgrip{top:50%;left:3px;transform:translateY(-50%) rotate(90deg)}

/* ---------- the brushes ---------- */
.brushbar{left:10px;top:50%;transform:translateY(-50%);z-index:11;width:126px;
  display:flex;flex-direction:column;gap:1px;padding:14px 5px 7px;border-radius:10px;
  background:rgba(0,0,0,.5);border:1px solid var(--stage-line,rgba(255,255,255,.12));
  backdrop-filter:blur(9px)}
.brushbar[hidden]{display:none}
.brbtn{display:flex;align-items:center;gap:7px;width:100%;padding:4px 6px;border:0;border-radius:6px;
  background:none;color:var(--stage-fg2,#9a938b);font:inherit;font-size:11.5px;cursor:pointer;text-align:start}
.brbtn svg{width:15px;height:15px;flex:none}
.brbtn:hover{background:var(--stage-hov,rgba(255,255,255,.1));color:var(--stage-fg,#e8e2da)}
.brbtn.on{background:color-mix(in srgb,var(--cat) 52%,transparent);color:#fff}
.brsep{height:1px;background:var(--stage-line,rgba(255,255,255,.14));margin:5px 3px}
.brrow{display:flex;align-items:center;gap:5px;padding:1px 4px}
.brrow label{flex:0 0 52px;font-size:10px;color:var(--stage-fg2,#9a938b);
  text-transform:uppercase;letter-spacing:.05em}
.brrow input{flex:1;min-width:0;accent-color:var(--cat);height:14px}
.brrow b{flex:0 0 22px;text-align:end;font-size:10.5px;color:var(--stage-fg,#e8e2da);
  font-variant-numeric:tabular-nums}
.brchips{display:flex;gap:4px;padding:4px 4px 2px}
.brchips .chip{flex:1;font-size:10.5px;padding:3px 4px}
.brhint{padding:3px 5px 0;font-size:9.5px;line-height:1.45;color:var(--stage-fg2,#9a938b);opacity:.8}
.brhint b{color:var(--stage-fg,#e8e2da)}

/* ---------- what is selected, over the picture ---------- */
.details{position:absolute;top:96px;inset-inline-end:12px;z-index:11;width:186px;
  padding:8px 10px;border-radius:9px;background:rgba(0,0,0,.42);
  border:1px solid var(--stage-line,rgba(255,255,255,.1));backdrop-filter:blur(8px);
  color:var(--stage-fg2,#9a938b);font-size:10.5px;line-height:1.6;
  font-variant-numeric:tabular-nums;pointer-events:none}
.details[hidden]{display:none}
.details .dt{display:flex;align-items:center;gap:6px;color:var(--stage-fg,#e8e2da);
  font-size:11.5px;font-weight:640;margin-block-end:4px}
.details .dt .dot{width:8px;height:8px;border-radius:2px;flex:none}
.details .dr{display:flex;justify-content:space-between;gap:10px}
.details .dr b{color:var(--stage-fg,#e8e2da);font-weight:600}
.details .dk{color:var(--stage-fg2,#9a938b);opacity:.8}
.details .dsec{margin-block-start:5px;padding-block-start:5px;
  border-block-start:1px solid var(--stage-line,rgba(255,255,255,.12))}

/* ---------- the tool shelf ----------
   Down the left edge, vertically centred so it clears the toolbar above and
   the heads-up display below. Icons only, with the name in the tooltip: a
   shelf wide enough for words is a shelf that has taken the viewport. */
.vshelf{position:absolute;left:10px;top:50%;transform:translateY(-50%);z-index:11;
  display:flex;flex-direction:column;gap:1px;padding:3px;border-radius:9px;
  background:rgba(0,0,0,.42);border:1px solid var(--stage-line,rgba(255,255,255,.1));
  backdrop-filter:blur(8px)}
.vshelf:empty{display:none}
.sbtn{width:28px;height:28px;border-radius:7px;border:0;background:none;cursor:pointer;
  color:var(--stage-fg2,#9a938b);display:grid;place-items:center;padding:0;flex:none;
  font:inherit;font-size:11px;font-weight:700;position:relative}
.sbtn svg{width:16px;height:16px}
.sbtn:hover{background:var(--stage-hov,rgba(255,255,255,.1));color:var(--stage-fg,#e8e2da)}
.sbtn.on{background:color-mix(in srgb,var(--cat) 52%,transparent);color:#fff;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--cat) 85%,transparent)}
.ssep{height:1px;background:var(--stage-line,rgba(255,255,255,.14));margin:3px 2px}

/* ---------- the orientation cube ----------
   A real cube, turned by the camera's own rotation. The faces are buttons, so
   the thing that tells you where you are is also the thing that takes you
   somewhere — which is the whole point of one. */
.vcube{position:absolute;top:12px;inset-inline-end:12px;z-index:12;
  display:flex;flex-direction:column;align-items:center;gap:6px;user-select:none}
.vcube-scene{width:76px;height:76px;perspective:340px}
.vcube-box{position:relative;width:46px;height:46px;margin:15px;
  transform-style:preserve-3d;transition:transform .18s ease-out}
.vcf{position:absolute;inset:0;display:grid;place-items:center;
  width:46px;height:46px;border:1px solid rgba(255,255,255,.22);border-radius:3px;
  background:rgba(24,22,20,.82);color:var(--stage-fg2,#9a938b);
  font:inherit;font-size:7.5px;font-weight:700;letter-spacing:.06em;cursor:pointer;
  backface-visibility:hidden}
.vcf:hover{background:color-mix(in srgb,var(--cat) 62%,rgba(24,22,20,.9));color:#fff;
  border-color:color-mix(in srgb,var(--cat) 80%,transparent)}
.vcf[data-view="front"] {transform:translateZ(23px)}
.vcf[data-view="back"]  {transform:rotateY(180deg) translateZ(23px)}
.vcf[data-view="right"] {transform:rotateY(90deg)  translateZ(23px)}
.vcf[data-view="left"]  {transform:rotateY(-90deg) translateZ(23px)}
.vcf[data-view="top"]   {transform:rotateX(90deg)  translateZ(23px)}
.vcf[data-view="bottom"]{transform:rotateX(-90deg) translateZ(23px)}
/* The axis letters, so X, Y and Z are named and not only implied. */
.vcube-axes{display:flex;gap:7px;font-size:9px;font-weight:700;letter-spacing:.08em}
.vcube-axes span{opacity:.9}
.vcube-axes .x{color:#e5675c}
.vcube-axes .y{color:#7fc95a}
.vcube-axes .z{color:#5a9ce5}
.vcube-row{display:flex;gap:3px;padding:3px;border-radius:8px;
  background:rgba(0,0,0,.32);border:1px solid var(--stage-line,rgba(255,255,255,.1))}
.vcb{width:24px;height:24px;border-radius:6px;border:0;background:none;cursor:pointer;
  color:var(--stage-fg2,#9a938b);font:inherit;font-size:11.5px;font-weight:640}
.vcb:hover{background:var(--stage-hov,rgba(255,255,255,.09));color:var(--stage-fg,#e8e2da)}

.hud{position:absolute;left:12px;bottom:12px;z-index:10;display:flex;flex-direction:column;gap:2px;
  padding:7px 10px;border-radius:8px;background:rgba(0,0,0,.34);border:1px solid var(--stage-line,rgba(255,255,255,.1));
  color:var(--stage-fg2,#9a938b);font-size:11px;line-height:1.5;font-variant-numeric:tabular-nums;
  pointer-events:none;max-width:280px}
.hud b{color:var(--stage-fg,#e8e2da);font-weight:640}
.hud:empty{display:none}
.wsnote{position:absolute;left:50%;bottom:14px;transform:translateX(-50%);z-index:10;max-width:min(560px,80%);
  padding:8px 13px;border-radius:9px;background:rgba(0,0,0,.42);border:1px solid var(--stage-line,rgba(255,255,255,.1));
  color:var(--stage-fg2,#9a938b);font-size:11.6px;line-height:1.55;text-align:center;pointer-events:none}
.wsnote:empty{display:none}
#brushRing{position:absolute;z-index:12;border:1.5px solid rgba(255,255,255,.85);border-radius:50%;
  pointer-events:none;mix-blend-mode:difference;display:none}

/* ---------- the viewport toolbar ----------
   Small icons, one row, top-left of the stage. The view cube is top-right, so
   the two never collide however narrow the window gets. */
.vbar{position:absolute;top:10px;left:10px;z-index:11;display:flex;align-items:center;gap:1px;
  padding:3px;border-radius:9px;background:rgba(0,0,0,.42);
  border:1px solid var(--stage-line,rgba(255,255,255,.1));backdrop-filter:blur(8px)}
.vbtn{width:26px;height:26px;border-radius:6px;border:0;background:none;cursor:pointer;
  color:var(--stage-fg2,#9a938b);display:grid;place-items:center;padding:0;flex:none}
.vbtn svg{width:15px;height:15px}
.vbtn:hover{background:var(--stage-hov,rgba(255,255,255,.1));color:var(--stage-fg,#e8e2da)}
.vbtn.on{background:color-mix(in srgb,var(--cat) 52%,transparent);color:#fff;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--cat) 85%,transparent)}
/* A lit dot in the corner, because a switch that is on should say so without
   the one next to it to compare against. */
.vbtn.on::after{content:"";position:absolute;inset-block-start:2px;inset-inline-end:2px;
  width:4px;height:4px;border-radius:50%;background:#fff;opacity:.9}
.vbtn{position:relative}
.vbtn[disabled]{opacity:.35;cursor:default}
#vpop h5.sp{margin-block-start:12px;padding-block-start:10px;border-block-start:1px solid var(--line)}
#vpop .q.b button{flex:1}
#vpop .q.v{flex-wrap:wrap}
#vpop .q.v button{flex:1 1 44%}
#vstats .gpu b{color:var(--t2)}
#vstats .lo{font-style:normal;font-size:9.5px;padding:1px 4px;border-radius:4px;
  background:color-mix(in srgb,var(--cat) 30%,transparent);color:#fff;margin-inline-start:4px}

/* the right-click menu — the menubar's own panel, put where the pointer is */
.ctxmenu{position:fixed;top:0;left:0;z-index:400;display:block;min-width:170px}
.ctxmenu[hidden]{display:none}

.vsep{width:1px;height:16px;background:var(--stage-line,rgba(255,255,255,.14));margin:0 3px;flex:none}
.vlab{font-size:10.5px;font-weight:640;letter-spacing:.03em;padding:0 7px;color:var(--stage-fg2,#9a938b);
  cursor:pointer;height:26px;display:inline-flex;align-items:center;border-radius:6px;border:0;background:none}
.vlab:hover{background:var(--stage-hov,rgba(255,255,255,.1));color:var(--stage-fg,#e8e2da)}

/* the popover the toolbar opens for the things that need more than a switch */
.vpop{position:absolute;top:44px;left:10px;z-index:14;min-width:210px;padding:9px;
  border-radius:10px;background:var(--popbg,var(--s1));border:1px solid var(--line2);
  box-shadow:0 22px 50px -18px rgba(0,0,0,.75)}
.vpop[hidden]{display:none}
.vpop h5{margin:0 0 7px;font-size:10.5px;font-weight:650;letter-spacing:.06em;text-transform:uppercase;color:var(--t3)}
.vpop .bgs{display:grid;grid-template-columns:repeat(4,1fr);gap:5px;margin-bottom:8px}
.vpop .bg{aspect-ratio:1;border-radius:7px;border:1px solid var(--line);cursor:pointer;padding:0}
.vpop .bg.on{outline:2px solid var(--cat);outline-offset:1px}
.vpop .q{display:flex;gap:4px;margin-bottom:7px}
.vpop .q button{flex:1;padding:5px 0;border-radius:7px;border:1px solid var(--line);background:var(--s2);
  color:var(--t2);font:inherit;font-size:11px;cursor:pointer}
.vpop .q button.on{background:var(--cat);border-color:transparent;color:#fff}
.vpop .note{margin-top:2px}

/* ---------- statistics over the picture ---------- */
.backend:hover{background:color-mix(in srgb,var(--cat) 24%,transparent)}
.gfxpick{display:flex;flex-direction:column;gap:7px;margin:2px 0 4px}
.gfxpick label{display:flex;gap:9px;align-items:flex-start;padding:9px 11px;border-radius:9px;
  border:1px solid var(--line);cursor:pointer}
.gfxpick label:hover{background:var(--s3)}
.gfxpick label.on{border-color:var(--cat);background:color-mix(in srgb,var(--cat) 10%,transparent)}
.gfxpick input{margin-block-start:2px}
.gfxpick .t{font-weight:640;font-size:12.5px}
.gfxpick .n{color:var(--t3);font-size:11.5px;line-height:1.5}
.gfxpick .live{margin-inline-start:6px;font-size:10px;font-weight:640;letter-spacing:.04em;
  color:var(--cat);text-transform:uppercase}
.mnote{color:var(--t3);font-size:11.5px;line-height:1.55;margin:2px 0 0}
.mnote.warn{color:#e2a03f}

/* The heads-up display: figures over the picture, low and to the left, with
   nothing drawn behind them. Deliberately not a panel. */
.vstats{position:absolute;left:12px;bottom:12px;z-index:11;display:flex;flex-wrap:wrap;
  gap:2px 14px;max-width:min(72%,720px);pointer-events:none;
  font-size:10.5px;line-height:1.5;font-variant-numeric:tabular-nums;
  text-shadow:0 1px 3px rgba(0,0,0,.85),0 0 10px rgba(0,0,0,.5)}
.vstats[hidden]{display:none}
.vstats .hs{display:inline-flex;align-items:baseline;gap:5px;white-space:nowrap}
.vstats .hs i{font-style:normal;color:var(--stage-fg2,#9a938b);opacity:.75;
  text-transform:uppercase;letter-spacing:.07em;font-size:9px}
.vstats .hs b{color:var(--stage-fg,#e8e2da);font-weight:640}
.vstats .warn b{color:#e2a03f}
.vstats .sel b{color:var(--cat)}
.vstats .lo b{color:#fff;background:color-mix(in srgb,var(--cat) 55%,transparent);
  padding:0 5px;border-radius:4px;font-size:9.5px;letter-spacing:.04em}

/* ---------- renaming, wherever a name is shown ---------- */
.rename{background:var(--s3);border:1px solid var(--cat);border-radius:5px;color:var(--text);
  font:inherit;font-size:12.3px;padding:1px 5px;width:100%;min-width:0}

/* ---------- assigning a material ---------- */
.mrow .assign{opacity:0;flex:none;padding:2px 8px;border-radius:6px;border:1px solid var(--line2);
  background:var(--s3);color:var(--t2);font:inherit;font-size:10.5px;cursor:pointer}
.mrow:hover .assign,.mrow.sel .assign{opacity:1}
.mrow .assign:hover{background:var(--cat);border-color:transparent;color:#fff}
.mrow .assign[disabled]{opacity:.3;cursor:default}
.mrow:hover .assign[disabled]{opacity:.3}

/* ---------- status ---------- */
.sbar{grid-area:status;display:flex;align-items:center;gap:12px;padding:0 11px;background:var(--s2);
  border-top:1px solid var(--line);color:var(--t3);font-size:11.4px;font-variant-numeric:tabular-nums}
.sbar .sp{flex:1}
.sbar b{color:var(--t2);font-weight:600}
.dot{width:7px;height:7px;border-radius:50%;background:var(--t3);flex:none}
.dot.ok{background:var(--ok,#46a758)}
.dot.warn{background:var(--warn,#e2a03f)}
.dot.bad{background:var(--bad,#e5484d)}

/* ---------- modal + toasts ---------- */
.modal{position:fixed;inset:0;z-index:500;display:grid;place-items:center;background:rgba(0,0,0,.5)}
.modal[hidden]{display:none}
.mcard{width:min(460px,92vw);background:var(--s1);border:1px solid var(--line2);border-radius:13px;padding:18px;
  box-shadow:0 30px 70px -24px rgba(0,0,0,.8)}
.mcard h3{margin:0 0 14px;font-size:14.5px;font-weight:640}
.mfoot{display:flex;justify-content:flex-end;gap:8px;margin-top:16px}
.toasts{position:fixed;bottom:34px;left:50%;transform:translateX(-50%);z-index:600;
  display:flex;flex-direction:column;gap:7px;align-items:center;pointer-events:none}
.toast{display:flex;align-items:center;gap:8px;padding:8px 13px;border-radius:9px;background:var(--s1);
  border:1px solid var(--line2);color:var(--text);font-size:12.5px;box-shadow:0 16px 38px -16px rgba(0,0,0,.75);
  transition:opacity .3s}
.toast .dot{background:var(--ok,#46a758)}
.toast .dot.bad{background:var(--bad,#e5484d)}
.toast .dot.warn{background:var(--warn,#e2a03f)}

/* ---------- narrow ----------
   A tablet in portrait has no room for three columns. The panes become sheets
   over the viewport rather than shrinking it to nothing. */
@media(max-width:980px){
  #app{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"menu" "ws" "opt" "stage" "status"}
  .pane{position:absolute;inset-block:0;width:min(320px,86vw);z-index:120;transform:translateX(-105%);
    transition:transform .22s;box-shadow:0 0 40px rgba(0,0,0,.5)}
  .pane-r{inset-inline-end:0;inset-inline-start:auto;transform:translateX(105%)}
  body.showL .pane-l,body.showR .pane-r{transform:none}
  .wstab span:not(.soon){display:none}
  .wstab{padding:0 10px}
}
