Site phase 1: standard VARASYS header + nav; editor → PE-1; Concepts library
- Shared site header in src/base.css (.site-head/.site-nav/.brand-logo + theme- aware logo + .tbtn). Applied to player/stage/micro (replacing their text topbars) so the VARASYS logo + tagline + Editor/Concepts nav is on every page. - Rebrand the editor: "Stackable Metronome" → "PE-1 — PolyMeter Editor" (title + h1), with a Concepts link in its header. - New concepts.html — the PolyMeter Concepts library: cards for the editor and each form factor (PM-1 Initial/Stage, PM-µ Micro) + a "more coming" card. - build.sh + deploy.sh build/deploy concepts.html; deploy.sh now loops over pages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c1488c0d32
commit
6568076563
8 changed files with 196 additions and 36 deletions
5
build.sh
5
build.sh
|
|
@ -30,7 +30,6 @@ def build(name):
|
||||||
out.write_text(src)
|
out.write_text(src)
|
||||||
return out.stat().st_size
|
return out.stat().st_size
|
||||||
|
|
||||||
i = build("index.html"); p = build("player.html"); a = build("stage.html"); u = build("micro.html")
|
for name in ("index.html","player.html","stage.html","micro.html","concepts.html"):
|
||||||
print("built index.html (%dKB) + player.html (%dKB) + stage.html (%dKB) + micro.html (%dKB)"
|
print("built %s (%dKB)" % (name, build(name) // 1024))
|
||||||
% (i // 1024, p // 1024, a // 1024, u // 1024))
|
|
||||||
PY
|
PY
|
||||||
|
|
|
||||||
126
concepts.html
Normal file
126
concepts.html
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>PolyMeter Concepts — VARASYS</title>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
|
||||||
|
<!-- The PolyMeter concept library: an ever-expanding gallery of form factors
|
||||||
|
(the PE-1 editor + the PM-1/PM-µ hardware mockups + web widgets). Static page. -->
|
||||||
|
<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; }
|
||||||
|
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
|
||||||
|
--panel-bg:#ffffff; --panel-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:26px auto 0; }
|
||||||
|
h1{ font-size:24px; margin:0 0 4px; }
|
||||||
|
.lead{ margin:0 0 22px; color:var(--muted); font-size:14px; line-height:1.55; max-width:62ch; }
|
||||||
|
.grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(250px, 1fr)); gap:16px; }
|
||||||
|
.card{ background:var(--panel-bg); border:1px solid var(--panel-bd); border-radius:14px; padding:16px;
|
||||||
|
display:flex; flex-direction:column; gap:9px; }
|
||||||
|
.card h3{ margin:0; font-size:16px; }
|
||||||
|
.chip{ align-self:flex-start; font-size:10px; text-transform:uppercase; letter-spacing:.08em;
|
||||||
|
padding:2px 9px; border-radius:999px; border:1px solid var(--panel-bd); color:var(--muted); }
|
||||||
|
.chip.hw{ color:var(--cyan); border-color:rgba(10,179,247,.45); }
|
||||||
|
.chip.app{ color:#2fe07a; border-color:rgba(47,224,160,.45); }
|
||||||
|
.card p{ margin:0; font-size:13px; color:var(--muted); line-height:1.5; flex:1; }
|
||||||
|
.card .links{ display:flex; gap:16px; margin-top:4px; }
|
||||||
|
.card .links a{ color:var(--link); text-decoration:none; font-size:13px; font-weight:600; }
|
||||||
|
.card.soon{ opacity:.65; border-style:dashed; }
|
||||||
|
.site-foot{ max-width:980px; margin:40px auto 0; font-size:12px; color:var(--muted); }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header class="site-head">
|
||||||
|
<div class="head-left">
|
||||||
|
<a class="brand" href="/" title="VARASYS — Simplifying Complexity">
|
||||||
|
<img class="brand-logo brand-dark" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" />
|
||||||
|
<img class="brand-logo brand-light" src="data:image/png;base64,@BUILD:logo-light@" alt="VARASYS — Simplifying Complexity" />
|
||||||
|
</a>
|
||||||
|
<span class="page-name"><b>PolyMeter</b> · Concepts</span>
|
||||||
|
</div>
|
||||||
|
<nav class="site-nav">
|
||||||
|
<a href="/index.html">Editor</a>
|
||||||
|
<span class="here">Concepts</span>
|
||||||
|
<button id="themeBtn" class="tbtn" title="toggle light / dark theme">☀</button>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<h1>PolyMeter Concepts</h1>
|
||||||
|
<p class="lead">One polymeter engine, many form factors. The same firmware/share-language drives the
|
||||||
|
web editor and every device idea below — an ever-expanding library of concepts, from a full editor to
|
||||||
|
pocket practice hardware. Open one to try it live.</p>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="card">
|
||||||
|
<span class="chip app">Web app</span>
|
||||||
|
<h3>PE‑1 — PolyMeter Editor</h3>
|
||||||
|
<p>The full editor: stack meter lanes, per‑step accents / ghosts / mutes, swing & ratio polyrhythm,
|
||||||
|
set lists, and shareable links. This is where you design grooves.</p>
|
||||||
|
<div class="links"><a href="/index.html">Open ↗</a></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<span class="chip">Concept</span>
|
||||||
|
<h3>PM‑1 — Initial</h3>
|
||||||
|
<p>The original idealized device mock — full multi‑lane display and set‑list navigation. A north‑star
|
||||||
|
concept (more than a single small unit can really show); the buildable take is Stage.</p>
|
||||||
|
<div class="links"><a href="/player.html">Open ↗</a></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<span class="chip hw">Hardware</span>
|
||||||
|
<h3>PM‑1 — Stage</h3>
|
||||||
|
<p>Pedalboard build: 2.0″ colour TFT, arcade buttons, thumb‑roller, 1/4″ instrument pass‑through with
|
||||||
|
analog click injection + balanced‑TRS out, 9 V DC / USB‑C. Bead‑blasted matte‑black anodised.</p>
|
||||||
|
<div class="links"><a href="/stage.html">Open ↗</a></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<span class="chip hw">Hardware</span>
|
||||||
|
<h3>PM‑µ — Micro</h3>
|
||||||
|
<p>Minimal home‑practice unit: one push scroll‑encoder, a red 7‑segment LED, a speaker and USB‑C.
|
||||||
|
Spin = tempo · press = start/stop · hold + spin = switch track.</p>
|
||||||
|
<div class="links"><a href="/micro.html">Open ↗</a></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card soon">
|
||||||
|
<span class="chip">Coming</span>
|
||||||
|
<h3>More form factors</h3>
|
||||||
|
<p>The library keeps growing — desktop, Eurorack, wearable, headless module… each a widget you can
|
||||||
|
embed. Ideas welcome.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="site-foot">VARASYS · Simplifying Complexity — <span id="appVersion">v0.0.1-dev</span></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const APP_VERSION = "v0.0.1-dev";
|
||||||
|
const $ = (id)=>document.getElementById(id);
|
||||||
|
try{ $("appVersion").textContent = "v"+APP_VERSION.replace(/^v/,""); }catch(e){}
|
||||||
|
const THEMES=["system","light","dark"];
|
||||||
|
function effectiveTheme(p){ return p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches?"light":"dark") : p; }
|
||||||
|
function themePref(){ try{ const p=localStorage.getItem("metronome.theme"); return (p==="light"||p==="dark"||p==="system")?p:"system"; }catch(e){ return "system"; } }
|
||||||
|
function applyTheme(p){ try{ localStorage.setItem("metronome.theme",p); }catch(e){}
|
||||||
|
document.documentElement.dataset.theme = effectiveTheme(p);
|
||||||
|
$("themeBtn").textContent = p==="system" ? "◐" : p==="light" ? "☀" : "☾"; $("themeBtn").title="Theme: "+p+" (system → light → dark)"; }
|
||||||
|
$("themeBtn").onclick = ()=> applyTheme(THEMES[(THEMES.indexOf(themePref())+1)%THEMES.length]);
|
||||||
|
matchMedia("(prefers-color-scheme: light)").addEventListener("change", ()=>{ if(themePref()==="system") applyTheme("system"); });
|
||||||
|
applyTheme(themePref());
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
13
deploy.sh
13
deploy.sh
|
|
@ -39,14 +39,11 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# stamp the version into the built copy only (source stays clean)
|
# stamp the version into the built copy only (source stays clean)
|
||||||
sed "s|const APP_VERSION = \"[^\"]*\";|const APP_VERSION = \"$BUILD\";|" "$DIST_DIR/index.html" > "$DEST_DIR/index.html"
|
echo "deployed v$BUILD -> $DEST_DIR"
|
||||||
echo "deployed v$BUILD ($(stat -c '%s' "$DEST_DIR/index.html") bytes) -> $DEST_DIR"
|
for f in index.html player.html stage.html micro.html concepts.html; do
|
||||||
sed "s|const APP_VERSION = \"[^\"]*\";|const APP_VERSION = \"$BUILD\";|" "$DIST_DIR/player.html" > "$DEST_DIR/player.html"
|
sed "s|const APP_VERSION = \"[^\"]*\";|const APP_VERSION = \"$BUILD\";|" "$DIST_DIR/$f" > "$DEST_DIR/$f"
|
||||||
echo "deployed player.html ($(stat -c '%s' "$DEST_DIR/player.html") bytes)"
|
echo " $f ($(stat -c '%s' "$DEST_DIR/$f") bytes)"
|
||||||
sed "s|const APP_VERSION = \"[^\"]*\";|const APP_VERSION = \"$BUILD\";|" "$DIST_DIR/stage.html" > "$DEST_DIR/stage.html"
|
done
|
||||||
echo "deployed stage.html ($(stat -c '%s' "$DEST_DIR/stage.html") bytes)"
|
|
||||||
sed "s|const APP_VERSION = \"[^\"]*\";|const APP_VERSION = \"$BUILD\";|" "$DIST_DIR/micro.html" > "$DEST_DIR/micro.html"
|
|
||||||
echo "deployed micro.html ($(stat -c '%s' "$DEST_DIR/micro.html") bytes)"
|
|
||||||
rm -f "$DEST_DIR/player-asbuilt.html" # renamed to stage.html
|
rm -f "$DEST_DIR/player-asbuilt.html" # renamed to stage.html
|
||||||
|
|
||||||
# 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),
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Stackable Metronome</title>
|
<title>PE‑1 — PolyMeter Editor</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
|
||||||
<script>
|
<script>
|
||||||
// Set theme before first paint (avoids a flash). Preference is system|light|dark
|
// Set theme before first paint (avoids a flash). Preference is system|light|dark
|
||||||
|
|
@ -216,8 +216,9 @@
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<div class="device">
|
<div class="device">
|
||||||
<div class="row appheader" style="align-items:center; flex-wrap:wrap; gap:6px 14px; margin-bottom:8px">
|
<div class="row appheader" style="align-items:center; flex-wrap:wrap; gap:6px 14px; margin-bottom:8px">
|
||||||
<h1 style="margin:0">Stackable Metronome <span class="lane-meta" id="appVersion" title="build version">v0.0.1-dev</span></h1>
|
<h1 style="margin:0">PE‑1 <span style="font-weight:400; opacity:.75">PolyMeter Editor</span> <span class="lane-meta" id="appVersion" title="build version">v0.0.1-dev</span></h1>
|
||||||
<div class="appheader-ctrls" style="display:flex; align-items:center; gap:10px">
|
<div class="appheader-ctrls" style="display:flex; align-items:center; gap:10px">
|
||||||
|
<a href="/concepts.html" style="font-size:13px; color:var(--muted); text-decoration:none" title="Concept gallery — hardware & widget form factors">Concepts</a>
|
||||||
<button id="themeBtn" title="toggle light / dark theme">☀</button>
|
<button id="themeBtn" title="toggle light / dark theme">☀</button>
|
||||||
<button id="helpBtn" title="keyboard shortcuts (?)">?</button>
|
<button id="helpBtn" title="keyboard shortcuts (?)">?</button>
|
||||||
<a class="brand" href="https://varasys.io" target="_blank" rel="noopener"
|
<a class="brand" href="https://varasys.io" target="_blank" rel="noopener"
|
||||||
|
|
|
||||||
20
micro.html
20
micro.html
|
|
@ -89,14 +89,20 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="topbar">
|
<header class="site-head">
|
||||||
<span><b>VARASYS PM‑µ</b> · micro (home practice)</span>
|
<div class="head-left">
|
||||||
<span class="topbar-right">
|
<a class="brand" href="/" title="VARASYS — Simplifying Complexity">
|
||||||
<button id="themeBtn" class="tbtn" title="toggle light / dark theme">☀</button>
|
<img class="brand-logo brand-dark" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" />
|
||||||
<a href="/stage.html">Stage ↗</a>
|
<img class="brand-logo brand-light" src="data:image/png;base64,@BUILD:logo-light@" alt="VARASYS — Simplifying Complexity" />
|
||||||
<a href="/index.html">Editor ↗</a>
|
</a>
|
||||||
</span>
|
<span class="page-name"><b>PM‑µ</b> · Micro (home practice)</span>
|
||||||
</div>
|
</div>
|
||||||
|
<nav class="site-nav">
|
||||||
|
<a href="/index.html">Editor</a>
|
||||||
|
<a href="/concepts.html">Concepts</a>
|
||||||
|
<button id="themeBtn" class="tbtn" title="toggle light / dark theme">☀</button>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
<div class="device">
|
<div class="device">
|
||||||
<div class="brandrow">
|
<div class="brandrow">
|
||||||
|
|
|
||||||
21
player.html
21
player.html
|
|
@ -194,16 +194,21 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="topbar">
|
<header class="site-head">
|
||||||
<span><b>VARASYS PM‑1</b> · hardware player (mockup)</span>
|
<div class="head-left">
|
||||||
<span class="topbar-right">
|
<a class="brand" href="/" title="VARASYS — Simplifying Complexity">
|
||||||
|
<img class="brand-logo brand-dark" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" />
|
||||||
|
<img class="brand-logo brand-light" src="data:image/png;base64,@BUILD:logo-light@" alt="VARASYS — Simplifying Complexity" />
|
||||||
|
</a>
|
||||||
|
<span class="page-name"><b>PM‑1</b> · Initial concept</span>
|
||||||
|
</div>
|
||||||
|
<nav class="site-nav">
|
||||||
|
<a href="/index.html">Editor</a>
|
||||||
|
<a href="/concepts.html">Concepts</a>
|
||||||
<button id="fsBtn" class="tbtn" title="Full screen (landscape)">⛶</button>
|
<button id="fsBtn" class="tbtn" title="Full screen (landscape)">⛶</button>
|
||||||
<button id="themeBtn" class="tbtn" title="toggle light / dark theme">☀</button>
|
<button id="themeBtn" class="tbtn" title="toggle light / dark theme">☀</button>
|
||||||
<a href="/stage.html">Stage ↗</a>
|
</nav>
|
||||||
<a href="/micro.html">Micro ↗</a>
|
</header>
|
||||||
<a href="/index.html">Open editor ↗</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ===================== THE DEVICE ===================== -->
|
<!-- ===================== THE DEVICE ===================== -->
|
||||||
<div class="device">
|
<div class="device">
|
||||||
|
|
|
||||||
21
src/base.css
21
src/base.css
|
|
@ -10,3 +10,24 @@ body {
|
||||||
font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
font-family: "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---- VARASYS site header (shared across every page) ---- */
|
||||||
|
.brand { display:inline-flex; align-items:center; flex:0 0 auto; }
|
||||||
|
.brand-logo { height:30px; width:auto; display:block; }
|
||||||
|
.brand-light { display:none; }
|
||||||
|
:root[data-theme="light"] .brand-dark { display:none; }
|
||||||
|
:root[data-theme="light"] .brand-light { display:block; }
|
||||||
|
.site-head { width:100%; max-width:980px; margin:0 auto; display:flex; align-items:center;
|
||||||
|
justify-content:space-between; gap:10px 16px; flex-wrap:wrap; }
|
||||||
|
.head-left { display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
|
||||||
|
.page-name { font-size:13px; color:var(--muted,#7f8b9a); letter-spacing:.02em; }
|
||||||
|
.page-name b { color:var(--txt,#c7d0db); }
|
||||||
|
.site-nav { display:flex; align-items:center; gap:14px; font-size:13px; }
|
||||||
|
.site-nav a { color:var(--muted,#7f8b9a); text-decoration:none; }
|
||||||
|
.site-nav a:hover { color:var(--txt,#c7d0db); }
|
||||||
|
.site-nav a.here { color:var(--cyan); }
|
||||||
|
.tbtn { background:transparent; color:var(--muted,#7f8b9a); border:1px solid var(--panel-bd,#2a313c);
|
||||||
|
border-radius:8px; padding:3px 9px; font-size:14px; line-height:1; cursor:pointer; }
|
||||||
|
.tbtn:hover { color:var(--txt,#c7d0db); }
|
||||||
|
/* embed mode: pages opened with ?embed=1 strip all site chrome (the widget only) */
|
||||||
|
body[data-embed] .site-head, body[data-embed] .site-foot { display:none !important; }
|
||||||
|
|
|
||||||
21
stage.html
21
stage.html
|
|
@ -196,15 +196,20 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="topbar">
|
<header class="site-head">
|
||||||
<span><b>VARASYS PM‑1</b> · stage (pedalboard build)</span>
|
<div class="head-left">
|
||||||
<span class="topbar-right">
|
<a class="brand" href="/" title="VARASYS — Simplifying Complexity">
|
||||||
<button id="themeBtn" class="tbtn" title="toggle light / dark theme">☀</button>
|
<img class="brand-logo brand-dark" src="data:image/png;base64,@BUILD:logo-dark@" alt="VARASYS — Simplifying Complexity" />
|
||||||
<a href="/micro.html">Micro ↗</a>
|
<img class="brand-logo brand-light" src="data:image/png;base64,@BUILD:logo-light@" alt="VARASYS — Simplifying Complexity" />
|
||||||
<a href="/player.html">Initial ↗</a>
|
</a>
|
||||||
<a href="/index.html">Editor ↗</a>
|
<span class="page-name"><b>PM‑1</b> · Stage (pedalboard build)</span>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<nav class="site-nav">
|
||||||
|
<a href="/index.html">Editor</a>
|
||||||
|
<a href="/concepts.html">Concepts</a>
|
||||||
|
<button id="themeBtn" class="tbtn" title="toggle light / dark theme">☀</button>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
<div class="cols">
|
<div class="cols">
|
||||||
<div class="col-left">
|
<div class="col-left">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue