  /* Pixuf — a pixel font, drawn onto the generated hat template (the "DRAWUNDER" labels on the taller 192x192
     sheet). Full glyph set kept (~4.7KB woff2, format-only - a future text tool will want every character);
     pixel-crisp at its native 8px. Canvas-only, so it's fetched on demand via document.fonts.load when that
     template is shown, not at page load. */
  @font-face{font-family:"Pixuf";src:url("/workbench/pixuf.woff2") format("woff2");font-display:swap}
  .wb{max-width:var(--maxw);margin:0 auto;padding:10px 16px 56px;--radius-sm:12px;
    --wb-bar:#fcfbf8;--wb-panel:#faf9f6;--wb-canvas:#f7f4ed;--wb-edge1:var(--line);--wb-edge2:#f7f4ed;--wb-edge3:#fcfbf6}   /* cozy reskin: round the squareish controls (tools, A/B, icon buttons, palette chrome) up toward the curvy popup/pill family. Full 14px would turn the small 30-38px icon buttons into circles, so 12px is the cozy-but-still-a-button sweet spot. Layered editor surfaces: bar (lightest) -> panels -> canvas (least), split by a graduated divider edge1(darkest)>edge2>edge3 so the chrome reads as stacked planes. */
  html[data-theme="dark"] .wb{--wb-bar:var(--raised);--wb-panel:var(--surface);--wb-canvas:var(--bg);--wb-edge1:var(--line);--wb-edge2:var(--line-strong);--wb-edge3:var(--line)}   /* same plane ordering in dark, mapped to the theme tokens (raised>surface>bg) */
  .ed{position:relative;display:grid;grid-template-rows:auto 1fr auto;height:min(82vh,900px);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--wb-canvas);box-shadow:var(--sh-sm);transition:grid-template-rows .26s ease}   /* same border + gentle shadow as the guides cards (.cardlink) */
  .ed.maxed{position:fixed;inset:0;z-index:200;height:100dvh;width:100vw;border:0;border-radius:0;margin:0;animation:edmax .18s ease-out}
  @keyframes edmax{from{transform:scale(.985);opacity:.55}to{transform:scale(1);opacity:1}}
  .ed__bar{display:flex;align-items:center;gap:6px;padding:8px 12px;background:var(--wb-bar);border-bottom:1px solid var(--wb-edge1)}   /* within-group 6px + the dividers' margin = clear groups; 12px left inset lines New up with the rail content below */
  .tools{display:flex;gap:4px;align-items:center}
  .splittool{display:flex;align-items:stretch}
  .splittool .tool{width:34px;border-top-right-radius:0;border-bottom-right-radius:0}   /* trimmed on the right; the freed width goes to the chevron so the caret isn't jammed */
  .toolchev{width:19px;border:1px solid transparent;border-radius:0 var(--radius-sm) var(--radius-sm) 0;background:none;color:var(--muted);cursor:pointer;display:grid;place-items:center;padding:0}
  .toolchev:hover{background:var(--raised);color:var(--ink)}
  .splittool .tool.on+.toolchev,.toolchev.open{background:var(--accent);color:var(--accent-ink)}   /* active tool: both halves carry the accent so the split reads as one button */
  .splittool .tool.on:hover,.splittool .tool.on+.toolchev:hover{background:var(--accent-strong)}   /* ...but each half still highlights on its own hover */
  .splittool.nochev .toolchev{display:none} .splittool.nochev .tool{width:38px;border-radius:var(--radius-sm)}   /* select only earns a chevron when there's >1 frame (its only option is all-frames); otherwise it's a plain full-width button */
  .toolchev svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round;transform:translateX(-2px)}   /* nudge left: the icon-to-caret gap made the geometric centre read right-heavy */
  .toolfly{display:none;position:fixed;z-index:401;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius);box-shadow:var(--sh);padding:13px 15px;flex-direction:column;gap:13px;min-width:160px}
  .toolfly.show{display:flex}
  .toolfly__arrow{position:absolute;top:-7px;left:18px;width:12px;height:12px;background:var(--surface);border-left:1px solid var(--line-strong);border-top:1px solid var(--line-strong);transform:rotate(45deg)}
  .flyrow{display:flex;flex-direction:column;gap:8px}
  .flyrow__l{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:700}
  .tool{width:38px;height:38px;display:grid;place-items:center;border:1px solid transparent;border-radius:var(--radius-sm);background:none;color:var(--muted);cursor:pointer}
  .tool:hover{background:var(--raised);color:var(--ink)} .tool.on{background:var(--accent);color:var(--accent-ink)}
  .tool svg{width:23px;height:23px;fill:none;stroke:currentColor;stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
  .barsep{width:1px;height:24px;background:var(--line-strong);margin:0 4px}   /* with the 6px bar gap this leaves ~21px between groups */
  .brushes{display:flex;align-items:center;gap:4px}
  .brush{width:32px;height:32px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--raised);display:grid;place-items:center;cursor:pointer}
  .brushsize{display:flex;align-items:center;gap:10px;flex:1}
  .brange{flex:1;min-width:0;-webkit-appearance:none;appearance:none;height:6px;border-radius:var(--pill);background:var(--line-strong);cursor:pointer}
  .brange::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;background:var(--accent);border:2px solid var(--surface);box-shadow:0 0 0 1px var(--line-strong);cursor:pointer}
  .brange::-moz-range-thumb{width:14px;height:14px;border:2px solid var(--surface);border-radius:50%;background:var(--accent);box-shadow:0 0 0 1px var(--line-strong);cursor:pointer}
  .bsval{font-size:12px;font-weight:700;color:var(--ink);min-width:30px;text-align:right;font-variant-numeric:tabular-nums}
  .brush.on{border-color:var(--accent);background:var(--accent-weak)} .brush i{display:block;border-radius:50%;background:var(--ink)}
  .fillopts,.selopts,.penopts{display:flex;align-items:center;gap:5px}
  .topt{border:1px solid var(--line-strong);border-radius:var(--pill);background:var(--raised);color:var(--muted);font:inherit;font-weight:600;font-size:12px;padding:5px 11px;cursor:pointer;white-space:nowrap}   /* nowrap: never let a label wrap to two lines and double the bar height */
  .topt:hover{color:var(--ink)} .topt.on{background:var(--accent-weak);color:var(--accent-strong);border-color:var(--accent-mid)} .topt:disabled{opacity:.45;cursor:default}
  .topt .t-ab{display:none}   /* the option labels carry a full + abbreviated form; show the short one when the bar gets tight */
  @media (max-width:1040px){ .topt .t-full{display:none} .topt .t-ab{display:inline} }
  .ops{display:flex;flex-direction:column;align-items:stretch;gap:8px} .ops__h{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:0}   /* section title for the type's tools, matched to the palette headings */
  .opsfor{font-size:12px;color:var(--ink);background:var(--raised);border:1px solid var(--line-strong);border-radius:var(--radius-sm);padding:5px 7px;font:inherit}
  .opbtn{border:1px solid var(--line-strong);border-radius:var(--pill);background:var(--surface);color:var(--ink);font:inherit;font-weight:600;font-size:13px;padding:6px 11px;cursor:pointer;white-space:nowrap}   /* quiet at rest; lights up on hover/active so the panel reads calm, not a wall of colour */
  .opbtn:hover{background:var(--raised)} .opbtn.on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}   /* neutral hover, accent only when active - same as the bar/palette icon buttons */
  .opbtn:disabled,.opbtn:disabled:hover{opacity:.4;cursor:default;background:var(--surface);color:var(--ink);border-color:var(--line-strong)}
  .ed__barright{margin-left:auto;display:flex;align-items:center;gap:6px}
  .zoom{display:flex;align-items:center;gap:2px;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--pill);padding:3px;box-shadow:var(--sh)}   /* matches the per-piece menu pill */
  .zoom button{width:26px;height:26px;border:0;border-radius:50%;background:none;color:var(--ink);font-size:16px;cursor:pointer;transition:transform .08s ease,background .12s ease,color .12s ease} .zoom button:hover{background:var(--accent);color:var(--accent-ink);transform:scale(1.08)}
  #zoomLbl{min-width:38px;text-align:center;font-size:13px;font-variant-numeric:tabular-nums;color:var(--muted)}
  .iconbtn{width:34px;height:34px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--surface);color:var(--ink);font-size:16px;cursor:pointer;display:grid;place-items:center}
  .iconbtn:hover{background:var(--raised)} .iconbtn:disabled{opacity:.4;cursor:default}
  .iconbtn svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
  .iconbtn.on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}   /* a pane is hidden */
  .panemenu{position:relative;display:inline-flex}
  .panepop{position:absolute;top:calc(100% + 9px);right:0;z-index:200;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius);box-shadow:var(--sh);padding:13px 14px;display:flex;flex-direction:column;gap:8px;min-width:150px}   /* same flyout look as the tool option menus */
  .panepop[hidden]{display:none}
  .panepop__arrow{position:absolute;top:-7px;right:13px;width:12px;height:12px;background:var(--surface);border-left:1px solid var(--line-strong);border-top:1px solid var(--line-strong);transform:rotate(45deg)}
  .panestack{display:flex;flex-direction:column;gap:6px} .panestack .topt{text-align:left}
  .ed.lmin #tgPanes .pi-l,.ed.rmin #tgPanes .pi-r,.ed.tlmin #tgPanes .pi-b{display:none}   /* the panels icon's divider lines = open panes (left / right / bottom); each line drops out as its pane hides */
  #tgPanes .pi-lo,#tgPanes .pi-ro{display:none}   /* lower stubs of the side dividers - hidden while the timeline bar caps them */
  .ed.tlmin #tgPanes .pi-lo,.ed.tlmin #tgPanes .pi-ro{display:inline}   /* timeline hidden: extend the side dividers all the way down */
  .ed.tlmin.lmin #tgPanes .pi-lo,.ed.tlmin.rmin #tgPanes .pi-ro{display:none}   /* ...unless that side pane is hidden too */
  .histbtns{display:flex;gap:4px}
  .histbtns svg{width:19px;height:19px;stroke-width:2.5}   /* the curved undo/redo arrows read small at the shared 17px - nudge up + thicken to match the bold chevron caret */
  .ghostbtn{border:1px solid var(--line-strong);border-radius:var(--pill);background:var(--surface);color:var(--ink);font:inherit;font-weight:600;font-size:13px;padding:7px 13px;cursor:pointer}.ghostbtn:hover{background:var(--raised)}
  .ed__main{display:grid;grid-template-columns:222px 1fr 222px;min-height:0;border-top:1px solid var(--wb-edge2);transition:grid-template-columns .26s ease}   /* edge2 = the second line of the toolbar divider, full width above all three columns */
  /* collapse panes to give the canvas room - the tracks slide shut (the canvas refits via a ResizeObserver) */
  .ed.lmin .ed__main{grid-template-columns:0 1fr 222px} .ed.rmin .ed__main{grid-template-columns:222px 1fr 0} .ed.lmin.rmin .ed__main{grid-template-columns:0 1fr 0}
  .ed.tlmin{grid-template-rows:auto 1fr 0}
  .ed.lmin .ed__preview,.ed.rmin .ed__palette,.ed.tlmin .ed__timeline{overflow:hidden;border-width:0}   /* clip the content as the track slides shut (no scrollbar flash, no border line left behind) */
  .ed__preview{border-right:1px solid var(--wb-edge1);border-top:1px solid var(--wb-edge3);background:var(--wb-panel);padding:12px;display:flex;flex-direction:column;overflow:auto}   /* rail rhythm via child margins (not a uniform gap): 8px label->control, 20px between sections. edge3 top border completes the split into the panel */
  .ed__preview h2{margin:0;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
  .prevtabs{display:inline-flex;align-self:center;align-items:stretch;height:34px;box-sizing:border-box;gap:2px;margin-bottom:8px;padding:3px;background:var(--raised);border:1px solid var(--line-strong);border-radius:var(--pill)}   /* a segmented switch, not underline tabs; 34px = the standard control height */
  .prevtab{display:flex;align-items:center;border:0;background:none;font:inherit;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);padding:0 13px;border-radius:var(--pill);cursor:pointer}
  .prevtab.on{background:var(--accent);color:var(--accent-ink)}   /* the selected segment fills, like the shell's .seg thumb */
  .prevtab:not(.on):not(:disabled):hover{color:var(--ink)}
  .prevtab:disabled{opacity:.4;cursor:default}
  .prevbox{position:relative;box-sizing:content-box;width:192px;height:192px;margin:0 auto 8px;background:var(--raised);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}   /* a fixed 192x192 (12 tile) interior: centring a 320 ground (20 tiles, also a multiple of 32) crops it to a whole 12x12 tiles, no half-tile at the edges. content-box so the 1px border doesn't shave the interior off the grid */
  #prevBg{position:absolute;inset:0;z-index:0;width:100%;height:100%;image-rendering:pixelated;pointer-events:none}
  .prevview{position:relative;z-index:1;display:grid;place-items:center;padding:10px;height:100%;overflow:hidden}
  #prevCanvas{image-rendering:pixelated;display:block}
  .grounds{display:flex;justify-content:center;gap:6px;margin:0 0 20px}   /* the backdrop row sits BELOW the character (the card leads with the character, not these chips) */
  .ground{width:24px;height:24px;border-radius:6px;border:2px solid var(--surface);box-shadow:0 0 0 1px var(--line-strong);cursor:pointer;background-size:cover;background-position:center;image-rendering:pixelated;padding:0}
  .ground:hover{box-shadow:0 0 0 1px var(--accent-mid)} .ground.on{box-shadow:0 0 0 2px var(--accent);transform:scale(1.08)}
  .ground.gnone{background:linear-gradient(135deg,transparent 47%,var(--muted) 47%,var(--muted) 53%,transparent 53%),var(--raised)}
  .zoom.prevzoom{position:absolute;right:6px;bottom:6px;z-index:2;padding:2px}
  .zoom.prevzoom button{width:22px;height:22px;font-size:14px} .zoom.prevzoom #pzoomLbl{min-width:30px;text-align:center;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
  .poselbl{text-align:center;font-size:12px;color:var(--muted);min-height:1.2em}
  .ed__stage{position:relative;overflow:hidden;background:var(--wb-canvas);touch-action:none;cursor:crosshair}
  .ed__stage.panning{cursor:grabbing} .ed__stage.over{outline:3px dashed var(--accent);outline-offset:-6px}
  #sheet{position:absolute;inset:0;image-rendering:pixelated}
  #cursorCv{position:absolute;inset:0;pointer-events:none;z-index:1}
  /* shield-only resize grips: a WHITE, ROUNDED (Animal-Crossing-soft) filled-triangle arrowhead in the popover's surface
     colour, wearing the popover styling - soft drop-shadow + a hairline edge, no chip. (Picked from four trial styles;
     now on all four corners, each triangle pointing its own diagonal.) White on light, dark on dark (var --surface);
     fat stroke + rounded corners. Fixed screen size at every zoom, the way resize handles work in design/dev tools. */
  .szhandle{position:absolute;left:0;top:0;width:24px;height:24px;z-index:4;box-sizing:border-box;touch-action:none;transition:transform .12s ease;filter:drop-shadow(0 0 .9px var(--line-strong)) drop-shadow(0 1.5px 2px rgba(0,0,0,.45))}
  .szhandle[hidden]{display:none}
  .szhandle::after{content:"";position:absolute;inset:0;background:var(--surface);-webkit-mask:no-repeat center/contain var(--szarrow);mask:no-repeat center/contain var(--szarrow)}
  .szhandle:hover{transform:scale(1.16)}
  #szTL{cursor:nwse-resize;--szarrow:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Cpath%20d='M5%205%20L11%205%20L5%2011%20Z'%20fill='%23000'%20stroke='%23000'%20stroke-width='2.8'%20stroke-linejoin='round'/%3E%3C/svg%3E")}        /* filled triangle, pointing the corner's diagonal */
  #szTR{cursor:nesw-resize;--szarrow:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Cpath%20d='M11%205%20L5%205%20L11%2011%20Z'%20fill='%23000'%20stroke='%23000'%20stroke-width='2.8'%20stroke-linejoin='round'/%3E%3C/svg%3E")}
  #szBL{cursor:nesw-resize;--szarrow:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Cpath%20d='M5%2011%20L5%205%20L11%2011%20Z'%20fill='%23000'%20stroke='%23000'%20stroke-width='2.8'%20stroke-linejoin='round'/%3E%3C/svg%3E")}
  #szBR{cursor:nwse-resize;--szarrow:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Cpath%20d='M11%2011%20L11%205%20L5%2011%20Z'%20fill='%23000'%20stroke='%23000'%20stroke-width='2.8'%20stroke-linejoin='round'/%3E%3C/svg%3E")}
  .szdim{position:absolute;left:0;top:0;z-index:5;pointer-events:none;transform:translate(10px,10px);font:600 11px/1 system-ui,sans-serif;color:var(--accent-ink);background:var(--accent);padding:4px 7px;border-radius:var(--pill);white-space:nowrap;box-shadow:0 1px 3px rgba(0,0,0,.3)}
  .szdim[hidden]{display:none}
  .stagehint{position:absolute;left:12px;bottom:10px;font-size:11px;color:var(--muted);background:color-mix(in srgb,var(--surface) 82%,transparent);border:1px solid var(--line);border-radius:var(--pill);padding:3px 10px;pointer-events:none;max-width:60%}
  .stagehint:empty{display:none}
  .stagehint.walking{pointer-events:auto;display:flex;align-items:center;gap:8px;max-width:82%;color:var(--accent-strong);background:color-mix(in srgb,var(--accent-weak) 92%,var(--surface));border-color:var(--accent-mid);font-size:12px}
  .stagehint .wbtn{border:1px solid var(--accent-mid);border-radius:var(--pill);background:var(--surface);color:var(--accent-strong);font:inherit;font-weight:600;font-size:11px;padding:2px 9px;cursor:pointer;white-space:nowrap}
  .stagehint .wbtn:hover{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
  /* the per-piece menu: the pill bar, bent into an arc that hugs the sprite (SVG = the curved pill, round chips ride it) */
  .piecehud{position:absolute;z-index:6;left:0;top:0;width:0;height:0}
  .piecehud[hidden]{display:none}
  #pieceBar{position:absolute;left:0;top:0;overflow:visible;pointer-events:none;filter:drop-shadow(0 2px 4px rgba(0,0,0,.22))}
  #pieceBar path{fill:none;stroke-linecap:round;stroke-linejoin:round}
  #pieceBarOutline{stroke:var(--line-strong);stroke-width:39;pointer-events:none}
  #pieceBarFill{stroke:var(--surface);stroke-width:36;pointer-events:stroke}
  .piecehud button{position:absolute;width:28px;height:28px;border:0;border-radius:50%;background:var(--raised);color:var(--ink);font-size:18px;line-height:1;cursor:pointer;display:grid;place-items:center;transition:transform .08s ease,background .12s ease,color .12s ease}
  .piecehud button svg{width:18px;height:18px}
  .piecehud button:hover{background:var(--accent);color:var(--accent-ink);transform:scale(1.1)}
  .piecehud button:active{transform:scale(.92)}
  .piecehud button.on{background:var(--accent);color:var(--accent-ink)}
  /* AC-style "pop": come in a touch big, settle to size. Reused by the tooltip (and, later, modals). */
  @keyframes acpop{0%{transform:scale(.82);opacity:0}62%{transform:scale(1.05);opacity:1}100%{transform:scale(1)}}
  /* tooltip wears the per-piece menu's skin (surface fill + line-strong outline + soft drop-shadow) for consistency
     - just a straight pill, not the curved bar. */
  .pietip{position:absolute;z-index:7;background:var(--surface);color:var(--ink);border:1.5px solid var(--line-strong);font-size:11px;font-weight:600;padding:4px 10px;border-radius:999px;pointer-events:none;white-space:nowrap;filter:drop-shadow(0 2px 4px rgba(0,0,0,.22));opacity:0;transform-origin:center}
  .pietip.show{opacity:1;animation:acpop .19s ease-out}
  .pietip.uitip{position:fixed;z-index:500}   /* the shared chrome tooltip (toolbar / palette / zoom / menu), floats over everything */
  #uitip .tipa{color:var(--muted)}   /* the alpha pair of an 8-digit color, tinted so a translucent swatch's tooltip reads as different */
  /* The workbench keeps its motion even under prefers-reduced-motion (owner's call). site.css globally strips
     transitions/animations with `*{...!important}`; these higher-specificity rules out-rank it so our UI still
     pops/fades. Extend this block whenever the workbench gains a new animation (modals, menu, etc.). */
  @media (prefers-reduced-motion:reduce){
    .pietip.show{opacity:1!important;animation:acpop .19s ease-out!important}
    .piecehud button{transition:transform .08s ease,background .12s ease,color .12s ease!important}
    .zoom button{transition:transform .08s ease,background .12s ease,color .12s ease!important}
    .modal__box{animation:acpop .2s ease-out!important}
    .ed__main{transition:grid-template-columns .26s ease!important} .ed{transition:grid-template-rows .26s ease!important}
  }
  .zoom.stagezoom{position:absolute;right:10px;bottom:10px;z-index:4}
  .sb{position:absolute;z-index:3;border-radius:7px;background:color-mix(in srgb,var(--ink) 7%,transparent);cursor:default} .sbv{right:3px;top:3px;bottom:62px;width:12px} .sbh{left:3px;right:122px;bottom:3px;height:12px}
  .sbt{position:absolute;background:color-mix(in srgb,var(--ink) 30%,transparent);border-radius:6px;cursor:grab}.sbv .sbt{left:2px;right:2px}.sbh .sbt{top:2px;bottom:2px}
  .sbt:hover,.sbt:active{background:color-mix(in srgb,var(--ink) 50%,transparent)}.sbt:active{cursor:grabbing}
  .ed__palette{border-left:1px solid var(--wb-edge1);border-top:1px solid var(--wb-edge3);background:var(--wb-panel);padding:12px;overflow:auto}
  .swgrid{display:grid;grid-template-columns:repeat(7,1fr);gap:8px}   /* the swatch grids are the densest thing in the panel - give them room to breathe */
  .sw{aspect-ratio:1;border-radius:7px;border:2px solid var(--surface);box-shadow:0 0 0 1px var(--line-strong);cursor:pointer}.sw.on{box-shadow:0 0 0 2px var(--accent);transform:scale(1.08)}
  .sw.onb{box-shadow:0 0 0 2px var(--ink)} .sw.on.onb{box-shadow:0 0 0 2px var(--accent),0 0 0 4px var(--ink)}   /* A = accent ring, B = ink ring; both rings stack when A and B are the same swatch */
  .palhead{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:20px 0 8px;display:flex;align-items:center;justify-content:space-between;gap:8px;cursor:pointer;user-select:none}
  .palhead:hover{color:var(--ink)}
  .palhead::after{content:"";flex:none;width:6px;height:6px;border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;transform:rotate(45deg);transition:transform .15s ease;margin-bottom:2px;opacity:.7}   /* chevron: down when open, left when folded */
  .palhead.collapsed::after{transform:rotate(135deg)}
  .palhead.collapsed + .swgrid,.palhead.collapsed + .palbar,.palhead.collapsed + .palbar + .swgrid{display:none}   /* fold the section's swatches (the preset section also folds its dropdown row) */
  .palhead--first{margin-top:0}
  .palbar{display:flex;gap:6px;align-items:center;margin:0 0 16px}   /* the dropdown is its own control; let the swatch grid sit clearly below it, not jammed against it */
  .abcolor{display:flex;align-items:stretch;gap:6px;margin:0 0 20px}
  .abstack{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}
  .abbox{box-sizing:border-box;display:flex;align-items:center;gap:8px;height:34px;padding:0 11px;border:2px solid var(--surface);border-radius:var(--radius-sm);box-shadow:0 0 0 1px var(--line-strong);cursor:pointer;font:inherit;font-weight:700;font-size:12px;letter-spacing:.03em;color:var(--ink)}   /* resting frame matches the palette swatch: 2px surface gap + thin line-strong outline */
  .abbox.abx{background:repeating-conic-gradient(var(--chk1) 0% 25%,var(--chk2) 0% 50%) 0 0/12px 12px}   /* subtle checker (not --dot) - the "Transparent" label sits on top, so it has to stay readable */
  .abA.picking{box-shadow:0 0 0 2px var(--accent)} .abB.picking{box-shadow:0 0 0 2px var(--ink)}   /* the palette ring only lights up while you're dropping into that slot — A=accent, B=ink */
  .abm{width:21px;height:21px;flex:none} .abt{line-height:1;font-variant-numeric:tabular-nums}
  .abswap{flex:none;width:32px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);background:var(--surface);color:var(--ink);display:grid;place-items:center;cursor:pointer;padding:0}
  .abswap:hover{background:var(--raised)} .abswap:disabled{opacity:.4;cursor:default} .abswap:disabled:hover{background:var(--surface)}
  .abswap svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
  .palsel{flex:1;min-width:0;font:inherit;font-size:12px;height:34px;padding:0 8px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--surface);color:var(--ink);cursor:pointer}   /* 34px = the standard control height (.iconbtn / .abbox), so the dropdown + its buttons line up with the rest */
  .paliconbtn{flex:none;width:34px;height:34px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--surface);color:var(--ink);cursor:pointer;display:grid;place-items:center;padding:0}
  .paliconbtn:hover{background:var(--raised)} .paliconbtn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
  .palmanage{max-height:min(58vh,420px);overflow:auto;margin:0 0 4px}
  .palrow{display:flex;align-items:center;gap:9px;padding:6px 2px;border-top:1px solid var(--line)} .palrow:first-child{border-top:0}
  .palrow__sw{display:flex;flex:none;border-radius:4px;overflow:hidden;box-shadow:0 0 0 1px var(--line-strong)} .palrow__sw span{width:11px;height:18px;display:block}
  .palrow__name{flex:1;min-width:0;font:inherit;font-size:13px;padding:5px 7px;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--ink)} .palrow__name:hover{border-color:var(--line)} .palrow__name:focus{outline:none;border-color:var(--accent-mid);background:var(--raised)}
  .palrow__del{flex:none;width:30px;height:30px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--surface);color:var(--ink);cursor:pointer;display:grid;place-items:center}
  .palrow__del svg{width:16px;height:16px} .palrow__del:hover{background:var(--danger);color:#fff;border-color:transparent}
  .sw.iso{outline:2px solid var(--sel);outline-offset:2px}
  .sw--empty{background:repeating-linear-gradient(45deg,var(--line-strong) 0 1.25px,transparent 1.25px 5px);opacity:.7;cursor:default}   /* a reserved-but-unfilled body color slot - slightly stronger stripes than before so they read, but not shouty */
  .sw--walk{box-shadow:0 0 0 2px var(--accent),0 0 0 6px var(--accent-weak);transform:scale(1.06);opacity:1}   /* the slot the "Set Body Colors" walk is on right now */
  .modal{position:absolute;inset:0;z-index:300;display:grid;place-items:center}   /* no dim; the overlay still blocks input + closes on an outside click. (Modal lives in #ed, NOT #stage, so the canvas's pointer handlers don't eat the buttons.) */
  .modal[hidden]{display:none}
  .modal__box{position:relative;background:var(--surface);border:1px solid var(--line-strong);border-radius:22px;box-shadow:var(--sh);padding:20px 22px;width:min(94vw,400px);transform-origin:center;animation:acpop .2s ease-out}   /* cozy AC/Tomodachi width, roomy enough for a 1:1 preview */
  .modal__x{position:absolute;right:9px;top:7px;border:0;background:none;font-size:21px;line-height:1;color:var(--muted);cursor:pointer}.modal__x:hover{color:var(--ink)}
  .modal__t{margin:0 0 13px;font-size:16px;text-align:center}
  .modal__body{display:flex;flex-direction:column;gap:9px}
  .modalopt{display:flex;flex-direction:column;gap:2px;text-align:left;border:1px solid var(--line-strong);border-radius:var(--radius-sm);background:var(--raised);padding:11px 13px;cursor:pointer;font:inherit}
  .modalopt:hover{border-color:var(--accent);background:var(--accent-weak)}
  .modalopt b{font-size:13.5px;color:var(--ink)}.modalopt span{font-size:12px;color:var(--muted)}
  .modalmsg{font-size:13px;color:var(--muted);line-height:1.5;margin:0;text-align:center}
  .modalbtns{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:2px}
  .modalopt--plain{text-align:center;padding:8px 22px;background:var(--accent);border-color:transparent;border-radius:var(--pill)}
  .modalopt--plain b{color:var(--accent-ink);font-size:13px}.modalopt--plain:hover{background:var(--accent);border-color:transparent;filter:brightness(1.04)}
  .modalopt--ghost{background:var(--raised);border-color:var(--line-strong)}.modalopt--ghost b{color:var(--ink)}.modalopt--ghost:hover{background:var(--raised);border-color:var(--accent);filter:none}
  .swipe{position:relative;border-radius:8px;overflow:hidden;background:var(--raised);margin:4px auto 2px;max-width:100%;touch-action:none;cursor:ew-resize}
  .swipe__img{position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated}
  .swipe__div{position:absolute;top:0;bottom:0;left:50%;width:4px;margin-left:-4px;background:var(--surface);border-left:2px solid var(--line-strong);border-right:2px solid var(--line-strong);pointer-events:none}   /* white track with side edges, like a switch splitting the image */
  .swipe__grip{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:28px;height:28px;border-radius:50%;background:var(--raised);border:1.5px solid var(--line-strong);box-shadow:var(--sh);display:grid;place-items:center;font-size:18px;color:var(--ink)}   /* matches the per-piece menu chips */
  /* ---- timeline: the asset's gif/mng FRAMES as clips along time (sized by frame delay) + transport + playhead ---- */
  .ed__timeline{background:var(--wb-bar);border-top:1px solid var(--wb-edge1);box-shadow:inset 0 1px 0 var(--wb-edge3);padding:9px 12px 11px;height:118px;box-sizing:border-box;display:flex;flex-direction:column;gap:8px}   /* mirror the top divider on the stage/timeline split */
  .tl__transport{display:flex;align-items:center;gap:12px}
  .tl__play{width:30px;height:30px;border:0;border-radius:50%;background:var(--accent);color:var(--accent-ink);cursor:pointer;font-size:13px;display:grid;place-items:center}
  .tl__play:disabled{opacity:.4;cursor:default}
  .tl__time{font-size:12.5px;font-variant-numeric:tabular-nums;color:var(--ink)}
  .tl__loop{border:1px solid var(--line-strong);background:var(--raised);color:var(--muted);border-radius:var(--pill);font-size:12px;padding:3px 9px;cursor:pointer}
  .tl__loop.on{background:var(--accent-weak);color:var(--accent-strong);border-color:var(--accent-mid)}
  .tl__add{border:1px solid var(--line-strong);background:var(--surface);color:var(--ink);border-radius:var(--pill);font:inherit;font-weight:600;font-size:12px;padding:3px 10px;cursor:pointer}.tl__add:hover{background:var(--raised)}
  /* "smooth" = motion-interpolate the frames; sits with loop, only shown when there are 2+ frames */
  .tl__smooth{display:inline-flex;align-items:center;gap:5px}
  .tl__smoothlbl{font-size:12px;color:var(--muted)}
  .tl__smoothsel{border:1px solid var(--line-strong);background:var(--raised);color:var(--ink);border-radius:var(--pill);font:inherit;font-size:12px;padding:2px 4px;cursor:pointer}
  .tl__smoothloop{display:inline-flex;align-items:center;gap:3px;font-size:12px;color:var(--muted);cursor:pointer;user-select:none}
  .tl__smoothloop input{margin:0;cursor:pointer}
  .tl__smoothbtn{border:1px solid var(--line-strong);background:var(--surface);color:var(--ink);border-radius:var(--pill);font:inherit;font-weight:600;font-size:12px;padding:3px 10px;cursor:pointer}
  .tl__smoothbtn:hover{background:var(--accent-weak);color:var(--accent-strong);border-color:var(--accent-mid)}
  .tl__smoothbtn:disabled{opacity:.5;cursor:default}
  .tl__smoothbtn.upd:not(:disabled){background:var(--accent-weak);color:var(--accent-strong);border-color:var(--accent-mid)}   /* "Update" reads as a ready action when a re-derive would change something */
  .tl__hint{margin-left:auto;font-size:11px;color:var(--muted)}
  .tl__track{position:relative;flex:1;min-height:0}
  .tl__ruler{display:none}
  .tl__lane{position:absolute;inset:0;border-radius:8px;background:var(--raised);overflow:hidden}
  .tl__clip{position:absolute;top:3px;bottom:3px;border-radius:7px;overflow:hidden;cursor:pointer;background:var(--raised);border:2px solid var(--surface);box-shadow:0 0 0 1px var(--line-strong);padding:3px}   /* same frame as a palette swatch: a 2px surface gap + a thin line-strong ring; the inner padding keeps the thumbnail off the edge so a full-height sheet (a body) doesn't read as cut off */
  .tl__clip.on{box-shadow:0 0 0 2px var(--accent);z-index:2}   /* selected = accent ring, the way an active swatch reads */
  /* smooth marks its output: generated in-between frames get a violet wash + ring; ones you've painted on go amber
     (so you can see exactly which frames an "Update" would overwrite). Background tint survives the .on accent ring. */
  .tl__clip--gen{background:color-mix(in srgb,#7b6fe0 16%,var(--raised));box-shadow:0 0 0 1px #7b6fe0}
  .tl__clip--genedit{background:color-mix(in srgb,#e08a2b 22%,var(--raised));box-shadow:0 0 0 1px #e08a2b}
  .tl__addtile{position:absolute;top:3px;bottom:3px;border-radius:7px;cursor:pointer;background:transparent;border:2px dashed var(--line-strong);color:var(--muted);display:grid;place-items:center;padding:0}   /* the blank "+" add-frame tile after the last frame */
  .tl__addtile:hover{border-color:var(--accent-mid);color:var(--accent-strong);background:var(--accent-weak)}
  .tl__addtile svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round}
  .tl__thumb{display:block;width:100%;height:100%;object-fit:contain;image-rendering:pixelated}
  .tl__num{position:absolute;left:3px;top:1px;font-size:9px;font-weight:700;color:#fff;text-shadow:0 0 3px #000,0 1px 1px #000;pointer-events:none}
  .tl__playhead{position:absolute;top:0;bottom:0;width:2px;background:var(--ink);pointer-events:none;z-index:3;transition:left .06s linear}
  .tl__playhead::before{content:"";position:absolute;top:0;left:-6px;width:14px;height:10px;border-radius:3px;background:var(--ink)}
  /* ----- MOBILE / TOUCH (layout) -----------------------------------------
     Desktop is a fixed 3-pane grid; on a phone that's hopeless, so below 760px
     we go canvas-first like the pixel-art apps: the stage fills the screen, the
     panels turn into swipe-up bottom sheets, and a thumb dock toggles them. The
     old "rotate to landscape" nag is gone - the full-screen button asks the
     browser for real full-screen instead. Everything's gated to the breakpoint
     so the desktop layout is untouched. (Touch gestures + bigger hit targets
     come separately, under (pointer:coarse).) ----------------------------- */
  .wbdock{display:none}
  @media (max-width:760px){
    .hero,footer.site{display:none}                 /* the canvas needs the screen, not the marketing */
    .chrome{padding:9px 12px;gap:8px}
    .chrome .navpill{display:none}                  /* the scrolling page-pill isn't useful mid-tool; the logo still goes home */
    .wb{padding:0}
    .ed{height:calc(100dvh - 58px);border:0;border-radius:0;box-shadow:none;display:flex;flex-direction:column}   /* fills what's left under the slim header; flex so the toolbar can drop to the bottom thumb zone */
    .ed:fullscreen{height:100dvh}
    .ed__bar{gap:5px;padding:7px 9px;overflow-x:auto;overflow-y:hidden;flex-wrap:nowrap;scrollbar-width:none;overscroll-behavior:contain;order:2;flex:0 0 auto;border-top:1px solid var(--line);border-bottom:0}   /* the toolbar drops to the bottom: thumb-reachable, scrolls sideways */
    .ed__bar::-webkit-scrollbar{display:none}
    .ed__bar>*{flex:none}
    .ed__barright .panemenu{display:none}           /* panels live in the top-right rail on a phone, not behind this popover */
    .ed__main{grid-template-columns:1fr!important;order:1;flex:1 1 auto;min-height:0}  /* canvas fills the top; one column - the px rails don't apply on a phone */
    .ed__preview,.ed__palette,.ed__timeline{position:fixed;left:0;right:0;bottom:0;z-index:120;max-height:72dvh;height:auto;overflow:auto;overscroll-behavior:contain;border:0;border-top:1px solid var(--line-strong);border-radius:18px 18px 0 0;box-shadow:0 -8px 28px rgba(0,0,0,.2);padding-top:22px;padding-bottom:66px;transform:translateY(102%);transition:transform .26s ease}
    .ed__preview::before,.ed__palette::before,.ed__timeline::before{content:"";position:absolute;top:8px;left:50%;transform:translateX(-50%);width:42px;height:4px;border-radius:2px;background:var(--line-strong)}   /* grab handle */
    .ed:not(.lmin) .ed__preview,.ed:not(.rmin) .ed__palette,.ed:not(.tlmin) .ed__timeline{transform:translateY(0)}   /* a sheet is "open" when its hide-class is off (same toggles as desktop) */
    .ed__timeline{top:58px;bottom:auto;border-top:0;border-bottom:1px solid var(--line-strong);border-radius:0 0 18px 18px;box-shadow:0 8px 28px rgba(0,0,0,.2);padding-top:11px;padding-bottom:20px;transform:translateY(-115%)}   /* the filmstrip rides up TOP - the bottom is the tool zone - sliding down from under the header */
    .ed.maxed .ed__timeline,.ed:fullscreen .ed__timeline{top:0}   /* no header to clear in full-screen */
    .ed__timeline::before{top:auto;bottom:8px}   /* grab handle at the bottom edge: swipe up to dismiss */
    .ed.lmin .ed__preview,.ed.rmin .ed__palette,.ed.tlmin .ed__timeline{border-top-width:0}
    .zoom.prevzoom{display:none}                    /* keep the in-game preview 1:1 so the sheet stays compact */
    .grounds{gap:5px}.ground{width:21px;height:21px}
    .grounds .ground:nth-child(n+4){display:none}   /* trim to a couple of backdrops on a phone */
    .wbdock{display:flex;flex-direction:column;position:fixed;top:50%;right:8px;transform:translateY(-50%);z-index:200;gap:3px;background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--pill);padding:5px;box-shadow:var(--sh)}   /* a right-edge rail, clear of the top timeline + bottom toolbar, for panels + fullscreen */
    .wbdock button{width:48px;height:42px;border:0;border-radius:var(--pill);background:none;color:var(--muted);display:grid;place-items:center;cursor:pointer}
    .wbdock button svg{width:23px;height:23px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
    .wbdock button.on{background:var(--accent);color:var(--accent-ink)}
  }
  /* touch devices of any size: two-finger pan/pinch replaces the drag scrollbars + the pan tool, and the on-canvas
     controls grow to a fat-finger size. (Layout above is phone-only; this is about hit targets + redundant chrome.) */
  @media (pointer:coarse){
    html,body{overscroll-behavior:none;touch-action:manipulation}   /* no pull-to-refresh (ANY touch device, incl. a tablet on the desktop UI - an accidental reload would nuke unsaved art) + no double-tap zoom */
    .tool{width:42px;height:42px}
    .brush{width:40px;height:40px}
    .iconbtn{width:40px;height:40px}
    .piecehud button{width:36px;height:36px}
    .ed{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}   /* a hold on the canvas is the eyedropper - don't let iOS pop its text-select / save-image callout */
    .ed input,.ed select,.ed [contenteditable]{-webkit-user-select:text;user-select:text}
  }
  /* ...but the controls that pinch / two-finger gestures REPLACE are only redundant when there's no mouse. A
     touch-first 2-in-1 (Surface Pro etc.) is `pointer:coarse` even with a mouse attached, and a mouse can't pinch
     or two-finger pan - so only hide these when no fine pointer exists at all, or we'd strand mouse users with no
     way to zoom or scroll. (Fat hit targets + the pull-to-refresh guard above stay on for any touch capability.) */
  @media (pointer:coarse) and (not (any-pointer:fine)){
    .ed__stage .sb{display:none}                    /* two-finger drag pans now - the drag scrollbars are redundant */
    .tools .tool[data-tool="pan"]{display:none}     /* ...and so is the pan tool */
    .zoom.stagezoom{display:none}                   /* you pinch to zoom on touch - the on-canvas +/- is redundant */
  }
