Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
adc8d28
plan+scaffold(asteroid): probe-verified #E plan + package skeleton
jowch May 29, 2026
c203a53
feat(#E): asteroid TUI demo — renderer-agnostic core + golden test
jowch May 29, 2026
ee56b8a
chore(#E): drop unused RERASTER_EVERY const (review nit)
jowch May 29, 2026
ce63d51
fix(#E): scatter fracture shards + presentation-quality golden frame
jowch May 29, 2026
942622f
docs(#E): point README to regenerated golden frame (drop stale excerpt)
jowch May 29, 2026
537c62f
feat(#E): showcase redesign — bigger shaped-text mass, motion, closed…
jowch May 29, 2026
3123c29
docs+cleanup(#E): fix stale README to hero scene; drop dead callout c…
jowch May 29, 2026
4a04751
Merge remote-tracking branch 'origin/main' into demos-E-asteroid-tui
jowch May 29, 2026
1592047
test(#E): headless game-loop smoke test — prove the game actually runs
jowch May 29, 2026
2d2612a
fix(#E): guard drain_to_tachikoma! with in_bounds — fixes real render…
jowch May 29, 2026
ddcb010
fix(#E): run_game crashed on startup — wrong Tachikoma Terminal API (…
jowch May 29, 2026
a9a8d14
feat(#E): real playable Asteroid TUI — input, render, injectable head…
jowch May 29, 2026
4b765e3
docs(#E): run.jl controls + refuse to start headless (no infinite loop)
jowch May 29, 2026
ee2c53f
docs(#E): reconcile stale "no-op present" header comments
jowch May 29, 2026
5333ead
docs(#E): interactive controls & collision polish design spec
jowch May 29, 2026
6153dd8
docs(#E): spec review round 1 — apply claim-verified fixes
jowch May 29, 2026
045c658
docs(#E): spec review round 2 — precision/completeness + refactoring …
jowch May 29, 2026
25b37b5
docs(#E): spec review round 3 — close specification gaps
jowch May 29, 2026
04d521c
docs(#E): spec review round 4 — refinements + risk-test
jowch May 29, 2026
c0efbe5
docs(#E): spec review round 5 — converged (0 majors)
jowch May 29, 2026
f829893
docs(#E): spec refinements from plan-detailing fan-out
jowch May 29, 2026
02beaf6
docs(#E): implementation plan (TDD, bite-sized) from detailing fan-out
jowch May 29, 2026
0ca438a
docs(#E): plan review round 1 — fix octant bug, blocker, vacuous reds
jowch May 29, 2026
c621b1d
docs(#E): plan review round 2 — converged (0 blocker/major)
jowch May 29, 2026
3796f77
build(#E): add [sources] so asteroid_tui Pkg.test() instantiates
jowch May 29, 2026
14415ad
feat(#E): wrap-aware delta + visual-space aim_heading helpers
jowch May 29, 2026
b1c3330
feat(#E): twin-stick Input — WASD strafe + mouse-aim cursor + statefu…
jowch May 29, 2026
2e68c8f
feat(#E): bump asteroid spawn velocity (rescale only; golden unpertur…
jowch May 29, 2026
d9f4d5a
fix(#E): fracture_asteroid! honours impact via cell→polygon frame con…
jowch May 29, 2026
5e17f64
feat(#E): asteroid↔asteroid wrap-aware bounce / fracture-both-on-hard…
jowch May 29, 2026
88f9fdc
feat(#E): wire ship↔asteroid death (kill_ship! on wrap-aware contact)
jowch May 29, 2026
f1d207f
feat(#E): field replenish — edge-spawn one asteroid per tick toward n…
jowch May 29, 2026
be4b595
feat(#E): directional 8-way ship glyph, beam-from-nose, cut targeting…
jowch May 29, 2026
8bc882c
test(#E): regenerate golden for directional ship glyph (visually veri…
jowch May 29, 2026
e9a6cce
fix(#E): wrap-aware beam→asteroid hit test (consistency with other re…
jowch May 29, 2026
ccd1ff2
tune(#E): slow asteroid field ~7× (coeff 1.4→0.2, SHATTER_CLOSING 0.9…
jowch May 29, 2026
bed6d45
perf(#E): precompile workload cuts asteroid_tui first-frame TTFX ~28s…
jowch May 29, 2026
c8b51b2
feat(#E): asteroids/shards don't wrap — leave + despawn off-screen; i…
jowch May 29, 2026
8922f4c
feat(#E): projectiles replace the laser beam — charge fires a (1+char…
jowch May 29, 2026
58170ab
feat(#E): asteroids visually rotate — silhouette tumbles + prose re-f…
jowch May 29, 2026
62fa161
feat(#E): single 8-way arrow ship glyph (replaces hull+octant-nose)
jowch May 29, 2026
266aedf
fix(#E): callout hugs the asteroid prose (anchor to content extent, n…
jowch May 29, 2026
b90f622
test(#E): regenerate golden for arrow ship + content-anchored callout…
jowch May 29, 2026
ef2c2bb
tune(#E): bump asteroid spin ~6× so rotation is actually perceptible
jowch May 29, 2026
d8b3238
design(gallery): impeccable house-style redesign + pinned fonts + /go…
jowch Jun 13, 2026
738e313
refactor(gallery): move DESIGN.md + PRODUCT.md under examples/
jowch Jun 13, 2026
1640d64
feat(gallery): font pre-flight smoke test + lock #H masthead brass role
jowch Jun 13, 2026
2eea62c
feat(#E): silhouette rim + brass footer middot + shard recolor
jowch Jun 18, 2026
f6add9b
chore(#E): add colored-HTML capture tool + ignore generated artifacts
jowch Jun 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ reference-conversation.md

# Visual-companion brainstorming session artifacts (per-session HTML mockups)
.superpowers/

# demo render artifacts + local review screenshots (generated)
examples/*/build/
.playwright-mcp/
*-filmstrip-*.png
E-*.png
112 changes: 77 additions & 35 deletions docs/superpowers/demos-house-style.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,106 @@
# TextMeasure.jl Demos — House Style

Single source of truth for the demo gallery (#E #F #G #H #K). All five demos MUST use
these exact values — no ranges, no per-demo drift. Authored by the design review pass
(2026-05-28), grounded in type-contrast / palette-discipline / spatial-composition /
depth / restraint principles. Coherence ≠ uniformity: a map, a magazine cover, and a TUI
should differ — but they share this spine so the gallery reads as authored, not assembled.
these exact values — no ranges, no per-demo drift. Redesigned 2026-06-13 under
[Impeccable](https://github.com/pbakaus/impeccable) + frontend-design guidance, anchored
by [`DESIGN.md`](../../examples/DESIGN.md) (the craft rubric) and [`PRODUCT.md`](../../examples/PRODUCT.md)
(what each piece must prove). Supersedes the 2026-05-28 spine (Liberation Serif / DejaVu
Sans / pure-white / three co-equal accents), which read disciplined-but-generic.

**Concept: "editorial instrument."** A compositor's eye (high-contrast editorial serif)
metered by a measuring tool (fixed-pitch mono). Coherence ≠ uniformity: a map, a magazine,
and a TUI differ — but they share this spine so the gallery reads as *authored by one
hand*, exact to the pixel, memorable in one detail.

## 1. Type — two faces, contrast axis

- **Serif** (display / title / deck / body / editorial): **Fraunces** (OFL). Use its
**display** optical size for mastheads (loud, high-contrast, light WONK) and its **text**
optical size for body / #K columns (calmed, justifies cleanly).
- **Mono** (caption / label / stat / axis / footer / **#E TUI**): **IBM Plex Mono** (OFL).
The fixed pitch *is* the concept — every advance exact.

**Sourcing (determinism).** Static TTFs are pinned in `examples/fonts/` (committed, with
each family's `OFL.txt`) — no system fonts, no variable-axis instances, so glyph advances and
goldens stay reproducible. **Load by file path, not family name:** these static instances
split weights/optical sizes into separate name-table families (`Fraunces 9pt`,
`Fraunces 9pt Black`, `IBM Plex Mono Medm`, …), so there is no single "Fraunces" family to
select — path-loading is the only deterministic selector. Pinned files:

- Body / small → `Fraunces/Fraunces9pt-{Regular,Italic,SemiBold,Black}.ttf` (text opsz)
- Subhead / title / deck → `Fraunces/Fraunces72pt-{Regular,Black}.ttf`
- Masthead → `Fraunces/Fraunces144pt-{Light,Regular,Black}.ttf` (display opsz)
- Mono (caption/label/stat/footer/TUI) → `IBMPlexMono/IBMPlexMono-{Regular,Italic,Text,Medium,SemiBold,Bold}.ttf`

Fixed size ramp (pt) — re-founded on **√2 (≈1.414)**, the ISO-216 paper ratio (the type
scale shares the proportion of the page it prints on). Pick the tier by role, never an
in-between value. Locked contrast anchors: **title = 2× body, display = 4× body.**

| Tier | pt | Face | Role |
|---------|----|------|------|
| caption | 9 | IBM Plex Mono | footers, source lines, axis/figure notes (legibility floor) |
| body | 11 | Fraunces text | paragraph prose, abstracts, column text |
| subhead | 16 | Fraunces | panel/section headers, stat labels, column titles |
| title | 22 | Fraunces | article/panel title (e.g. DOI panel headlines) **(2× body)** |
| deck | 31 | Fraunces | section decks / secondary display |
| display | 44 | Fraunces display | mastheads only: CALIFORNIA, "The Newer Yorker", main figure title **(4× body)** |

## 1. Type
Display-to-body contrast = **4×**; title-to-body = **2×**. Locked — do not soften.

- **Serif** (body / editorial / titles): `Liberation Serif`
- **Sans** (labels / captions / UI / stats / TUI): `DejaVu Sans`
Body sets **ragged-right** by default (no full-justify) **except #K**, whose justified
columns *are* the demo.

Both are already pinned in the demos — no new font installs.
## 2. Palette — two layers, OKLCH-tuned, locked

Fixed size ramp (pt) — pick the tier by role, never an in-between value:
Identity comes from paper + ink + one signature; the old blue/green/red are demoted to
**data encoding only** (a bar, a winner, a correctness flag *inside* a demo), never
identity decoration.

| Tier | pt | Role |
|---------|----|------|
| caption | 9 | footers, source lines, axis/figure captions |
| body | 11 | paragraph prose, abstracts, column text |
| subhead | 14 | panel/section headers, stat labels, column titles |
| title | 22 | article/panel title (e.g. DOI panel headlines) |
| display | 44 | mastheads only: VERMONT, "The Newer Yorker", main figure title |
### Identity layer

Display-to-body contrast = **4×**; title-to-body = **2×**. Locked — do not soften.

Body sets **ragged-right** by default (no full-justify) **except #K**, whose justified
columns *are* the demo.
| Name | Hex | RGBA | Role |
|------|-----|------|------|
| PAPER (background) | `#FBFAF7` | `RGBA(0.984, 0.980, 0.969, 1)` | every surface — off-white stock, faint chroma toward brass. **Never `#FFFFFF`.** |
| INK (text) | `#1E1C1A` | `RGBA(0.118, 0.110, 0.102, 1)` | body / titles — warm near-black |
| BRASS (signature) | `#B5793C` | `RGBA(0.710, 0.475, 0.235, 1)` | masthead **rules & datelines** (never the wordmark itself — brass carries structure/accents, not large identity text), structural rules, footer middot, registration/measurement marks. The one color threading all five pieces. |

## 2. Palette — 3 accents + 1 gray, locked
### Data layer (encoding-only — NOT identity)

| Name | Hex | RGBA | Used by |
|-------|-----|------|---------|
| BLUE (neutral/data) | `#2B6CB0` | `RGBA(0.169, 0.424, 0.690, 1)` | #F citation bars + tag chips; #H skyline inset base tone |
| GREEN (good/winner) | `#1B7A3D` | `RGBA(0.106, 0.478, 0.239, 1)` | #G silhouette fill; #K K–P column label; #F green-OA label |
| RED (problem/attention) | `#C0392B` | `RGBA(0.753, 0.224, 0.169, 1)` | #H "A Correctness Exhibit" subtitle; #K river overlays |
| GRAY (captions/footers/rules) | `#6B7280` | `RGBA(0.420, 0.447, 0.502, 1)` | all footers, captions, hairline rules (alpha 0.15–1.0 per below) |
| Name | Hex | RGBA | Used by |
|------|-----|------|---------|
| BLUE (data/neutral) | `#2E6FB5` | `RGBA(0.180, 0.435, 0.710, 1)` | #F citation bars + tag chips; #H skyline inset base tone |
| GREEN (good/winner) | `#2E7D4F` | `RGBA(0.180, 0.490, 0.310, 1)` | #G silhouette fill; #K K–P column label; #F green-OA label |
| RED (problem/attention) | `#C0432F` | `RGBA(0.753, 0.263, 0.184, 1)` | #H "A Correctness Exhibit" subtitle; #K river overlays |
| GRAY (structure) | `#6B7280` | `RGBA(0.420, 0.447, 0.502, 1)` | captions/footers body, hairline rules (alpha 0.15–1.0 per §5) |

Background = pure white `#FFFFFF`. Body text = near-black `#1A1A1A` `RGBA(0.10,0.10,0.10,1)`.
These four are the ONLY accent colors. No other blues/greens/reds anywhere.
PAPER, INK, BRASS + the four data colors are the ONLY colors. No other hues anywhere. A
data color used for identity (or off its assigned meaning) is a defect.

## 3. Footer (all print pieces #F #G #H #K)

- **Text**: `TextMeasure.jl · <demo name>` (middot U+00B7, single spaces) — e.g.
`TextMeasure.jl · DOI Infographic` / `· Vermont` / `· The Newer Yorker` / `· Knuth–Plass`
- **Font/size**: DejaVu Sans, 9 pt (caption tier)
- **Color**: GRAY `#6B7280`
`TextMeasure.jl · DOI Infographic` / `· California` / `· The Newer Yorker` / `· Knuth–Plass`
- **Font/size**: IBM Plex Mono, 9 pt (caption tier)
- **Color**: text in GRAY `#6B7280`; the **middot in BRASS** `#B5793C` (the signature's
smallest appearance)
- **Position**: bottom-left, baseline on the inner margin line
- **Outer margin**: **36 px on all four sides** of every print piece (content inside this box)
- **TUI #E**: no px footer; reserve the bottom border row for the same string.
- **TUI #E**: no px footer; reserve the bottom border row for the same string (mono, ink on
paper-equivalent cell, brass middot).

## 4. Caption / figure-note style

- Font: DejaVu Sans · Size: 9 pt (caption tier) · Color: GRAY `#6B7280`
- Font: IBM Plex Mono · Size: 9 pt (caption tier) · Color: GRAY `#6B7280`
- Align: **LEFT**, anchored to the left edge of the content block it describes (never page-centered)
- Leading: 1.3×
- Applies to: #K figure note, #G footer, #F per-panel DOI/source line, #H byline.

## 5. Rules / hairlines (shared)

- Hairline (separators/gutters): 0.5 px, GRAY `#6B7280` @ alpha **0.15**
- Structural rules (masthead underline, pull-quote rules): 1.0 px, GRAY @ alpha **1.0**
- Structural rules (masthead underline, pull-quote rules): 1.0 px, **BRASS `#B5793C` @ alpha
1.0** (the signature does the structural work; reserve GRAY @ 1.0 for non-signature rules)
- Chart baselines (#F bars): 1 px GRAY @ alpha **0.25**
- Registration / measurement marks (optional per piece): BRASS, 0.5 px — crop-mark /
surveyor's-tick motif reinforcing the "instrument" concept. Use sparingly; restraint over
decoration.
Loading