metronome/index.html
Me Here f0cc30f373 Dedicated landing page at /; move the editor to /editor.html
The site now opens on a proper front door: a hero (logo + tagline + pitch),
an "Open the Editor →" CTA, and form-factor cards (Editor, Stage, Micro, Embed)
linking out to each page + info. The PE-1 editor app moves from index.html to
editor.html; every "Editor"/"Open" link, the embed.js editor variant, and the
editor's own brand-logo (now → /) are repointed. build.sh + deploy.sh build and
publish both index.html (landing) and editor.html (app).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 12:19:24 -05:00

148 lines
8.2 KiB
HTML
Raw Permalink 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; }
.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 — Stage</h3>
<p>Pedalboard build: 2.0″ colour TFT, arcade buttons, thumbroller, 1/4″ instrument passthrough with
analog click injection + balancedTRS out. Beadblasted matteblack anodised.</p>
<div class="links"><a href="/stage.html">Open ↗</a><a href="/info-stage.html">Info &amp; BOM ⓘ</a></div>
</div>
<div class="card">
<span class="chip hw">Hardware</span>
<h3>PMµ — Micro</h3>
<p>Minimal homepractice unit: one push scrollencoder, a red 7segment LED, a speaker and USBC.
Spin = tempo · press = start/stop · hold + spin = switch track.</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>
</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>