Split each form factor into a lean widget page + a separate info page

Previously every device .html bundled its full narrative (purpose, BOM,
dimensioned drawings, embedding docs) inside a #techinfo block that embed
mode (?embed=1) only CSS-hid — so every embedder and every landing-page
iframe downloaded all of it (showcase 77%, teacher 49% of the file) for
content no embedder ever sees.

Now:
  - <device>.html is the lean widget only: header + front view/controls +
    title + summary + program box. ?embed=1 still collapses to the bare
    widget; the heavy narrative is gone from the payload.
  - info-<device>.html (new, one per form factor) carries all the words —
    purpose, dimensions, priced BOM, embedding docs — and embeds the live
    widget at the top via the existing iframe + auto-resize protocol
    (new shared src/infoembed.html + src/infoembed.js).
  - Each device links out to its info page ("…dimensions & BOM →"); the
    landing panes and viewport bar now offer both Open ↗ and Specs & info ⓘ.
  - Dropped the now-dead "Show info" toggle (CSS + progbox.js).

Branding: adopt the official VARASYS "tagline on the bottom" logos from the
brand kit (light-background variant now matches; dark already did). The
tagline is baked into the PNGs, so remove the CSS .brand-tag / .dev-tag
spans and the showcase canvas-drawn tagline. Brand cyan #0AB3F7 / navy
#1C283F already match the official palette.

build.sh / deploy.sh: build + deploy the six new info-*.html pages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-28 14:18:23 -05:00
parent f622e58a49
commit 9e5c79b3b2
20 changed files with 703 additions and 355 deletions

File diff suppressed because one or more lines are too long

View file

