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:
parent
f622e58a49
commit
9e5c79b3b2
20 changed files with 703 additions and 355 deletions
File diff suppressed because one or more lines are too long
3
build.sh
3
build.sh
|
|
@ -30,7 +30,8 @@ def build(name):
|
||||||
return out.stat().st_size
|
return out.stat().st_size
|
||||||
|
|
||||||
for name in ("index.html","editor.html","player.html","teacher.html","stage.html","micro.html","showcase.html",
|
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))
|
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
|
pathlib.Path("dist/embed.js").write_text(pathlib.Path("embed.js").read_text()) # loader, served as-is
|
||||||
print("copied embed.js")
|
print("copied embed.js")
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,16 @@ fi
|
||||||
# stamp the version into the built copy only (source stays clean)
|
# stamp the version into the built copy only (source stays clean)
|
||||||
echo "deployed v$BUILD -> $DEST_DIR"
|
echo "deployed v$BUILD -> $DEST_DIR"
|
||||||
for f in index.html editor.html player.html teacher.html stage.html micro.html showcase.html \
|
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"
|
sed "s|const APP_VERSION = \"[^\"]*\";|const APP_VERSION = \"$BUILD\";|" "$DIST_DIR/$f" > "$DEST_DIR/$f"
|
||||||
echo " $f ($(stat -c '%s' "$DEST_DIR/$f") bytes)"
|
echo " $f ($(stat -c '%s' "$DEST_DIR/$f") bytes)"
|
||||||
done
|
done
|
||||||
cp "$DIST_DIR/embed.js" "$DEST_DIR/embed.js"; echo " embed.js ($(stat -c '%s' "$DEST_DIR/embed.js") bytes)"
|
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/player-asbuilt.html" # renamed to teacher.html
|
||||||
rm -f "$DEST_DIR/concepts.html" # Concepts is now the landing (/)
|
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
|
# info-*.html are first-class pages again: each form factor has a lean widget page
|
||||||
# (stage.html / info-stage.html are deployed again — now the foot-pedal Stage stompbox)
|
# (<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),
|
# If real audio samples are added later (see the plan's GM-sample note),
|
||||||
# sync that directory too.
|
# sync that directory too.
|
||||||
|
|
|
||||||
11
index.html
11
index.html
|
|
@ -43,7 +43,8 @@
|
||||||
.pane .chip.hw{ color:var(--cyan); border-color:rgba(10,179,247,.45); }
|
.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 .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 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: the live, selected device */
|
||||||
.viewport{ margin-top:16px; border:1px solid var(--panel-bd); border-radius:14px; overflow:hidden; background:var(--field-bg); }
|
.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="panes" id="panes"></div>
|
||||||
|
|
||||||
<div class="viewport">
|
<div class="viewport">
|
||||||
<div class="vp-bar"><span id="vpName"><b>PM_E‑1 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_E‑1 Editor</b></span><span><a id="vpInfo" href="/info-editor.html" target="_blank" rel="noopener">Specs & info ⓘ</a> · <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>
|
<iframe id="vp" title="PolyMeter — live viewport" allow="autoplay"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -154,7 +155,10 @@ function renderPanes() {
|
||||||
<div class="pane" data-key="${v.key}" role="button" tabindex="0">
|
<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>
|
<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>
|
<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 & info ⓘ</a>
|
||||||
|
</div>
|
||||||
</div>`).join("");
|
</div>`).join("");
|
||||||
$("panes").querySelectorAll(".pane").forEach((el) => {
|
$("panes").querySelectorAll(".pane").forEach((el) => {
|
||||||
const k = el.dataset.key;
|
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));
|
$("panes").querySelectorAll(".pane").forEach((p) => p.classList.toggle("active", p.dataset.key === key));
|
||||||
$("vpName").innerHTML = "<b>" + v.name + "</b>";
|
$("vpName").innerHTML = "<b>" + v.name + "</b>";
|
||||||
$("vpOpen").href = v.file;
|
$("vpOpen").href = v.file;
|
||||||
|
$("vpInfo").href = v.file.replace("/", "/info-");
|
||||||
vp.style.height = (v.h || 440) + "px";
|
vp.style.height = (v.h || 440) + "px";
|
||||||
vp.src = v.file + "?embed=1" + (prog ? "#p=" + encodeURIComponent(prog) : "");
|
vp.src = v.file + "?embed=1" + (prog ? "#p=" + encodeURIComponent(prog) : "");
|
||||||
if (prog && !userEditing) box.value = prog;
|
if (prog && !userEditing) box.value = prog;
|
||||||
|
|
|
||||||
68
info-editor.html
Normal file
68
info-editor.html
Normal 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_E‑1 PolyMeter Editor — what it is</title>
|
||||||
|
<meta name="description" content="PM_E‑1 PolyMeter Editor — the web workbench for the family: stack independent meter lanes with their own subdivision, drum voice, per‑step accents/ghosts/mutes, swing, polyrhythm, set lists and per‑lane 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_E‑1 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 per‑step <b>accents, ghosts and mutes</b>, plus swing, ratio polyrhythm, set lists and a
|
||||||
|
per‑lane <b>dB gain</b>. It's zero‑install — 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 share‑language. 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><div></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_E‑1 PolyMeter Editor" };
|
||||||
|
/*@BUILD:include:src/infoembed.js@*/
|
||||||
|
/*@BUILD:include:src/chrome.js@*/
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
129
info-micro.html
Normal file
129
info-micro.html
Normal 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_P‑1 Practice — purpose, dimensions & bill of materials</title>
|
||||||
|
<meta name="description" content="PM_P‑1 Practice — a long, narrow inline practice bar: one clickable thumb‑roller, amber 14‑segment display, analog instrument pass‑through 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_P‑1 Practice</h1>
|
||||||
|
<p class="sub">A long, narrow inline practice bar — patch it into your signal, drive everything from one clickable thumb‑roller, and read tempo and track names off an amber 14‑segment 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 one‑off</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 thumb‑roller does everything (roll = tempo, press = start/stop,
|
||||||
|
hold + roll = switch track), and an amber 14‑segment 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
|
||||||
|
USB‑C — a wall adapter for a permanent practice‑space 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 & 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">14‑seg display</div>
|
||||||
|
<div class="jl" style="left:58%; bottom:5px">thumb‑roller</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">USB‑C · 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 & bill of materials</summary>
|
||||||
|
<div class="spec-body">
|
||||||
|
<p class="sub">Rough parts list — a USB‑C‑powered RP2040 inline bar with analog click injection.
|
||||||
|
Ballpark one‑off 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 & display</td></tr>
|
||||||
|
<tr><td class="part">RP2040 board, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
|
||||||
|
<tr><td class="part">4‑char 14‑segment alphanumeric LED + I²C driver <span class="spec">— amber; HT16K33. Shows BPM & 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 thumb‑roller <span class="spec">— EC11 encoder + roller wheel · roll / press / hold‑roll</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">— line‑level click</span></td><td class="q">1</td><td class="c">3</td></tr>
|
||||||
|
<tr><td class="part">Dual op‑amp, NE5532 / OPA2134 <span class="spec">— hi‑Z instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
|
||||||
|
<tr><td class="part">PAM8302A mono Class‑D + 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 & 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">USB‑C 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">— bead‑blasted, matte‑black anodised</span></td><td class="q">1</td><td class="c">8</td></tr>
|
||||||
|
<tr class="total"><td>Total (one‑off)</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><div></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_P‑1 Practice" };
|
||||||
|
/*@BUILD:include:src/infoembed.js@*/
|
||||||
|
/*@BUILD:include:src/chrome.js@*/
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
68
info-player.html
Normal file
68
info-player.html
Normal 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_C‑1 Concept — the idealized player</title>
|
||||||
|
<meta name="description" content="PM_C‑1 Concept — the idealized, screen‑first player render: full set‑list 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_C‑1 Concept</h1>
|
||||||
|
<p class="sub">The idealized concept render — a clean, screen‑first player with a colour beat display, set‑list 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_C‑1): the player as a clean, screen‑first device with no concession to mechanical parts yet.
|
||||||
|
It's the look we design <i>toward</i> — full set‑list 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_T‑1 Teacher</a> (full priced BOM there);
|
||||||
|
for the smallest practical unit, see the <a href="/info-micro.html">PM_P‑1 Practice</a>.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code><div></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_C‑1 Concept" };
|
||||||
|
/*@BUILD:include:src/infoembed.js@*/
|
||||||
|
/*@BUILD:include:src/chrome.js@*/
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
123
info-showcase.html
Normal file
123
info-showcase.html
Normal 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_D‑1 Display — purpose, dimensions & bill of materials</title>
|
||||||
|
<meta name="description" content="PM_D‑1 Display — a pyramid display‑piece 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_D‑1 Display</h1>
|
||||||
|
<p class="sub">A display‑piece metronome — the pendulum is an RGB light bar that combines every lane's subdivisions & 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 one‑off</span></div>
|
||||||
|
<p>A metronome as an object: the silhouette of a classic pyramid wind‑up unit, but the swinging pendulum is
|
||||||
|
pure <b>RGB light</b>. The whole bar is the display — every lane's subdivisions & 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 USB‑C with a second "thru" port to daisy‑chain. 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 & profile — ≈ 4.7 × 7.1 × 3.1 in (120 × 180 × 80 mm), a truncated‑pyramid 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">RGB‑light 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">USB‑C in base</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dvx">↔ 3.1 in (80 mm) deep</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<details class="spec" open>
|
||||||
|
<summary>Spec & bill of materials</summary>
|
||||||
|
<div class="spec-body">
|
||||||
|
<p class="sub">Rough parts list — a USB‑C‑powered RP2040 display piece driving addressable RGB light.
|
||||||
|
Ballpark one‑off 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, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero</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 / light‑guide <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 & build</td></tr>
|
||||||
|
<tr><td class="part">2× USB‑C (data+power & power‑thru) + PWR LED <span class="spec">— daisy‑chain</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 (one‑off)</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><div></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_D‑1 Display" };
|
||||||
|
/*@BUILD:include:src/infoembed.js@*/
|
||||||
|
/*@BUILD:include:src/chrome.js@*/
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
130
info-stage.html
Normal file
130
info-stage.html
Normal 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_S‑1 Stage — purpose, dimensions & bill of materials</title>
|
||||||
|
<meta name="description" content="PM_S‑1 Stage — a foot‑pedal polymeter stompbox: hands‑free footswitches, expression‑pedal tempo, a floor‑readable RGB beat light, analog instrument pass‑through. 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_S‑1 Stage</h1>
|
||||||
|
<p class="sub">A foot‑pedal polymeter stompbox — hands‑free footswitches, expression‑pedal tempo, a floor‑readable RGB beat light, and analog instrument pass‑through 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>Foot‑pedal stompbox</span><span>~$52 one‑off</span></div>
|
||||||
|
<p>A foot‑operated polymeter stompbox for the stage: drive it hands‑free 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″ expression‑pedal 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 USB‑C — with a second USB‑C <b>"thru"</b> port so several pedals
|
||||||
|
daisy‑chain off one charger or power bank.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="dview">
|
||||||
|
<p class="cap">Dimensions & layout — ≈ 4.7 × 3.7 × 1.5 in (120 × 93 × 38 mm), a 1590BB‑style 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 · USB‑C · USB‑C thru</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dvx">↔ 4.7 in (120 mm)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<details class="spec" open>
|
||||||
|
<summary>Spec & bill of materials</summary>
|
||||||
|
<div class="spec-body">
|
||||||
|
<p class="sub">Rough parts list — a foot‑operated RP2040 stompbox (USB‑C, dual‑port) with analog click injection.
|
||||||
|
Ballpark one‑off 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 & display</td></tr>
|
||||||
|
<tr><td class="part">RP2040 board, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero</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">High‑bright diffused RGB beat indicator <span class="spec">— floor‑readable</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">Heavy‑duty momentary footswitch (soft‑touch) <span class="spec">— Tap · Next</span></td><td class="q">2</td><td class="c">6</td></tr>
|
||||||
|
<tr><td class="part">1/4″ expression‑pedal 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">— line‑level click</span></td><td class="q">1</td><td class="c">3</td></tr>
|
||||||
|
<tr><td class="part">Dual op‑amp, NE5532 / OPA2134 <span class="spec">— hi‑Z 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 & 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× USB‑C (data+power & power‑thru) + power‑path/protection + PWR LED <span class="spec">— daisy‑chain 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">Die‑cast aluminium stompbox (Hammond 1590BB‑style) <span class="spec">— bead‑blasted, matte‑black Type II anodise, laser‑etched</span></td><td class="q">1</td><td class="c">12</td></tr>
|
||||||
|
<tr class="total"><td>Total (one‑off)</td><td class="q"></td><td class="c">≈ $52</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p class="sub" style="margin-top:12px">No built‑in speaker — the Stage feeds your amp / PA. The click is summed in
|
||||||
|
the <b>analog domain</b> (hi‑Z instrument buffer + DAC → balanced line driver), so your instrument is never
|
||||||
|
re‑digitised (no added latency).</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code><div></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_S‑1 Stage" };
|
||||||
|
/*@BUILD:include:src/infoembed.js@*/
|
||||||
|
/*@BUILD:include:src/chrome.js@*/
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
105
info-teacher.html
Normal file
105
info-teacher.html
Normal 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_T‑1 Teacher — purpose, spec & bill of materials</title>
|
||||||
|
<meta name="description" content="PM_T‑1 Teacher — a full‑feature studio / lesson desk console: a colour TFT of every lane, arcade buttons, a thumb‑roller, and analog instrument pass‑through 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_T‑1 Teacher</h1>
|
||||||
|
<p class="sub">The full‑feature studio / lesson desk console — a colour TFT showing every lane, arcade buttons and a thumb‑roller, 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 one‑off</span></div>
|
||||||
|
<p>The full‑feature desktop console: a colour readout of every lane, fast set‑list navigation, and your
|
||||||
|
instrument running straight through with the click mixed in — the hands‑on unit for a studio desk or a
|
||||||
|
teaching room, on a non‑reflective matte‑black case. (For hands‑free live use, see the foot‑operated
|
||||||
|
<a href="/info-stage.html">Stage</a> stompbox.)</p>
|
||||||
|
<p>Top‑mounted 1/4″ jacks keep cabling tidy; the metronome click is summed into the signal in the
|
||||||
|
<b>analog domain</b> (no re‑digitising, no added latency) and sent to a balanced 1/4″ TRS output for the
|
||||||
|
desk or interface, plus a small monitor speaker. Powered over USB‑C — a wall adapter or a power bank. The
|
||||||
|
colour TFT shows tempo, the item name and all lane patterns; arcade buttons + a recessed thumb‑roller make
|
||||||
|
it quick to drive while you teach or track.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<details class="spec" open>
|
||||||
|
<summary>Spec & bill of materials</summary>
|
||||||
|
<div class="spec-body">
|
||||||
|
<p class="sub">Rough parts list — a desk/studio RP2040 build (USB‑C powered) with analog click injection.
|
||||||
|
Ballpark one‑off 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 & display</td></tr>
|
||||||
|
<tr><td class="part">RP2040 board, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero / Pico‑clone</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) + side‑mount thumb‑roller <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">— line‑level click</span></td><td class="q">1</td><td class="c">3</td></tr>
|
||||||
|
<tr><td class="part">Dual op‑amp, NE5532 / OPA2134 <span class="spec">— hi‑Z 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 cross‑coupled op‑amp) → 1/4″ TRS out</span></td><td class="q">1</td><td class="c">4</td></tr>
|
||||||
|
<tr><td class="part">PAM8302A mono Class‑D + 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 & 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">USB‑C 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">Die‑cast aluminium enclosure (Hammond 1590‑style) <span class="spec">— bead‑blasted, matte‑black Type II anodise, laser‑etched legends</span></td><td class="q">1</td><td class="c">12</td></tr>
|
||||||
|
<tr class="total"><td>Total (one‑off)</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
|
||||||
|
high‑impedance 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 re‑digitised (no added latency).</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code><div></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_T‑1 Teacher" };
|
||||||
|
/*@BUILD:include:src/infoembed.js@*/
|
||||||
|
/*@BUILD:include:src/chrome.js@*/
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
85
micro.html
85
micro.html
|
|
@ -82,7 +82,7 @@
|
||||||
linear-gradient(180deg, #2b2d33, #161719); /* matte anodised graphite */
|
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) }
|
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 }
|
.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{ display:flex; align-items:center; gap:7px; color:var(--silk) }
|
||||||
.silk .model{ font-size:8.5px; text-transform:uppercase; letter-spacing:.16em; opacity:.85 }
|
.silk .model{ font-size:8.5px; text-transform:uppercase; letter-spacing:.16em; opacity:.85 }
|
||||||
.meta{ display:flex; align-items:center; gap:12px }
|
.meta{ display:flex; align-items:center; gap:12px }
|
||||||
|
|
@ -140,7 +140,7 @@
|
||||||
<!-- TOP FACE: display + roller + speaker -->
|
<!-- TOP FACE: display + roller + speaker -->
|
||||||
<div class="face">
|
<div class="face">
|
||||||
<div class="brandrow">
|
<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_P‑1 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_P‑1 Practice</span></div>
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<div class="pwr" title="Powered over USB‑C — wall adapter or power bank"><span class="dot"></span>USB‑C PWR</div>
|
<div class="pwr" title="Powered over USB‑C — wall adapter or power bank"><span class="dot"></span>USB‑C PWR</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -346,86 +346,7 @@ window.loadProgramString = function(plain){ var s=patchToSetup(plain); tracks=[{
|
||||||
/*@BUILD:include:src/progbox.js@*/
|
/*@BUILD:include:src/progbox.js@*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (dimensions, BOM, embedding)</label>
|
<p class="ff-link pageonly"><a href="/info-micro.html">Purpose, dimensions & bill of materials →</a></p>
|
||||||
<div id="techinfo" class="pageonly" hidden>
|
|
||||||
|
|
||||||
<section class="about">
|
|
||||||
<h2>PM_P‑1 — Practice</h2>
|
|
||||||
<div class="ff-tags"><span class="hw">Hardware</span><span>Inline practice bar</span><span>~$35 one‑off</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 thumb‑roller does everything (roll = tempo, press = start/stop,
|
|
||||||
hold + roll = switch track), and an amber 14‑segment 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
|
|
||||||
USB‑C — a wall adapter for a permanent practice‑space 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 & 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">14‑seg display</div>
|
|
||||||
<div class="jl" style="left:58%; bottom:5px">thumb‑roller</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">USB‑C · 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 & bill of materials</summary>
|
|
||||||
<div class="spec-body">
|
|
||||||
<p class="sub">Rough parts list — a USB‑C‑powered RP2040 inline bar with analog click injection.
|
|
||||||
Ballpark one‑off 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 & display</td></tr>
|
|
||||||
<tr><td class="part">RP2040 board, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero</span></td><td class="q">1</td><td class="c">4</td></tr>
|
|
||||||
<tr><td class="part">4‑char 14‑segment alphanumeric LED + I²C driver <span class="spec">— amber; HT16K33. Shows BPM & 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 thumb‑roller <span class="spec">— EC11 encoder + roller wheel · roll / press / hold‑roll</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">— line‑level click</span></td><td class="q">1</td><td class="c">3</td></tr>
|
|
||||||
<tr><td class="part">Dual op‑amp, NE5532 / OPA2134 <span class="spec">— hi‑Z instrument buffer + summing mixer</span></td><td class="q">1</td><td class="c">1</td></tr>
|
|
||||||
<tr><td class="part">PAM8302A mono Class‑D + 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 & 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">USB‑C 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">— bead‑blasted, matte‑black anodised</span></td><td class="q">1</td><td class="c">8</td></tr>
|
|
||||||
<tr class="total"><td>Total (one‑off)</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><div></code> + a script —
|
|
||||||
see <a href="/embed.html">the embed docs</a>.</p>
|
|
||||||
</div><!-- /#techinfo -->
|
|
||||||
|
|
||||||
/*@BUILD:include:src/footer.html@*/
|
/*@BUILD:include:src/footer.html@*/
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
21
player.html
21
player.html
|
|
@ -84,8 +84,7 @@
|
||||||
|
|
||||||
.brandrow{ display:flex; align-items:center; justify-content:space-between; margin:2px 6px 16px; }
|
.brandrow{ display:flex; align-items:center; justify-content:space-between; margin:2px 6px 16px; }
|
||||||
.logo{ display:flex; align-items:center; gap:11px }
|
.logo{ display:flex; align-items:center; gap:11px }
|
||||||
.logo .dev-logo{ height:19px }
|
.logo .dev-logo{ height:26px }
|
||||||
.logo .dev-tag{ color:var(--dmuted) }
|
|
||||||
.logo .model{ color:var(--dmuted); font-size:12px; letter-spacing:.04em }
|
.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{ 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 }
|
.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>
|
<span class="screw bl"></span><span class="screw br"></span>
|
||||||
|
|
||||||
<div class="brandrow">
|
<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_C‑1 · 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_C‑1 · Concept</span></div>
|
||||||
<div class="pwr"><span class="dot"></span>PWR</div>
|
<div class="pwr"><span class="dot"></span>PWR</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -493,21 +492,7 @@ requestAnimationFrame(draw);
|
||||||
/*@BUILD:include:src/progbox.js@*/
|
/*@BUILD:include:src/progbox.js@*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info</label>
|
<p class="ff-link pageonly"><a href="/info-player.html">About this concept →</a></p>
|
||||||
<div id="techinfo" class="pageonly" hidden>
|
|
||||||
<section class="about">
|
|
||||||
<h2>PM_C‑1 — 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_C‑1): the player as a clean, screen‑first device with no concession to mechanical parts yet.
|
|
||||||
It's the look we design <i>toward</i> — full set‑list 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_T‑1 Teacher</a> (full priced BOM there);
|
|
||||||
for the smallest practical unit, see the <a href="/micro.html">PM_P‑1 Practice</a>.</p>
|
|
||||||
</section>
|
|
||||||
</div><!-- /#techinfo -->
|
|
||||||
|
|
||||||
/*@BUILD:include:src/footer.html@*/
|
/*@BUILD:include:src/footer.html@*/
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -75,80 +75,7 @@
|
||||||
|
|
||||||
/*@BUILD:include:src/progbox.html@*/
|
/*@BUILD:include:src/progbox.html@*/
|
||||||
|
|
||||||
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (dimensions, BOM, embedding)</label>
|
<p class="ff-link pageonly"><a href="/info-showcase.html">Purpose, dimensions & bill of materials →</a></p>
|
||||||
<div id="techinfo" class="pageonly" hidden>
|
|
||||||
|
|
||||||
<section class="about">
|
|
||||||
<h2>PM_D‑1 — Display</h2>
|
|
||||||
<div class="ff-tags"><span class="hw">Hardware</span><span>Display piece</span><span>~$41 one‑off</span></div>
|
|
||||||
<p>A metronome as an object: the silhouette of a classic pyramid wind‑up unit, but the swinging pendulum is
|
|
||||||
pure <b>RGB light</b>. The whole bar is the display — every lane's subdivisions & 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 USB‑C with a second "thru" port to daisy‑chain. 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 & profile — ≈ 4.7 × 7.1 × 3.1 in (120 × 180 × 80 mm), a truncated‑pyramid 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">RGB‑light 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">USB‑C in base</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dvx">↔ 3.1 in (80 mm) deep</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<details class="spec pageonly">
|
|
||||||
<summary>Spec & bill of materials</summary>
|
|
||||||
<div class="spec-body">
|
|
||||||
<p class="sub">Rough parts list — a USB‑C‑powered RP2040 display piece driving addressable RGB light.
|
|
||||||
Ballpark one‑off 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, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero</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 / light‑guide <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 & build</td></tr>
|
|
||||||
<tr><td class="part">2× USB‑C (data+power & power‑thru) + PWR LED <span class="spec">— daisy‑chain</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 (one‑off)</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><div></code> + a script —
|
|
||||||
see <a href="/embed.html">the embed docs</a>.</p>
|
|
||||||
</div><!-- /#techinfo -->
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
/*@BUILD:include:src/footer.html@*/
|
/*@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.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.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();
|
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
|
// official VARASYS logo (the "Simplifying Complexity" tagline is baked into the image) + model
|
||||||
const lw=60, lh=Math.round(lw*82/304), lx=CW/2-lw/2, ly=15;
|
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);
|
if(logoReady) g.drawImage(LOGO, lx, ly, lw, lh);
|
||||||
g.textAlign="center";
|
g.textAlign="center";
|
||||||
g.fillStyle="#8f9aa6"; g.font="600 5px 'Segoe UI',Roboto,Arial,sans-serif"; g.globalAlpha=.85;
|
g.fillStyle="#aab2bc"; g.font="600 7px 'Segoe UI',Roboto,Arial,sans-serif"; g.fillText("PM_D‑1 DISPLAY", CW/2, ly+lh+11);
|
||||||
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_D‑1 DISPLAY", CW/2, ly+lh+17);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawPendulum(){
|
function drawPendulum(){
|
||||||
|
|
|
||||||
34
src/base.css
34
src/base.css
|
|
@ -11,18 +11,16 @@ body {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- VARASYS brand lockup: wordmark + "Simplifying Complexity" tagline beneath ---- */
|
/* ---- VARASYS brand lockup (the official logo PNGs already bake in the
|
||||||
.brand { display:inline-flex; flex-direction:column; align-items:stretch; flex:0 0 auto; gap:2px; text-decoration:none; }
|
"Simplifying Complexity" tagline — dark variant for dark themes, light for light) ---- */
|
||||||
.brand-logo { height:28px; width:auto; display:block; }
|
.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; }
|
.brand-light { display:none; }
|
||||||
:root[data-theme="light"] .brand-dark { display:none; }
|
:root[data-theme="light"] .brand-dark { display:none; }
|
||||||
:root[data-theme="light"] .brand-light { display:block; }
|
: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;
|
/* on-device silkscreen brand (official logo image, tagline included) — used in device brandrows */
|
||||||
color:var(--muted,#7f8b9a); white-space:nowrap; }
|
.dev-lock { display:inline-flex; align-items:center; }
|
||||||
/* on-device silkscreen brand lockup (wordmark image + tagline) — used in device brandrows */
|
.dev-logo { display:block; width:auto; height:20px; }
|
||||||
.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; }
|
|
||||||
.site-head { width:100%; max-width:980px; margin:0 auto; display:flex; align-items:center;
|
.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; }
|
justify-content:space-between; gap:10px 16px; flex-wrap:wrap; }
|
||||||
.head-left { display:flex; align-items:center; gap:12px; 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-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; }
|
.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; }
|
[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) ---- */
|
/* ---- 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;
|
.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 { 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 .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; }
|
.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; }
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
<a class="brand" href="/" title="VARASYS — Simplifying Complexity">
|
<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-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" />
|
<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>
|
</a>
|
||||||
<nav class="site-nav">
|
<nav class="site-nav">
|
||||||
<a href="/">Concepts</a>
|
<a href="/">Concepts</a>
|
||||||
|
|
|
||||||
7
src/infoembed.html
Normal file
7
src/infoembed.html
Normal 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
21
src/infoembed.js
Normal 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();
|
||||||
|
})();
|
||||||
|
|
@ -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.
|
Uses the engine codec (patchToSetup / setupToPatch / codeToSetlist) for decode + lint.
|
||||||
Host page provides: window.currentProgramString() and window.loadProgramString(plain).
|
Host page provides: window.currentProgramString() and window.loadProgramString(plain).
|
||||||
Exposes window.progRefresh() — call it after the device's program changes. When the
|
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.
|
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 () {
|
(function () {
|
||||||
var embedded = document.documentElement.dataset.embed === "1";
|
var embedded = document.documentElement.dataset.embed === "1";
|
||||||
var box, msg, editing = false;
|
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(); }
|
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();
|
window.progRefresh();
|
||||||
}
|
}
|
||||||
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", init); else init();
|
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", init); else init();
|
||||||
|
|
|
||||||
86
stage.html
86
stage.html
|
|
@ -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 }
|
.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 }
|
.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{ display:flex; align-items:center; gap:7px; color:var(--silk) }
|
||||||
.silk .model{ font-size:8.5px; text-transform:uppercase; letter-spacing:.16em; opacity:.85 }
|
.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 }
|
.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>
|
||||||
|
|
||||||
<div class="brandrow">
|
<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_S‑1 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_S‑1 Stage</span></div>
|
||||||
<div class="pwr"><span class="dot"></span>USB‑C PWR</div>
|
<div class="pwr"><span class="dot"></span>USB‑C PWR</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -306,87 +306,7 @@ window.loadProgramString = function(plain){ var s=patchToSetup(plain); tracks=[{
|
||||||
/*@BUILD:include:src/progbox.js@*/
|
/*@BUILD:include:src/progbox.js@*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (dimensions, BOM, embedding)</label>
|
<p class="ff-link pageonly"><a href="/info-stage.html">Purpose, dimensions & bill of materials →</a></p>
|
||||||
<div id="techinfo" class="pageonly" hidden>
|
|
||||||
|
|
||||||
<section class="about">
|
|
||||||
<h2>PM_S‑1 — Stage</h2>
|
|
||||||
<div class="ff-tags"><span class="hw">Hardware</span><span>Foot‑pedal stompbox</span><span>~$52 one‑off</span></div>
|
|
||||||
<p>A foot‑operated polymeter stompbox for the stage: drive it hands‑free 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″ expression‑pedal 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 USB‑C — with a second USB‑C <b>"thru"</b> port so several pedals
|
|
||||||
daisy‑chain off one charger or power bank.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div class="dview">
|
|
||||||
<p class="cap">Dimensions & layout — ≈ 4.7 × 3.7 × 1.5 in (120 × 93 × 38 mm), a 1590BB‑style 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 · USB‑C · USB‑C thru</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dvx">↔ 4.7 in (120 mm)</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<details class="spec pageonly">
|
|
||||||
<summary>Spec & bill of materials</summary>
|
|
||||||
<div class="spec-body">
|
|
||||||
<p class="sub">Rough parts list — a foot‑operated RP2040 stompbox (USB‑C, dual‑port) with analog click injection.
|
|
||||||
Ballpark one‑off 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 & display</td></tr>
|
|
||||||
<tr><td class="part">RP2040 board, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero</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">High‑bright diffused RGB beat indicator <span class="spec">— floor‑readable</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">Heavy‑duty momentary footswitch (soft‑touch) <span class="spec">— Tap · Next</span></td><td class="q">2</td><td class="c">6</td></tr>
|
|
||||||
<tr><td class="part">1/4″ expression‑pedal 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">— line‑level click</span></td><td class="q">1</td><td class="c">3</td></tr>
|
|
||||||
<tr><td class="part">Dual op‑amp, NE5532 / OPA2134 <span class="spec">— hi‑Z 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 & 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× USB‑C (data+power & power‑thru) + power‑path/protection + PWR LED <span class="spec">— daisy‑chain 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">Die‑cast aluminium stompbox (Hammond 1590BB‑style) <span class="spec">— bead‑blasted, matte‑black Type II anodise, laser‑etched</span></td><td class="q">1</td><td class="c">12</td></tr>
|
|
||||||
<tr class="total"><td>Total (one‑off)</td><td class="q"></td><td class="c">≈ $52</td></tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p class="sub" style="margin-top:12px">No built‑in speaker — the Stage feeds your amp / PA. The click is summed in
|
|
||||||
the <b>analog domain</b> (hi‑Z instrument buffer + DAC → balanced line driver), so your instrument is never
|
|
||||||
re‑digitised (no added latency).</p>
|
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code><div></code> + a script —
|
|
||||||
see <a href="/embed.html">the embed docs</a>.</p>
|
|
||||||
</div><!-- /#techinfo -->
|
|
||||||
|
|
||||||
/*@BUILD:include:src/footer.html@*/
|
/*@BUILD:include:src/footer.html@*/
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
58
teacher.html
58
teacher.html
|
|
@ -89,7 +89,7 @@
|
||||||
}
|
}
|
||||||
.brandrow{ display:flex; align-items:flex-end; justify-content:space-between; margin:0 2px 12px; }
|
.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 }
|
.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 }
|
.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{ 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 }
|
.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="device">
|
||||||
|
|
||||||
<div class="brandrow">
|
<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_T‑1 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_T‑1 Teacher</span></div>
|
||||||
<div class="pwr"><span class="dot"></span>PWR</div>
|
<div class="pwr"><span class="dot"></span>PWR</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -278,59 +278,7 @@
|
||||||
</div><!-- /col-left -->
|
</div><!-- /col-left -->
|
||||||
</div><!-- /cols -->
|
</div><!-- /cols -->
|
||||||
|
|
||||||
<label class="info-toggle pageonly"><input type="checkbox" id="infoToggle"> Show technical info (front/top views, dimensions, BOM, embedding)</label>
|
<p class="ff-link pageonly"><a href="/info-teacher.html">Purpose, spec & bill of materials →</a></p>
|
||||||
<div id="techinfo" class="pageonly" hidden>
|
|
||||||
|
|
||||||
<section class="about">
|
|
||||||
<h2>PM_T‑1 — Teacher</h2>
|
|
||||||
<div class="ff-tags"><span class="hw">Hardware</span><span>Studio / lesson console</span><span>~$59 one‑off</span></div>
|
|
||||||
<p>The full‑feature desktop console: a colour readout of every lane, fast set‑list navigation, and your
|
|
||||||
instrument running straight through with the click mixed in — the hands‑on unit for a studio desk or a
|
|
||||||
teaching room, on a non‑reflective matte‑black case. (For hands‑free live use, see the foot‑operated
|
|
||||||
<a href="/stage.html">Stage</a> stompbox.)</p>
|
|
||||||
<p>Top‑mounted 1/4″ jacks keep cabling tidy; the metronome click is summed into the signal in the
|
|
||||||
<b>analog domain</b> (no re‑digitising, no added latency) and sent to a balanced 1/4″ TRS output for the
|
|
||||||
desk or interface, plus a small monitor speaker. Powered over USB‑C — a wall adapter or a power bank. The
|
|
||||||
colour TFT shows tempo, the item name and all lane patterns; arcade buttons + a recessed thumb‑roller make
|
|
||||||
it quick to drive while you teach or track.</p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<details class="spec pageonly">
|
|
||||||
<summary>Spec & bill of materials</summary>
|
|
||||||
<div class="spec-body">
|
|
||||||
<p class="sub">Rough parts list — a desk/studio RP2040 build (USB‑C powered) with analog click injection.
|
|
||||||
Ballpark one‑off 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 & display</td></tr>
|
|
||||||
<tr><td class="part">RP2040 board, USB‑C <span class="spec">— e.g. Waveshare RP2040‑Zero / Pico‑clone</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) + side‑mount thumb‑roller <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">— line‑level click</span></td><td class="q">1</td><td class="c">3</td></tr>
|
|
||||||
<tr><td class="part">Dual op‑amp, NE5532 / OPA2134 <span class="spec">— hi‑Z 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 cross‑coupled op‑amp) → 1/4″ TRS out</span></td><td class="q">1</td><td class="c">4</td></tr>
|
|
||||||
<tr><td class="part">PAM8302A mono Class‑D + 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 & 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">USB‑C 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">Die‑cast aluminium enclosure (Hammond 1590‑style) <span class="spec">— bead‑blasted, matte‑black Type II anodise, laser‑etched legends</span></td><td class="q">1</td><td class="c">12</td></tr>
|
|
||||||
<tr class="total"><td>Total (one‑off)</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
|
|
||||||
high‑impedance 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 re‑digitised (no added latency).</p>
|
|
||||||
</div>
|
|
||||||
</details>
|
|
||||||
</div><!-- /#techinfo -->
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const APP_VERSION = "v0.0.1-dev";
|
const APP_VERSION = "v0.0.1-dev";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue