← Commit history

fusion-hero skill: the hero recipe

John Lauer ·134b790630 ·2mo ago ·parent 34659c5
1 file changed +111
skills/fusion-hero/SKILL.mdadded+111
@@ -0,0 +1,111 @@+# fusion-hero - making the Fusion bridge's hero image++The exact, human-approved recipe behind `screenshots/hero.png` on adom/fusion-bridge.+Iterated live with John (2026-08-09) over six versions; every number below survived his+review. Use this to REGENERATE the fusion hero, and as the reference recipe for any+bridge hero that showcases a real desktop app window (the kicad bridge is the sibling+case). Family references: pup's hero (adom/pup-bridge hero-v9.png) and nb's.++Trigger words: fusion hero, hero image, regenerate the hero, bridge hero, hero recipe.++## Content contract (locked with John, do not re-guess)++| Field | Value |+|---|---|+| Hero title | **Fusion** - ONLY the single word users type to their AI. The page's dynamic title carries the rest |+| Page title | Fusion - the Fusion 360 Bridge (parallel to "Pup - Puppeteer Bridge") |+| Subtitle | Your real CAD, driven by AI. - ONE line, accent gradient on "driven by AI." |+| Chip | BRIDGE, solid mint pill, top right. The ONLY pill (see the double-pill trap below) |+| Vitrine | The REAL Fusion window, native chrome, UNCROPPED, showing the BQ25792 board in 3D PCB on a dark canvas |+| Not present | No URL line, no prompt pill, no detail line. The pup/nb family is minimal |++## 1. Prepare Fusion (on the user's box, background verbs)++1. Dark mode first, all three layers - see the `fusion-dark-mode` skill. The one that+   matters for the shot: viewport Display Settings > Environment > **River Rubicon**.+   A white canvas kills the hero (John: "we use dark mode at adom").+2. Open the canonical board: `fusion_open_cloud_file {"fileName":"BQ25792",+   "projectName":"Main","folderPath":"Molecules/XRP/Power"}` then the view chain+   `fusion_show_2d_board` -> `fusion_show_3d_board` (3D is reachable only from 2D).+3. Reshape the window toward the TALLEST aspect Fusion allows, remembering its hard+   floor: **min width 1822 physical px at 150% DPI** (the ribbon). `desktop_set_window_bounds+   {w:1440,h:1470}` yields 1822x1470. Record the original rect and RESTORE it after.+4. Frame the board centered, filling the viewport:+   `fusion_run_modeling_script` with `vp.fit(); cam.viewExtents *= 0.88; vp.camera = cam; vp.refresh()`+   (pass `expectDocument:"BQ25792"`). Verify the board's pixel extent in the capture+   (green-pixel scan) leaves margins on all sides; tune the 0.88 factor, do not guess.+5. Capture in the background: `desktop_screenshot_window {hwnd}`; use the auto-pulled+   `.full.png`. Fusion never comes to the foreground for any of this.++## 2. The layout (1600x1000 authoring canvas, rendered @2x, delivered 2000x1250)++Measured computationally from pup's hero PNG, then adjusted through John's margin+reviews. All values in canvas px:++| Element | Spec |+|---|---|+| Background | `radial-gradient(1100px 750px at 92% -8%, rgba(0,184,177,.16), transparent 60%), linear-gradient(155deg,#0a0e14,#0d1117 48%,#0a1216)` |+| ADOM wordmark | left 64, top 51, height 40 (white SVG) |+| Title | Familjen Grotesk 700, **235px**, letter-spacing -7px, #eef3f8, at left 64, top 128 |+| Subtitle | Satoshi 400, 35px, at left 68, top 405 - close enough to the title to feel CONNECTED, one line, accent span `linear-gradient(100deg,#39b8ff,#5ea0f2 60%,#8c6bf7)` text-clipped |+| BRIDGE pill | top 42, right 42, `background:#7ce0d3`, radius 999, padding 10x22, Familjen 700 16px, ls 2.4px, color #0b2723 |+| Vitrine | left 807, top 270, width 751, height = width x capture aspect (1265/1568 -> 606). Radius 12, `box-shadow: 0 30px 90px rgba(0,0,0,.66), 0 0 0 1px rgba(255,255,255,.08)` |++The margin rhythm those numbers encode (John's "margins like a professional graphic+designer leaves"):++- title -> vitrine gutter: **130px** (55 and 90 were both rejected)+- vitrine bottom -> canvas bottom: **~124px** (50 too tight, 230 too empty)+- vitrine right edge ALIGNED with the pill's right edge on the 42px margin line+- clear air between the pill's bottom and the vitrine's top++## 3. The two hard rules learned the expensive way++- **NEVER crop the screenshot to fit a slot.** John: "i hate when you crop the+  screenshot in the vitrine." Resize the APP WINDOW to the aspect you need. When the+  app has a hard minimum (Fusion's 1822px width), derive the SLOT from the app's+  achievable aspect instead. The vitrine img is always `width:100%` with NO+  object-fit cover, full chrome visible including min/max/close.+- **Look at every render before shipping.** The margin failures above were invisible+  in code and obvious in the PNG.++## 4. Render pipeline++Fonts and machinery live in the `adom-wiki-hero-image` skill dir:++```bash+CHROME=$(ls -d ~/.cache/puppeteer/chrome/linux-*/chrome-linux64/chrome | head -1)+CHROME=$CHROME node <skilldir>/render.js hero.html 1600 1000 [email protected] 2+# then PIL: resize (2000,1250) LANCZOS, save optimize=True  (target well under 1MB)+```++## 5. The Hero Studio gate (a human generates, never you)++1. `hero-studio pose adom/fusion-bridge --surface pup --port <free>` - a parallel+   instance if another thread's gate is open. The pup leg is broken post-rename+   (hero-studio#559): when it exits 3, open the studio proxy URL in a pup session+   yourself and poll GET /state for `approved` in place of the dead pose waiter.+2. Stage the finished PNG as a FULL-hero import: `hero-studio vitrine --file+   screenshots/hero.png --full --port <p>`. Re-run after every revision; the open+   gate updates live (verify by sha: state.vitrine.src bytes == local file).+3. **`hero-studio set overlay.pill=false`** - a full import plus our baked BRIDGE+   chip otherwise exports TWO pills (the studio bakes its type pill top right).+4. If the page title changed since pose, refresh the studio's snapshot:+   `POST /api/pages {"owner","slug","title","brief"}` - the marquee band previews+   stale data otherwise.+5. Signal the human by FLASHING, never foregrounding - and use ab's+   `desktop_flash_window {hwnd}` directly; `pup_alert_window` no-ops silently once+   the window title has changed.+6. After the human clicks Generate: read the pose `changes` ledger, sync page.json,+   then publish.++## 6. Publish (the hero-unlink trap)++```bash+adom-wiki repo push adom/fusion-bridge --files screenshots/hero.png -m "hero"+adom-wiki repo push adom/fusion-bridge --files page.json -m "page.json LAST"  # keeps hero linked+```++page.json's hero block is `{"type":"image","path":"screenshots/hero.png"}` - same+path on every revision so the URL stays stable. Always push a COMPLETE page.json+LAST; a stale one clobbers the renamed title (done once, restored by hand).