Take 01 ยท The chart

How this instrument was cut.

Cadence is one build in a ten site study of what one model does with taste. This page is the session log: the brief as it was handed down, the techniques that carry the concept, where every asset came from, and what three hostile critique passes actually caught.

The brief, as given.

Concept
A fictional type foundry that believes letterforms are rhythm. The hero specimen is a sixteen step sequencer: each row a variable font axis, each column a beat. Press play and the specimen word dances in time.
Rows
wght, CASL, slnt, MONO. One variable typeface exploited across its entire range; the whole site is that one font. That is the point.
The law
Time drives the type. The cursor never does. Cursor proximity effects of any kind were banned outright, so there are none: every letterform on this page answers to the clock or to a click, never to hover position.
Palette
Concrete #e9e7e2, ink #191919, tempo #e8ff2a reserved for live beat elements only, held under fifteen percent of the surface.
Motion
Under prefers reduced motion the sequencer never autoplays, steps change with zero animation, and the page is fully composed at rest. Audio never starts without an explicit gesture on the sound switch.
Mobile
The sequencer stays usable by touch at 390px: fixed row labels, a horizontally scrolling step grid with snap points every four steps, and a playhead that keeps itself in view without fighting the user.

Five moves carry the whole thing.

Swing is arithmetic

Swing lives inside pairs of sixteenths: the even step sits on the grid and the odd step slides late within its pair. Fifty percent is straight time, sixty six leans on the triplet. One function times the audio, the playhead, the ampersand, and the scroll reveals, so the whole page shares a single sense of where the beat is.

js/clock.js
// Swing lives inside pairs of sixteenths: the even step sits on the grid,
// the odd step slides late within its pair. 54% is a polite lean.
_delta(fromStep) {
  const pair = this.stepDur() * 2;
  const frac = this.swingPct / 100;
  return fromStep % 2 === 0 ? pair * frac : pair * (1 - frac);
}

One clock, two audiences

A requestAnimationFrame loop runs a look ahead horizon. Anything inside the next 130 milliseconds gets scheduled for audio with an exact timestamp and pushed onto a queue; the visual step fires only when its moment actually arrives. Audio is tight, pixels are honest, and both derive from the same timeline.

js/clock.js
// Schedule ahead: audio gets exact times, visuals get queued.
while (this._nextTime < now + HORIZON) {
  const s = this._nextStep;
  const t = this._nextTime;
  this._scheduleFns.forEach((f) => f(s, t));
  this._queue.push({ s, t });
  this._nextTime += this._delta(s);
  this._nextStep = (s + 1) % 16;
}

// Fire the newest step whose time has arrived.
let due = null;
while (this._queue.length && this._queue[0].t <= now) due = this._queue.shift();
if (due && due.s !== this._lastVisual) {
  this._lastVisual = due.s;
  this._stepFns.forEach((f) => f(due.s));
}

Audio borrows the visual timeline

The drum voices are synthesized at schedule time, and their trigger moments are converted from the page clock into AudioContext seconds right before scheduling. When sound is off this function is never called; the context itself is only created inside the sound switch click, so no audio machinery exists until a person asks for it.

js/audio.js
_toCtxTime(perfMs) {
  return this.ctx.currentTime + Math.max(0.002, (perfMs - performance.now()) / 1000);
}

schedule(rows, perfMs, accent) {
  if (!this.on || !this.ctx) return;
  const t = this._toCtxTime(perfMs);
  const g = accent ? 1.25 : 1;
  if (rows[0]) this.kick(t, g);
  if (rows[1]) this.snare(t, g);
  if (rows[2]) this.hat(t, g);
  if (rows[3]) this.block(t, g);
}

Every letterform hangs off five custom properties

One universal rule maps five inherited custom properties onto font variation settings, so any element can be posed or played by writing CSS variables at any level. The sequencer snaps the big specimen by setting five properties on its stage; the axis panels, the ampersand, and the glyph stand all reuse the same tiny writer. Snaps are instant by design: no transition ever runs on a letterform.