@ -30,7 +30,8 @@ def build(name):
return out.stat().st_size
for name in ("index.html","editor.html","player.html","teacher.html","stage.html","micro.html","showcase.html",
"embed.html"):
"embed.html",
"info-editor.html","info-player.html","info-teacher.html","info-stage.html","info-micro.html","info-showcase.html"):
print("built %s (%dKB)" % (name, build(name) // 1024))
pathlib.Path("dist/embed.js").write_text(pathlib.Path("embed.js").read_text()) # loader, served as-is
print("copied embed.js")

View file

@ -41,15 +41,16 @@ fi
# stamp the version into the built copy only (source stays clean)
echo "deployed v$BUILD -> $DEST_DIR"
for f in index.html editor.html player.html teacher.html stage.html micro.html showcase.html \
embed.html; do
embed.html \
info-editor.html info-player.html info-teacher.html info-stage.html info-micro.html info-showcase.html; do
sed "s|const APP_VERSION = \"[^\"]*\";|const APP_VERSION = \"$BUILD\";|" "$DIST_DIR/$f" > "$DEST_DIR/$f"
echo " $f ($(stat -c '%s' "$DEST_DIR/$f") bytes)"
done
cp "$DIST_DIR/embed.js" "$DEST_DIR/embed.js"; echo " embed.js ($(stat -c '%s' "$DEST_DIR/embed.js") bytes)"
rm -f "$DEST_DIR/player-asbuilt.html" # renamed to teacher.html
rm -f "$DEST_DIR/concepts.html" # Concepts is now the landing (/)
rm -f "$DEST_DIR"/info-*.html # info pages merged into each form-factor page
# (stage.html / info-stage.html are deployed again — now the foot-pedal Stage stompbox)
# info-*.html are first-class pages again: each form factor has a lean widget page
# (<device>.html) + a separate spec/BOM page (info-<device>.html that embeds it).
# If real audio samples are added later (see the plan's GM-sample note),
# sync that directory too.

View file

@ -43,7 +43,8 @@
.pane .chip.hw{ color:var(--cyan); border-color:rgba(10,179,247,.45); }
.pane .chip.app{ color:#2fe07a; border-color:rgba(47,224,160,.45); }
.pane p{ margin:0; font-size:12px; color:var(--muted); line-height:1.45; flex:1; }
.pane .open{ font-size:11px; color:var(--link); text-decoration:none; font-weight:600; align-self:flex-start; }
.pane .links{ display:flex; gap:14px; align-items:center; flex-wrap:wrap; }
.pane .open{ font-size:11px; color:var(--link); text-decoration:none; font-weight:600; }
/* viewport: the live, selected device */
.viewport{ margin-top:16px; border:1px solid var(--panel-bd); border-radius:14px; overflow:hidden; background:var(--field-bg); }
@ -109,7 +110,7 @@
<div class="panes" id="panes"></div>
<div class="viewport">
<div class="vp-bar"><span id="vpName"><b>PM_E1 Editor</b></span><a id="vpOpen" href="/editor.html" target="_blank" rel="noopener">Open full page ↗</a></div>
<div class="vp-bar"><span id="vpName"><b>PM_E1 Editor</b></span><span><a id="vpInfo" href="/info-editor.html" target="_blank" rel="noopener">Specs &amp; info ⓘ</a> &nbsp;·&nbsp; <a id="vpOpen" href="/editor.html" target="_blank" rel="noopener">Open full page ↗</a></span></div>
<iframe id="vp" title="PolyMeter — live viewport" allow="autoplay"></iframe>
</div>
@ -154,7 +155,10 @@ function renderPanes() {
<div class="pane" data-key="${v.key}" role="button" tabindex="0">
<div class="ph"><span class="chip ${v.chip}">${v.chip === "app" ? "Web app" : v.chip === "hw" ? "Hardware" : "Concept"}</span><h3>${v.name}</h3></div>
<p>${v.sum}</p>
<a class="open" href="${v.file}" target="_blank" rel="noopener" onclick="event.stopPropagation()">Open full page ↗</a>
<div class="links">
<a class="open" href="${v.file}" target="_blank" rel="noopener" onclick="event.stopPropagation()">Open ↗</a>
<a class="open" href="${v.file.replace("/", "/info-")}" target="_blank" rel="noopener" onclick="event.stopPropagation()">Specs &amp; info ⓘ</a>
</div>
</div>`).join("");
$("panes").querySelectorAll(".pane").forEach((el) => {
const k = el.dataset.key;
@ -167,6 +171,7 @@ function loadVersion(key, prog) {
$("panes").querySelectorAll(".pane").forEach((p) => p.classList.toggle("active", p.dataset.key === key));
$("vpName").innerHTML = "<b>" + v.name + "</b>";
$("vpOpen").href = v.file;
$("vpInfo").href = v.file.replace("/", "/info-");
vp.style.height = (v.h || 440) + "px";
vp.src = v.file + "?embed=1" + (prog ? "#p=" + encodeURIComponent(prog) : "");
if (prog && !userEditing) box.value = prog;

68
info-editor.html Normal file
View file

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VARASYS PM_E1 PolyMeter Editor — what it is</title>
<meta name="description" content="PM_E1 PolyMeter Editor — the web workbench for the family: stack independent meter lanes with their own subdivision, drum voice, perstep accents/ghosts/mutes, swing, polyrhythm, set lists and perlane dB gain. Design once; it plays on any form factor." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
<script>
(function(){ try{ var p = localStorage.getItem("metronome.theme");
if (p!=="light" && p!=="dark" && p!=="system") p = "system";
document.documentElement.dataset.theme = p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p;
} catch(e){ document.documentElement.dataset.theme = "dark"; } })();
</script>
<style>
/*@BUILD:include:src/base.css@*/
:root{ --bg1:#12151c; --bg2:#05070a; --txt:#c7d0db; --muted:#7f8b9a; --link:#6cb6ff;
--panel-bg:#161b22; --panel-bd:#2a313c; --field-bg:#0e1116; --field-bd:#2a313c; --silk:#aab2bc; }
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
--panel-bg:#ffffff; --panel-bd:#d2dae4; --field-bg:#f1f4f8; --field-bd:#d2dae4; }
body{ margin:0; min-height:100vh; padding:22px 16px 56px; color:var(--txt);
background:radial-gradient(circle at 50% -8%, var(--bg1), var(--bg2)); }
a{ color:var(--link); }
main{ width:100%; max-width:980px; margin:0 auto; }
.info-hero{ text-align:center; padding:16px 8px 2px; }
.info-hero h1{ font-size:clamp(24px,5vw,36px); margin:0; letter-spacing:-.01em; }
.info-hero .sub{ margin:9px auto 0; max-width:64ch; font-size:14.5px; }
</style>
</head>
<body>
/*@BUILD:include:src/header.html@*/
<main>
<section class="info-hero">
<h1>PM_E1 PolyMeter Editor</h1>
<p class="sub">The web workbench for the whole family — design grooves here, and the same program string plays identically on every form factor.</p>
</section>
/*@BUILD:include:src/infoembed.html@*/
<section class="about">
<h2>What it is</h2>
<div class="ff-tags"><span>Web app</span><span>The workbench</span><span>Runs in any browser</span></div>
<p>The editor is where you build a groove: stack independent <b>meter lanes</b>, each with its own subdivision,
drum voice and perstep <b>accents, ghosts and mutes</b>, plus swing, ratio polyrhythm, set lists and a
perlane <b>dB gain</b>. It's zeroinstall — it runs in any modern browser and works fully offline.</p>
<p>Everything you design saves to a compact <b>program string</b> in the shared sharelanguage. That same string
loads into any of the hardware concepts or an embedded widget, so a groove built here plays back identically
everywhere. There's no bill of materials — it's the software workbench, not a buildable device; the buildable
realizations are the <a href="/info-teacher.html">Teacher</a>, <a href="/info-stage.html">Stage</a>,
<a href="/info-micro.html">Practice</a> and <a href="/info-showcase.html">Display</a>.</p>
</section>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed the editor (or any device) elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</main>
/*@BUILD:include:src/footer.html@*/
<script>
const APP_VERSION = "v0.0.1-dev";
window.INFO_DEVICE = { file:"/editor.html", name:"PM_E1 PolyMeter Editor" };
/*@BUILD:include:src/infoembed.js@*/
/*@BUILD:include:src/chrome.js@*/
</script>
</body>
</html>

129
info-micro.html Normal file
View file

@ -0,0 +1,129 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VARASYS PM_P1 Practice — purpose, dimensions &amp; bill of materials</title>
<meta name="description" content="PM_P1 Practice — a long, narrow inline practice bar: one clickable thumbroller, amber 14segment display, analog instrument passthrough with the click mixed in. Dimensions and a priced BOM." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
<script>
(function(){ try{ var p = localStorage.getItem("metronome.theme");
if (p!=="light" && p!=="dark" && p!=="system") p = "system";
document.documentElement.dataset.theme = p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p;
} catch(e){ document.documentElement.dataset.theme = "dark"; } })();
</script>
<style>
/*@BUILD:include:src/base.css@*/
:root{ --bg1:#12151c; --bg2:#05070a; --txt:#c7d0db; --muted:#7f8b9a; --link:#6cb6ff;
--panel-bg:#161b22; --panel-bd:#2a313c; --field-bg:#0e1116; --field-bd:#2a313c; --silk:#aab2bc; }
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
--panel-bg:#ffffff; --panel-bd:#d2dae4; --field-bg:#f1f4f8; --field-bd:#d2dae4; }
body{ margin:0; min-height:100vh; padding:22px 16px 56px; color:var(--txt);
background:radial-gradient(circle at 50% -8%, var(--bg1), var(--bg2)); }
a{ color:var(--link); }
main{ width:100%; max-width:980px; margin:0 auto; }
.info-hero{ text-align:center; padding:16px 8px 2px; }
.info-hero h1{ font-size:clamp(24px,5vw,36px); margin:0; letter-spacing:-.01em; }
.info-hero .sub{ margin:9px auto 0; max-width:64ch; font-size:14.5px; }
</style>
</head>
<body>
/*@BUILD:include:src/header.html@*/
<main>
<section class="info-hero">
<h1>PM_P1 Practice</h1>
<p class="sub">A long, narrow inline practice bar — patch it into your signal, drive everything from one clickable thumbroller, and read tempo and track names off an amber 14segment display.</p>
</section>
/*@BUILD:include:src/infoembed.html@*/
<section class="about">
<h2>What it is</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Inline practice bar</span><span>~$35 oneoff</span></div>
<p>A long, narrow practice bar you patch <i>into</i> your signal: instrument in one end, amp or headphones out
the other, the click mixed in. One clickable thumbroller does everything (roll = tempo, press = start/stop,
hold + roll = switch track), and an amber 14segment display shows tempo and track names.</p>
<p>The click is summed into your signal in the <b>analog domain</b> (plus a small monitor speaker). Powered over
USBC — a wall adapter for a permanent practicespace install, or a pocket power bank when you're mobile (no
internal battery to wear out); ships with the editor's grooves built in.</p>
</section>
<div class="dview">
<p class="cap">Dimensions &amp; layout — ≈ 6.3 × 1.4 × 1.0 in (160 × 36 × 26 mm), an extruded bar</p>
<div class="drow">
<div class="dvy">↕ 1.4 in<br>(36 mm)</div>
<div class="dschem" style="height:70px">
<span class="scap">Front (top face)</span>
<div class="scr" style="left:9%; top:24px; width:42%; height:30px"></div>
<div class="ctl" style="left:60%; top:21px; width:36px; height:36px; border-radius:8px"></div>
<div class="jl" style="left:9%; bottom:5px">14seg display</div>
<div class="jl" style="left:58%; bottom:5px">thumbroller</div>
</div>
</div>
<div class="dvx">↔ 6.3 in (160 mm) long</div>
<div class="drow" style="margin-top:12px; gap:14px">
<div style="flex:1">
<div class="dschem" style="height:64px">
<span class="scap">Left end</span>
<div class="jk" style="left:calc(50% - 6px); top:26px"></div>
<div class="jl" style="left:0; right:0; bottom:5px">TRS In (instrument)</div>
</div>
</div>
<div style="flex:1">
<div class="dschem" style="height:64px">
<span class="scap">Right end</span>
<div class="jk u" style="left:30%; top:29px"></div>
<div class="jk" style="left:58%; top:26px"></div>
<div class="jl" style="left:0; right:0; bottom:5px">USBC · TRS Out</div>
</div>
</div>
</div>
<div class="dvx" style="margin-left:0">↕ ends ≈ 1.0 in (26 mm) deep</div>
</div>
<details class="spec" open>
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a USBCpowered RP2040 inline bar with analog click injection.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain &amp; display</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">4char 14segment alphanumeric LED + I²C driver <span class="spec">— amber; HT16K33. Shows BPM &amp; track names</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Control</td></tr>
<tr><td class="part">Clickable thumbroller <span class="spec">— EC11 encoder + roller wheel · roll / press / holdroll</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr class="grp"><td colspan="3">Audio — analog click injection</td></tr>
<tr><td class="part">PCM5102A I²S DAC <span class="spec">— linelevel click</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Dual opamp, NE5532 / OPA2134 <span class="spec">— hiZ instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr><td class="part">PAM8302A mono ClassD + 8 Ω speaker <span class="spec">— monitor</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Connectors &amp; power</td></tr>
<tr><td class="part">1/4″ jack <span class="spec">— Inst In (TS) · Out (TRS)</span></td><td class="q">2</td><td class="c">2</td></tr>
<tr><td class="part">USBC bus power (5 V) + PWR LED <span class="spec">— wall adapter or power bank; also carries config</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Build</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">Passives, headers, wire <span class="spec">— R/C for the analog stage + decoupling</span></td><td class="q"></td><td class="c">2</td></tr>
<tr><td class="part">Extruded aluminium bar enclosure + end caps <span class="spec">— beadblasted, matteblack anodised</span></td><td class="q">1</td><td class="c">8</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $35</td></tr>
</tbody>
</table>
</div>
</details>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</main>
/*@BUILD:include:src/footer.html@*/
<script>
const APP_VERSION = "v0.0.1-dev";
window.INFO_DEVICE = { file:"/micro.html", name:"PM_P1 Practice" };
/*@BUILD:include:src/infoembed.js@*/
/*@BUILD:include:src/chrome.js@*/
</script>
</body>
</html>

68
info-player.html Normal file
View file

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VARASYS PM_C1 Concept — the idealized player</title>
<meta name="description" content="PM_C1 Concept — the idealized, screenfirst player render: full setlist navigation, a colour beat display of every lane, theming and a fullscreen stage view. The buildable realizations are the Teacher and Practice units." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
<script>
(function(){ try{ var p = localStorage.getItem("metronome.theme");
if (p!=="light" && p!=="dark" && p!=="system") p = "system";
document.documentElement.dataset.theme = p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p;
} catch(e){ document.documentElement.dataset.theme = "dark"; } })();
</script>
<style>
/*@BUILD:include:src/base.css@*/
:root{ --bg1:#12151c; --bg2:#05070a; --txt:#c7d0db; --muted:#7f8b9a; --link:#6cb6ff;
--panel-bg:#161b22; --panel-bd:#2a313c; --field-bg:#0e1116; --field-bd:#2a313c; --silk:#aab2bc; }
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
--panel-bg:#ffffff; --panel-bd:#d2dae4; --field-bg:#f1f4f8; --field-bd:#d2dae4; }
body{ margin:0; min-height:100vh; padding:22px 16px 56px; color:var(--txt);
background:radial-gradient(circle at 50% -8%, var(--bg1), var(--bg2)); }
a{ color:var(--link); }
main{ width:100%; max-width:980px; margin:0 auto; }
.info-hero{ text-align:center; padding:16px 8px 2px; }
.info-hero h1{ font-size:clamp(24px,5vw,36px); margin:0; letter-spacing:-.01em; }
.info-hero .sub{ margin:9px auto 0; max-width:64ch; font-size:14.5px; }
</style>
</head>
<body>
/*@BUILD:include:src/header.html@*/
<main>
<section class="info-hero">
<h1>PM_C1 Concept</h1>
<p class="sub">The idealized concept render — a clean, screenfirst player with a colour beat display, setlist navigation, theming and a fullscreen landscape view.</p>
</section>
/*@BUILD:include:src/infoembed.html@*/
<section class="about">
<h2>What it is</h2>
<div class="ff-tags"><span>Concept</span><span>Idealized device</span><span>Not buildable as drawn</span></div>
<p>The idealized concept (PM_C1): the player as a clean, screenfirst device with no concession to mechanical parts yet.
It's the look we design <i>toward</i> — full setlist navigation, a colour beat display showing every lane,
light/dark theming, and a fullscreen landscape "stage" view. It runs the same engine and program strings as
everything else in the family, but as an <i>idealized</i> object, before deciding which buttons, encoders,
jacks and enclosure actually make it real.</p>
<p>Because it's a concept, there's <b>no bill of materials</b> — there's nothing to source for a render. The
buildable realization of this idea is the <a href="/info-teacher.html">PM_T1 Teacher</a> (full priced BOM there);
for the smallest practical unit, see the <a href="/info-micro.html">PM_P1 Practice</a>.</p>
</section>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</main>
/*@BUILD:include:src/footer.html@*/
<script>
const APP_VERSION = "v0.0.1-dev";
window.INFO_DEVICE = { file:"/player.html", name:"PM_C1 Concept" };
/*@BUILD:include:src/infoembed.js@*/
/*@BUILD:include:src/chrome.js@*/
</script>
</body>
</html>

123
info-showcase.html Normal file
View file

@ -0,0 +1,123 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VARASYS PM_D1 Display — purpose, dimensions &amp; bill of materials</title>
<meta name="description" content="PM_D1 Display — a pyramid displaypiece metronome whose pendulum is an RGB light bar combining every lane's subdivisions and accents, with a printed tempo scale and sliding weight. Dimensions and a priced BOM." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
<script>
(function(){ try{ var p = localStorage.getItem("metronome.theme");
if (p!=="light" && p!=="dark" && p!=="system") p = "system";
document.documentElement.dataset.theme = p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p;
} catch(e){ document.documentElement.dataset.theme = "dark"; } })();
</script>
<style>
/*@BUILD:include:src/base.css@*/
:root{ --bg1:#12151c; --bg2:#05070a; --txt:#c7d0db; --muted:#7f8b9a; --link:#6cb6ff;
--panel-bg:#161b22; --panel-bd:#2a313c; --field-bg:#0e1116; --field-bd:#2a313c; --silk:#aab2bc; }
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
--panel-bg:#ffffff; --panel-bd:#d2dae4; --field-bg:#f1f4f8; --field-bd:#d2dae4; }
body{ margin:0; min-height:100vh; padding:22px 16px 56px; color:var(--txt);
background:radial-gradient(circle at 50% -8%, var(--bg1), var(--bg2)); }
a{ color:var(--link); }
main{ width:100%; max-width:980px; margin:0 auto; }
.info-hero{ text-align:center; padding:16px 8px 2px; }
.info-hero h1{ font-size:clamp(24px,5vw,36px); margin:0; letter-spacing:-.01em; }
.info-hero .sub{ margin:9px auto 0; max-width:64ch; font-size:14.5px; }
</style>
</head>
<body>
/*@BUILD:include:src/header.html@*/
<main>
<section class="info-hero">
<h1>PM_D1 Display</h1>
<p class="sub">A displaypiece metronome — the pendulum is an RGB light bar that combines every lane's subdivisions &amp; accents; a printed tempo scale with a sliding weight sets the tempo.</p>
</section>
/*@BUILD:include:src/infoembed.html@*/
<section class="about">
<h2>What it is</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Display piece</span><span>~$41 oneoff</span></div>
<p>A metronome as an object: the silhouette of a classic pyramid windup unit, but the swinging pendulum is
pure <b>RGB light</b>. The whole bar is the display — every lane's subdivisions &amp; accents ride along its
length as moving points of light (all meters combined), a printed tempo scale runs up the vertical axis,
and a sliding <b>weight</b> sets the tempo just like the mechanical original.</p>
<p>It's a beautiful, glanceable tempo reference for the shelf, the studio, or a shop window: accents glow
amber, normal steps cyan, ghosts soft violet, and the pendulum eases to each beat exactly as a weighted rod
would. It runs the same grooves as everything else (load any program string), plays the click through a
small speaker, and is powered over USBC with a second "thru" port to daisychain. There's no power switch —
the real unit starts when you lift it from its holder / set it swinging. No instrument I/O; it's a showpiece.</p>
</section>
<div class="dview">
<p class="cap">Dimensions &amp; profile — ≈ 4.7 × 7.1 × 3.1 in (120 × 180 × 80 mm), a truncatedpyramid plinth</p>
<div class="drow">
<div class="dvy">↕ 7.1 in (180 mm)</div>
<div class="dschem" style="height:184px">
<span class="scap">Front</span>
<div style="position:absolute; inset:6px; clip-path:polygon(34% 2%, 66% 2%, 93% 98%, 7% 98%);
background:linear-gradient(180deg,#2c2e34,#15171b); border:1px solid #33363c;"></div>
<div style="position:absolute; left:calc(50% - 4px); top:24px; width:8px; height:120px; border-radius:4px;
background:linear-gradient(180deg,#33d0ff,#178fb0); box-shadow:0 0 10px #33d0ff;"></div>
<div class="jl" style="left:0; right:0; bottom:5px">RGBlight pendulum bar + tempo scale</div>
</div>
</div>
<div class="dvx">↔ 4.7 in (120 mm) base</div>
<div class="drow" style="margin-top:12px">
<div class="dvy">↕ 7.1 in (180 mm)</div>
<div class="dschem" style="height:184px; max-width:200px">
<span class="scap">Side</span>
<div style="position:absolute; inset:6px; clip-path:polygon(40% 2%, 60% 2%, 86% 98%, 14% 98%);
background:linear-gradient(180deg,#26282d,#141519); border:1px solid #33363c;"></div>
<div class="jk u" style="left:calc(50% - 7px); bottom:14px; top:auto"></div>
<div class="jl" style="left:0; right:0; bottom:1px">USBC in base</div>
</div>
</div>
<div class="dvx">↔ 3.1 in (80 mm) deep</div>
</div>
<details class="spec" open>
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a USBCpowered RP2040 display piece driving addressable RGB light.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">RGB light</td></tr>
<tr><td class="part">Addressable RGB LEDs (WS2812B) <span class="spec">— a strip down the pendulum bar, ~40 px</span></td><td class="q">1</td><td class="c">5</td></tr>
<tr><td class="part">Frosted acrylic diffuser / lightguide <span class="spec">— the glowing pendulum bar</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr class="grp"><td colspan="3">Audio</td></tr>
<tr><td class="part">MAX98357A I²S amp + small speaker <span class="spec">— the click</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Power &amp; build</td></tr>
<tr><td class="part">2× USBC (data+power &amp; powerthru) + PWR LED <span class="spec">— daisychain</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Tilt / lift sensor (accelerometer) <span class="spec">— starts when lifted from its holder</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">Passives, wire</td><td class="q"></td><td class="c">2</td></tr>
<tr><td class="part">Pyramid enclosure <span class="spec">— cast/CNC aluminium or hardwood, frosted front panel</span></td><td class="q">1</td><td class="c">14</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $41</td></tr>
</tbody>
</table>
</div>
</details>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</main>
/*@BUILD:include:src/footer.html@*/
<script>
const APP_VERSION = "v0.0.1-dev";
window.INFO_DEVICE = { file:"/showcase.html", name:"PM_D1 Display" };
/*@BUILD:include:src/infoembed.js@*/
/*@BUILD:include:src/chrome.js@*/
</script>
</body>
</html>

130
info-stage.html Normal file
View file

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VARASYS PM_S1 Stage — purpose, dimensions &amp; bill of materials</title>
<meta name="description" content="PM_S1 Stage — a footpedal polymeter stompbox: handsfree footswitches, expressionpedal tempo, a floorreadable RGB beat light, analog instrument passthrough. Dimensions and a priced BOM." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
<script>
(function(){ try{ var p = localStorage.getItem("metronome.theme");
if (p!=="light" && p!=="dark" && p!=="system") p = "system";
document.documentElement.dataset.theme = p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p;
} catch(e){ document.documentElement.dataset.theme = "dark"; } })();
</script>
<style>
/*@BUILD:include:src/base.css@*/
:root{ --bg1:#12151c; --bg2:#05070a; --txt:#c7d0db; --muted:#7f8b9a; --link:#6cb6ff;
--panel-bg:#161b22; --panel-bd:#2a313c; --field-bg:#0e1116; --field-bd:#2a313c; --silk:#aab2bc; }
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
--panel-bg:#ffffff; --panel-bd:#d2dae4; --field-bg:#f1f4f8; --field-bd:#d2dae4; }
body{ margin:0; min-height:100vh; padding:22px 16px 56px; color:var(--txt);
background:radial-gradient(circle at 50% -8%, var(--bg1), var(--bg2)); }
a{ color:var(--link); }
main{ width:100%; max-width:980px; margin:0 auto; }
.info-hero{ text-align:center; padding:16px 8px 2px; }
.info-hero h1{ font-size:clamp(24px,5vw,36px); margin:0; letter-spacing:-.01em; }
.info-hero .sub{ margin:9px auto 0; max-width:64ch; font-size:14.5px; }
</style>
</head>
<body>
/*@BUILD:include:src/header.html@*/
<main>
<section class="info-hero">
<h1>PM_S1 Stage</h1>
<p class="sub">A footpedal polymeter stompbox — handsfree footswitches, expressionpedal tempo, a floorreadable RGB beat light, and analog instrument passthrough with the click mixed in.</p>
</section>
/*@BUILD:include:src/infoembed.html@*/
<section class="about">
<h2>What it is</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Footpedal stompbox</span><span>~$52 oneoff</span></div>
<p>A footoperated polymeter stompbox for the stage: drive it handsfree with two heavy footswitches and an
expression pedal, read it off the floor from the big RGB beat light, and run your instrument through it with
the click mixed in. (For a desk/lesson unit with a full screen, see the <a href="/info-teacher.html">Teacher</a>.)</p>
<p>The controls are built for feet: the <b>left footswitch</b> taps tempo (hold to start/stop), the <b>right</b>
steps through your set list (hold for previous), and a <b>1/4″ expressionpedal input</b> sweeps tempo on the
fly. Your instrument passes through (1/4″ in) with the click summed in the <b>analog domain</b> and sent to a
balanced 1/4″ TRS out. Powered over USBC — with a second USBC <b>"thru"</b> port so several pedals
daisychain off one charger or power bank.</p>
</section>
<div class="dview">
<p class="cap">Dimensions &amp; layout — ≈ 4.7 × 3.7 × 1.5 in (120 × 93 × 38 mm), a 1590BBstyle stompbox</p>
<div class="drow">
<div class="dvy">↕ 3.7 in (93 mm)</div>
<div class="dschem" style="height:150px">
<span class="scap">Front</span>
<div class="scr" style="left:18%; right:18%; top:22px; height:34px"></div>
<div class="ctl" style="left:calc(50% - 15px); top:64px; width:30px; height:30px"></div>
<div class="ctl" style="left:20%; top:100px; width:34px; height:34px"></div>
<div class="ctl" style="left:calc(80% - 34px); top:100px; width:34px; height:34px"></div>
<div class="jl" style="left:0; right:0; bottom:5px">angled TFT · RGB beat light · Tap + Next footswitches</div>
</div>
</div>
<div class="dvx">↔ 4.7 in (120 mm) wide</div>
<div class="drow" style="margin-top:12px">
<div class="dvy">↕ 1.5 in (38 mm)</div>
<div class="dschem" style="height:56px">
<span class="scap">Top edge — I/O</span>
<div class="jk" style="left:7%; top:18px"></div><div class="jk" style="left:22%; top:18px"></div>
<div class="jk" style="left:37%; top:18px"></div><div class="jk" style="left:52%; top:18px"></div>
<div class="jk u" style="left:68%; top:21px"></div><div class="jk u" style="left:83%; top:21px"></div>
<div class="jl" style="left:0; right:0; bottom:4px">Trig · Inst In · Out TRS · Exp · USBC · USBC thru</div>
</div>
</div>
<div class="dvx">↔ 4.7 in (120 mm)</div>
</div>
<details class="spec" open>
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a footoperated RP2040 stompbox (USBC, dualport) with analog click injection.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain &amp; display</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">1.3″ IPS TFT, ST7789 <span class="spec">— SPI; angled BPM / item readout</span></td><td class="q">1</td><td class="c">6</td></tr>
<tr><td class="part">Highbright diffused RGB beat indicator <span class="spec">— floorreadable</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Controls</td></tr>
<tr><td class="part">Heavyduty momentary footswitch (softtouch) <span class="spec">— Tap · Next</span></td><td class="q">2</td><td class="c">6</td></tr>
<tr><td class="part">1/4″ expressionpedal input jack (TRS) <span class="spec">— tempo sweep</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Audio — analog click injection</td></tr>
<tr><td class="part">PCM5102A I²S DAC <span class="spec">— linelevel click</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Dual opamp, NE5532 / OPA2134 <span class="spec">— hiZ instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr><td class="part">Balanced line driver, DRV134 <span class="spec">— → 1/4″ TRS out</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Connectors &amp; power</td></tr>
<tr><td class="part">1/4″ jack <span class="spec">— Inst In (TS) · Out (TRS) · Trig In (TS)</span></td><td class="q">3</td><td class="c">3</td></tr>
<tr><td class="part">2× USBC (data+power &amp; powerthru) + powerpath/protection + PWR LED <span class="spec">— daisychain pedals</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr class="grp"><td colspan="3">Build</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">5</td></tr>
<tr><td class="part">Passives, headers, wire <span class="spec">— R/C for the analog stage + decoupling</span></td><td class="q"></td><td class="c">3</td></tr>
<tr><td class="part">Diecast aluminium stompbox (Hammond 1590BBstyle) <span class="spec">— beadblasted, matteblack Type II anodise, laseretched</span></td><td class="q">1</td><td class="c">12</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $52</td></tr>
</tbody>
</table>
<p class="sub" style="margin-top:12px">No builtin speaker — the Stage feeds your amp / PA. The click is summed in
the <b>analog domain</b> (hiZ instrument buffer + DAC → balanced line driver), so your instrument is never
redigitised (no added latency).</p>
</div>
</details>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</main>
/*@BUILD:include:src/footer.html@*/
<script>
const APP_VERSION = "v0.0.1-dev";
window.INFO_DEVICE = { file:"/stage.html", name:"PM_S1 Stage" };
/*@BUILD:include:src/infoembed.js@*/
/*@BUILD:include:src/chrome.js@*/
</script>
</body>
</html>

105
info-teacher.html Normal file
View file

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VARASYS PM_T1 Teacher — purpose, spec &amp; bill of materials</title>
<meta name="description" content="PM_T1 Teacher — a fullfeature studio / lesson desk console: a colour TFT of every lane, arcade buttons, a thumbroller, and analog instrument passthrough with the click mixed in. Spec and a priced BOM." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
<script>
(function(){ try{ var p = localStorage.getItem("metronome.theme");
if (p!=="light" && p!=="dark" && p!=="system") p = "system";
document.documentElement.dataset.theme = p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p;
} catch(e){ document.documentElement.dataset.theme = "dark"; } })();
</script>
<style>
/*@BUILD:include:src/base.css@*/
:root{ --bg1:#12151c; --bg2:#05070a; --txt:#c7d0db; --muted:#7f8b9a; --link:#6cb6ff;
--panel-bg:#161b22; --panel-bd:#2a313c; --field-bg:#0e1116; --field-bd:#2a313c; --silk:#aab2bc; }
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
--panel-bg:#ffffff; --panel-bd:#d2dae4; --field-bg:#f1f4f8; --field-bd:#d2dae4; }
body{ margin:0; min-height:100vh; padding:22px 16px 56px; color:var(--txt);
background:radial-gradient(circle at 50% -8%, var(--bg1), var(--bg2)); }
a{ color:var(--link); }
main{ width:100%; max-width:980px; margin:0 auto; }
.info-hero{ text-align:center; padding:16px 8px 2px; }
.info-hero h1{ font-size:clamp(24px,5vw,36px); margin:0; letter-spacing:-.01em; }
.info-hero .sub{ margin:9px auto 0; max-width:64ch; font-size:14.5px; }
</style>
</head>
<body>
/*@BUILD:include:src/header.html@*/
<main>
<section class="info-hero">
<h1>PM_T1 Teacher</h1>
<p class="sub">The fullfeature studio / lesson desk console — a colour TFT showing every lane, arcade buttons and a thumbroller, with your instrument running through and the click mixed in.</p>
</section>
/*@BUILD:include:src/infoembed.html@*/
<section class="about">
<h2>What it is</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Studio / lesson console</span><span>~$59 oneoff</span></div>
<p>The fullfeature desktop console: a colour readout of every lane, fast setlist navigation, and your
instrument running straight through with the click mixed in — the handson unit for a studio desk or a
teaching room, on a nonreflective matteblack case. (For handsfree live use, see the footoperated
<a href="/info-stage.html">Stage</a> stompbox.)</p>
<p>Topmounted 1/4″ jacks keep cabling tidy; the metronome click is summed into the signal in the
<b>analog domain</b> (no redigitising, no added latency) and sent to a balanced 1/4″ TRS output for the
desk or interface, plus a small monitor speaker. Powered over USBC — a wall adapter or a power bank. The
colour TFT shows tempo, the item name and all lane patterns; arcade buttons + a recessed thumbroller make
it quick to drive while you teach or track.</p>
</section>
<details class="spec" open>
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a desk/studio RP2040 build (USBC powered) with analog click injection.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain &amp; display</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero / Picoclone</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">2.0″ 320×240 IPS TFT, ST7789 <span class="spec">— SPI</span></td><td class="q">1</td><td class="c">8</td></tr>
<tr class="grp"><td colspan="3">Controls</td></tr>
<tr><td class="part">Arcade pushbutton, 24 mm <span class="spec">— Prev · Next · Tap</span></td><td class="q">3</td><td class="c">4</td></tr>
<tr><td class="part">Arcade pushbutton, 30 mm <span class="spec">— Play</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr><td class="part">Detented encoder (EC11 / PEC12) + sidemount thumbroller <span class="spec">— recessed; nothing to snap off</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr class="grp"><td colspan="3">Audio — analog click injection</td></tr>
<tr><td class="part">PCM5102A I²S DAC <span class="spec">— linelevel click</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Dual opamp, NE5532 / OPA2134 <span class="spec">— hiZ instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr><td class="part">Balanced line driver, DRV134 <span class="spec">— (or crosscoupled opamp) → 1/4″ TRS out</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">PAM8302A mono ClassD + 8 Ω 2 W speaker <span class="spec">— monitor</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Connectors &amp; power</td></tr>
<tr><td class="part">1/4″ jack <span class="spec">— Inst In (TS) · Out (TRS) · Trig In (TS)</span></td><td class="q">3</td><td class="c">3</td></tr>
<tr><td class="part">USBC bus power (5 V) + PWR LED <span class="spec">— wall adapter or power bank; same port carries config; no battery</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Build</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">5</td></tr>
<tr><td class="part">Passives, headers, wire <span class="spec">— R/C for the analog stage + decoupling</span></td><td class="q"></td><td class="c">3</td></tr>
<tr><td class="part">Diecast aluminium enclosure (Hammond 1590style) <span class="spec">— beadblasted, matteblack Type II anodise, laseretched legends</span></td><td class="q">1</td><td class="c">12</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $56</td></tr>
</tbody>
</table>
<p class="sub" style="margin-top:12px">Audio is summed in the <b>analog domain</b>: the DAC's click is mixed with a
highimpedance buffer of the 1/4″ instrument input, then fed to the balanced line driver (1/4″ TRS out) and the
monitor amp — so your instrument is never redigitised (no added latency).</p>
</div>
</details>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</main>
/*@BUILD:include:src/footer.html@*/
<script>
const APP_VERSION = "v0.0.1-dev";
window.INFO_DEVICE = { file:"/teacher.html", name:"PM_T1 Teacher" };
/*@BUILD:include:src/infoembed.js@*/
/*@BUILD:include:src/chrome.js@*/
</script>
</body>
</html>

View file

@ -82,7 +82,7 @@
linear-gradient(180deg, #2b2d33, #161719); /* matte anodised graphite */
box-shadow:0 24px 50px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.05), inset 0 -2px 8px rgba(0,0,0,.5) }
.brandrow{ display:flex; align-items:center; justify-content:space-between; margin:0 }
.dev-logo{ height:13px }
.dev-logo{ height:22px }
.silk{ display:flex; align-items:center; gap:7px; color:var(--silk) }
.silk .model{ font-size:8.5px; text-transform:uppercase; letter-spacing:.16em; opacity:.85 }
.meta{ display:flex; align-items:center; gap:12px }
@ -140,7 +140,7 @@
<!-- TOP FACE: display + roller + speaker -->
<div class="face">
<div class="brandrow">
<div class="silk"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS" /><span class="dev-tag">Simplifying Complexity</span></span><span class="model">PM_P1 Practice</span></div>
<div class="silk"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" /></span><span class="model">PM_P1 Practice</span></div>
<div class="meta">
<div class="pwr" title="Powered over USBC — wall adapter or power bank"><span class="dot"></span>USBC&nbsp;PWR</div>
</div>
@ -346,86 +346,7 @@ window.loadProgramString = function(plain){ var s=patchToSetup(plain); tracks=[{
/*@BUILD:include:src/progbox.js@*/
</script>
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (dimensions, BOM, embedding)</label>
<div id="techinfo" class="pageonly" hidden>
<section class="about">
<h2>PM_P1 — Practice</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Inline practice bar</span><span>~$35 oneoff</span></div>
<p>A long, narrow practice bar you patch <i>into</i> your signal: instrument in one end, amp or headphones out
the other, the click mixed in. One clickable thumbroller does everything (roll = tempo, press = start/stop,
hold + roll = switch track), and an amber 14segment display shows tempo and track names.</p>
<p>The click is summed into your signal in the <b>analog domain</b> (plus a small monitor speaker). Powered over
USBC — a wall adapter for a permanent practicespace install, or a pocket power bank when you're mobile (no
internal battery to wear out); ships with the editor's grooves built in.</p>
</section>
<div class="dview">
<p class="cap">Dimensions &amp; layout — ≈ 6.3 × 1.4 × 1.0 in (160 × 36 × 26 mm), an extruded bar</p>
<div class="drow">
<div class="dvy">↕ 1.4 in<br>(36 mm)</div>
<div class="dschem" style="height:70px">
<span class="scap">Front (top face)</span>
<div class="scr" style="left:9%; top:24px; width:42%; height:30px"></div>
<div class="ctl" style="left:60%; top:21px; width:36px; height:36px; border-radius:8px"></div>
<div class="jl" style="left:9%; bottom:5px">14seg display</div>
<div class="jl" style="left:58%; bottom:5px">thumbroller</div>
</div>
</div>
<div class="dvx">↔ 6.3 in (160 mm) long</div>
<div class="drow" style="margin-top:12px; gap:14px">
<div style="flex:1">
<div class="dschem" style="height:64px">
<span class="scap">Left end</span>
<div class="jk" style="left:calc(50% - 6px); top:26px"></div>
<div class="jl" style="left:0; right:0; bottom:5px">TRS In (instrument)</div>
</div>
</div>
<div style="flex:1">
<div class="dschem" style="height:64px">
<span class="scap">Right end</span>
<div class="jk u" style="left:30%; top:29px"></div>
<div class="jk" style="left:58%; top:26px"></div>
<div class="jl" style="left:0; right:0; bottom:5px">USBC · TRS Out</div>
</div>
</div>
</div>
<div class="dvx" style="margin-left:0">↕ ends ≈ 1.0 in (26 mm) deep</div>
</div>
<details class="spec pageonly">
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a USBCpowered RP2040 inline bar with analog click injection.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain &amp; display</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">4char 14segment alphanumeric LED + I²C driver <span class="spec">— amber; HT16K33. Shows BPM &amp; track names</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Control</td></tr>
<tr><td class="part">Clickable thumbroller <span class="spec">— EC11 encoder + roller wheel · roll / press / holdroll</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr class="grp"><td colspan="3">Audio — analog click injection</td></tr>
<tr><td class="part">PCM5102A I²S DAC <span class="spec">— linelevel click</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Dual opamp, NE5532 / OPA2134 <span class="spec">— hiZ instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr><td class="part">PAM8302A mono ClassD + 8 Ω speaker <span class="spec">— monitor</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Connectors &amp; power</td></tr>
<tr><td class="part">1/4″ jack <span class="spec">— Inst In (TS) · Out (TRS)</span></td><td class="q">2</td><td class="c">2</td></tr>
<tr><td class="part">USBC bus power (5 V) + PWR LED <span class="spec">— wall adapter or power bank; also carries config</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Build</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">Passives, headers, wire <span class="spec">— R/C for the analog stage + decoupling</span></td><td class="q"></td><td class="c">2</td></tr>
<tr><td class="part">Extruded aluminium bar enclosure + end caps <span class="spec">— beadblasted, matteblack anodised</span></td><td class="q">1</td><td class="c">8</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $35</td></tr>
</tbody>
</table>
</div>
</details>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</div><!-- /#techinfo -->
<p class="ff-link pageonly"><a href="/info-micro.html">Purpose, dimensions &amp; bill of materials →</a></p>
/*@BUILD:include:src/footer.html@*/
</body>

View file

@ -84,8 +84,7 @@
.brandrow{ display:flex; align-items:center; justify-content:space-between; margin:2px 6px 16px; }
.logo{ display:flex; align-items:center; gap:11px }
.logo .dev-logo{ height:19px }
.logo .dev-tag{ color:var(--dmuted) }
.logo .dev-logo{ height:26px }
.logo .model{ color:var(--dmuted); font-size:12px; letter-spacing:.04em }
.pwr{ display:flex; align-items:center; gap:7px; font-size:10px; color:var(--dmuted); text-transform:uppercase; letter-spacing:.12em }
.pwr .dot{ width:8px; height:8px; border-radius:50%; background:#2fe07a; box-shadow:0 0 8px #2fe07a }
@ -222,7 +221,7 @@
<span class="screw bl"></span><span class="screw br"></span>
<div class="brandrow">
<div class="logo"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS" /><span class="dev-tag">Simplifying Complexity</span></span><span class="model">PM_C1 · Concept</span></div>
<div class="logo"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" /></span><span class="model">PM_C1 · Concept</span></div>
<div class="pwr"><span class="dot"></span>PWR</div>
</div>
@ -493,21 +492,7 @@ requestAnimationFrame(draw);
/*@BUILD:include:src/progbox.js@*/
</script>
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info</label>
<div id="techinfo" class="pageonly" hidden>
<section class="about">
<h2>PM_C1 — Concept</h2>
<div class="ff-tags"><span>Concept</span><span>Idealized device</span><span>Not buildable as drawn</span></div>
<p>The idealized concept (PM_C1): the player as a clean, screenfirst device with no concession to mechanical parts yet.
It's the look we design <i>toward</i> — full setlist navigation, a colour beat display showing every lane,
light/dark theming, and a fullscreen landscape "stage" view. It runs the same engine and program strings as
everything else in the family, but as an <i>idealized</i> object, before deciding which buttons, encoders,
jacks and enclosure actually make it real.</p>
<p>Because it's a concept, there's <b>no bill of materials</b> — there's nothing to source for a render. The
buildable realization of this idea is the <a href="/teacher.html">PM_T1 Teacher</a> (full priced BOM there);
for the smallest practical unit, see the <a href="/micro.html">PM_P1 Practice</a>.</p>
</section>
</div><!-- /#techinfo -->
<p class="ff-link pageonly"><a href="/info-player.html">About this concept →</a></p>
/*@BUILD:include:src/footer.html@*/
</body>

View file

@ -75,80 +75,7 @@
/*@BUILD:include:src/progbox.html@*/
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (dimensions, BOM, embedding)</label>
<div id="techinfo" class="pageonly" hidden>
<section class="about">
<h2>PM_D1 — Display</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Display piece</span><span>~$41 oneoff</span></div>
<p>A metronome as an object: the silhouette of a classic pyramid windup unit, but the swinging pendulum is
pure <b>RGB light</b>. The whole bar is the display — every lane's subdivisions &amp; accents ride along its
length as moving points of light (all meters combined), a printed tempo scale runs up the vertical axis,
and a sliding <b>weight</b> sets the tempo just like the mechanical original.</p>
<p>It's a beautiful, glanceable tempo reference for the shelf, the studio, or a shop window: accents glow
amber, normal steps cyan, ghosts soft violet, and the pendulum eases to each beat exactly as a weighted rod
would. It runs the same grooves as everything else (load any program string), plays the click through a
small speaker, and is powered over USBC with a second "thru" port to daisychain. There's no power switch —
the real unit starts when you lift it from its holder / set it swinging. No instrument I/O; it's a showpiece.</p>
</section>
<div class="dview">
<p class="cap">Dimensions &amp; profile — ≈ 4.7 × 7.1 × 3.1 in (120 × 180 × 80 mm), a truncatedpyramid plinth</p>
<div class="drow">
<div class="dvy">↕ 7.1 in (180 mm)</div>
<div class="dschem" style="height:184px">
<span class="scap">Front</span>
<div style="position:absolute; inset:6px; clip-path:polygon(34% 2%, 66% 2%, 93% 98%, 7% 98%);
background:linear-gradient(180deg,#2c2e34,#15171b); border:1px solid #33363c;"></div>
<div style="position:absolute; left:calc(50% - 4px); top:24px; width:8px; height:120px; border-radius:4px;
background:linear-gradient(180deg,#33d0ff,#178fb0); box-shadow:0 0 10px #33d0ff;"></div>
<div class="jl" style="left:0; right:0; bottom:5px">RGBlight pendulum bar + tempo scale</div>
</div>
</div>
<div class="dvx">↔ 4.7 in (120 mm) base</div>
<div class="drow" style="margin-top:12px">
<div class="dvy">↕ 7.1 in (180 mm)</div>
<div class="dschem" style="height:184px; max-width:200px">
<span class="scap">Side</span>
<div style="position:absolute; inset:6px; clip-path:polygon(40% 2%, 60% 2%, 86% 98%, 14% 98%);
background:linear-gradient(180deg,#26282d,#141519); border:1px solid #33363c;"></div>
<div class="jk u" style="left:calc(50% - 7px); bottom:14px; top:auto"></div>
<div class="jl" style="left:0; right:0; bottom:1px">USBC in base</div>
</div>
</div>
<div class="dvx">↔ 3.1 in (80 mm) deep</div>
</div>
<details class="spec pageonly">
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a USBCpowered RP2040 display piece driving addressable RGB light.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">RGB light</td></tr>
<tr><td class="part">Addressable RGB LEDs (WS2812B) <span class="spec">— a strip down the pendulum bar, ~40 px</span></td><td class="q">1</td><td class="c">5</td></tr>
<tr><td class="part">Frosted acrylic diffuser / lightguide <span class="spec">— the glowing pendulum bar</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr class="grp"><td colspan="3">Audio</td></tr>
<tr><td class="part">MAX98357A I²S amp + small speaker <span class="spec">— the click</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Power &amp; build</td></tr>
<tr><td class="part">2× USBC (data+power &amp; powerthru) + PWR LED <span class="spec">— daisychain</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Tilt / lift sensor (accelerometer) <span class="spec">— starts when lifted from its holder</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">Passives, wire</td><td class="q"></td><td class="c">2</td></tr>
<tr><td class="part">Pyramid enclosure <span class="spec">— cast/CNC aluminium or hardwood, frosted front panel</span></td><td class="q">1</td><td class="c">14</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $41</td></tr>
</tbody>
</table>
</div>
</details>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</div><!-- /#techinfo -->
<p class="ff-link pageonly"><a href="/info-showcase.html">Purpose, dimensions &amp; bill of materials →</a></p>
</main>
/*@BUILD:include:src/footer.html@*/
@ -226,15 +153,11 @@ function drawBody(){
g.beginPath(); g.moveTo(tlx,topY); g.lineTo(trx,topY); g.lineTo(brx,botY); g.lineTo(blx,botY); g.closePath();
g.fillStyle=grd; g.fill(); g.lineWidth=1.5; g.strokeStyle="rgba(255,255,255,.06)"; g.stroke();
g.beginPath(); g.moveTo(tlx,topY); g.lineTo(blx,botY); g.lineWidth=2; g.strokeStyle="rgba(255,255,255,.05)"; g.stroke();
// proper VARASYS logo (wordmark image) + tagline + model
const lw=60, lh=Math.round(lw*82/304), lx=CW/2-lw/2, ly=15;
// official VARASYS logo (the "Simplifying Complexity" tagline is baked into the image) + model
const lw=92, lh=Math.round(lw*82/304), lx=CW/2-lw/2, ly=14;
if(logoReady) g.drawImage(LOGO, lx, ly, lw, lh);
g.textAlign="center";
g.fillStyle="#8f9aa6"; g.font="600 5px 'Segoe UI',Roboto,Arial,sans-serif"; g.globalAlpha=.85;
try{ g.letterSpacing="1.4px"; }catch(e){}
g.fillText("SIMPLIFYING COMPLEXITY", CW/2, ly+lh+7);
try{ g.letterSpacing="0px"; }catch(e){} g.globalAlpha=1;
g.fillStyle="#aab2bc"; g.font="600 7px 'Segoe UI',Roboto,Arial,sans-serif"; g.fillText("PM_D1 DISPLAY", CW/2, ly+lh+17);
g.fillStyle="#aab2bc"; g.font="600 7px 'Segoe UI',Roboto,Arial,sans-serif"; g.fillText("PM_D1 DISPLAY", CW/2, ly+lh+11);
}
function drawPendulum(){

View file

@ -11,18 +11,16 @@ body {
-webkit-font-smoothing: antialiased;
}
/* ---- VARASYS brand lockup: wordmark + "Simplifying Complexity" tagline beneath ---- */
.brand { display:inline-flex; flex-direction:column; align-items:stretch; flex:0 0 auto; gap:2px; text-decoration:none; }
.brand-logo { height:28px; width:auto; display:block; }
/* ---- VARASYS brand lockup (the official logo PNGs already bake in the
"Simplifying Complexity" tagline dark variant for dark themes, light for light) ---- */
.brand { display:inline-flex; align-items:center; flex:0 0 auto; text-decoration:none; }
.brand-logo { height:34px; width:auto; display:block; }
.brand-light { display:none; }
:root[data-theme="light"] .brand-dark { display:none; }
:root[data-theme="light"] .brand-light { display:block; }
.brand-tag { font-size:7px; line-height:1; letter-spacing:.26em; text-transform:uppercase; text-align:center;
color:var(--muted,#7f8b9a); white-space:nowrap; }
/* on-device silkscreen brand lockup (wordmark image + tagline) — used in device brandrows */
.dev-lock { display:inline-flex; flex-direction:column; align-items:stretch; gap:1px; }
.dev-logo { display:block; width:auto; height:14px; }
.dev-tag { font-size:5px; line-height:1; letter-spacing:.16em; text-transform:uppercase; text-align:center; opacity:.8; white-space:nowrap; }
/* on-device silkscreen brand (official logo image, tagline included) — used in device brandrows */
.dev-lock { display:inline-flex; align-items:center; }
.dev-logo { display:block; width:auto; height:20px; }
.site-head { width:100%; max-width:980px; margin:0 auto; display:flex; align-items:center;
justify-content:space-between; gap:10px 16px; flex-wrap:wrap; }
.head-left { display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
@ -84,6 +82,17 @@ details.spec .spec-body { padding:2px 16px 16px; }
.ff-title { font-size:20px; margin:6px 0 2px; text-align:center; color:var(--txt,#c7d0db); }
.ff-sum { max-width:60ch; margin:0 auto; text-align:center; color:var(--muted,#7f8b9a); font-size:13.5px; line-height:1.55; }
[data-embed] .ff-title, [data-embed] .ff-sum { display:none !important; }
/* link from the lean device page out to its info page (specs / dimensions / BOM) */
.ff-link { text-align:center; margin:16px auto 0; font-size:13px; }
.ff-link a { font-weight:600; }
/* ---- info-<device>.html: the embedded live widget at the top of the spec page ---- */
.infoview { width:100%; max-width:760px; margin:18px auto 0; border:1px solid var(--panel-bd,#2a313c);
border-radius:14px; overflow:hidden; background:var(--field-bg,#0e1116); }
.iv-bar { display:flex; align-items:center; justify-content:space-between; gap:10px; padding:8px 12px;
border-bottom:1px solid var(--panel-bd,#2a313c); font-size:12px; color:var(--muted,#7f8b9a); }
.iv-bar b { color:var(--txt,#c7d0db); }
.infoview iframe { display:block; width:100%; height:440px; border:0; background:var(--field-bg,#0e1116); transition:height .15s; }
/* ---- per-device program I/O box (plain view) ---- */
.progbox { width:100%; max-width:620px; margin:14px auto 0; display:flex; align-items:center; gap:9px; flex-wrap:wrap;
@ -117,10 +126,3 @@ details.spec .spec-body { padding:2px 16px 16px; }
.dschem .jk { position:absolute; width:12px; height:12px; border-radius:50%; border:2px solid #5b6470; background:radial-gradient(circle at 40% 34%,#333a44,#07090c 72%); }
.dschem .jk.u { width:14px; height:6px; border-radius:3px; }
.dschem .jl { position:absolute; font-size:7px; color:var(--silk,#aab2bc); letter-spacing:.03em; text-transform:uppercase; opacity:.85; text-align:center; line-height:1.1; }
/* ---- "Show info" toggle + technical section ---- */
.info-toggle { display:flex; align-items:center; justify-content:center; gap:8px; margin:18px auto 0; max-width:620px;
font-size:13px; color:var(--muted,#7f8b9a); cursor:pointer; }
.info-toggle input { width:15px; height:15px; cursor:pointer; }
[data-embed] .info-toggle { display:none !important; }
#techinfo[hidden] { display:none; }

View file

@ -4,7 +4,6 @@
<a class="brand" href="/" title="VARASYS — Simplifying Complexity">
<img class="brand-logo brand-dark" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" />
<img class="brand-logo brand-light" src="data:image/png;base64,@BUILD:logo-light@" alt="VARASYS — Simplifying Complexity" />
<span class="brand-tag">Simplifying Complexity</span>
</a>
<nav class="site-nav">
<a href="/">Concepts</a>

7
src/infoembed.html Normal file
View file

@ -0,0 +1,7 @@
<!-- Shared info-page live widget — assembled into each info-<device>.html by build.sh.
The host page sets window.INFO_DEVICE = {file, name}; infoembed.js wires the iframe
to <device>.html?embed=1 (default set lists) and auto-sizes it to the widget. -->
<div class="infoview">
<div class="iv-bar"><span class="iv-name" id="ivName"></span><a class="iv-open" id="ivOpen" target="_blank" rel="noopener">Open the full device ↗</a></div>
<iframe id="ifr" title="VARASYS PolyMeter — live widget" allow="autoplay"></iframe>
</div>

21
src/infoembed.js Normal file
View file

@ -0,0 +1,21 @@
/* Info-page live widget loader assembled into each info-<device>.html by build.sh.
The host page sets window.INFO_DEVICE = {file, name}. This builds the embedded widget
(<device>.html?embed=1, which loads the default set lists) and auto-sizes the iframe
from the {type:'varasys-h'} height the widget posts back. Defers to DOM-ready. */
(function () {
function init() {
var d = window.INFO_DEVICE || { file: "/editor.html", name: "PolyMeter" };
var ifr = document.getElementById("ifr"),
nm = document.getElementById("ivName"),
op = document.getElementById("ivOpen");
if (nm) nm.innerHTML = "<b>" + d.name + "</b>";
if (op) op.href = d.file;
if (ifr) ifr.src = d.file + "?embed=1";
}
addEventListener("message", function (e) {
var ifr = document.getElementById("ifr");
if (!e.data || !ifr || e.source !== ifr.contentWindow) return;
if (e.data.type === "varasys-h" && typeof e.data.h === "number") ifr.style.height = e.data.h + "px";
});
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", init); else init();
})();

View file

@ -1,9 +1,10 @@
/* Per-device program I/O + "Show info" toggle assembled into each form-factor page.
/* Per-device program I/O assembled into each form-factor page (the thin widget).
Uses the engine codec (patchToSetup / setupToPatch / codeToSetlist) for decode + lint.
Host page provides: window.currentProgramString() and window.loadProgramString(plain).
Exposes window.progRefresh() call it after the device's program changes. When the
page is embedded it posts {type:'varasys-prog'} to the parent instead of touching the box.
Defers to DOM-ready so the box/toggle/techinfo are found wherever they sit on the page. */
(Specs / dimensions / BOM live on the separate info-<device>.html page, not here.)
Defers to DOM-ready so the box is found wherever it sits on the page. */
(function () {
var embedded = document.documentElement.dataset.embed === "1";
var box, msg, editing = false;
@ -48,15 +49,6 @@
try { navigator.clipboard.writeText(box.value); copyBtn.textContent = "Copied!"; setTimeout(function () { copyBtn.textContent = "Copy"; }, 1200); } catch (e) { box.select(); }
});
}
// "Show info" toggle — reveals the technical section (#techinfo + any .tech); ?info=1 opens it checked
var tog = document.getElementById("infoToggle"), tech = document.getElementById("techinfo");
if (tog) {
var extra = document.querySelectorAll(".tech");
var apply = function (on) { if (tech) tech.hidden = !on; for (var i = 0; i < extra.length; i++) extra[i].hidden = !on; };
var open = /[?&]info=1/.test(location.search);
tog.checked = open; apply(open);
tog.addEventListener("change", function () { apply(tog.checked); });
}
window.progRefresh();
}
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", init); else init();

View file

@ -59,7 +59,7 @@
.jk b{ font-size:6.5px; font-weight:700; color:var(--silk); letter-spacing:.03em; text-transform:uppercase; opacity:.9; text-align:center; line-height:1.2 }
.brandrow{ display:flex; align-items:center; justify-content:space-between; margin:13px 16px 10px }
.dev-logo{ height:13px }
.dev-logo{ height:22px }
.silk{ display:flex; align-items:center; gap:7px; color:var(--silk) }
.silk .model{ font-size:8.5px; text-transform:uppercase; letter-spacing:.16em; opacity:.85 }
.pwr{ display:flex; align-items:center; gap:5px; font-size:7.5px; color:var(--silk); text-transform:uppercase; letter-spacing:.12em; opacity:.85 }
@ -126,7 +126,7 @@
</div>
<div class="brandrow">
<div class="silk"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS" /><span class="dev-tag">Simplifying Complexity</span></span><span class="model">PM_S1 Stage</span></div>
<div class="silk"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" /></span><span class="model">PM_S1 Stage</span></div>
<div class="pwr"><span class="dot"></span>USBC&nbsp;PWR</div>
</div>
@ -306,87 +306,7 @@ window.loadProgramString = function(plain){ var s=patchToSetup(plain); tracks=[{
/*@BUILD:include:src/progbox.js@*/
</script>
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (dimensions, BOM, embedding)</label>
<div id="techinfo" class="pageonly" hidden>
<section class="about">
<h2>PM_S1 — Stage</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Footpedal stompbox</span><span>~$52 oneoff</span></div>
<p>A footoperated polymeter stompbox for the stage: drive it handsfree with two heavy footswitches and an
expression pedal, read it off the floor from the big RGB beat light, and run your instrument through it with
the click mixed in. (For a desk/lesson unit with a full screen, see the <a href="/teacher.html">Teacher</a>.)</p>
<p>The controls are built for feet: the <b>left footswitch</b> taps tempo (hold to start/stop), the <b>right</b>
steps through your set list (hold for previous), and a <b>1/4″ expressionpedal input</b> sweeps tempo on the
fly. Your instrument passes through (1/4″ in) with the click summed in the <b>analog domain</b> and sent to a
balanced 1/4″ TRS out. Powered over USBC — with a second USBC <b>"thru"</b> port so several pedals
daisychain off one charger or power bank.</p>
</section>
<div class="dview">
<p class="cap">Dimensions &amp; layout — ≈ 4.7 × 3.7 × 1.5 in (120 × 93 × 38 mm), a 1590BBstyle stompbox</p>
<div class="drow">
<div class="dvy">↕ 3.7 in (93 mm)</div>
<div class="dschem" style="height:150px">
<span class="scap">Front</span>
<div class="scr" style="left:18%; right:18%; top:22px; height:34px"></div>
<div class="ctl" style="left:calc(50% - 15px); top:64px; width:30px; height:30px"></div>
<div class="ctl" style="left:20%; top:100px; width:34px; height:34px"></div>
<div class="ctl" style="left:calc(80% - 34px); top:100px; width:34px; height:34px"></div>
<div class="jl" style="left:0; right:0; bottom:5px">angled TFT · RGB beat light · Tap + Next footswitches</div>
</div>
</div>
<div class="dvx">↔ 4.7 in (120 mm) wide</div>
<div class="drow" style="margin-top:12px">
<div class="dvy">↕ 1.5 in (38 mm)</div>
<div class="dschem" style="height:56px">
<span class="scap">Top edge — I/O</span>
<div class="jk" style="left:7%; top:18px"></div><div class="jk" style="left:22%; top:18px"></div>
<div class="jk" style="left:37%; top:18px"></div><div class="jk" style="left:52%; top:18px"></div>
<div class="jk u" style="left:68%; top:21px"></div><div class="jk u" style="left:83%; top:21px"></div>
<div class="jl" style="left:0; right:0; bottom:4px">Trig · Inst In · Out TRS · Exp · USBC · USBC thru</div>
</div>
</div>
<div class="dvx">↔ 4.7 in (120 mm)</div>
</div>
<details class="spec pageonly">
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a footoperated RP2040 stompbox (USBC, dualport) with analog click injection.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain &amp; display</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">1.3″ IPS TFT, ST7789 <span class="spec">— SPI; angled BPM / item readout</span></td><td class="q">1</td><td class="c">6</td></tr>
<tr><td class="part">Highbright diffused RGB beat indicator <span class="spec">— floorreadable</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Controls</td></tr>
<tr><td class="part">Heavyduty momentary footswitch (softtouch) <span class="spec">— Tap · Next</span></td><td class="q">2</td><td class="c">6</td></tr>
<tr><td class="part">1/4″ expressionpedal input jack (TRS) <span class="spec">— tempo sweep</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Audio — analog click injection</td></tr>
<tr><td class="part">PCM5102A I²S DAC <span class="spec">— linelevel click</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Dual opamp, NE5532 / OPA2134 <span class="spec">— hiZ instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr><td class="part">Balanced line driver, DRV134 <span class="spec">— → 1/4″ TRS out</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Connectors &amp; power</td></tr>
<tr><td class="part">1/4″ jack <span class="spec">— Inst In (TS) · Out (TRS) · Trig In (TS)</span></td><td class="q">3</td><td class="c">3</td></tr>
<tr><td class="part">2× USBC (data+power &amp; powerthru) + powerpath/protection + PWR LED <span class="spec">— daisychain pedals</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr class="grp"><td colspan="3">Build</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">5</td></tr>
<tr><td class="part">Passives, headers, wire <span class="spec">— R/C for the analog stage + decoupling</span></td><td class="q"></td><td class="c">3</td></tr>
<tr><td class="part">Diecast aluminium stompbox (Hammond 1590BBstyle) <span class="spec">— beadblasted, matteblack Type II anodise, laseretched</span></td><td class="q">1</td><td class="c">12</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $52</td></tr>
</tbody>
</table>
<p class="sub" style="margin-top:12px">No builtin speaker — the Stage feeds your amp / PA. The click is summed in
the <b>analog domain</b> (hiZ instrument buffer + DAC → balanced line driver), so your instrument is never
redigitised (no added latency).</p>
</div>
</details>
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code>&lt;div&gt;</code> + a script —
see <a href="/embed.html">the embed docs</a>.</p>
</div><!-- /#techinfo -->
<p class="ff-link pageonly"><a href="/info-stage.html">Purpose, dimensions &amp; bill of materials →</a></p>
/*@BUILD:include:src/footer.html@*/
</body>

View file

@ -89,7 +89,7 @@
}
.brandrow{ display:flex; align-items:flex-end; justify-content:space-between; margin:0 2px 12px; }
.silk{ display:flex; align-items:center; gap:8px; color:var(--silk); letter-spacing:.04em }
.dev-logo{ height:16px }
.dev-logo{ height:24px }
.silk .model{ font-size:10px; text-transform:uppercase; letter-spacing:.18em; opacity:.8 }
.pwr{ display:flex; align-items:center; gap:6px; font-size:9px; color:var(--silk); text-transform:uppercase; letter-spacing:.14em; opacity:.85 }
.pwr .dot{ width:7px; height:7px; border-radius:50%; background:#2fe07a; box-shadow:0 0 7px #2fe07a }
@ -231,7 +231,7 @@
<div class="device">
<div class="brandrow">
<div class="silk"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS" /><span class="dev-tag">Simplifying Complexity</span></span><span class="model">PM_T1 Teacher</span></div>
<div class="silk"><span class="dev-lock"><img class="dev-logo" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" /></span><span class="model">PM_T1 Teacher</span></div>
<div class="pwr"><span class="dot"></span>PWR</div>
</div>
@ -278,59 +278,7 @@
</div><!-- /col-left -->
</div><!-- /cols -->
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (front/top views, dimensions, BOM, embedding)</label>
<div id="techinfo" class="pageonly" hidden>
<section class="about">
<h2>PM_T1 — Teacher</h2>
<div class="ff-tags"><span class="hw">Hardware</span><span>Studio / lesson console</span><span>~$59 oneoff</span></div>
<p>The fullfeature desktop console: a colour readout of every lane, fast setlist navigation, and your
instrument running straight through with the click mixed in — the handson unit for a studio desk or a
teaching room, on a nonreflective matteblack case. (For handsfree live use, see the footoperated
<a href="/stage.html">Stage</a> stompbox.)</p>
<p>Topmounted 1/4″ jacks keep cabling tidy; the metronome click is summed into the signal in the
<b>analog domain</b> (no redigitising, no added latency) and sent to a balanced 1/4″ TRS output for the
desk or interface, plus a small monitor speaker. Powered over USBC — a wall adapter or a power bank. The
colour TFT shows tempo, the item name and all lane patterns; arcade buttons + a recessed thumbroller make
it quick to drive while you teach or track.</p>
</section>
<details class="spec pageonly">
<summary>Spec &amp; bill of materials</summary>
<div class="spec-body">
<p class="sub">Rough parts list — a desk/studio RP2040 build (USBC powered) with analog click injection.
Ballpark oneoff prices (USD); cheaper at volume.</p>
<table class="bom">
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
<tbody>
<tr class="grp"><td colspan="3">Brain &amp; display</td></tr>
<tr><td class="part">RP2040 board, USBC <span class="spec">— e.g. Waveshare RP2040Zero / Picoclone</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">2.0″ 320×240 IPS TFT, ST7789 <span class="spec">— SPI</span></td><td class="q">1</td><td class="c">8</td></tr>
<tr class="grp"><td colspan="3">Controls</td></tr>
<tr><td class="part">Arcade pushbutton, 24 mm <span class="spec">— Prev · Next · Tap</span></td><td class="q">3</td><td class="c">4</td></tr>
<tr><td class="part">Arcade pushbutton, 30 mm <span class="spec">— Play</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr><td class="part">Detented encoder (EC11 / PEC12) + sidemount thumbroller <span class="spec">— recessed; nothing to snap off</span></td><td class="q">1</td><td class="c">2</td></tr>
<tr class="grp"><td colspan="3">Audio — analog click injection</td></tr>
<tr><td class="part">PCM5102A I²S DAC <span class="spec">— linelevel click</span></td><td class="q">1</td><td class="c">3</td></tr>
<tr><td class="part">Dual opamp, NE5532 / OPA2134 <span class="spec">— hiZ instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr><td class="part">Balanced line driver, DRV134 <span class="spec">— (or crosscoupled opamp) → 1/4″ TRS out</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr><td class="part">PAM8302A mono ClassD + 8 Ω 2 W speaker <span class="spec">— monitor</span></td><td class="q">1</td><td class="c">4</td></tr>
<tr class="grp"><td colspan="3">Connectors &amp; power</td></tr>
<tr><td class="part">1/4″ jack <span class="spec">— Inst In (TS) · Out (TRS) · Trig In (TS)</span></td><td class="q">3</td><td class="c">3</td></tr>
<tr><td class="part">USBC bus power (5 V) + PWR LED <span class="spec">— wall adapter or power bank; same port carries config; no battery</span></td><td class="q">1</td><td class="c">1</td></tr>
<tr class="grp"><td colspan="3">Build</td></tr>
<tr><td class="part">Custom PCB (or perfboard)</td><td class="q">1</td><td class="c">5</td></tr>
<tr><td class="part">Passives, headers, wire <span class="spec">— R/C for the analog stage + decoupling</span></td><td class="q"></td><td class="c">3</td></tr>
<tr><td class="part">Diecast aluminium enclosure (Hammond 1590style) <span class="spec">— beadblasted, matteblack Type II anodise, laseretched legends</span></td><td class="q">1</td><td class="c">12</td></tr>
<tr class="total"><td>Total (oneoff)</td><td class="q"></td><td class="c">≈ $56</td></tr>
</tbody>
</table>
<p class="sub" style="margin-top:12px">Audio is summed in the <b>analog domain</b>: the DAC's click is mixed with a
highimpedance buffer of the 1/4″ instrument input, then fed to the balanced line driver (1/4″ TRS out) and the
monitor amp — so your instrument is never redigitised (no added latency).</p>
</div>
</details>
</div><!-- /#techinfo -->
<p class="ff-link pageonly"><a href="/info-teacher.html">Purpose, spec &amp; bill of materials →</a></p>
<script>
const APP_VERSION = "v0.0.1-dev";