:root{
  --bg:#F5F5F6;--surface:#FFFFFF;--surface-2:#F7F7F8;--hover:#F0F0F2;
  --border:#E6E6E9;--border-strong:#D2D2D7;--ink:#0B0B0D;--muted:#6B6B73;--faint:#9C9CA4;
  --btn:#0B0B0D;--btn-ink:#FFFFFF;--ring:#0B0B0D;--edge:rgb(0 0 0/.14);
  --stage-a:#FFFFFF;--stage-b:#E6E7EB;--chip:rgb(255 255 255/.86);
  --live:#16A34A;
  --ease:cubic-bezier(.2,0,0,1);--ease-io:cubic-bezier(.4,0,.2,1);
  --fast:120ms;--base:180ms;--slow:260ms;
  color-scheme:light dark;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --bg:#0B0B0D;--surface:#121214;--surface-2:#17171A;--hover:#1D1D21;
  --border:#232328;--border-strong:#33333A;--ink:#EDEDEF;--muted:#9C9CA5;--faint:#6E6E77;
  --btn:#EDEDEF;--btn-ink:#0B0B0D;--ring:#EDEDEF;--edge:rgb(255 255 255/.18);
  --stage-a:#2A2B30;--stage-b:#0F0F12;--chip:rgb(22 22 26/.86);--live:#34D399;
}}
:root[data-theme="dark"]{
  --live:#34D399;
  --bg:#0B0B0D;--surface:#121214;--surface-2:#17171A;--hover:#1D1D21;
  --border:#232328;--border-strong:#33333A;--ink:#EDEDEF;--muted:#9C9CA5;--faint:#6E6E77;
  --btn:#EDEDEF;--btn-ink:#0B0B0D;--ring:#EDEDEF;--edge:rgb(255 255 255/.18);
  --stage-a:#2A2B30;--stage-b:#0F0F12;--chip:rgb(22 22 26/.86);
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:var(--bg);color:var(--ink);font:14px/1.5 Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased;overflow:hidden}
button,input{font:inherit;color:inherit}
button{cursor:pointer}
:focus-visible{outline:2px solid var(--ring);outline-offset:2px;border-radius:8px}
/* scrollbars blend in everywhere (option list, look slider, page on phones): thin, quiet thumb, no track */
*{scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-track,::-webkit-scrollbar-corner{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border) padding-box;border:2px solid transparent;border-radius:999px}
::-webkit-scrollbar-thumb:hover{background-color:var(--border-strong)}

.app{display:grid;grid-template-columns:minmax(0,1fr) 420px;grid-template-rows:56px minmax(0,1fr);height:100dvh}
@media (max-width:900px){body{overflow:auto}.app{grid-template-columns:minmax(0,1fr);grid-template-rows:52px 56dvh auto;height:auto}}

.stage{position:relative;background:radial-gradient(120% 90% at 50% 40%,var(--stage-a) 0%,var(--stage-b) 100%);overflow:hidden;min-height:320px}
@media (max-width:900px){.stage{position:sticky;top:52px;z-index:2;height:56dvh}}
canvas{display:block;width:100%;height:100%;touch-action:none;outline:none}
.hint{position:absolute;top:18px;right:20px;color:var(--muted);font-size:12px;transition:opacity var(--slow) var(--ease)}
@media (max-width:900px){.hint{right:auto;left:16px;top:14px}}
@media (max-width:640px){.hint{display:none}}

/* top bar: name, camera controls, price and the main action, above the stage and the panel */
.topbar{grid-column:1/-1;position:relative;z-index:4;display:flex;align-items:center;gap:16px;min-width:0;padding:0 16px 0 20px;
  background:var(--surface);border-bottom:1px solid var(--border)}
