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.14.1
5 files changed
+19−14
SKILL.md+2−1@@ -162,7 +162,8 @@ hero: an explainer, a per-item checklist, and a Generate button that unlocks only when every item is confirmed (clicking it locked explains why). A WALKTHROUGH spotlights each item in place: "this is your title", subtitle, vitrine, then the type pill (where the human catches an AI's wrong app/skill/-component call); "Looks good" ticks that check and advances. The homepage-+hardware call; hardware is the launch name for the old component type, which+survives as a kind); "Looks good" ticks that check and advances. The homepage- marquee overlay composites over the hero by default in the gate so the human SEES where the wiki URL, pill, and today's duplicated title land (annotated with adom/wiki#80, which will drop the duplicate). STAGE HYGIENE (hero-studio#23): the stage shows ONLY final-hero
data/pages.json+6−5@@ -229,7 +229,7 @@ "score": 539, "stars": 0, "installs30d": 82,- "brief": "adom-lbr , the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad ⇄ Altium ⇄ EAGLE/Fusion) through one canonical adom-lbr JSON , symbol + footp",+ "brief": "adom-lbr , the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad \u21c4 Altium \u21c4 EAGLE/Fusion) through one canonical adom-lbr JSON , symbol + footp", "tags": [ "eda", "altium",@@ -275,22 +275,23 @@ "updated_at": "2026-07-10T20:18:03.283Z" }, {- "owner": "adom",- "slug": "wiki", "type": "skill", "title": "Adom Wiki", "author": "Kyle Bergstedt", "score": 418, "stars": 1, "installs30d": 60,- "brief": "How the Adom Wiki (wiki.adom.inc) works and how to drive it with the adom-wiki CLI: the two storage layers (git page repo vs package registry), hosting source by pushing files (not a tarball), making",+ "brief": "The shared electronics wiki for the AI age", "tags": [ "wiki", "cli", "packages", "registry" ],- "updated_at": "2026-07-10T19:58:57.304Z"+ "updated_at": "2026-07-10T19:58:57.304Z",+ "owner": "adom",+ "slug": "wiki",+ "description": "The shared electronics wiki for the AI age" }, { "owner": "adom",
package.json+1−1@@ -2,7 +2,7 @@ "slug": "hero-studio", "title": "Hero Studio", "type": "app",- "version": "0.14.0",+ "version": "0.14.1", "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.14.0",+ "version": "0.14.1", "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/index.html+9−6@@ -810,7 +810,7 @@ body[data-render] #hero { width:1600px; max-width:none; aspect-ratio:auto; heigh <span class="mqo-owner" id="mqo-owner"></span> <div class="mqo-prompt" id="mqo-prompt" style="display:none"><span id="mqo-prompt-text"></span><button id="mqo-prompt-copy">copy</button></div> </div>- <div class="pill-tr" id="pill-tr" data-tip="Type pill: bakes into the PNG top right (app / skill / component). Toggle under Image badges"><span class="pill app" id="l-pill">APP</span></div>+ <div class="pill-tr" id="pill-tr" data-tip="Type pill: bakes into the PNG top right (app / skill / hardware). Toggle under Image badges"><span class="pill app" id="l-pill">APP</span></div> <div class="slug-br" id="slug-br" data-tip="Wiki slug: bakes into the PNG bottom right. Toggle under Image badges"><a class="l-slug" id="l-slug" target="_blank" href="#"></a></div> <div class="lower"> <div class="lowerin">@@ -907,6 +907,9 @@ let state = null; const $ = (id) => document.getElementById(id); const send = (patch) => fetch('state', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(patch) }).catch(()=>{}); +function canonType(t) { return t === 'hardware' ? 'component' : (t || 'app'); }+// the LAUNCH spelling for display + bake: the wiki's public name is hardware+function wireLabel(t) { return canonType(t) === 'component' ? 'hardware' : (t || 'app'); } function pageByKey(key) { return pages.find(p => p.owner + '/' + p.slug === key) || pages[0]; } function compById(id) { return comps.find(c => c.id === id) || comps[0]; } /* the object the overlay, header, and context cards render: page or component */@@ -987,8 +990,8 @@ function render() { } else if (!flags[key] && mark) mark.remove(); } const types = (Array.isArray(d.types) && d.types.length ? d.types : [d.type]);- const modeMatchesType = (d.type === 'component') === (mode === 'component');- $('v-type-label').textContent = 'Page type matches: page is "' + types.join(' + ') + '", studio mode is "' + mode + '"' + (modeMatchesType ? '' : ' (MISMATCH: switch mode at the top of the panel)');+ const modeMatchesType = (canonType(d.type) === 'component') === (mode === 'component');+ $('v-type-label').textContent = 'Page type matches: page is "' + types.map(wireLabel).join(' + ') + '", studio mode is "' + mode + '"' + (modeMatchesType ? '' : ' (MISMATCH: switch mode at the top of the panel)'); $('v-type-label').classList.toggle('warn', !modeMatchesType); const anyFlag = Object.values(flags).some(Boolean); const lintFail = (state.lint || []).some(l => l.level === 'fail');@@ -1030,7 +1033,7 @@ function render() { // composited over the hero so redundancy and balance are judgeable hero.classList.toggle('show-mq', !!state.marqueePreview && mode === 'app'); if (state.marqueePreview) {- $('mqo-badges').innerHTML = '<span class="badge badge-' + d.type + '">' + d.type + '</span>' ++ $('mqo-badges').innerHTML = '<span class="badge badge-' + canonType(d.type) + '">' + wireLabel(d.type) + '</span>' + (d.score > 0 ? '<span class="ts-slide-score">' + TREND13 + ' ' + d.score + '</span>' : '') + (d.stars > 0 ? '<span class="ts-slide-stars">' + STAR12 + ' ' + d.stars + '</span>' : ''); // TODAY-REALITY on purpose (Colby): the homepage still overlays its own@@ -1127,7 +1130,7 @@ function render() { // them as one clustered badge box; the linter treats the cluster as one box. const ptr = $('pill-tr'); ptr.style.display = state.overlay.pill ? '' : 'none';- ptr.innerHTML = types.map(t => '<span class="pill ' + t + '">' + String(t).toUpperCase() + '</span>').join('');+ ptr.innerHTML = types.map(t => '<span class="pill ' + canonType(t) + '">' + wireLabel(t).toUpperCase() + '</span>').join(''); $('l-trend').style.display = state.overlay.scores ? '' : 'none'; $('l-trend').querySelector('b').textContent = d.score.toLocaleString('en-US'); $('l-stars').style.display = state.overlay.scores ? '' : 'none';@@ -1419,7 +1422,7 @@ const TOUR_STEPS = [ { key: 'vitrine', el: 'vitrine-img', fallbackEl: 'circuitcanvas', winSel: '.window', title: 'This is your vitrine', body: 'The app window. It should show YOUR app, not a generic chart. If it looks generic, tell your AI to capture a real screenshot at the slot size shown in the left panel.' }, { key: 'type', el: 'pill-tr', title: 'This is your type pill',- body: 'app / skill / component / bootstrap. AIs pick this wrong often; if it says the wrong thing, yell at yours now, before it bakes.' },+ body: 'app / skill / hardware / bootstrap (hardware is the launch name; component is its legacy spelling and survives as a kind). AIs pick this wrong often; if it says the wrong thing, yell at yours now, before it bakes.' }, ]; let tourIdx = -1; function tourTarget(step) {