metronome/index.html
Me Here ce6166a721 Rename "Stage" -> "Teacher" (studio/lesson console); free the Stage name
The full-feature desktop console (big TFT, arcade buttons, instrument pass-through)
is repositioned as the "Teacher" for studio desks and lessons:
- stage.html -> teacher.html, info-stage.html -> info-teacher.html (git mv)
- all links/paths, the embed variant (stage -> teacher), nav, cards, embed docs,
  README, build.sh + deploy.sh updated; deploy cleans the stale live stage files
The "Stage" name is now free for a forthcoming foot-pedal stompbox (/stage.html).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 08:16:15 -05:00

180 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>VARASYS PolyMeter — polymetric groove trainer &amp; metronome</title>
<meta name="description" content="PolyMeter — a polymetric groove trainer and metronome. One engine, many form factors: a free web editor, hardware concepts, and an embeddable widget." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
<!-- Landing page: the front door to the PolyMeter family. The app itself is /editor.html. 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:0 auto; }
/* hero */
.hero{ text-align:center; padding:54px 12px 38px; }
.hero h1{ font-size:clamp(40px, 9vw, 76px); margin:0; letter-spacing:-.02em; line-height:1;
background:linear-gradient(90deg, var(--cyan), #6cb6ff); -webkit-background-clip:text; background-clip:text; color:transparent; }
.hero .tagline{ margin:16px auto 0; font-size:clamp(16px, 2.6vw, 21px); color:var(--txt); font-weight:600; }
.hero .pitch{ margin:14px auto 0; max-width:60ch; color:var(--muted); font-size:15px; line-height:1.6; }
.cta{ display:flex; gap:12px; justify-content:center; flex-wrap:wrap; margin-top:26px; }
.btn{ display:inline-flex; align-items:center; gap:6px; text-decoration:none; font-weight:600; font-size:15px;
padding:11px 20px; border-radius:10px; border:1px solid var(--panel-bd); color:var(--txt); background:var(--panel-bg);
transition:.14s; }
.btn:hover{ border-color:var(--cyan); }
.btn.primary{ color:#04121b; border-color:transparent; background:linear-gradient(180deg, #34c6ff, var(--cyan)); }
.btn.primary:hover{ filter:brightness(1.06); }
/* form-factor cards (shared look with the Concepts gallery) */
.section-label{ text-align:center; font-size:11px; text-transform:uppercase; letter-spacing:.12em; color:var(--muted); margin:30px 0 14px; }
.grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(230px, 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; }
.more{ text-align:center; margin-top:18px; font-size:14px; }
/* philosophy section */
.philosophy{ margin-top:34px; }
.phil-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); gap:16px; }
.phil{ background:var(--panel-bg); border:1px solid var(--panel-bd); border-radius:14px; padding:18px 18px 16px; }
.phil h3{ margin:0 0 8px; font-size:15px; display:flex; align-items:center; gap:8px; }
.phil .ic{ font-size:17px; line-height:1; filter:grayscale(.1); }
.phil p{ margin:0; font-size:13.5px; color:var(--muted); line-height:1.62; }
.phil p b{ color:var(--txt); }
.site-foot{ max-width:980px; margin:42px auto 0; font-size:12px; color:var(--muted); text-align:center; }
.site-foot a{ 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></span>
</div>
<nav class="site-nav">
<a href="/editor.html">Editor</a>
<a href="/concepts.html">Concepts</a>
<a href="/embed.html">Embed</a>
<button id="themeBtn" class="tbtn" title="toggle light / dark theme"></button>
</nav>
</header>
<main>
<section class="hero">
<h1>PolyMeter</h1>
<p class="tagline">Polymetric grooves — one engine, many form factors.</p>
<p class="pitch">Stack independent meter lanes, each with its own subdivision, drum voice and perstep
accents, to build true polymeter and ratio polyrhythm. Design it in the browser, save it as a compact
program string, and play it back on the editor, the hardware concepts, or an embedded widget — all the
same engine.</p>
<div class="cta">
<a class="btn primary" href="/editor.html">Open the Editor →</a>
<a class="btn" href="/concepts.html">Browse concepts</a>
</div>
</section>
<div class="section-label">The PolyMeter family</div>
<div class="grid">
<div class="card">
<span class="chip app">Web app</span>
<h3>PE1 — PolyMeter Editor</h3>
<p>The full editor: stack meter lanes, perstep accents / ghosts / mutes, swing &amp; ratio polyrhythm,
set lists, and shareable links. This is where you design grooves.</p>
<div class="links"><a href="/editor.html">Open ↗</a><a href="/info-editor.html">Info ⓘ</a></div>
</div>
<div class="card">
<span class="chip hw">Hardware</span>
<h3>PM1 — Teacher</h3>
<p>Fullfeature desktop console for studio &amp; lessons: 2.0″ colour TFT showing every lane, arcade buttons,
thumbroller, 1/4″ instrument passthrough with analog click injection + balancedTRS out. USBC powered.</p>
<div class="links"><a href="/teacher.html">Open ↗</a><a href="/info-teacher.html">Info &amp; BOM ⓘ</a></div>
</div>
<div class="card">
<span class="chip hw">Hardware</span>
<h3>PMµ — Micro</h3>
<p>Long, narrow inline practice bar: instrument in one end, amp/headphones out the other, click mixed in.
Clickable thumbroller, amber 14segment display, USBC powered.</p>
<div class="links"><a href="/micro.html">Open ↗</a><a href="/info-micro.html">Info &amp; BOM ⓘ</a></div>
</div>
<div class="card">
<span class="chip">Widget</span>
<h3>Embed anywhere</h3>
<p>Drop any form factor into your own page with one <code>&lt;div&gt;</code> + a script — preloaded with a
program string and autosizing. Our own pages use the same loader.</p>
<div class="links"><a href="/embed.html">Docs ↗</a></div>
</div>
</div>
<p class="more"><a href="/concepts.html">See all concepts, including the PM1 Initial render →</a></p>
<section class="philosophy">
<div class="section-label">Philosophy</div>
<div class="phil-grid">
<div class="phil">
<h3><span class="ic">🛠️</span> Program on the web, play on any device</h3>
<p>The website is the workbench. Design your grooves in the <a href="/editor.html">PE1 editor</a>
stack meters, set perstep accents, build set lists — and every pattern saves to a compact
<b>program string</b> (a whole set list to a single code). That same string loads into whichever
form factor fits the moment: the <a href="/teacher.html">Teacher</a> on a studio desk, the
<a href="/micro.html">Micro</a> inline at the practice desk, or an <a href="/embed.html">embedded
widget</a> in someone else's app. One engine, one language — you author once and run it anywhere,
choosing the device by the use scenario rather than relearning a new box each time.</p>
</div>
<div class="phil">
<h3><span class="ic">🔌</span> USBC power everywhere — no batteries</h3>
<p>Every device in the family is powered over a single <b>USBC</b> port — no internal battery to
swell, leak or wear out, and nothing proprietary to replace. Plug into a wall adapter for a
permanent install, or carry a power bank exactly the way you already do for your phone. Standardising
on one connector across the whole range keeps the builds simple and <b>futureproofs</b> the
project as USBC becomes universal.</p>
</div>
</div>
</section>
</main>
<div class="site-foot">VARASYS · Simplifying Complexity ·
<a href="https://codeberg.org/VARASYS/metronome" target="_blank" rel="noopener">source</a>
<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>