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
← Commit history
Publish 0.19.4
4 files changed
+47−9
package.json+1−1@@ -2,7 +2,7 @@ "slug": "hero-studio", "title": "Hero Studio", "type": "app",- "version": "0.19.3",+ "version": "0.19.4", "description": "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. Adom-org pages get the house wordmark and palette automatically; every other owner brings their own accent and background colors, with placement fixed for all. The floating app window is the vitrine: it auto-loads a real screenshot from the package's wiki page (screenshots/, docs/), takes a manual import, or a full-hero import (the human-ratified re-stamp path for existing heroes). The pose gate opens in verification mode: per-item checklist (title, subtitle, vitrine, type match) and a Generate that unlocks only fully confirmed. Includes vitrine bleeds, brand tile themes, gradient angles, pixel-faithful wiki marquee and index-card previews, and a component-hero mode with a photo/raytrace/phong fallback ladder.", "license": "MIT", "tags": [
page.json+1−1@@ -2,7 +2,7 @@ "slug": "hero-studio", "title": "Hero Studio", "type": "app",- "version": "0.19.3",+ "version": "0.19.4", "description": "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. Adom-org pages get the house wordmark and palette automatically; every other owner brings their own accent and background colors, with placement fixed for all. The floating app window is the vitrine: it auto-loads a real screenshot from the package's wiki page (screenshots/, docs/), takes a manual import, or a full-hero import (the human-ratified re-stamp path for existing heroes). The pose gate opens in verification mode: per-item checklist (title, subtitle, vitrine, type match) and a Generate that unlocks only fully confirmed. Includes vitrine bleeds, brand tile themes, gradient angles, pixel-faithful wiki marquee and index-card previews, and a component-hero mode with a photo/raytrace/phong fallback ladder.", "license": "MIT", "tags": [
public/js/wizard.js+33−6@@ -448,12 +448,38 @@ function wizRenderReview(host) { const act = document.createElement('div'); act.className = 'rv-col'; const lintBox = document.createElement('div');- const fails = (state.lint || []).filter(l => l.level === 'fail').length;- const warns = (state.lint || []).filter(l => l.level === 'warn').length;- lintBox.innerHTML = '<div class="wiz-lab">Layout lint</div>' + (- fails ? '<div class="lint-item lint-fail">' + fails + ' hard problem(s): Generate stays locked. Details in the classic lint box.</div>'- : warns ? '<div class="lint-item lint-warn">' + warns + ' warning(s). The studio measures; you decide.</div>'- : '<div class="lint-item lint-ok">No layout findings.</div>');+ lintBox.className = 'wiz-lintbox';+ const lab = document.createElement('div');+ lab.className = 'wiz-lab'; lab.textContent = 'Layout lint';+ lintBox.appendChild(lab);+ const items = state.lint || [];+ if (!items.length) {+ const okRow = document.createElement('div');+ okRow.className = 'lint-item lint-ok';+ okRow.textContent = 'No layout findings.';+ lintBox.appendChild(okRow);+ } else {+ items.forEach((it) => {+ const row = document.createElement('div');+ row.className = 'lint-item lint-' + (it.level || 'warn');+ row.textContent = (it.level === 'fail' ? 'BLOCKS GENERATE: ' : '') + it.msg;+ // best effort spotlight: most lint ids end in the element they measured+ row.style.cursor = 'pointer';+ row.title = 'Click to highlight it on the hero';+ row.addEventListener('click', () => {+ const parts = String(it.id || '').split('-');+ for (let n = 1; n < parts.length; n++) {+ const el = document.getElementById(parts.slice(n).join('-'));+ if (el) {+ el.classList.add('tour-glow');+ setTimeout(() => el.classList.remove('tour-glow'), 2200);+ return;+ }+ }+ });+ lintBox.appendChild(row);+ });+ } act.append(lintBox); wrap.append(views, checks, act);@@ -554,6 +580,7 @@ function wizardRender() { const cards = $('wcards'); cards.textContent = '';+ cards.classList.toggle('custom', !s.options); const showArrows = !!s.options; $('warr-l').style.visibility = showArrows ? 'visible' : 'hidden'; $('warr-r').style.visibility = showArrows ? 'visible' : 'hidden';
public/studio.css+12−1@@ -296,7 +296,7 @@ body.classic #wdock, body.classic #weditring { display:none !important; } .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:wrap; }+#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; }@@ -403,3 +403,14 @@ body.wizard.show-ctx #contexts { display:flex; } #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; }+#wcardsrow:has(> #wcards.custom) { align-items:stretch; }+#wcards.custom { height:100%; align-self:stretch; }