CHOIR is a mute vaulted nave that only sings when you move. There are no recordings: a formant-synthesis voice is built live in WebAudio, its vowel set by your cursor's horizontal position, its pitch by the vertical, wrapped in a synthesised stone reverb — and it dies to breath the instant you hold still.
Four pigments from a scriptorium: the near-black of oak-gall ink, the warm off-white of vellum, the fired red of a rubricated initial, and the dull gold of gilt. On the dark nave the vellum carries all body text, while the rubric and gilt are held back for the marks, the rules and the illuminated capitals. Because deep red and dark gold both fail on near-black at small sizes, every accent has a lit twin — a brighter rubric and a gold-leaf tone — reserved for the few places accent text sits on the dark.
Cardo is a scholarly, liturgical serif drawn for classicists — the right voice for a cathedral. It sets the wordmark, every heading and the rubricated drop-caps. In the wordmark the two vowels O and I are pulled out in gold and red, so the name itself spells the site's subject.
EB Garamond, a warm old-style face, carries the reading columns, the inscribed small-caps labels and the tabular formant tables. Its even colour keeps long text calm against the dark, and its numerals sit cleanly in the vowel reference.
setTargetAtTime. That is what gives the continuous, portamento feel of a real singer sliding between vowels.AnalyserNode taps the master bus. Its spectrum scrolls across the predella as a spectrogram — you can watch the formant bands slide as you cross the nave — while a second canvas draws the live resonance curve of the three filters.No AudioContext exists until your first gesture. The moment the cursor stirs, the graph is created and a voice appears from silence — horizontal position chooses the vowel by interpolating between the five cardinal formant patterns (ah, eh, ee, oh, oo), vertical position sets the pitch across two octaves, and the loudness rises with how fast you move. Hold still and the voiced tone dissolves within a breath, leaving only aspiration in the last vowel's shape. The rose window at the vanishing point brightens with your loudness. Nothing here has a voice but the one your hand makes — and it exists only while you are moving.
#CF5A48 and #C8A24B twins for the handful of accent labels that sit on the dark. No small text sits on the raw rubric or gilt.AudioContext exists — so it stayed empty and the scrolling throat never drew a single column, even though the voice was plainly audible. This is the exact failure a "no console errors, hero visible" check sails straight past. Rebuilt the map the instant audio starts and corrected the self-copy scroll; a pixel-count assertion in the headless driver now guards it (it went from 0% to 90% lit).fin()) and used setTargetAtTime throughout so no interpolation can ever pass a NaN or a zero to an exponential ramp — the failure mode that silently killed earlier audio sites.prefers-reduced-motion the spectrogram stops scrolling and shows a calm, low-rate instantaneous spectrum, the rose stops pulsing and the throat redraws only a few times a second — never blank, and the voice still answers the cursor because that is the whole point. Verified by driving the pointer under the reduced-motion media feature and asserting the voice still sounds and the throat stays lit.scrollWidth — that the wordmark, nav and voice rail sit inside the viewport, and bound pointer events with touch-action:none so a dragged finger sings on a phone exactly as a cursor does on a desktop.