app
Hero Studio
Public Made by Adomby adom
The hero-image lab with a human gate: `hero-studio pose <owner/slug>` opens the studio in front of the human, posed for their package, and blocks until they click Generate, producing the provenance-stamped 2000x1250 PNG the registry's hero gate requires. The image carries the title and artwork; the exported image also bakes the type pill (top right) and full wiki slug (bottom right); the page shows the hero bare, and only the homepage marquee overlays its own dynamic info. Every hero wears its P
master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
/* studio.css: the app chrome around the hero (header, panel, gate bars,
modal, toasts, tooltips). Redesign work happens here and only here. */
/* ---------- 44px header, three zones ---------- */
header {
height:44px; flex:0 0 44px; display:flex; align-items:center; gap:12px;
padding:0 12px; background:var(--surface); border-bottom:1px solid var(--border);
}
.brand { display:flex; align-items:center; gap:8px; white-space:nowrap; }
.brand svg { width:16px; height:16px; stroke:var(--text); }
.brand .name { font-family:'Familjen Grotesk'; font-weight:500; font-size:14px; color:var(--accent); }
.brand .sub { color:var(--text-2); font-size:13px; }
.vsep { width:1px; height:22px; background:var(--border); flex:0 0 1px; }
.subject { display:flex; align-items:baseline; gap:10px; min-width:0; }
.subject b { font-weight:700; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.subject .meta { font-family:'JetBrains Mono',monospace; font-size:11.5px; color:var(--text-2); white-space:nowrap; }
.actions { margin-left:auto; display:flex; gap:6px; }
.iconbtn {
width:30px; height:30px; border:1px solid var(--border); border-radius:8px; background:transparent;
display:flex; align-items:center; justify-content:center; cursor:pointer; transition:all .15s ease;
}
.iconbtn svg { width:16px; height:16px; stroke:var(--text); fill:none; stroke-width:1.8; }
.iconbtn:hover { background:var(--elevated); border-color:var(--text-3); }
.iconbtn.on { border-color:var(--accent); background:rgba(0,184,176,.08); }
@media (max-width:720px){ .subject .meta { display:none; } }
/* ---------- body ---------- */
main { flex:1; display:flex; min-height:0; }
#panel {
flex:0 0 264px; overflow-y:auto; background:var(--surface); border-right:1px solid var(--border);
padding:14px 14px 40px;
}
#panel h3 {
font-family:'Familjen Grotesk'; font-weight:500; font-size:11px; letter-spacing:.08em;
text-transform:uppercase; color:var(--text-2); margin:18px 0 8px;
}
#panel h3:first-child { margin-top:2px; }
select {
width:100%; background:var(--elevated); color:var(--text); border:1px solid var(--border);
border-radius:8px; padding:7px 8px; font-family:'Satoshi'; font-size:13px; cursor:pointer;
}
.optgrid { display:flex; flex-wrap:wrap; gap:6px; }
.opt {
border:1px solid var(--border); background:var(--elevated); color:var(--text-2); border-radius:8px;
padding:6px 9px; font-size:12.5px; cursor:pointer; transition:all .15s ease; font-family:'Satoshi';
}
.opt:hover { color:var(--text); border-color:var(--text-3); }
.opt.on { color:var(--text); border-color:var(--accent); background:rgba(0,184,176,.10); }
.swatches { display:flex; gap:6px; }
.swatch {
width:38px; height:26px; border-radius:6px; border:1px solid var(--border); cursor:pointer;
transition:all .15s ease; position:relative;
}
.swatch.on { outline:2px solid var(--accent); outline-offset:1px; }
.sw-midnight { background:linear-gradient(155deg,#0a0e14,#0d1117 45%,#071318); }
.sw-image { background:repeating-conic-gradient(#1c2530 0 25%, #0d1117 0 50%) 0 0/8px 8px; }
.sw-pcb { background:linear-gradient(155deg,#03211f,#04302c); }
.sw-onion { background:repeating-radial-gradient(circle at 90% 10%, #101a2c 0 4px, #16223a 4px 6px); }
.sw-pill { background:#0c3a3c; }
.sw-grid { background:#0c3a3c url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12"><rect x="2" y="2" width="8" height="8" fill="none" stroke="%23ffffff" stroke-opacity=".35" stroke-width="1"/></svg>'); }
.sw-grad { background:linear-gradient(100deg,#00e6dc,#39b8ff 60%,#8c6bf7); }
input[type=range] { width:100%; accent-color:var(--accent); cursor:pointer; }
label.chk { display:flex; align-items:center; gap:8px; padding:5px 0; cursor:pointer; color:var(--text); font-size:13px; }
label.chk input { accent-color:var(--accent); width:14px; height:14px; cursor:pointer; }
.hint { font-size:11.5px; color:var(--text-2); line-height:1.45; margin-top:6px; }
#renderer-line.bad, #wrenderer.bad { color:#ff7b72; font-weight:600; }
#wrenderer { padding:4px 14px 0; font-size:11.5px; }
.btn {
width:100%; margin-top:8px; padding:8px 10px; border-radius:8px; border:1px solid var(--border);
background:var(--elevated); color:var(--text); font-family:'Satoshi'; font-size:13px; cursor:pointer;
transition:all .15s ease;
}
.btn:hover { border-color:var(--accent); background:rgba(0,184,176,.08); }
/* ---------- stage + hero canvas ---------- */
#stage { flex:1; display:flex; flex-direction:column; align-items:center; justify-content:flex-start; gap:18px; padding:22px; min-width:0; min-height:0; overflow:auto; }
/* wizard: the hero ALWAYS fits the stage (#48: a human-facing image must be
seen whole; a cropped hero hides what the edit just did). Width-limited on
wide panes, height-limited on short ones: the 16:10 box takes min(100%
width, available height * 1.6). The stage no longer scrolls in the wizard. */
body.wizard #stage { overflow:hidden; justify-content:center; }
/* Pure flex, no magic numbers: the hero may SHRINK in the column (flex-shrink,
min-height:0) and keeps 16:10, so on a short pane the height binds and the
width follows; on a wide pane max-width binds. The stagebar / approved
banner above it simply take their share first. */
/* Width is the driving axis (cqw typography depends on it). Pure CSS cannot
make a definite width FOLLOW a height cap without squashing the ratio, so
wizard.js measures the stage's free height into --stage-free (px) and the
width is min(pane width, 1000px, free height * 1.6): wide panes are
width-bound, short panes are height-bound, and 16:10 never breaks. */
body.wizard #hero { flex:0 0 auto; height:auto; aspect-ratio:16/10;
width:min(100%, 1000px, calc(var(--stage-free, 100000px) * 1.6)); }
/* the stagebar (#21/#23): stage chrome lives ABOVE the stage, never on it */
#stagebar { display:none; align-items:center; gap:10px; margin:10px 0 8px; }
#stagebar.on { display:flex; }
#stagebar .seg { display:flex; border:1px solid #30363d; border-radius:8px; overflow:hidden; }
#stagebar .seg button { background:#0d1117; color:var(--text); border:0; padding:6px 12px; font-size:12.5px; cursor:pointer; }
#stagebar .seg button.on { background:rgba(0,184,176,.18); color:var(--accent-bright); }
#stagebar .legend { font-size:12px; color:#8b949e; line-height:1.35; }
#stagebar .legend b { color:#e8a13c; font-weight:600; }
.brandrow { display:flex; align-items:center; gap:8px; margin:6px 0; }
.brandrow label { font-size:12px; color:var(--text-2); width:84px; }
.brandrow input[type=color] { width:44px; height:26px; border:1px solid var(--border); border-radius:6px; background:var(--surface); padding:1px; cursor:pointer; }
#approvedbar { display:none; margin:0 0 14px; border:1px solid #2ea06b; background:rgba(46,160,107,.09);
border-radius:10px; padding:14px 16px; }
#approvedbar .ab-head { font-family:'Familjen Grotesk'; font-weight:700; color:#4ade80; margin-bottom:6px; }
#approvedbar .ab-body { font-size:13px; color:var(--text); line-height:1.5; margin-bottom:10px; }
#genmodal .gen-approved { font-family:'Familjen Grotesk'; font-weight:700; color:#4ade80; margin-bottom:6px; }
#verifybar { display:none; margin:0 0 14px; border:1px solid var(--accent); background:rgba(0,184,176,.07); border-radius:10px; padding:14px 16px; }
#verifybar .vhead { font-size:13px; color:var(--text); margin-bottom:10px; line-height:1.5; }
#verifybar .vchk { display:block; margin:6px 0; }
#verifybar .vchk .warn { color:#e8a13c; }
#verifybar .vchk .flagged { color:#f85149; font-weight:600; margin-left:6px; }
#v-generate { margin-top:10px; font-size:14px; padding:10px 18px; }
#v-generate:disabled { opacity:.45; cursor:not-allowed; }
/* the layout linter (#18): the studio notices, the human decides */
#lintbox { margin-top:8px; }
#lintbox .lint-item { font-size:12.5px; margin:4px 0; cursor:pointer; line-height:1.4; }
#lintbox .lint-warn { color:#e8a13c; }
#lintbox .lint-fail { color:#f85149; font-weight:600; }
#lintbox .lint-ok { color:#3fb950; font-size:12px; }
#lintbox .lint-info { color:#8b949e; }
#tourpop .tp-flag { background:rgba(248,81,73,.12); border:1px solid rgba(248,81,73,.6); color:#f85149; }
#tourpop .tp-head { cursor:grab; user-select:none; }
#tourpop.dragging .tp-head { cursor:grabbing; }
/* page-field editors (#20) */
.pf-in { width:100%; box-sizing:border-box; background:#0d1117; color:var(--text); border:1px solid #30363d; border-radius:6px; padding:6px 8px; font:inherit; font-size:12.5px; margin:2px 0 8px; }
.pf-in:focus { border-color:var(--accent); outline:none; }
/* zen focus (#12): the hero gets the whole surface */
body.zen #panel { display:none; }
body.zen main { max-width:none; }
.sw-aurora { background:radial-gradient(8px 6px at 30% 20%, rgba(0,230,220,.8), transparent), radial-gradient(10px 8px at 70% 80%, rgba(140,107,247,.7), transparent), #0a0f16; }
.sw-mesh { background:conic-gradient(from 155deg at 40% 40%, rgba(0,184,177,.5), transparent 40%), #0b1016; }
.sw-circuitry { background:repeating-linear-gradient(45deg, rgba(0,184,177,.5) 0 1px, transparent 1px 5px), #080d13; }
/* verification walkthrough popout */
#tourpop { display:none; position:fixed; z-index:900; max-width:300px;
background:var(--elevated); border:1px solid var(--accent); border-radius:10px;
padding:12px 14px; box-shadow:0 12px 40px rgba(0,0,0,.6); font-size:13px; }
#tourpop .tp-title { font-family:'Familjen Grotesk'; font-weight:700; margin-bottom:6px; color:var(--accent-bright); }
#tourpop .tp-body { color:var(--text); line-height:1.45; margin-bottom:10px; }
#tourpop .tp-row { display:flex; gap:8px; }
.tour-above { position:relative !important; z-index:901 !important; }
.tour-glow { outline:3px solid var(--accent-bright) !important; outline-offset:3px; border-radius:4px;
box-shadow:0 0 24px rgba(0,230,220,.35) !important; }
/* generated-hero preview modal */
#genmodal { position:fixed; inset:0; z-index:99997; background:rgba(5,9,14,.8); display:none; align-items:center; justify-content:center; padding:32px; }
#genmodal.show { display:flex; }
.genbox { max-width:min(1000px, 92vw); background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:14px; box-shadow:0 24px 80px rgba(0,0,0,.6); }
.genbox img { display:block; width:100%; border-radius:8px; border:1px solid var(--border); }
.genrow { display:flex; align-items:center; gap:10px; margin-top:10px; }
.genrow .hint { margin:0; flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.genrow a { color:var(--accent); font-size:13px; text-decoration:none; }
.genrow a:hover { color:var(--accent-bright); }
.btn-primary { border-color:var(--accent); background:rgba(0,184,176,.12); font-weight:500; }
.btn-primary:hover { background:rgba(0,184,176,.2); }
.btn-primary:disabled { opacity:.55; cursor:wait; }
/* tooltip + toast */
#tip {
position:fixed; z-index:99999; background:var(--overlay); border:1px solid var(--border);
color:var(--text); font-size:12px; line-height:1.4; padding:6px 9px; border-radius:8px;
max-width:240px; pointer-events:none; opacity:0; transform:translateY(3px);
transition:opacity .18s ease, transform .18s ease; text-transform:none;
}
#tip.show { opacity:1; transform:none; }
#toasts { position:fixed; left:50%; bottom:18px; transform:translateX(-50%); z-index:99998; display:flex; flex-direction:column-reverse; gap:8px; }
.toast {
display:flex; align-items:center; gap:8px; background:var(--overlay); border:1px solid var(--border);
border-left:3px solid var(--accent); border-radius:8px; padding:9px 13px; font-size:13px;
box-shadow:0 8px 30px rgba(0,0,0,.45); animation:tin .2s ease;
}
.toast.success { border-left-color:var(--green); }
.toast.error { border-left-color:var(--red); }
@keyframes tin { from { opacity:0; transform:translateY(6px);} }
/* ---------- the wizard dock (M4): default chrome; classic is one toggle away ---------- */
body.wizard #panel { display:none; }
body.wizard #tourpop { display:none !important; }
body.wizard #verifybar { display:none !important; }
body.classic #wdock, body.classic #weditring { display:none !important; }
/* The dock is a fixed-height pane with FIXED chrome and exactly ONE scroll
region. The grip, intro, step rail and step header never scroll away
(Colby: "the resize tab should always be at the top"); only #wcardsrow
scrolls, so there is never a scrollbar inside a scrollbar (#46 #47). */
#wdock { flex:0 0 auto; background:var(--surface); border-top:1px solid var(--border); padding:10px 18px 14px;
display:flex; flex-direction:column; gap:10px; height:min(44vh, 330px); overflow:hidden; scrollbar-width:thin; }
#wdockintro { font-size:12px; color:var(--text-2); padding:0 2px 2px; }
#wdockintro b { color:var(--text); font-weight:600; }
#wdockintro .ref { font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--accent); }
#wrailwrap { position:relative; min-width:0; }
#wrailwrap::before, #wrailwrap::after { content:''; position:absolute; top:0; bottom:2px; width:36px; pointer-events:none; opacity:0; transition:opacity .15s ease; z-index:2; }
#wrailwrap::before { left:0; background:linear-gradient(90deg, var(--surface) 20%, transparent); }
#wrailwrap::after { right:0; background:linear-gradient(270deg, var(--surface) 20%, transparent); }
#wrailwrap.can-left::before { opacity:1; }
#wrailwrap.can-right::after { opacity:1; }
#wsteprail { display:flex; gap:6px; overflow-x:auto; padding-bottom:2px; scrollbar-width:none; }
#wsteprail > :first-child { margin-left:auto; }
#wsteprail > :last-child { margin-right:auto; }
#wsteprail::-webkit-scrollbar { display:none; }
#wsteprail.compact .schip .v { display:none; }
#wsteprail.mini .schip:not(.active) .t { display:none; }
#wsteprail.mini .schip:not(.active) { padding:4px 8px 4px 5px; }
.schip { display:flex; align-items:center; gap:8px; border:1px solid var(--border); background:var(--elevated); border-radius:999px;
padding:4px 12px 4px 5px; cursor:pointer; white-space:nowrap; transition:all .15s ease; font-family:'Satoshi'; }
.schip:hover { border-color:var(--text-3); }
.schip .n { width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center;
font-size:11px; font-family:'JetBrains Mono',monospace; background:var(--overlay); color:var(--text-2); border:1px solid var(--border); flex:0 0 20px; }
.schip .n svg { width:11px; height:11px; stroke:var(--green); stroke-width:2.5; fill:none; }
.schip .t { font-size:12.5px; color:var(--text-2); }
.schip .v { font-size:11px; color:var(--text-3); max-width:110px; overflow:hidden; text-overflow:ellipsis; }
.schip.active { border-color:var(--accent); background:rgba(0,184,176,.10); }
.schip.active .t { color:var(--text); font-weight:500; }
.schip.active .n { background:var(--accent); color:#04211f; border-color:transparent; }
.schip.done .n { background:rgba(63,185,80,.12); border-color:rgba(63,185,80,.45); }
#wdockhead { display:flex; align-items:center; gap:8px 12px; min-height:26px; flex-wrap:nowrap; }
#wdockhead .wdtitle { font-family:'Familjen Grotesk'; font-weight:700; font-size:15px; color:var(--text); }
#wdockhead .wdcount { font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--text-2); }
#wdockhead .wdhint { font-size:12px; color:var(--text-2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1; min-width:0; }
#wbtn-generate { font-size:15px; font-weight:600; padding:10px 26px; border-radius:10px; }
#wbtn-generate:not(:disabled) { box-shadow:0 0 18px rgba(0,184,176,.35); }
#wcardsrow { display:flex; gap:10px; align-items:center; min-height:0; flex:1 1 0; overflow:hidden; }
#wcards { display:flex; gap:10px; overflow-x:auto; overflow-y:hidden; flex:1; min-width:0; min-height:0; scrollbar-width:none; align-items:center; padding:2px; }
#wcards::-webkit-scrollbar { display:none; }
#wcards > :first-child { margin-left:auto; }
#wcards > :last-child { margin-right:auto; }
.warrow { flex:0 0 44px; height:110px; align-self:center; border:1px solid var(--border); background:var(--elevated); border-radius:10px; color:var(--text-2);
font-size:20px; cursor:pointer; }
.warrow:hover { border-color:var(--text-3); color:var(--text); }
#wcards .card { flex:0 0 auto; width:128px; border:1px solid var(--border); background:var(--elevated); border-radius:10px;
padding:10px; cursor:pointer; display:flex; flex-direction:column; gap:4px; justify-content:center; text-align:center; transition:all .15s ease; }
#wcards .card:hover { border-color:var(--text-3); }
#wcards .card.on { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
#wcards .card.wide { width:170px; }
#wcards .card .card-label { font-size:13px; color:var(--text); }
#wcards .card.on .card-label { color:var(--accent); }
#wcards .card .card-sub { font-size:11px; color:var(--text-3); line-height:1.35; }
#weditring { position:absolute; border:2px dashed var(--accent); border-radius:10px; pointer-events:none;
z-index:9; opacity:0; transition:opacity .25s ease, top .2s ease, left .2s ease, width .2s ease, height .2s ease;
box-shadow:0 0 22px rgba(0,184,176,.18); }
#weditring.on { opacity:.85; }
.wiz-lab { font-size:11px; color:var(--text-2); letter-spacing:.06em; text-transform:uppercase; font-family:'Familjen Grotesk'; }
.wiz-headline { flex:1; display:flex; flex-direction:column; gap:7px; max-width:560px; margin:0 auto; }
.wiz-sizerow { display:flex; align-items:center; gap:10px; }
.wiz-sizerow .wiz-lab { flex:0 0 auto; }
.wiz-sizerow input[type=range] { flex:1; min-width:120px; accent-color:var(--accent); }
.wiz-sizerow .wiz-sizeval { font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--text-2); width:52px; text-align:right; }
.wiz-sizerow .btn { flex:0 0 auto; }
.wiz-headline .hin { background:var(--overlay); border:1px solid var(--border); border-radius:8px; color:var(--text);
padding:8px 12px; font-size:14px; font-family:'Satoshi'; }
.wordpick { display:flex; flex-wrap:wrap; gap:4px; max-width:560px; }
.wtok { padding:2px 8px; border:1px solid var(--border); border-radius:6px; font-size:12px; cursor:pointer;
color:var(--text-2); background:var(--elevated); transition:all .12s ease; user-select:none; }
.wtok:hover { border-color:var(--text-3); }
.wtok.on { border-color:var(--accent); background:var(--grad); -webkit-background-clip:text; background-clip:text; color:transparent; font-weight:600; }
.wiz-finish { flex:1; display:flex; gap:10px; align-items:center; justify-content:center; flex-wrap:wrap; }
.wiz-review { flex:1; display:flex; gap:14px 22px; align-items:flex-start; justify-content:center; min-width:0; flex-wrap:wrap; }
.wiz-review .rv-col { display:flex; flex-direction:column; gap:8px; min-width:230px; }
.rv-check { display:flex; align-items:center; gap:10px; border:1px solid var(--border); border-radius:9px; padding:7px 10px; }
.rv-check .q { flex:1; font-size:12.5px; color:var(--text-2); }
.rv-check.ok { border-color:rgba(63,185,80,.5); }
.rv-check.ok .q { color:var(--green); }
.rv-check.flag { border-color:rgba(248,81,73,.5); }
.wseg { display:flex; border:1px solid var(--border); border-radius:9px; overflow:hidden; width:fit-content; }
.wseg button { background:var(--elevated); border:none; color:var(--text-2); font-size:12px; padding:7px 12px; cursor:pointer; }
.wseg button.on { background:rgba(0,184,176,.14); color:var(--accent); }
.wiz-legend { font-size:11.5px; color:#e8a13c; max-width:280px; }
/* wizard layout: header / stage / dock as one column; the dock owns the
bottom edge and the stage flexes (its own overflow already scrolls) */
body.wizard { display:flex; flex-direction:column; height:100vh; overflow:hidden; }
body.wizard main { flex:1 1 auto; min-height:0; }
/* dockhead buttons: right-aligned cluster, never stretched */
#wdockhead .wdhint { order:0; }
#wbtn-finetune, #wbtn-generate, #wbtn-next { flex:0 0 auto; width:auto; margin-left:0; }
#wbtn-generate { margin-left:auto; }
#wbtn-next { margin-left:auto; }
#wbtn-generate + #wbtn-next { margin-left:8px; }
.rv-check .q { min-width:150px; }
.wiz-review .rv-col { flex:0 1 440px; }
/* render mode exports HERO PIXELS ONLY: the wizard is stage chrome */
body[data-render] #wdock, body[data-render] #weditring { display:none !important; }
/* card previews (the visuals are the point) */
#wcards .card .thumb { width:100%; aspect-ratio:100/62; border-radius:6px; overflow:hidden; border:1px solid var(--border); }
#wcards .card .thumb svg { width:100%; height:100%; display:block; }
#wcards .card .swx { width:100%; aspect-ratio:16/10; border-radius:6px; border:1px solid var(--border); }
.sw-midnight { background:linear-gradient(155deg,#0a0e14,#0d1117 45%,#071318); }
.sw-pcb { background:linear-gradient(155deg,#03211f,#04302c); }
.sw-onion { background:repeating-radial-gradient(circle at 90% 10%, #101a2c 0 4px, #16223a 4px 6px); }
.sw-pill { background:#0c3a3c; }
.sw-grid { background:#0c3a3c url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12"><rect x="2" y="2" width="8" height="8" fill="none" stroke="%23ffffff" stroke-opacity=".35" stroke-width="1"/></svg>'); }
.sw-grad { background:linear-gradient(100deg,#00e6dc,#39b8ff 60%,#8c6bf7); }
.sw-aurora { background:radial-gradient(28px 20px at 30% 20%, rgba(0,230,220,.8), transparent), radial-gradient(34px 26px at 70% 80%, rgba(140,107,247,.7), transparent), #0a0f16; }
.sw-mesh { background:conic-gradient(from 155deg at 40% 40%, rgba(0,184,177,.5), transparent 40%), #0b1016; }
.sw-circuitry { background:repeating-linear-gradient(45deg, rgba(0,184,177,.5) 0 1.5px, transparent 1.5px 7px), #080d13; }
.sw-image { background:repeating-conic-gradient(#1c2530 0 25%, #0d1117 0 50%) 0 0/12px 12px; }
#wcards .card:has(.thumb), #wcards .card:has(.swx) { width:150px; }
/* context previews: Review-step opt-in, not standing furniture */
body.wizard #contexts { display:none; }
body.wizard.show-ctx #contexts { display:flex; }
/* header buttons: one quiet family, labels not mystery icons */
.hbtn { display:inline-flex; align-items:center; gap:6px; border:1px solid var(--border); background:transparent;
color:var(--text-2); border-radius:8px; padding:5px 12px; font-size:12.5px; font-family:'Satoshi'; cursor:pointer;
transition:all .15s ease; }
.hbtn:hover { border-color:var(--accent); color:var(--text); background:rgba(0,184,176,.07); }
.hbtn svg { width:13px; height:13px; stroke:currentColor; stroke-width:2; fill:none; }
.hbtn.on { border-color:var(--accent); color:var(--accent); }
#approvedbar { position:relative; }
#ab-close { position:absolute; top:8px; right:10px; background:none; border:none; color:var(--text-2);
font-size:18px; line-height:1; cursor:pointer; padding:2px 6px; border-radius:6px; }
#ab-close:hover { color:var(--text); background:rgba(255,255,255,.06); }
/* finishing + package cards: one size, aligned */
.wiz-finish .card { width:200px; min-height:92px; justify-content:center; }
/* verdicts you can see from across the room */
.rv-check .btn.okon { background:rgba(63,185,80,.18); border-color:var(--green); color:var(--green); font-weight:600; }
.rv-check .btn.flagon { background:rgba(248,81,73,.16); border-color:#f85149; color:#f85149; font-weight:600; }
/* scrollable rows SAY they scroll: thin themed scrollbar on the card row */
#wcards { scrollbar-width:thin; scrollbar-color:var(--border) transparent; padding-bottom:6px; }
#wcards::-webkit-scrollbar { display:block; height:7px; }
#wcards::-webkit-scrollbar-thumb { background:var(--border); border-radius:4px; }
#wcards::-webkit-scrollbar-thumb:hover { background:var(--text-3); }
#wcards::-webkit-scrollbar-track { background:transparent; }
/* draggable dock: the grab bar resizes it; double-click resets */
#wdock { height:var(--dock-h, min(44vh, 330px)); position:relative; }
#wdock-grip { position:absolute; top:-1px; left:0; right:0; height:8px; cursor:ns-resize; z-index:5; }
#wdock-grip::after { content:''; position:absolute; left:50%; top:2px; transform:translateX(-50%);
width:44px; height:4px; border-radius:999px; background:var(--border); transition:background .15s; }
#wdock-grip:hover::after { background:var(--accent); }
.wiz-lintbox { display:flex; flex-direction:column; gap:5px; max-width:330px; max-height:150px; overflow-y:auto; scrollbar-width:thin; }
.wiz-lintbox .lint-item { font-size:12px; line-height:1.4; }
.wiz-lintbox .lint-warn { color:#e8a13c; }
.wiz-lintbox .lint-fail { color:#f85149; font-weight:600; }
.wiz-lintbox .lint-ok { color:#3fb950; }
.wiz-lintbox .lint-info { color:#8b949e; }
/* two card-row modes: option rows center natural-height cards; custom step
content (review, headline, package) fills the space and scrolls itself */
#wcards.custom { align-items:stretch; overflow-y:auto; overflow-x:hidden; height:100%; align-self:stretch; min-height:0;
scrollbar-width:thin; scrollbar-color:var(--border) transparent; }
#wcardsrow:has(> #wcards.custom) { align-items:stretch; }
#wcards.custom::-webkit-scrollbar { display:block; width:7px; }
/* Brand step: the sentences about this guide read as a compact wrapping
line above the things the human acts on. A column of full-width lines
overflowed the dock and clipped both the first note and the cards. */
.wiz-brand { flex:1; display:flex; flex-direction:column; gap:8px; align-items:stretch; justify-content:center; min-height:0; }
.wiz-brand-notes { display:flex; flex-direction:row; flex-wrap:wrap; gap:4px 16px; align-items:baseline; }
.wiz-brand-notes .hint { margin:0; }
.wiz-brand .wiz-finish { flex:0 0 auto; justify-content:flex-start; gap:8px; }
.wiz-swatches { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
/* #wcards .card:has(.swx) sets width:150px and the swatch a 16/10 box, both
too tall for this step's row; match that specificity to override. */
#wcards .wiz-swatches .card, #wcards .wiz-swatches .card:has(.swx) { width:112px; min-height:64px; justify-content:center; padding:8px 6px; }
#wcards .wiz-swatches .card .swx { width:100%; height:24px; aspect-ratio:auto; border-radius:6px; }
#wcards .wiz-brand .wiz-finish > .card { min-height:64px; }
/* ---- the Background step's thumbnails in the OWNER's colors -------------
These previews are how the human picks a background, so an Adom-teal grid
of swatches on someone else's page is the leak they actually SEE. Each
swatch keeps its own pattern and value and only changes hue, derived from
the same variables the hero uses (mirrored onto :root by applyGuide).
Both swatch sizes are restyled: studio.css defines them twice, small for
Classic and large for the wizard cards. */
body.branded .sw-midnight {
background: linear-gradient(155deg,
color-mix(in srgb, var(--brand-bg) 88%, black),
var(--brand-bg) 45%,
color-mix(in srgb, var(--brand-bg) 82%, var(--brand-primary)));
}
body.branded .sw-pcb {
background: linear-gradient(155deg,
color-mix(in srgb, var(--brand-bg) 86%, var(--brand-primary)),
color-mix(in srgb, var(--brand-bg) 70%, var(--brand-primary)));
}
body.branded .sw-onion {
background: repeating-radial-gradient(circle at 90% 10%,
color-mix(in srgb, var(--brand-bg) 88%, var(--brand-accent)) 0 4px,
color-mix(in srgb, var(--brand-bg) 74%, var(--brand-accent)) 4px 6px);
}
body.branded .sw-pill {
background: color-mix(in srgb, var(--brand-bg) 72%, var(--brand-accent));
}
body.branded .sw-grid {
background-color: color-mix(in srgb, var(--brand-bg) 72%, var(--brand-primary));
}
body.branded .sw-grad {
background: var(--brand-grad, linear-gradient(100deg, var(--brand-primary), var(--brand-accent)));
}
body.branded .sw-aurora {
background:
radial-gradient(28px 20px at 30% 20%, color-mix(in srgb, var(--brand-primary) 80%, transparent), transparent),
radial-gradient(34px 26px at 70% 80%, color-mix(in srgb, var(--brand-accent) 70%, transparent), transparent),
var(--brand-bg);
}
body.branded .sw-mesh {
background:
conic-gradient(from 90deg at 30% 30%, color-mix(in srgb, var(--brand-primary) 30%, transparent), transparent 33%),
conic-gradient(from 210deg at 72% 68%, color-mix(in srgb, var(--brand-accent) 26%, transparent), transparent 36%),
var(--brand-bg);
}
body.branded .sw-circuitry { background: var(--brand-bg); }
/* A step walked past but not actually finished: the Brand step over an
unconfirmed guide. A tick there says "nothing to do" about the one decision
only the human can make. */
.schip.needs { border-color: color-mix(in srgb, #f0a33c 55%, transparent); }
.schip.needs .n { background: #f0a33c; color: #1a1205; font-weight: 700; }
.schip.needs .t { color: #f0a33c; }
/* The Confirm action is the only thing that finishes the Brand step, so it
reads as the primary action rather than another swatch card. */
.wiz-brand-call { color: #f0a33c !important; max-width: 62ch; }
#wcards .card.wiz-confirm-cta {
border-color: #f0a33c;
background: color-mix(in srgb, #f0a33c 12%, transparent);
}
#wcards .card.wiz-confirm-cta .card-label { color: #f0a33c; font-weight: 700; }
/* Circuit options use the owner's colors in the picker as well as the art. */
.sw-circuit-field, .sw-circuit-tile {
background-color:var(--brand-bg, #0d1117);
background-image:repeating-linear-gradient(135deg, transparent 0 13px, color-mix(in srgb, var(--brand-primary, #00b8b0) 45%, transparent) 14px 15px, transparent 16px 26px);
}
.sw-circuit-tile { background-size:28px 28px; background-image:repeating-linear-gradient(90deg, transparent 0 12px, var(--brand-primary, #00b8b0) 13px 14px, transparent 15px 28px); }
.trace-controls { display:flex; flex-wrap:wrap; gap:10px 16px; padding:12px; align-items:center; }
.trace-controls[hidden] { display:none; }
.trace-controls label { display:flex; align-items:center; gap:8px; font-size:12px; }
.trace-controls input[type=range] { width:95px; }
.trace-controls input[type=number] { width:115px; }
.trace-controls button { width:auto; }
.trace-controls output { min-width:28px; font-variant-numeric:tabular-nums; }
.trace-controls .hint { flex-basis:100%; }
#wtrace-controls { flex:0 0 auto; max-height:140px; overflow:auto; }
#wdock.has-trace-controls { height:min(55vh, calc(var(--dock-h, min(44vh, 330px)) + 90px)); }