# Cadence

> **Category:** Landing Page
> **Effect:** A metronome pendulum sweeping a tick-marked arc while a hairline beat grid pulses and concentric rings burst from the pivot on every beat
> **Platform:** cmd-code (`cmdcode`)
> **Model:** `xiaomi/mimo-v2.6-pro` — Xiaomi MiMo v2.6 Pro (xiaomi/mimo-v2.6-pro)
> **License:** Free / MIT — copy, paste, ship.
> **Self-contained:** yes — one `index.html`, no build step, no external media.

---

## 🎬 Live demo

Open [`public/demos/cadence/index.html`](../public/demos/cadence/index.html) — generated by the model
above from the prompt below, with no human edits to the markup.

## ✅ Verification

<!-- VERIFICATION:START -->
_Pending — this block is written by `tools/verify.mjs` after the build run._
<!-- VERIFICATION:END -->

## 📋 Prompt

```text
## A. WHAT IS BEING BUILT

One complete, valid index.html — single-viewport cinematic landing page for **Cadence**, a live-music tech company locking stage lighting, LED walls and cameras to a band's live tempo. Document title: "Cadence — Every Surface on the Beat". html lang="en". ONE file: plain HTML + one style block + one vanilla script at end of body. No build step, no framework, no bundler.

**Viewport rule:** at width >= 901px the page is exactly one frame: html, body { height:100%; overflow:hidden } and .page { height:100dvh; overflow:hidden }. NO SCROLL on desktop. At width <= 900px it may scroll vertically. No horizontal overflow at 390, 768, 1440, 1920.

**Do NOT build:** no video, mp4/webm/gif, remote images, base64 photo blobs, third-party CDN URLs, WebGL, Three.js, GSAP, Lottie, jQuery, Tailwind, React, audio, forms, pricing, testimonials, blog, cookie banner, scroll indicator, modals, waveform galleries, nothing beyond header / hero / meter / stats footer, desktop hamburger (burger <= 900px only). Google Fonts is the ONLY network request.

**The single visual idea:** a black rehearsal room, one machine — a room-sized metronome. A weighted rod sweeps a smooth arc from a pivot near the top of frame, ticking at each extreme. Behind it a hairline beat grid pulses per beat and concentric rings emit from the pivot (heavier downbeat). Bottom-right: a monospace BPM readout (96.0 BPM, 4/4) with a four-bar beat meter. Nearly monochrome — graphite, bone white — one warm accent (#ff8a3d) for the beat only: rings, measure lines, active meter bar, pivot core.

**Beat clock (one clock, all of it obeys):** BPM = 96. BEAT = 60/96 = 0.625 s. BAR (4/4) = 2.5 s. Pendulum sweep T = 2 beats = 1.25 s. Beats fire at the swing extremes (tick at the ends); the downbeat is the right extreme.

---

## B. THE BACKDROP — the metronome stage (counts, gradient stops, blur radii, drift periods)

One fixed .backdrop (inset:0; overflow:hidden; pointer-events:none; z-index:0) holds:

1. **.bg** (z 0): radial-gradient(circle at 50% 7.5%, rgba(255,138,61,0.13) 0%, rgba(255,138,61,0.05) 26%, transparent 52%); linear-gradient(180deg, #0a0a0b 0%, #101013 44%, #0c0c0e 74%, #08080a 100%).
2. **.glow** (z 1) pivot halo: left:50%; top:7.5%; 720x720px; translate(-50%,-50%); radial-gradient(circle, rgba(255,170,96,0.22) 0%, rgba(255,138,61,0.09) 34%, transparent 68%); filter:blur(44px); opacity:0.8; animation glow-breathe 11s ease-in-out infinite (opacity 0.62 <-> 0.92, scale 1 <-> 1.06).
3. **canvas#stage** (z 2) fixed inset:0; width:100%; height:100%. Repainted EVERY frame, never static; draws back to front: beat grid, pivot rings, pendulum.
4. **.scrim** (z 3) fixed inset:0: linear-gradient(180deg, rgba(8,8,10,0.58) 0%, rgba(8,8,10,0.10) 26%, rgba(8,8,10,0.52) 64%, rgba(8,8,10,0.90) 100%) — also fades the grid hairlines at top and bottom.
5. **.grain** (z 30) fixed inset:-50%; 200%x200%; opacity:0.05; SVG feTurbulence data-URI (fractalNoise, baseFrequency 0.8, numOctaves 2, stitchTiles, then saturate 0), tile 160px; animation grain 0.9s steps(4) infinite, translating among (0,0) (-2%,1%) (1%,-2%) (-1%,2%).

**Geometry (canvas 2D, no libraries).** Cached { w, h } read once per resize. Pivot P = (w * 0.5, h * 0.075; h * 0.06 at <=900). Rod L = h * 0.52 (>=1600) / h * 0.50 (1280-1599) / h * 0.48 (901-1279) / h * 0.44 (max-height 850) / h * 0.38 (max-height 720) / min(h * 0.34, 300px) (<=900) / min(h * 0.28, 220px) (<=560). Weight 44x64px default; 48x70 (>=1600), 52x76 (>=1920), 38x54 (max-height 850), 32x46 (max-height 720), 34x50 (<=900), 28x40 (<=560). Amplitude A = 26deg (24deg <=900, 22deg at max-height 720). theta(t) = A * cos(2 * PI * t / 1.25); at t = 0.625 * k the angle is exactly +/- A — the beat tick.

**1. Beat grid:** hairlines x_i = i * PITCH, i = 0..ceil(w/PITCH). PITCH = 30 (>=1600) / 26 (1280-1599) / 22 (901-1279) / 18 (<=900) / 14 (<=560) px — 56 lines at 1440x900. Weak lines (i % 8 !== 0): rgba(226,226,222, a_i), 1px. Measure lines (i % 8 === 0; 7 at 1440x900): rgba(255,138,61, a_i * 0.85), 1.4px. Full height (.scrim fades the ends). Alpha:
  - p = (t / 0.625) mod 1; beatEnv = exp(-5.2 * p) (1.000 at the tick, 0.006 at the next).
  - shimmer = 0.05 * (0.5 + 0.5 * sin(i * 0.45 - t * 1.7)).
  - a_i = 0.045 + 0.22 * beatEnv + shimmer + (i % 8 === 0 ? 0.10 : 0).
  Batch into 6 alpha buckets, ONE beginPath() per bucket — 6 draw calls for 56 lines.

**2. Pivot rings:** 4 pre-allocated slots (NO allocation in the loop), slot beatIndex % 4; on each beat boundary store born = t, down = (beatIndex % 4 === 0). Age a = t - born <= 1.6s: r = 14 + 300 * a px (494px at death); stroke rgba(255,138,61, 0.30 * pow(1 - a / 1.6, 1.7) * (down ? 1.4 : 1)); lineWidth = down ? 2 : 1.2. Housing circle at P: r = 22px, rgba(226,226,222,0.14), 1px.

**3. Pendulum:** pivot cap: filled r=7px #0a0a0b, 1.5px rgba(226,226,222,0.55) ring, accent core dot r=2.5px rgba(255,138,61,0.95). Rod: 3px line (2px <=900) P -> tip at L, rgba(232,232,228,0.92), round caps. Weight: rounded rect centred at 0.70 L, rotated with the rod — fill #d9d9d5, 1px rgba(255,138,61,0.55) stroke, radius 5px, one 1px rgba(10,10,11,0.5) groove. Tip cap r=5px rgba(255,138,61,0.9). Trail: 4 ghost rods at t - 0.024 / 0.048 / 0.072 / 0.096 s, 2px, alphas 0.07 / 0.05 / 0.035 / 0.02. Scale arc: 11 ticks -A..+A (step 5.2deg), radius L*1.02 -> L*1.06, 1px rgba(226,226,222,0.22), extremes rgba(255,138,61,0.55); hairline arc at L*1.02 across 52deg, rgba(226,226,222,0.12).

**Resolution trick:** dpr = Math.min(window.devicePixelRatio || 1, 2); canvas.width = cssW * dpr; canvas.height = cssH * dpr; ctx.setTransform(dpr, 0, 0, dpr, 0, 0). getBoundingClientRect only inside resizeCanvas(). Resize: one boolean resizeQueued + requestAnimationFrame.

**Per-frame cost budget (1440x900):** 1 clearRect + 6 batched grid paths (56 strokes) + 3 ring arcs + 5 rods + 11 ticks + 1 arc + 5 fills = 12 draw calls. ZERO ctx.filter / ctx.shadowBlur anywhere, ZERO DOM writes. Under 2 ms/frame; >= 20 frames per 1.2s headless. document.hidden: keep loop and counter, skip the paint.

**Drift periods (non-harmonic on purpose):** pendulum 1.25s, beat 0.625s, bar 2.5s, glow-breathe 11s, grain 0.9s.

---

## C. THE LAYER STACK (back -> front, z-index)

1. html, body — #0a0a0b, forced twice (Failure Guards).
2. .backdrop — z 0, fixed inset:0, pointer-events:none, overflow:hidden. Inside: .bg 0, .glow 1, canvas#stage 2, .scrim 3, .grain 30.
3. .page — z 40; position:relative; display:grid; grid-template-rows:auto minmax(0,1fr) auto; min-height:100dvh (height:100dvh inside the desktop lock).
4. main.hero — z 50.
5. header.site-header, footer.stats-footer — z 60.
6. .menu (mobile, open) — fixed inset:0, z 80.

---

## D. TOKEN TABLE (defaults at 1440x900)

```
--bg:            #0a0a0b
--bg-2:          #101013
--text:          #f2f2f0
--text-soft:     #d6d6d2
--muted:         #9a9a96
--dim:           #6a6a66
--accent:        #ff8a3d
--accent-hot:    #ffc38a
--accent-soft:   rgba(255,138,61,0.55)
--accent-line:   rgba(255,138,61,0.32)
--grid-line:     rgba(226,226,222,0.22)
--border:        rgba(242,242,240,0.14)
--border-soft:   rgba(242,242,240,0.08)
--focus:         #ffc38a
--sans:          "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif
--mono:          "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace
--logo:          16px
--logo-track:    0.20em
--nav:           13.5px
--nav-h:         38px
--btn:           13.5px
--btn-h:         44px
--chip-h:        30px
--eyebrow:       11.5px
--h1:            76px
--lead:          18px
--bpm:           64px
--bpm-unit:      13px
--meter-label:   11px
--meter-h:       26px
--stat-val:      26px
--stat-label:    12px
--header-y:      26px
--header-x:      44px
--hero-x:        44px
--hero-bottom:   56px
--copy-max:      700px
--meter-w:       300px
--radius-pill:   999px
--radius-sm:     5px
--focus-w:       2px
--focus-offset:  3px
--grain-op:      0.05
--glow-blur:     44px
--ease-out:      cubic-bezier(0.16,1,0.3,1)
--enter-dur:     0.95s
```

Fonts: Google Fonts ONLY — Inter 400;500;600, JetBrains Mono 400;500 — one preconnect to https://fonts.gstatic.com (crossorigin) + one stylesheet link with display=swap, fallbacks as above. BPM digits use font-variant-numeric: tabular-nums.

---

## E. THE COMPOSITION — exact build order

**.page** holds <header class="site-header">, <main class="hero">, <footer class="stats-footer"> in grid rows auto / 1fr / auto.

**HEADER** — display:flex; align-items:center; justify-content:space-between; gap:24px; padding:var(--header-y) var(--header-x).

- a.brand (href "#", accessible name "Cadence home"): inline SVG mark 22x22 — metronome glyph <path d="M11 2.5 L19 19.5 L3 19.5 Z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/> plus rod <path d="M11 17 L15.4 7.2" stroke="#ff8a3d" stroke-width="1.6" stroke-linecap="round"/> — then "CADENCE" (var(--sans), var(--logo), weight 600, letter-spacing var(--logo-track), color var(--text)) and a 6px square .beat-dot (background var(--accent); radius 1px; margin-left:10px), opacity written per beat by JS (1 -> 0.25).
- nav, exactly 4 links — "Engine", "Rigs", "Pricing", "Docs" — href "#", var(--sans), var(--nav), weight 500, color var(--muted), flex; gap:30px; height:var(--nav-h). Hover: color var(--text), 0.18s.
- a.cta (href "#", "Get the SDK"): height var(--btn-h); padding 0 20px; inline-flex; radius var(--radius-pill); var(--btn) weight 600; color var(--accent-hot); border 1px solid var(--accent-line); background linear-gradient(180deg, rgba(255,138,61,0.16) 0%, rgba(255,138,61,0.05) 100%).

**MAIN (hero, bottom-anchored)** — display:flex; align-items:flex-end; justify-content:space-between; gap:48px; padding:0 var(--hero-x) var(--hero-bottom). Left .hero-copy (max-width:var(--copy-max); flex column; align-items:flex-start); right aside.meter (width:var(--meter-w); flex:0 0 auto). Copy hugs the LEFT padding.

1. .chip (a <p>, not interactive): height var(--chip-h); padding 0 14px; inline-flex; align-items:center; radius var(--radius-pill); border 1px solid var(--border); background rgba(255,138,61,0.06); var(--mono) at var(--eyebrow), letter-spacing 0.18em, uppercase, color var(--accent). Copy: "LIVE TEMPO SYNC ENGINE".
2. h1 — EXACTLY ONE <h1>, var(--sans), weight 600, var(--h1), line-height 0.98, letter-spacing -0.045em, color var(--text), margin: 20px 0 0. Two masked lines (Motion): "Every surface" / "on the beat." with <em>beat</em> in var(--mono), font-style normal, weight 500, font-size 0.94em, letter-spacing -0.03em, color var(--accent-hot).
3. .lead — var(--sans), var(--lead), line-height 1.55, letter-spacing -0.012em, color var(--text-soft), max-width 560px, margin: 22px 0 0. Copy: "Cadence locks lighting, LED walls and cameras to the band's live tempo — one shared clock, drifting less than a quarter of a millisecond across a three-hour set."
4. .actions — flex; gap:12px; flex-wrap:wrap; margin-top:30px. .btn--primary "#" "Book a demo"; .btn--ghost "#" "Explore the engine".

**aside.meter (BPM instrument panel, bottom-right)** — flex column; gap:14px; padding:20px 22px; border:1px solid var(--border-soft); radius:var(--radius-sm); background rgba(10,10,11,0.42).

- .meter-top — flex; justify-content:space-between; align-items:baseline: <span class="meter-label">TEMPO</span> left, "4 / 4" right (var(--mono), var(--meter-label), letter-spacing 0.22em, color var(--dim)).
- .bpm-line — flex; align-items:baseline; gap:8px: <span class="bpm-val">96.0</span> (var(--mono), weight 500, var(--bpm), letter-spacing -0.04em, tabular-nums, color var(--text)) + <span class="bpm-unit">BPM</span> (var(--mono), var(--bpm-unit), letter-spacing 0.16em, color var(--dim)).
- .beat-row — flex; align-items:flex-end; gap:8px. Exactly 4 <span class="beat-seg"> bars: flex:1; height:var(--meter-h); radius:2px; background var(--accent-line); transform-origin:50% 100%; transform:scaleY(0.22); opacity:0.28; transition transform/opacity 220ms var(--ease-out). .on: background var(--accent); transform:scaleY(1); opacity:1. Then <span class="beat-count">BEAT <span class="beat-num">1</span> / 4</span> (var(--mono), var(--meter-label), letter-spacing 0.16em, color var(--dim), margin-left:6px).

**FOOTER (three-item stats)** — display:grid; grid-template-columns:repeat(3, 1fr); padding: 22px var(--header-x) 28px; border-top:1px solid var(--border-soft). Exactly one <ul>, three <li>. Each li: display:grid; gap:6px; padding:0 30px; first-child padding-left:0; last-child padding-right:0; li + li border-left:1px solid var(--border-soft); 2nd centred, 3rd right. Each li: <strong class="stat-val"> (var(--mono), var(--stat-val), weight 500, letter-spacing -0.02em, color var(--text)) + <span class="stat-label"> (var(--mono), var(--stat-label), letter-spacing 0.14em, uppercase, color var(--dim)). Pairs: "0.24 ms" / "peak drift over 3 h"; "64" / "DMX universes driven"; "3 h 12 m" / "longest locked set".

---

## F. THE UI LANGUAGE

- **.btn base:** inline-flex; centred; height var(--btn-h); padding 0 22px; radius var(--radius-pill); var(--sans) var(--btn) weight 600; letter-spacing 0.01em; no underline; relative; overflow:hidden; transition transform/border-color/background/color/box-shadow 220ms var(--ease-out).
- **.btn--primary:** color #1c0d02; border 1px solid rgba(255,195,138,0.65); background linear-gradient(180deg, #ffc38a 0%, #ff8a3d 52%, #d96a1e 100%); box-shadow 0 14px 44px rgba(255,138,61,0.20), inset 0 1px 0 rgba(255,255,255,0.55). Hover: background linear-gradient(180deg, #ffd7ae 0%, #ff9a52 48%, #e67526 100%), translateY(-1px), box-shadow 0 18px 54px rgba(255,138,61,0.30).
- **.btn--ghost:** color var(--text-soft); border 1px solid var(--border); background rgba(242,242,240,0.035). Hover: color var(--text), border-color var(--accent-line), background rgba(255,138,61,0.08), translateY(-1px).
- **Tick glint** on .btn and .cta: content ""; absolute; inset:-1px; background linear-gradient(112deg, transparent 0% 36%, rgba(255,195,138,0.20) 50%, transparent 64% 100%); translateX(-140%); transition 680ms var(--ease-out); hover -> translateX(140%).
- **.cta** = .btn base at padding 0 20px with section E's hairline look; hover: border-color var(--accent-soft), background linear-gradient(180deg, rgba(255,138,61,0.24) 0%, rgba(255,138,61,0.08) 100%), box-shadow 0 0 20px rgba(255,138,61,0.18).
- **Nav links** plain, no pills/underline; hover var(--text). **.chip** and **aside.meter** never react — readouts.
- **Focus:** a/button :focus-visible { outline: var(--focus-w) solid var(--focus); outline-offset: var(--focus-offset); border-radius: var(--radius-pill) }. ::selection { background: rgba(255,138,61,0.30); color: #140903 }. No default blue ring, no underline anywhere.

---

## G. MOTION — entrance stagger and named keyframes

Entrance animations: duration var(--enter-dur); fill-mode both; timing var(--ease-out); delay var(--d, 0.08s); each element .appear + one modifier + inline --d (resting state = final state).

Stagger table (element -> modifier = class .appear--X -> --d):
```
brand          fade    0.08s
nav 1          fade    0.16s
nav 2          fade    0.24s
nav 3          fade    0.32s
nav 4          fade    0.40s
header cta     chip    0.48s
eyebrow chip   pop     0.60s
h1 line 1      mask    0.74s
h1 line 2      mask    0.90s
lead           soft    1.08s
primary btn    chip    1.22s
ghost btn      chip    1.30s
meter panel    meter   1.42s   (duration 1.1s)
stat 1         stat    1.54s
stat 2         stat    1.62s
stat 3         stat    1.70s
```

Entrance keyframes (end at opacity 1 / identity):
```
in-fade   opacity 0 -> 1
in-soft   opacity 0, translateY(14px), blur(4px) -> 1, none, blur(0)
in-mask   opacity 0, translateY(108%) -> 1, none
in-chip   opacity 0, translateY(10px) scale(0.96) -> 1, none
in-pop    0% 0 scale(0.94) / 68% 1 scale(1.03) / 100% 1, none
in-meter  opacity 0, translateY(16px) scaleY(0.9), origin 50% 100% -> 1, none
in-stat   opacity 0, translateY(12px) -> 1, none
```

Continuous keyframes: glow-breathe 11s ease-in-out infinite — 0%,100% { opacity: 0.62; transform: translate(-50%,-50%) scale(1) }, 50% { opacity: 0.92; transform: translate(-50%,-50%) scale(1.06) }; grain 0.9s steps(4) infinite (offsets per B.5).

H1 masking: .line { display:block; overflow:hidden; padding: 0.06em 0.06em 0.12em } > .line-inner { display:inline-block } carrying .appear--mask — type rising from a hard edge.

Musical periods (pendulum 1.25s, grid 0.625s, rings 1.6s, meter 220ms) obey the ONE JS clock of section J — never CSS — so nothing drifts; glow-breathe (11s) and grain (0.9s) alone are CSS, non-harmonic.

---

## H. RESPONSIVE TABLE — exact token overrides per breakpoint

```
>= 1600px:
  --h1: 90px  --bpm: 74px  --lead: 19px  --logo: 17px  --nav: 14px  --nav-h: 40px
  --btn: 14px  --btn-h: 46px  --stat-val: 30px  --meter-w: 340px  --meter-h: 30px
  --header-y: 30px  --header-x: 56px  --hero-x: 56px  --hero-bottom: 64px  --copy-max: 800px

>= 1920px:
  --h1: 104px  --bpm: 84px  --lead: 20px  --stat-val: 34px  --stat-label: 12.5px
  --header-x: 72px  --hero-x: 72px  --hero-bottom: 72px  --copy-max: 880px  --meter-w: 380px

1280px – 1599px:
  --h1: 72px  --bpm: 60px  --copy-max: 660px  --meter-w: 280px

901px – 1279px:
  --h1: 56px  --bpm: 52px  --lead: 16px  --stat-val: 24px  --nav: 12.5px  --btn: 12.5px
  --header-x: 30px  --hero-x: 30px  --hero-bottom: 44px  --copy-max: 560px  --meter-w: 250px

>= 901px AND max-height 850px:
  --h1: 54px  --bpm: 48px  --lead: 16px  --stat-val: 22px  --chip-h: 28px  --meter-h: 22px
  --header-y: 18px  --hero-bottom: 36px  (h1 margin-top 14px, lead 16px, actions 22px)

>= 901px AND max-height 720px:
  --h1: 44px  --bpm: 42px  --lead: 15px  --eyebrow: 11px  --stat-val: 20px  --stat-label: 11px
  --chip-h: 26px  --btn-h: 38px  --meter-h: 18px  --header-y: 14px  --hero-bottom: 26px
  (footer padding 14px top, 18px bottom)

