# Credits, sources and how to run this

Everything visual on this page traces to exactly **four** sources: one woodblock print, two
fonts, and original geometry. There is no fifth. (It was three until the terminal captures were
given a font of their own — see [The grid font](#the-grid-font).)

## Running it

The page loads its terminal captures from `data/frames.json`, so it needs to be served over
HTTP — opening `index.html` from the filesystem will leave the captures blank.

```sh
python3 -m http.server 8080     # then http://localhost:8080
```

## Artwork

Every photographic surface on the page is one artwork, shown in fragments:

> **Okumura Masanobu** (1686–1764), *Perspective View of the Interior of the Nakamura Theater
> with Ichikawa Ebizo II as Yanone Goro*, 1740. Hand-coloured woodblock print.
> Cleveland Museum of Art, Gift of Mr. and Mrs. J. H. Wade, accession **1916.1154**.
> **CC0 / public domain.**
>
> - Museum record: <https://www.clevelandart.org/art/1916.1154>
> - Source file: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Okumura_Masanobu_-_Perspective_View_of_the_Interior_of_the_Nakamura_Theater_with_Ichikawa_Ebiz_-_1916.1154_-_Cleveland_Museum_of_Art.tif)

CC0 imposes no attribution requirement. The credit is here because the museum digitised it and
because the print is doing a great deal of the argument's work: it shows a raised stage dead
centre, tiered boxes of seats down both walls all sighted on it, and a row of hanging lanterns
across the ceiling.

The CC0 status was verified independently against the Cleveland Museum of Art's open-access API
(`share_license_status: CC0`) and the Commons file page, rather than taken from a previous
credit line. Note that the Commons **filename truncates the title** to `…Ichikawa_Ebiz` — the
full title, and the one that should be quoted, ends *with Ichikawa Ebizo II as Yanone Goro*.
The date is a firm 1740, not "c. 1740".

The crops are duotoned into the product's own palette by `tools/build-assets.py`, which
downloads the source, cuts the four regions and writes WebP + JPEG at 2× and 1×:

```sh
python3 tools/build-assets.py            # uses the cached download if present
python3 tools/build-assets.py --force    # re-download the source
```

All three generators write into `public/assets/`. They used to write into a sibling `assets/`
directory, left over from when the page lived in `site/` — so after that directory was deleted a
regenerated mark landed somewhere nothing serves and the page silently kept the old one. Nine of
those files are *also* served from the site root, because that is where the `<link>`s and
`og:image` point; `make icons` now refreshes both and `make preflight` fails if they diverge.

The source is 5412 × 3389 and only four crops are used. A new section should **cut another
crop, not source another work** — the single-artwork reveal only holds because the fragments
are demonstrably one room.

## Typography in the mark

The hiragana ぶたい in the logo are outlines extracted from **Noto Sans JP**
(© Google, [SIL Open Font License 1.1](https://openfontlicense.org/)) at weight 700, and baked
into the SVG as paths. Verified against the font's own `name` table, not from documentation.

They are paths rather than live text on purpose: a visitor with no CJK font installed would
otherwise see tofu boxes where the brand is. **The font itself is not shipped** — only the
outlines the page uses. The OFL permits this; it restricts redistribution of the font software,
not artwork produced with it.

**On the script.** 舞台 is an ordinary Japanese word and its unmarked written form is the kanji,
which is what the hero gloss and the footer use. The mark is a logotype rather than running
text, so it sets the name phonetically. It used to set it in katakana (ブタイ); that is a real
convention for native words on signage, but stripped of the kanji it stops distinguishing 舞台
"stage" from 部隊 "military unit", which is the ambiguity `NAMING-ROUND-7.md` already flags.
Hiragana keeps the reading unambiguous and sits better beside the arch. `tools/build-logo.py`
and `tools/build-icons.py` both set it, and `build-icons.py` carries baked fallback outlines for
machines without fontTools — all three had to change together, or a build without the font would
have quietly emitted the old script.

The proscenium arch, the curtain legs and the stage apron are **original geometry**, drawn in
code. No font, no trace, no third-party source.

## Icons and the share card

```sh
pip install Pillow cairosvg fonttools
python3 tools/build-icons.py             # writes the whole set into assets/
```

Twenty-five files: favicons at 16/32/48 plus a multi-resolution `.ico`, `apple-touch-icon`,
PWA icons at 192/512 in both `any` and `maskable` cuts, a single-ink monochrome mark, the
1200 × 630 Open Graph card, the 1280 × 640 GitHub social preview, iOS masters (light, dark and
tinted) with an Xcode asset catalog, and a 10-slot `.icns` for macOS.

Two things the generator handles that are easy to get wrong: the maskable icons carry the 20%
safe zone, and the macOS master carries a 10% margin because macOS expects the squircle to sit
inside the canvas rather than fill it.

## Terminal captures

Nothing on this page is a screenshot. `data/frames.json` holds real captured cell grids —
styled runs of `[text, styleIndex]` — taken off a running daemon, and `js/terminal.js` paints
them into DOM spans at load.

See [`data/CAPTURING.md`](../data/CAPTURING.md) for the command that regenerates them. The
product is under active development, so **re-capture before any release of this page**; frames
taken against an older build will quietly misrepresent what ships.

The two stage diagrams are drawings. Everything else that looks like the product is the product.

**One redaction, applied after capture.** The SYSTEM rail reports the machine the capture ran
on, and that machine is a real one: it named a CPU model, a GPU model, its network interfaces
(including a Tailscale device) and its mount points with their sizes. Those runs are rewritten
to generic equivalents — `8-core x86`, `discrete`, `eth0`, `vpn0`, `/work`, `/data` — **each
one exactly as many characters as the string it replaces**, because a cell grid that changes
width is a cell grid that shears. The rewrite asserts that no row's width changed. Nothing else
is altered: every glyph, colour and weight is what the daemon drew.

The same reason the page no longer carries a "real capture" badge: the frames are real, the
gauges are redacted, and a badge asserting more than that would be overclaiming.

## The grid font

`assets/grid.woff2` (13 KB) is the font the terminal captures are painted in, and it is the
only font this site ships as a font.

It is built by [`tools/build-gridfont.py`](../../tools/build-gridfont.py) from **DejaVu Sans
Mono** with the braille block (U+2800-28FF) grafted in from **DejaVu Sans**, and two symbols
(U+23FA, U+23BF) remapped onto glyphs the font already has. DejaVu is distributed under the
[DejaVu licence](https://dejavu-fonts.github.io/License.html), a permissive Bitstream Vera
derivative that allows both redistribution and modification.

**Why it exists.** The captures were previously set in a system stack, and most monospace fonts
have no braille — which this UI is full of, because the SYSTEM sparklines are braille and every
working agent shows a braille spinner. The browser was serving those glyphs from a fallback
face **22% wider than a cell** (9.522px against 7.802px), so every sparkline and every spinner
row slid right. Worse, which font answered depended on the visitor's OS, so the page sheared
differently on every machine and was only ever checked on one.

`build-gridfont.py --check` fails if any codepoint in `frames.json` is missing from the font or
if two glyphs disagree on advance. Run it after any re-capture: a new screen can introduce a
glyph the subset does not carry.

## One deliberate palette deviation

`css/tokens.css` mirrors the `blueprint-dark` theme in `butai-core/src/theme.rs` so the page and
the captures cannot drift. One token departs: `--faint` is lifted from the theme's `#66738a` to
`#7d899f`, because the theme value is 3.64:1 on the page background and this page uses it only
at small sizes, where WCAG AA requires 4.5:1. The fix belongs in the theme; when it lands there,
this deviation should be removed. It does not affect the captures, which carry colours the
daemon resolved.
