← Commit history

Hero v6: rendered the canonical way via adom-wiki-hero build-variants.js (bottom x pcb); commit generator source for reproducibility

John Lauer ·87b38fe961 ·3mo ago ·parent be57c31
3 files changed +168−2
adom-sfconvert-hero-v6.pngadded
⋯ 1 unchanged line ⋯
hero-build-variants.jsadded+166
@@ -0,0 +1,166 @@+// build-variants.js — generate adom-wiki-hero heroes across two axes: LAYOUT × THEME.+// Usage:+//   node build-variants.js                      -> writes the curated showcase set (see COMBOS)+//   node build-variants.js <layout> <theme>     -> one hero, e.g. "bleedRight pcb"+//   node build-variants.js name <comboName>     -> one named combo from COMBOS+// LAYOUTS: bottom | mirror | bleedRight | contained+// THEMES:  midnight | pcb | onion | pill | gradient+// Brand assets (fonts, wordmark, Kickstand tiles) are bundled under assets/, referenced relatively.+const fs = require('fs');+const path = require('path');+const DIR = __dirname;++const WORDMARK = fs.readFileSync(path.join(DIR, 'assets', 'adom-white.svg'), 'utf8')+  .replace(/<\?xml[^>]*\?>/, '').replace(/<style>[\s\S]*?<\/style>/, '').replace(/class="cls-1"/g, 'fill="#fff"');++// recolor a currentColor tile SVG and return a CSS background data-URI+function tile(name, color) {+  const svg = fs.readFileSync(path.join(DIR, 'assets', 'tiling', name), 'utf8').replace(/currentColor/g, color);+  return `url("data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}")`;+}++// ---- content (adom-sfconvert hero) ----+const C = {+  headline: 'EAGLE, Fusion 360<br>&amp; Altium <span class="accent">&rarr; KiCad</span>',+  sub: 'Converts EAGLE/Fusion <b>.lbr</b> and Altium <b>.SchLib/.PcbLib</b> <b>into</b> KiCad — each format rendered from its <b>own geometry</b> as a native SVG. No KiCad install.',+  chip: 'SF Convert', prompt: 'convert this EAGLE .lbr to KiCad',+  url: 'wiki.adom.inc/adom/adom-sfconvert',+  winlabel: 'adom-sfconvert · ADS1263 footprint · four-source compare · Adom webview',+  shot: 'file:///tmp/herowork2/shot.png',+};++// ---- THEMES: background + texture overlay + text colors ----+const THEMES = {+  midnight: {+    bg: `radial-gradient(1200px 800px at 88% -10%, rgba(0,184,177,.22), transparent 60%),+         radial-gradient(900px 700px at -5% 110%, rgba(140,107,247,.18), transparent 55%),+         linear-gradient(155deg,#0a0e14 0%,#0d1117 45%,#071318 100%)`,+    tex: `background:${tile('dot-grid.svg', '#ffffff')} 0 0/24px repeat;opacity:.05;+          -webkit-mask-image:linear-gradient(115deg,transparent 0%,#000 48%);mask-image:linear-gradient(115deg,transparent 0%,#000 48%)`,+    text: '#e6edf3', sub: '#aeb8c4', chipB: 'rgba(0,184,177,.34)', chipF: 'rgba(0,184,177,.07)', chipT: '#7fe3dd', accent: true,+  },+  // PCB traces — Kickstand "ethereal circuit field" on deep brand teal+  pcb: {+    bg: `radial-gradient(1000px 760px at 86% -5%, rgba(0,184,177,.28), transparent 60%),+         linear-gradient(160deg,#022a2b 0%,#003c3f 46%,#021a1c 100%)`,+    tex: `background:${tile('pcb-trace.svg', '#8FD3D4')} center/170px repeat;opacity:.16;+          -webkit-mask-image:linear-gradient(115deg,transparent 6%,#000 52%);mask-image:linear-gradient(115deg,transparent 6%,#000 52%)`,+    text: '#eafdfb', sub: '#a9d6d2', chipB: 'rgba(143,211,212,.40)', chipF: 'rgba(0,184,177,.10)', chipT: '#8fd3d4', accent: true,+  },+  // Onion corner — signature concentric-arc motif on solid navy (deck "substance" slide)+  onion: {+    bg: `radial-gradient(900px 700px at 80% -10%, rgba(100,171,255,.16), transparent 60%),+         linear-gradient(160deg,#021a36 0%,#00204f 50%,#01122b 100%)`,+    tex: `background:${tile('onion-corner.svg', '#8FD3D4')} right bottom/62% no-repeat;opacity:.5`,+    text: '#eaf2ff', sub: '#a9c0e0', chipB: 'rgba(100,171,255,.40)', chipF: 'rgba(100,171,255,.10)', chipT: '#9fc4ff', accent: true,+  },+  // Pill field on navy+  pill: {+    bg: `radial-gradient(900px 700px at 85% 0%, rgba(100,171,255,.18), transparent 60%),+         linear-gradient(160deg,#001a3f 0%,#00204f 50%,#001129 100%)`,+    tex: `background:${tile('pill-field.svg', '#64ABFF')} center/64px repeat;opacity:.5;+          -webkit-mask-image:linear-gradient(115deg,transparent 4%,#000 50%);mask-image:linear-gradient(115deg,transparent 4%,#000 50%)`,+    text: '#eaf2ff', sub: '#a9c0e0', chipB: 'rgba(100,171,255,.40)', chipF: 'rgba(100,171,255,.10)', chipT: '#9fc4ff', accent: true,+  },+  // Brand gradient — the "wow"/cover-slide look; left scrim keeps copy readable+  gradient: {+    bg: `linear-gradient(90deg, rgba(5,8,12,.82) 0%, rgba(5,8,12,.42) 42%, rgba(5,8,12,.08) 70%),+         radial-gradient(800px 600px at 90% 0%, rgba(255,255,255,.12), transparent 55%),+         linear-gradient(115deg,#00b8b1 0%,#0061ef 52%,#8c6bf7 100%)`,+    tex: ``,+    text: '#ffffff', sub: '#d7e2ee', chipB: 'rgba(255,255,255,.40)', chipF: 'rgba(255,255,255,.10)', chipT: '#ffffff', accent: true,+  },+};++// ---- LAYOUTS: window position/shape + text side ----+const LAYOUTS = {+  bottom:     { side: 'left',  win: 'right:72px;top:280px;width:806px;border-radius:16px 16px 0 0', imgH: 760 },+  mirror:     { side: 'right', win: 'left:72px;top:280px;width:806px;border-radius:16px 16px 0 0',  imgH: 760 },+  bleedRight: { side: 'left',  win: 'right:-74px;top:104px;width:900px;border-radius:16px 0 0 16px', imgH: 812 },+  contained:  { side: 'left',  win: 'right:80px;top:150px;width:752px;border-radius:16px',           imgH: 672 },+};++function html(L, T) {+  const left = L.side === 'left';+  return `<!DOCTYPE html><html><head><meta charset="utf-8">+<style>+@font-face{font-family:'Familjen Grotesk';font-weight:700;font-display:block;src:url('assets/fonts/familjen-grotesk-700-normal.woff2') format('woff2')}+@font-face{font-family:'Satoshi';font-weight:400;font-display:block;src:url('assets/fonts/satoshi-400-normal.woff2') format('woff2')}+@font-face{font-family:'Satoshi';font-weight:500;font-display:block;src:url('assets/fonts/satoshi-500-normal.woff2') format('woff2')}+*{margin:0;padding:0;box-sizing:border-box}+html,body{width:1600px;height:1000px;overflow:hidden}+body{font-family:'Satoshi',sans-serif;color:${T.text};position:relative;background:${T.bg};}+.tex{position:absolute;inset:0;z-index:0;${T.tex}}+.zone{position:absolute;inset:0;padding:80px 92px 0;z-index:3;display:flex;flex-direction:column}+.top{display:flex;align-items:flex-start;justify-content:space-between}+.wordmark svg{height:44px;width:auto;display:block}+.chip{border:1px solid ${T.chipB};background:${T.chipF};border-radius:999px;padding:9px 17px;font-size:14px;+  letter-spacing:2.5px;text-transform:uppercase;color:${T.chipT};display:inline-flex;align-items:center;gap:9px;font-weight:600}+.chip .dot{width:8px;height:8px;border-radius:50%;background:#00e6dc;box-shadow:0 0 10px #00e6dc}+.col{max-width:600px;${left ? '' : 'margin-left:auto;text-align:right;display:flex;flex-direction:column;align-items:flex-end'}}+h1{font-family:'Familjen Grotesk',sans-serif;font-weight:700;font-size:54px;line-height:1.04;letter-spacing:-1.4px;color:${T.text};margin-top:46px;margin-bottom:22px}+h1 .accent{${T.accent ? 'background:linear-gradient(100deg,#00e6dc,#39b8ff 60%,#8c6bf7);-webkit-background-clip:text;background-clip:text;color:transparent' : 'color:' + T.text}}+.sub{font-size:23px;line-height:1.5;color:${T.sub};max-width:500px;margin-bottom:30px}+.sub b{color:${T.text};font-weight:500}+.prompt{display:inline-flex;align-items:center;gap:12px;background:rgba(255,255,255,.06);border:1px solid rgba(0,230,220,.30);+  border-radius:14px;padding:15px 20px;font-size:19px;color:#e3eaf2}+.prompt .q{color:#00e6dc;font-weight:700}.prompt .ask{color:#9aa6b5;font-size:15px;margin-left:6px}+.url{position:absolute;${left ? 'left:92px' : 'right:92px'};bottom:54px;z-index:3;color:#00e6dc;font-weight:600;font-size:19px;font-family:'Familjen Grotesk',sans-serif}+.window{position:absolute;${L.win};overflow:hidden;z-index:1;+  box-shadow:0 28px 80px rgba(0,0,0,.62), 0 0 0 1px rgba(255,255,255,.07), 0 0 130px rgba(0,184,177,.07)}+.chrome{height:42px;background:#1b2128;display:flex;align-items:center;padding-left:18px;border-bottom:1px solid #232a33}+.chrome .ct{color:#8b949e;font-size:15px;margin-right:auto}+.winbtns{display:flex;height:100%}.winbtns .b{width:48px;height:100%;display:flex;align-items:center;justify-content:center;color:#b9c2cd}+.winbtns .min i{display:block;width:12px;height:1.5px;background:#b9c2cd}+.winbtns .max i{display:block;width:11px;height:11px;border:1.5px solid #b9c2cd;border-radius:1px}+.winbtns .cls{font-family:Arial,sans-serif;font-size:18px;line-height:1}+.window img{width:100%;height:${L.imgH}px;display:block;object-fit:cover;object-position:top left}+</style></head><body>+  <div class="tex"></div>+  <div class="window">+    <div class="chrome"><span class="ct">${C.winlabel}</span>+      <div class="winbtns"><span class="b min"><i></i></span><span class="b max"><i></i></span><span class="b cls">&#10005;</span></div></div>+    <img src="${C.shot}">+  </div>+  <div class="zone">+    <div class="top"><div class="wordmark">${WORDMARK}</div><div class="chip"><span class="dot"></span>${C.chip}</div></div>+    <div class="col">+      <h1>${C.headline}</h1>+      <div class="sub">${C.sub}</div>+      <div class="prompt"><span class="q">"${C.prompt}"</span><span class="ask">— just ask Claude</span></div>+    </div>+  </div>+  <div class="url">${C.url}</div>+</body></html>`;+}++// curated showcase set: name -> [layout, theme]+const COMBOS = {+  'midnight':           ['bottom', 'midnight'],+  'mirror':             ['mirror', 'midnight'],+  'pcb':                ['bottom', 'pcb'],+  'onion':              ['bottom', 'onion'],+  'pill':               ['bottom', 'pill'],+  'gradient':           ['bottom', 'gradient'],+  'bleed-right':        ['bleedRight', 'midnight'],+  'bleed-right-pcb':    ['bleedRight', 'pcb'],+  'contained':          ['contained', 'midnight'],+  'contained-gradient': ['contained', 'gradient'],+};++function write(name, layoutKey, themeKey) {+  const L = LAYOUTS[layoutKey], T = THEMES[themeKey];+  if (!L || !T) throw new Error('bad layout/theme: ' + layoutKey + '/' + themeKey);+  const out = path.join(DIR, `variant-${name}.html`);+  fs.writeFileSync(out, html(L, T));+  console.log('wrote', out, `(${layoutKey} × ${themeKey})`);+}++const a = process.argv.slice(2);+if (a.length === 0) {+  for (const [name, [l, t]] of Object.entries(COMBOS)) write(name, l, t);+} else if (a[0] === 'name') {+  const [l, t] = COMBOS[a[1]]; write(a[1], l, t);+} else {+  write(`${a[0]}-${a[1]}`, a[0], a[1]);+}
package.json+2−2
@@ -24,7 +24,7 @@   ],   "hero": {     "type": "image",-    "path": "adom-sfconvert-hero-v5.png"+    "path": "adom-sfconvert-hero-v6.png"   },   "discovery_triggers": [     "convert eagle to kicad",@@ -38,7 +38,7 @@   "license": "MIT",   "files": [     "skills/adom-sfconvert/SKILL.md",-    "adom-sfconvert-hero-v5.png",+    "adom-sfconvert-hero-v6.png",     "README.md",     "SKILL.md",     "install.sh",