css/style.css and js/main.js
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-variation-settings:
    "MONO" var(--mono, 0),
    "CASL" var(--casl, 0),
    "slnt" var(--slnt, 0),
    "CRSV" var(--crsv, 0.5),
    "wght" var(--wght, 400);
}

function setAxisProps(el, active) {
  el.style.setProperty('--wght', active[0] ? 1000 : 400);
  el.style.setProperty('--casl', active[1] ? 1 : 0);
  el.style.setProperty('--slnt', active[2] ? -15 : 0);
  el.style.setProperty('--mono', active[3] ? 1 : 0);
  el.style.setProperty('--crsv', active[1] || active[2] ? 1 : 0.5);
}

Reveals land on the grid

Scroll reveals are staggered by whole sixteenth notes at the current tempo, not by arbitrary milliseconds. Change the BPM and the page literally enters at a different speed. Under reduced motion the reveal system never engages and everything is simply present.

js/main.js
// stagger lands on the sixteenth-note grid of the current tempo
const d = (Number(e.target.dataset.rvN) * clock.stepDur()) / 1000;
e.target.style.setProperty('--rv-d', `${d.toFixed(3)}s`);
e.target.classList.add('on');

Asset provenance.

Fully procedural. Zero raster images, zero stock, zero downloaded assets. The favicon and the paper grain are inline SVG data URIs. Every rule, tick, and texture is CSS.

The typeface is Recursive, a variable font served through Google Fonts with its full axis space loaded: wght 300 to 1000, CASL 0 to 1, slnt 0 to minus fifteen, CRSV 0 to 1, MONO 0 to 1. It is the only font on the site, which is the concept: one instrument, played across its whole range. On the specimen page the family performs under the fictional name Pocket.

Every drum voice is synthesized in WebAudio at trigger time. The kick is a pitched sine drop, the snare is bandpassed noise over a short triangle body, the hat is a forty millisecond burst of highpassed noise, the block is a damped triangle pair. No samples, no audio files, nothing fetched.

What the passes actually caught.

  1. Pass one

    The sync chip's indicator collapsed into a one pixel sliver that read as a stray text caret; chips were not flex containers. The playhead smeared olive where tempo yellow decayed over an ink cell, because background color was transitioning. The MONO panel's glyph pair crowded its border. The footer legal line sat at twenty five percent opacity, roughly 2.4 to 1 contrast, a plain failure. All fixed, sections tightened one notch, and the kick thump was added: on every kick hit the stage takes a 1.3 percent scale bump on an overshoot curve, so the word moves air on the one.

  2. Pass two

    A pixel zoom proved the playhead still ghosted across two columns: the hover transition on box shadow was animating the scan ring's exit. Cells now change with no transition at all, like hardware. A sixteen check Playwright harness verified autoplay, gesture gated sound, preset repaints, reduced motion compose and play, mobile grid scrolling, and zero horizontal overflow. The upgrade was Copy groove: the pattern, tempo, and swing pack into four hex words in the URL hash, and a shared link rebuilds the exact groove before anything moves.

  3. Pass three

    Content sweeps confirmed no banned dashes, no default easings, no dead controls; the accent budget was measured from final pixels and the interlude ruler, missed by both earlier scroll ladders, got its own verified viewport. The upgrade was tap tempo: four clicks on TAP average into a BPM, clamped to the transport's range, with a tempo flash on the readout. Counting a band in is how drummers set a clock, so the instrument had to allow it.

  4. Pass four

    A directed pass from the ranking round. The hero now opens with a one shot overture: bar one states the house groove, bar two plays a fill that stacks all four axes into the last sixteenth, and the stop lands exactly on the one, which is the composed rest state. It never loops, never runs under reduced motion, and grabbing any control takes the instrument over mid bar. The concrete field got material: procedural paper grain multiplied over the page, pressed plate offsets under the chrome, and a registration offset on the big specimens, all within the same three inks. And the weights table became notation: a dynamics column runs pp to ffff, and on first entry the whole crescendo rolls up from Light, each weight landing on an eighth note of the current tempo before settling into its printed state.