>= 901px (desktop lock, all heights):
  html, body { height:100%; overflow:hidden }  .page { height:100dvh; overflow:hidden }

<= 900px:
  no viewport lock; vertical scroll; nav + CTA move into a burger menu:
  - header keeps .brand + <button class="burger" aria-label="Open navigation" aria-expanded="false">, three 18x1.5px bars, var(--text), gap 5px
  - .menu { position:fixed; inset:0; z-index:80; background: rgba(10,10,11,0.94); backdrop-filter: blur(14px); flex column; align-items:flex-start; justify-content:center; padding: 0 32px; gap: 26px; transform: translateY(-100%); transition: transform 0.45s var(--ease-out) }  .menu.open { transform: none }
  - menu: the 4 nav links at 22px + the .cta chip; Escape, link click, resize > 900px close it
  - main.hero stacks: flex-direction:column; gap:32px; aside.meter { width:100% }
  --h1: 46px  --bpm: 54px  --lead: 16px  --stat-val: 22px  --meter-w: 100%  --meter-h: 24px
  --header-x: 24px  --hero-x: 24px  --hero-bottom: 40px  --copy-max: 100%

<= 560px:
  --h1: 36px  --bpm: 46px  --lead: 15px  --eyebrow: 11px  --stat-val: 19px  --stat-label: 10.5px
  --header-x: 20px  --hero-x: 20px  --hero-bottom: 32px  --meter-h: 20px
  stats footer stacks: grid-template-columns:1fr; li { padding: 12px 0; text-align:left !important }; li + li { border-left:0; border-top:1px solid var(--border-soft) }
  .actions { width:100% }  .btn { flex: 1 1 100% }
  (canvas L, PITCH, weight and A per section B)
