# Living type

One reusable writer for the opening and later short thoughts.

## What it does

Kalam Bold supplies broad, soft marker shapes. For each character, the browser draws the font into a small offscreen canvas, computes a one-pixel centreline with iterative thinning, measures local stroke thickness, and walks the resulting network. A nib-sized mask follows that network and exposes the actual font silhouette behind it. No horizontal wipe, text-width clipping, character pop-in, or opacity reveal is used for the writing.

Font outlines do not record how the hand moved. The engine therefore adds writing-order rules for the title's letters: stems before crossbars, the e beginning at its middle, counterclockwise bowls, the y returning down its stem, and retraced shoulders in m and n. The i receives its dot after the stem. Other characters use the general traversal. Brief lifts separate strokes; longer pauses separate words. The default phrase takes 4.4 seconds. New text adjusts the duration to its length, capped at twelve seconds.

“Try a line” accepts up to forty characters and reruns the same pipeline. The tested phrase was “what comes next?”. Text wraps by word on small screens; the opening becomes three lines. The accessible heading updates once per phrase, not on every animation frame.

## Paper and typography

Kalam Bold is the marker voice; DM Mono is the only supporting face. A light neutral sheet (`#f7f6f0`) has the quietest procedural grain of the three studies. A faint blur expands under each new stroke, and small opacity breaks let the paper tooth show through the ink. Stroke intersections were checked and softened so the joins do not turn into dark blobs.

## Libraries and assets

No JavaScript library. The centreline, distance field, path walking, and timing are implemented in plain JavaScript, using Canvas 2D. This keeps the demo self-contained and permits genuinely new input text. Font files come from the [Kalam source](https://github.com/google/fonts/tree/main/ofl/kalam) and [DM Mono source](https://github.com/google/fonts/tree/main/ofl/dmmono). Local WOFF2 files retain the font character sets; `Kalam-OFL.txt` and `DMMono-OFL.txt` include the SIL Open Font License notices. No third-party imagery.

## Known gaps

- Generic skeleton traversal cannot infer a perfect human ductus for every glyph. The title's letters are corrected; a production dynamic-text engine would need broader order rules and multilingual shaping tests.
- Kalam is intentionally broader and more regular than the team's hand. This route compares scalability, not photographic fidelity.
- The forty-character editor is a short-line demonstrator, not streaming response integration. Long unbroken words shrink to fit; unsupported glyphs may fall back to another browser font.
- Physical phone performance and Safari have not been measured. The grain and absorption are visual approximations.

## Verification

Rendered with the project's `concepts/tools/render.cjs`, using headless Chrome at 1440×900 and 390×844, with a 5000 ms settle and no scrolling. Both PNGs were inspected. Frozen writing frames at 900, 1800, 2800, 3700, and 5400 ms were also inspected, including partial letters. The evidence lives in `shots/`.

Replay works with a pointer and keyboard. Initial reduced motion, changing reduced-motion preference, and replay under reduced motion all show the finished line. The page does not scroll at 320×568, 390×844, 844×390, 1440×900, or 1920×1080. A readable static phrase remains with JavaScript disabled. All headless browser instances were closed after their checks.

## Controls and capture

Use the replay button to restart. Add `?t=1800` to freeze at an elapsed millisecond; `?t=0` shows the blank page. Reduced motion overrides this parameter. `window.demo.draw(ms)` is a deterministic capture hook. The page stops scheduling animation frames after the ink has settled.

## Local footprint

The HTML, script, loaded fonts, and ink asset total approximately 168.2 KiB before HTTP compression. There are no external runtime requests. In the local 390×844, DPR 2 headless check, initial readiness was 164 ms and mean JavaScript draw cost was 1.18 ms across thirty sample times. These are local measurements, not network-load or physical-device benchmarks.