.tbrand{display:flex;align-items:center;gap:10px;min-width:0}
.tname{font-weight:600;font-size:15px;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.live{display:inline-flex;align-items:center;gap:6px;flex:none;color:var(--muted);font-weight:500;font-size:12px;padding:2px 8px;border:1px solid var(--border-strong);border-radius:999px;white-space:nowrap}
.live i{width:6px;height:6px;border-radius:50%;background:var(--live);flex:none;animation:livePulse 2s ease-in-out infinite}
@keyframes livePulse{0%,100%{opacity:1}50%{opacity:.4}}
@media (prefers-reduced-motion:reduce){.live i{animation:none}}
.buy{margin-left:auto;display:flex;align-items:center;gap:8px;flex:none}
.price{display:flex;flex-direction:column;align-items:flex-end;line-height:1.2;margin-right:4px;white-space:nowrap}
.price .total{font-size:16px;font-weight:600;letter-spacing:-.01em}
.price .extra{font-size:11px;color:var(--muted)}
.price .extra:empty{display:none}
.ib{width:36px;height:36px;flex:none;border:1px solid var(--border-strong);border-radius:10px;background:var(--surface);display:grid;place-items:center;color:var(--ink);transition:background-color var(--fast) var(--ease)}
.ib svg{width:16px;height:16px}
@media (hover:hover){.ib:hover{background:var(--hover)}}
.ib:active{transform:scale(.97)}
.topbar .btn{height:36px;font-size:13px;padding:0 14px;white-space:nowrap}

/* camera controls: a segmented control in the top bar */
.toolbar{display:flex;align-items:center;gap:8px;min-width:0;margin-left:8px}
.views{display:flex;gap:2px;padding:3px;background:var(--hover);border-radius:10px}
.tools{display:flex;align-items:center;gap:2px}
.tb{white-space:nowrap;height:30px;min-width:30px;padding:0 10px;border:0;background:transparent;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;gap:6px;font-size:13px;font-weight:500;color:var(--muted);
  transition:background-color var(--fast) var(--ease),color var(--fast) var(--ease),box-shadow var(--fast) var(--ease)}
.tools .tb{height:34px;min-width:34px;border-radius:8px}
.tb svg{width:16px;height:16px;flex:none}
.views .tb.on{color:var(--ink);background:var(--surface);box-shadow:0 1px 2px rgb(0 0 0/.1)}
.tools .tb.on,.tools .tb[aria-expanded="true"]{color:var(--ink);background:var(--hover)}
@media (hover:hover){.tb:hover{color:var(--ink)}.tools .tb:hover{background:var(--hover)}}
.tb:active{transform:scale(.97)}
.tb:disabled{opacity:.4;cursor:default}
@media (max-width:1240px){.toolbar .tb[data-view] .lbl,#spinBtn .lbl,#shotBtn .lbl{display:none}.views .tb{padding:0}}
@media (max-width:1040px){.live{display:none}}

/* phones: the controls move onto the stage (script in index.html) as a vertical stack of glass buttons on the right edge */
@media (max-width:900px){
  .topbar{position:sticky;top:0;gap:10px;padding:0 12px}
  .tbrand,.tname{flex:1}
  .live,.ib{display:none}
  .price .total{font-size:15px}
  .stage .toolbar{position:absolute;z-index:2;top:12px;right:12px;margin:0;flex-direction:column;align-items:stretch;gap:8px}
  .stage .views,.stage .tools{flex-direction:column;gap:2px;padding:2px;border-radius:12px;background:var(--chip);border:1px solid var(--border);
    backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);box-shadow:0 8px 24px -12px rgb(0 0 0/.25)}
  .stage .tb{width:36px;height:36px;min-width:0;padding:0;border-radius:9px}
  .stage .tb .lbl{display:none}
  .stage .views .tb.on{background:var(--hover);box-shadow:none}
}

/* quality menu */
.qwrap{position:relative;display:flex}
.qmenu{position:absolute;left:-4px;top:calc(100% + 10px);z-index:5;width:244px;padding:6px;display:grid;gap:2px;
  background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:0 12px 32px -12px rgb(0 0 0/.3)}
.qmenu[hidden]{display:none}
.qmenu button{display:grid;grid-template-columns:16px minmax(0,1fr);column-gap:8px;align-items:center;padding:8px 10px;border:0;border-radius:8px;
  background:transparent;text-align:left;transition:background-color var(--fast) var(--ease)}
@media (hover:hover){.qmenu button:hover{background:var(--hover)}}
.qmenu button:focus-visible{background:var(--hover);outline-offset:-2px}
.qmenu b{font-size:13px;font-weight:600}
.qmenu span{grid-column:2;font-size:12px;color:var(--muted)}
.qchk{grid-row:span 2;width:14px;height:14px;color:var(--ink);opacity:0}
.qmenu [aria-checked="true"] .qchk{opacity:1}
@media (max-width:900px){.stage .qmenu{left:auto;top:0;right:calc(100% + 8px)}}

.loader{position:absolute;inset:0;display:grid;place-items:center;transition:opacity var(--slow) var(--ease);z-index:3}
.loader.done{opacity:0;pointer-events:none}
/* poster: sized like the camera frames the bike (height-fit on wide stages, width-fit below 0.9 aspect) */
.stage{container-type:size}
.poster{position:absolute;z-index:1;pointer-events:none;opacity:1;transition:opacity var(--slow) var(--ease)}
.poster:not([src]){display:none}
.poster.d{left:50%;top:50%;height:min(100cqh,100cqw);transform:translate(-50%,-50%)}
.poster.m{left:0;top:50%;width:100cqw;transform:translateY(-50%)}
.poster.dim{opacity:.4}
.poster.gone{opacity:0}
.stage.hasPoster .loader{place-items:end center;padding-bottom:28px}
.stage.hasPoster .loader .box{width:auto;padding:8px 14px;border-radius:999px;background:var(--chip);border:1px solid var(--border);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.stage.hasPoster .loader .bar{display:none}
.loader .box{width:240px;text-align:center;color:var(--muted);font-size:13px}
.bar{height:3px;border-radius:2px;background:var(--border);margin-top:10px;overflow:hidden}
.bar i{display:block;height:100%;width:0;background:var(--ink);transition:width var(--base) var(--ease)}
.partTip{position:absolute;pointer-events:none;padding:4px 10px;border-radius:999px;background:var(--chip);backdrop-filter:blur(10px);border:1px solid var(--border);font-size:12px;font-weight:500;transform:translate(-50%,-150%);opacity:0;transition:opacity var(--fast) var(--ease);white-space:nowrap;z-index:2}
.partTip.on{opacity:1}

.panel{background:var(--surface);border-left:1px solid var(--border);display:flex;flex-direction:column;min-height:0;min-width:0}
@media (max-width:900px){.panel{border-left:0;border-top:1px solid var(--border)}}
.phead{padding:22px 24px 12px}
.eyebrow{font-size:12px;color:var(--muted);font-weight:500}
.title{font-size:26px;line-height:32px;font-weight:600;letter-spacing:-.02em;margin:2px 0 4px}
.desc{color:var(--muted);font-size:13px;margin:0}
/* look cards: a preset replaces the whole build, so each card shows the whole bike */
.lhead{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.lnote{font-size:12px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--muted);white-space:nowrap}
.looks{position:relative;display:flex;gap:10px;overflow-x:auto;padding:4px 24px 8px;scroll-snap-type:x mandatory;scroll-padding-inline:24px;overscroll-behavior-x:contain}
.look{flex:none;width:168px;scroll-snap-align:start;display:flex;flex-direction:column;padding:0;border:1px solid var(--border);border-radius:12px;background:var(--surface);text-align:left;overflow:hidden;transition:border-color var(--fast) var(--ease)}
@media (hover:hover){.look:hover{border-color:var(--border-strong)}}
.lthumb{position:relative;display:block;height:92px;background:radial-gradient(120% 110% at 50% 35%,var(--stage-a) 0%,var(--stage-b) 100%)}
.lthumb img{position:absolute;inset:0;width:100%;height:100%;opacity:0;transition:opacity var(--slow) var(--ease)}
.lthumb img.on{opacity:1}
.lthumb:after{content:"";position:absolute;inset:0;background:var(--hover);transition:opacity var(--slow) var(--ease)}  /* skeleton */
.look.ready .lthumb:after{opacity:0}
.lmeta{display:block;padding:8px 10px 10px;border-top:1px solid var(--border)}
.lname{display:flex;align-items:center;gap:5px;font-size:13px;font-weight:600;min-width:0}
.lname b{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.ledit{display:none;font-size:12px;font-weight:500;color:var(--muted);white-space:nowrap}
.look.edited .ledit{display:inline}
.chk{width:14px;height:14px;flex:none;margin-left:auto;color:var(--ink);opacity:0;transition:opacity var(--base) var(--ease),color var(--base) var(--ease)}
.look[aria-pressed="true"] .chk{opacity:1}
.look.edited .chk{color:var(--faint)}
.ldesc{display:block;font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
.lprice{display:block;font-size:12px;font-weight:500;margin-top:4px}
/* the selection border is one element that slides to the selected card */
.lookSel{position:absolute;left:0;top:4px;width:168px;border:2px solid var(--ink);border-radius:12px;pointer-events:none;opacity:0;z-index:1;
  transition:transform var(--slow) var(--ease),opacity var(--base) var(--ease),border-color var(--base) var(--ease)}
.lookSel.on{opacity:1}
.lookSel.edited{border-color:var(--faint)}
.plabel{padding:14px 24px 8px;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}

.sections{flex:1;overflow-y:auto;padding:0 12px 16px;min-height:0}
@media (max-width:900px){.sections{overflow:visible}}
/* a 16 px fade at the top and bottom of the option list, only while there is more to scroll that way (main.js sets
   .fadeT/.fadeB). The second mask layer keeps the scrollbar column unmasked. */
@property --fadeT{syntax:"<length>";inherits:false;initial-value:0px}
@property --fadeB{syntax:"<length>";inherits:false;initial-value:0px}
@media (min-width:901px){
  .sections{--fadeT:0px;--fadeB:0px;transition:--fadeT var(--base) var(--ease),--fadeB var(--base) var(--ease);
    -webkit-mask:linear-gradient(transparent,#000 var(--fadeT),#000 calc(100% - var(--fadeB)),transparent) 0 0/calc(100% - 8px) 100% no-repeat,
      linear-gradient(#000,#000) 100% 0/8px 100% no-repeat;
    mask:linear-gradient(transparent,#000 var(--fadeT),#000 calc(100% - var(--fadeB)),transparent) 0 0/calc(100% - 8px) 100% no-repeat,
      linear-gradient(#000,#000) 100% 0/8px 100% no-repeat}
  .sections.fadeT{--fadeT:16px}
  .sections.fadeB{--fadeB:16px}
}
.sec{--row:var(--surface);border-radius:12px;transition:background-color var(--base) var(--ease)}
.sec.open{--row:var(--surface-2);background:var(--surface-2)}
.sec+.sec{margin-top:2px}
.shead{width:100%;display:flex;align-items:center;gap:12px;padding:12px;border:0;background:transparent;border-radius:12px;text-align:left}
@media (hover:hover){.sec:not(.open) .shead:hover{--row:var(--hover);background:var(--hover)}}
/* part icon tile, with the part's current color as a badge */
.sicon{position:relative;flex:none;width:36px;height:36px;border-radius:10px;background:var(--surface);border:1px solid var(--border);display:grid;place-items:center;color:var(--ink)}
.sicon svg{width:22px;height:22px}
.sdot{position:absolute;right:-4px;bottom:-4px;width:13px;height:13px;border-radius:50%;box-shadow:0 0 0 2px var(--row),inset 0 0 0 1px var(--edge);
  transition:background var(--slow) var(--ease),box-shadow var(--base) var(--ease)}
.sname{font-weight:600;font-size:14px;white-space:nowrap}
.sval{margin-left:auto;color:var(--muted);font-size:13px;text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.chev{width:16px;height:16px;color:var(--faint);flex:none;transition:transform var(--base) var(--ease)}
.sec.open>.shead .chev{transform:rotate(180deg)}
.sbody{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--slow) var(--ease)}
.sec.open .sbody{grid-template-rows:1fr}
.sbody>div{overflow:hidden}
.sinner{padding:0 12px 16px 60px}
@media (max-width:420px){.sinner{padding-left:12px}}
.ctrl+.ctrl{margin-top:16px}
.glabel{font-size:12px;color:var(--muted);margin:2px 0 8px;display:flex;gap:6px;align-items:baseline}
.glabel b{color:var(--ink);font-weight:500}
.swatches{display:flex;flex-wrap:wrap;gap:10px}
.sw{position:relative;width:34px;height:34px;border-radius:50%;border:0;padding:0;background:transparent}
.sw i{position:absolute;inset:3px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--edge)}
.sw:before{content:"";position:absolute;inset:0;border-radius:50%;box-shadow:0 0 0 1.5px transparent;transition:box-shadow var(--base) var(--ease)}
.sw[aria-checked="true"]:before{box-shadow:0 0 0 2px var(--ink)}
@media (hover:hover){.sw:hover:not([aria-checked="true"]):before{box-shadow:0 0 0 1.5px var(--border-strong)}}
.sw .plus{position:absolute;top:-6px;right:-9px;font-size:9px;font-weight:600;background:var(--ink);color:var(--surface);border-radius:999px;padding:1px 4px;line-height:12px}
.sw.match:not([data-match]) i{background:conic-gradient(var(--surface) 0 50%, var(--faint) 0 100%)!important}
.seg{display:inline-flex;flex-wrap:wrap;gap:2px;padding:3px;background:var(--hover);border-radius:10px;position:relative}
.seg button{position:relative;z-index:1;border:0;background:transparent;padding:6px 12px;border-radius:7px;font-size:13px;font-weight:500;color:var(--muted);transition:color var(--fast) var(--ease),background-color var(--base) var(--ease),box-shadow var(--base) var(--ease)}
.seg button[aria-checked="true"]{color:var(--ink);background:var(--surface);box-shadow:0 1px 2px rgb(0 0 0/.1)}
.seg small{font-size:11px;color:var(--faint);margin-left:4px}
.cards{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.card{border:1px solid var(--border);background:var(--surface);border-radius:10px;padding:10px 12px;text-align:left;transition:border-color var(--fast) var(--ease)}
.card b{display:block;font-size:13px;font-weight:600}
.card span{display:block;font-size:12px;color:var(--muted);margin-top:2px}
.card[aria-checked="true"]{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
@media (hover:hover){.card:hover:not([aria-checked="true"]){border-color:var(--border-strong)}}
.range{width:100%;accent-color:var(--ink)}
.rangeRow{display:flex;justify-content:space-between;font-size:11px;color:var(--faint);margin-top:2px}
.textIn{width:100%;height:38px;border:1px solid var(--border-strong);border-radius:10px;background:var(--surface);padding:0 12px;font-weight:600;letter-spacing:.02em;text-transform:uppercase}
.textIn.asis{text-transform:none}
.help{font-size:12px;color:var(--faint);margin-top:6px}
[hidden]{display:none!important}

/* switch */
.toggle{width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;border:0;background:transparent;padding:2px 0;font-size:13px;font-weight:500;text-align:left}
.toggle i{position:relative;flex:none;width:34px;height:20px;border-radius:999px;background:var(--border-strong);transition:background-color var(--base) var(--ease)}
.toggle i:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--surface);box-shadow:0 1px 2px rgb(0 0 0/.2);transition:transform var(--base) var(--ease)}
.toggle[aria-checked="true"] i{background:var(--ink)}
.toggle[aria-checked="true"] i:after{transform:translateX(14px)}

/* font picker: each option previews its own typeface */
.fonts{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px}
.fontcard{height:44px;border:1px solid var(--border);background:var(--surface);border-radius:10px;padding:0;font-size:19px;line-height:1;display:grid;place-items:center;transition:border-color var(--fast) var(--ease)}
.fontcard[aria-checked="true"]{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
@media (hover:hover){.fontcard:hover:not([aria-checked="true"]){border-color:var(--border-strong)}}
/* effect previews */
.fxp{display:inline-block;margin-right:6px;font-weight:800;color:var(--ink)}
.fxp.fx1{color:var(--surface);-webkit-text-stroke:1.2px var(--ink);paint-order:stroke}
.fxp.fx2{text-shadow:1.5px 1.5px 0 var(--faint)}
.fxp.fx3{transform:skewX(-14deg)}

/* text spots: one row per logo spot, each with an inline editor */
.spots{border:1px solid var(--border);border-radius:12px;background:var(--surface);overflow:hidden}
.spot+.spot{border-top:1px solid var(--border)}
.sphead{width:100%;display:flex;align-items:center;gap:10px;padding:10px 12px;border:0;background:transparent;text-align:left;transition:background-color var(--fast) var(--ease)}
@media (hover:hover){.spot:not(.open) .sphead:hover{background:var(--hover)}}
.spname{font-size:13px;font-weight:600;white-space:nowrap}
.spval{margin-left:auto;font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.spot.custom .spval{color:var(--ink);font-weight:500}
.spot.open>.sphead .chev{transform:rotate(180deg)}
.spbody{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--slow) var(--ease)}
.spot.open .spbody{grid-template-rows:1fr}
.spbody>div{overflow:hidden}
.spinner{padding:2px 12px 14px}
.spot:not(.custom) .ifcustom{display:none}
.ifcustom>.ctrl{margin-top:16px}

/* style / pattern cards with a tiny preview chip */
.pcard{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:10px;align-items:center}
.pcard .chip{grid-row:span 2;width:24px;height:24px;border-radius:7px;box-shadow:inset 0 0 0 1px var(--edge);transition:background var(--slow) var(--ease)}
.pcard b small{font-size:11px;font-weight:500;color:var(--faint)}
.pcard span{margin-top:0}
.cards[data-pv]{grid-template-columns:repeat(2,minmax(0,1fr))}

/* "More options" disclosure */
.moreBtn{display:inline-flex;align-items:center;gap:4px;border:0;background:transparent;padding:2px 0;font-size:12px;font-weight:600;color:var(--muted);transition:color var(--fast) var(--ease)}
@media (hover:hover){.moreBtn:hover{color:var(--ink)}}
.moreBtn .chev{width:14px;height:14px}
.more.open .moreBtn .chev{transform:rotate(180deg)}
.moreBody{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--slow) var(--ease)}
.more.open .moreBody{grid-template-rows:1fr}
.moreBody>div{overflow:hidden}
.moreInner{padding-top:12px}
.moreInner>.ctrl+.ctrl{margin-top:16px}

.btn{flex:none;height:44px;border-radius:10px;border:1px solid var(--border-strong);background:var(--surface);padding:0 14px;font-weight:600;font-size:14px;display:inline-flex;align-items:center;justify-content:center;gap:8px;transition:background-color var(--fast) var(--ease),transform 80ms var(--ease)}
.btn svg{width:16px;height:16px}
.btn.primary{background:var(--btn);color:var(--btn-ink);border-color:var(--btn)}
@media (hover:hover){.btn:not(.primary):hover{background:var(--hover)}.btn.primary:hover{opacity:.92}}
.btn:active{transform:scale(.98)}
.perfHud{position:fixed;left:12px;bottom:12px;z-index:30;padding:8px 10px;border-radius:10px;background:var(--chip);border:1px solid var(--border);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);font-size:11px;line-height:1.5;color:var(--muted);pointer-events:none}
.perfHud b{color:var(--ink);font-weight:600}
.toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%,8px);opacity:0;background:var(--ink);color:var(--surface);padding:10px 16px;border-radius:10px;font-size:13px;font-weight:500;z-index:20;transition:opacity var(--slow) var(--ease),transform var(--slow) var(--ease);pointer-events:none}
.toast.on{opacity:1;transform:translate(-50%,0)}
.toast{white-space:nowrap;max-width:calc(100vw - 32px);overflow:hidden;text-overflow:ellipsis}
@media (min-width:901px){.toast{left:calc((100% - 420px) / 2)}}                      /* centered on the stage */
@media (max-width:900px){.toast{bottom:calc(24px + env(safe-area-inset-bottom))}}
.toast.act{pointer-events:auto}
.tact{border:0;background:transparent;padding:0;color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px}
@media (max-width:420px){.lnote{font-size:11px}}
@media (prefers-reduced-motion:reduce){*,*:before{transition-duration:.01ms!important;animation-duration:.01ms!important}}
