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.20.3
4 files changed
+33−3
package.json+1−1@@ -2,7 +2,7 @@ "slug": "hero-studio", "title": "Hero Studio", "type": "app",- "version": "0.20.2",+ "version": "0.20.3", "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 showcase: 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, showcase, type match) and a Generate that unlocks only fully confirmed. Includes showcase 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.20.2",+ "version": "0.20.3", "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 showcase: 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, showcase, type match) and a Generate that unlocks only fully confirmed. Includes showcase 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+26−1@@ -193,6 +193,31 @@ const WIZ_STEPS = [ const fitb = document.createElement('button'); fitb.className = 'btn small'; fitb.textContent = 'Make it as big as fits'; fitb.addEventListener('click', () => runFit(null));+ // Title size: the missing "smaller" half (Colby: a long title wraps deep+ // and pushes the subtitle under the homepage overlay band; fit only+ // finds the LARGEST size, this lets a human bring it DOWN). Same 5-13+ // cqw bounds as Classic's slider and the fit solver. The hero updates+ // per tick locally; the send is debounced so slider spam coalesces to+ // one ledger entry.+ const sizeRow = document.createElement('div');+ sizeRow.className = 'wiz-sizerow';+ const srange = document.createElement('input');+ srange.type = 'range'; srange.min = '5'; srange.max = '13'; srange.step = '0.1';+ srange.value = String((state.fontSize || {}).title || 8);+ const sval = document.createElement('span');+ sval.className = 'wiz-sizeval';+ sval.textContent = srange.value + 'cqw';+ let szt = null;+ srange.addEventListener('input', () => {+ const v = Number(srange.value);+ sval.textContent = v + 'cqw';+ wizMerge(state, { fontSize: { title: v } });+ hero.style.setProperty('--fs-title', v + 'cqw');+ render();+ clearTimeout(szt);+ szt = setTimeout(() => send({ fontSize: { title: v } }), 250);+ });+ sizeRow.append(mk('Title size'), srange, sval, fitb); const sin = document.createElement('input'); sin.type = 'text'; sin.className = 'hin'; sin.placeholder = firstSentence(wp().brief, 80);@@ -235,7 +260,7 @@ const WIZ_STEPS = [ }); }; renderPick();- wrap.append(mk('Headline'), hin, fitb, mk('Text under it'), sin, mk('Tap words to color them'), pick);+ wrap.append(mk('Headline'), hin, sizeRow, mk('Text under it'), sin, mk('Tap words to color them'), pick); host.appendChild(wrap); }, },
public/studio.css+5@@ -344,6 +344,11 @@ body.classic #wdock, body.classic #weditring { display:none !important; } #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; }