```

---

## I. FAILURE GUARDS — the page is never blank, never broken

1. **Black-first:** the FIRST CSS rule is html, body { background:#0a0a0b !important; color:#f2f2f0 }; body carries style="background:#0a0a0b;color:#f2f2f0"; a later rule restates html, body { background:#0a0a0b; background: var(--bg, #0a0a0b) }.
2. **Resting opacity is 1:** every .appear element's un-animated style is its final state (opacity 1, no transform, no filter); keyframes own the FROM states; fill-mode:both holds them only during delay. Broken CSS or missing JS leaves the page complete.
3. **Two-rAF entrance fallback:** after two nested requestAnimationFrame callbacks, per .appear run el.getAnimations({ subtree:false }); if none reports playState "running"/"finished", add .is-in to ALL .appear. No getAnimations: sweep unconditionally after the two rAFs. .is-in forces animation:none !important; opacity:1 !important; transform:none !important; filter:none !important; clip-path:none !important.
4. **Canvas fallback:** missing canvas or getContext("2d") -> .no-canvas on <html>, push "canvas-unavailable" into errors, static stage on .backdrop::after: repeating-linear-gradient(90deg, var(--grid-line) 0 1px, transparent 1px 26px) grid; two 1px rgba(255,138,61,0.30) circles (border-radius:50%, 220px and 380px, centred at 50% 7.5%) as frozen rings; one static 3px bone-white rod rotated 14deg from P. Type, meter, footer stay visible.
5. **Reduced motion:** @media (prefers-reduced-motion: reduce): *, *::before, *::after { transition:none !important; animation:none !important }, .appear/.is-in forced to opacity:1 !important; transform:none !important; filter:none !important; clip-path:none !important. Canvas paints ONE frozen frame at t = 0.22s (theta = 14.3deg, beatEnv 0.32, static ring arcs aged 0.22 / 0.85 / 1.48s, meter bar 1 .on, 2-4 off, .beat-num "1"), then no further rAF: ready = true, frames = 1. .glow rests opacity 0.8 scale 1; .grain display:none. Nothing moves.
6. **Contrast floor:** h1/bpm-val #f2f2f0 on #0a0a0b, lead #d6d6d2 over the scrim, labels #6a6a66 11px uppercase above 4.5:1; text opacity never below 0.86.
7. **Zero console output:** no console calls, no throws, every DOM and canvas call guarded.

---

## J. THE EXACT JS (only this, vanilla, one IIFE at end of body)

1. **Telemetry first:** window.__DEMO__ = { name: 'cadence', ready: false, frames: 0, effects: [], errors: [] }; push once, in order: 'metronome-arc', 'beat-grid', 'pivot-rings', 'beat-meter', 'film-grain'; then window.addEventListener('error', function (e) { window.__DEMO__.errors.push(String(e.message || e)); }).
2. **Clock constants:** BPM = 96, BEAT = 0.625, T_SWING = 1.25, A = 26 (deg), RING_R0 = 14, RING_V = 300, RING_LIFE = 1.6. theta(t), beatEnv, a_i exactly as section B; beatIndex = Math.floor(t / BEAT); p = t / BEAT - beatIndex; beatInBar = beatIndex % 4.
3. **Canvas stage loop:** cache documentElement, canvas#stage, the 2D context (null -> .no-canvas path, push "canvas-unavailable"), cached { w, h } + geometry from resizeCanvas(), and 4 pre-allocated ring slots { born, down } (born = -10). drawStage(t): clearRect; beat grid via B.1 batching; on a NEW beatIndex (vs lastBeat) write slot lastBeat % 4 = { born: t, down: beatInBar === 0 } and move the meter DOM (4 .on moves, .beat-num textContent = String(beatInBar + 1), .beat-dot style.opacity = '1'); rings by B.2; rods, weight, caps, 11-tick arc by B.3. Each rAF tick increments window.__DEMO__.frames by exactly 1 then paints; FIRST completed paint sets ready = true. NEVER ctx.filter, ctx.shadowBlur, getBoundingClientRect in the loop; zero DOM reads beyond cached handles. document.hidden: skip paint, keep loop and counter.
4. **Resize:** resizeCanvas() reads canvas.getBoundingClientRect() ONCE (the only permitted call), recomputes { w, h } + geometry, dpr = Math.min(window.devicePixelRatio || 1, 2), canvas.width = w * dpr, canvas.height = h * dpr, ctx.setTransform(dpr, 0, 0, dpr, 0, 0), repaints. One boolean resizeQueued + requestAnimationFrame — no timers.
5. **Entrance fallback:** Guard 3's two nested rAFs + getAnimations .is-in sweep.
6. **Mobile menu (<= 900px):** burger toggles .menu.open + aria-expanded; Escape, link click, resize > 900px close.
7. **prefers-reduced-motion:** matchMedia('(prefers-reduced-motion: reduce)') once; if matched: drawStage(0.22) once (Guard 5), meter beat 1, ready on that paint, frames = 1, no further rAF.

No other JS. No libraries. No timers. No console calls.

---

TECHNICAL CONTRACT (non-negotiable):

1. Deliver ONE single file: a complete, valid `index.html`. No build step, no bundler,
   no framework, no package install. It must open correctly by double-clicking the file
   and also over http://.
2. Vanilla only. No React, no Tailwind CDN, no GSAP, no Three.js, no jQuery, no Lottie.
   Plain HTML + CSS + modern JavaScript in <style> and <script> tags.
3. NO external media. No .mp4, no .webm, no .gif, no remote images, no base64 blobs of
   photos. Every visual must be generated procedurally with CSS gradients, SVG, or
   <canvas>. This keeps the page free to host and impossible to break with a dead link.
4. Google Fonts is the ONLY permitted network request, and it must be declared with a
   <link rel="preconnect"> plus a system-font fallback stack so the page still looks
   intentional offline. If you prefer, skip it and use a pure system stack.
5. Responsive and correct at 390x844 (phone), 768x1024 (tablet) and 1440x900 (desktop).
   No horizontal scrollbar at any of those widths. Nothing may overflow its container.
6. Accessibility: exactly one <h1>; real <header>/<main>/<footer>/<nav> landmarks; every
   interactive element is a <button> or <a> with an accessible name; visible :focus-visible
   ring; body text contrast ratio >= 4.5:1 against its background.
7. Motion safety: wrap all continuous motion in
   `@media (prefers-reduced-motion: reduce)` rules that reduce it to a static or
   near-static state. The page must remain fully readable and usable with motion off.
8. Performance: no layout thrash. Cache DOM reads, batch writes inside a single
   requestAnimationFrame loop, use transform/opacity for animation, and never allocate
   inside the hot loop. Target 60fps on a 2019 laptop. Total file under 90 KB.
9. Runtime telemetry hook (used by the automated verifier — implement it exactly):
   at the top of your script define
     window.__DEMO__ = { name: '<slug>', ready: false, frames: 0, effects: [], errors: [] };
   then set `ready = true` after the first paint of your main effect, increment
   `frames` once per animation frame inside your rAF loop, and push the name of each
   implemented effect into `effects`. Add a `window.addEventListener('error', ...)`
   handler that pushes messages into `errors`. Do not rename these fields.
10. Zero console output in the happy path. No console.log left behind. No uncaught
    exceptions, no failed network requests.

RESPONSE FORMAT:
Return ONLY the raw HTML inside a single ```html fenced code block. No explanation, no
preamble, no commentary before or after the fence. The file must be complete and
immediately runnable — never truncate, never write "// rest of code here".
```

---

*LandingPagePrompts Prompt Library — free, verified, model-attributed.*
