# Heddle Loom

Heddle Loom is Tapestry's custom type family. It has three voices built around
one hierarchy:

- **Heddle Loom Mono** — display headlines, identity, code, paths, and IDs.
- **Heddle Loom Serif** — reading, editorial prose, ledes, and italic emphasis.
- **Heddle Loom Sans** — product UI, controls, navigation, and dense metadata.

## Files

- The three voice-specific `*-VF.ttf` files expose `wght` and seven named
  instances from ExtraLight 200 through ExtraBold 800.
- `*-VF.woff2` files are optimized web builds. The technical faces expose the
  `wght` axis only and contain a curated Latin/developer character set.
- `HeddleLoomTechnical-VF.ttf` and `.woff2` are the shared four-axis technical
  build: `wght` 200–800, `MONO` Sans 0 → Mono 1, `wdth` 100–125, and `slnt`
  0 → −11°. The site aliases Sans and Mono to this one resource.
- `HeddleLoomSerif-Italic.ttf` and `.woff2` are variable italic companions
  covering `wght` 200–800 and the native `opsz` 6–72 optical-size range.
- `*-Regular.otf`, `*-Semibold.otf`, and `*-Bold.otf` are static CFF OpenType
  instances. Static Bold is 700; 800 remains the variable ExtraBold. The serif
  also includes Italic, Semibold Italic, and Bold Italic OTFs.

## Character

The technical faces preserve a clean, sturdy skeleton. The identity capitals
H/E/D/L are optically centered within their cells so the HEDDLE wordmark keeps
an even rhythm at every weight. All encoded Mono outlines use centered cell
origins, while Sans enforces optical sidebearing floors for narrow letters and
figures. The voice-specific Sans and Mono files are packaged from these same
Technical endpoints so spacing cannot drift between desktop and web builds.
The uppercase Q uses a square-ended diagonal rail with a compact 4% em descent,
so it remains distinct from O without breaking all-caps lines.
Rectilinear rail intersections are boolean-unified rather than overlapped,
preventing hairline seams at display scale.

The sans and mono include one opt-in wordmark signature. Defaults remain quiet
for code and product UI.

- `ss01` — **Knot**: a diamond-shaped period for the HEDDLE wordmark.

The Knot interpolates with `wght`: it stays quiet beside light text and gains
area with the bold wordmark. Its left edge stays anchored to the wordmark
rhythm, and its bottom edge shares the E baseline with the round period through
the weight range. The technical faces also include arrows, common
comparison/math signs, a check mark, Shift, and a core light/heavy box-drawing
set so product and terminal UI do not fall back to another font.

Heddle Loom Sans includes class-based GPOS kerning for common uppercase,
lowercase, diagonal, punctuation, and quote transitions, plus a legacy `kern`
table for older desktop software. In the shared Technical font, GPOS kerning
scales through `wdth`/`slnt` and fades continuously to zero at `MONO` 1. Its
standard `liga` feature resolves `fi`, `fl`, `ff`,
`ffi`, `ffl`, `il`, `li`, and `ll` with shared crossbar or baseline rails. These are
collision-control forms, not decorative substitutions. Fixed-cell contextual
alternates are removed from Sans so prose spacing remains stable.

Heddle Loom Mono keeps programming ligatures off by default. Enable `dlig` to
shape `!=`, `<=`, `>=`, `->`, and `=>`; each operator preserves the width of
its two source characters so terminal and editor alignment remains stable.

## Provenance and license

Heddle Loom is a modified font family derived from Newsreader and Monaspace
Neon. Both foundations are distributed under the SIL Open Font License 1.1.
The derivative uses new family names and remains under the OFL. See `OFL.txt`.

- Newsreader: https://github.com/productiontype/Newsreader
- Monaspace: https://github.com/githubnext/monaspace

## Rebuild

```sh
python3 -m pip install -r scripts/requirements-fonts.txt
python3 scripts/build-heddle-loom-fonts.py
python3 scripts/validate-heddle-loom-fonts.py
```

The Newsreader and Monaspace build inputs live in `scripts/font-sources/` and
are intentionally kept outside the public `static/` tree. All release files
use installable embedding (`OS/2.fsType = 0`).
