feat(mockups): 12 vellum atlas (11's navigation in 10's style, motif toggle A/B/C)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas Winther
2026-10-30 00:06:43 +01:00
co-authored by Claude Opus 5.5
parent 89a30e5479
commit 298efca711
3 changed files with 82 additions and 60 deletions
+6
View File
@@ -161,6 +161,12 @@ This file exists because of that request. It gets updated after every user messa
agent to continue from the report's checklist; check its screenshots; rebuild the preview
container (command in §7); tell the user 12 is live and ask A/B/C.
### 11. Resumed
> "All right, usage limits back. Continue."
- Resumed from §10: one agent continues 12 from its pause report.
## Open questions (in priority order)
1. ~~Which sea-chart approach (08–11) reads best, or which mix?~~ 11's navigation + 10's style (§9).
@@ -1,63 +1,76 @@
# 12-vellum-atlas: PAUSE report (work in progress)
# 12-vellum-atlas: report
Status: **paused** to stay under the usage limit. Nothing is committed. The server on port 4112 is stopped.
Status: **done** (spike quality). Nothing is committed. Code: `src/mockups/12-vellum-atlas/` (`geo.ts`, `main.ts`, `style.css`).
`bun test` (44 pass) and `bun run typecheck` pass; `style.css` is unique among the mockups.
## What is done
The code is in `src/mockups/12-vellum-atlas/` (`geo.ts`, `main.ts` and `style.css`). It typechecks, and the last edits did too.
- **Navigation is 11's, unchanged in structure.** That covers:
- the overview and plate zoom;
- the cartouche, the locator, the breadcrumbs and prev/next;
- "continued on plate" notes;
- the scale of story time;
- the ←/→/Esc keys;
- the slip;
## What was built
- **11's navigation, unchanged in structure.** It has these parts:
- the general chart (overview) with a zoom into an inset plate per island;
- plate furniture: a cartouche, a locator "Key to the general chart", breadcrumbs, prev/next buttons, "From plate I" and "Continued on plate III" notes, and a scale of story time;
- the ←/→/Esc keys and the bottom song slip;
- `?saga= ?song= ?motif= ?overlay=1`, kept in sync with the URL;
- the overlay with "You are here" and "Sail here".
- **The look is 10's vellum portolan.** That includes:
- the paper, made from an feTurbulence grain and edge foxing;
- rods at both plate edges with curl shading;
- the red dashed course, rhumb lines and compass roses;
- the tan land with a green coast-wash and dashed water-lines;
- 10's storm swirl and ship glyph, the iron-gall motif inks and the dark desk.
- **Plates are re-laid with the land along the top.** This keeps the song slip from hiding the island. The order from top to bottom is:
- the land (Troy's coast, or the Island of the Cyclopes);
- the titles, the course and the story time;
- the motif marks;
- the scale bar, with a rose at the bottom right.
- **Motif toggle.** It is in the themes panel ("Themes on the plate: A Threads / B Pennants / C Ink only"), it accepts `?motifs=a|b|c` with `a` as the default, and the key changes per mode.
- **A:** wavy threads beneath the course, with knots at ports and names at the left. A thread runs off the plate edge when its theme plays on other plates. A selected thread is lit, its knots are labelled with part names, and the other threads fade.
- **B:** bunting pennants under each port. A selected theme hides the other pennants and draws one current under the bunting, with dotted tethers, chevrons, and "from earlier plates" or "on to later plates" at the edges.
- **C:** nothing shows until a theme is picked. Then its ports get hand-drawn ink rings and an italic part-name note with a flourish.
- **The overview keeps the halo, the "plays in N of M" badges and "silent here".** The silent badge now sits outside the dimmed island group, so it stays readable.
- **Cheap fixes from the 11 report:**
- an overlay (the "Captain's table") with a "You are here: Survive" chip, a ship on the chart, and a "Sail here" popover when you click a port.
- **10's vellum portolan look.** It has these parts:
- grain and foxing on the paper, rods with curl shading at the plate edges, and the red dashed course;
- rhumb lines and compass roses, tan land with a green coast-wash and dashed water-lines;
- 10's storm swirl and ship, the iron-gall motif inks, Cormorant and Inter type, and the dark desk.
- None of 11's slate cloth, cool paper or transit-style motif band is used.
- **Plates have the land along the top.** Below it come the titles, the course and the story time, then the motif marks, then the scale bar. As a result, the song slip (29% of the plate height) covers only open sea, never the island.
- **Motif toggle on plates.** "Themes on the plate: A Threads · B Pennants · C Ink only" sits at the top of the side panel. It also accepts `?motifs=a|b|c`, defaults to `a`, and the key changes per mode.
- **A, threads under the sea:** soft wavy threads in each theme's ink, knotted at the ports where the theme plays, with labels at the left. A thread runs off the plate edge when the theme continues on another plate. Picking a theme lights its thread, labels its knots with part names ("Verse 1") and fades the rest.
- **B, pennants at ports:** small bunting under each port, one pennant per theme. Picking a theme hides the other pennants and draws one faint current with chevrons, tethered to its ports. The current says "from earlier plates" or "on to later plates" at the edges.
- **C, ink only:** nothing shows at rest. Picking a theme rings its ports in hand-drawn ink and writes the part name below each one in a hand-lettered italic, with a flourish.
- **The overview's motif behaviour is kept from 11 and restyled.** It has the halo, the "Polyphemus plays in 2 of 4" badges and "silent here".
- **Fixes taken from 11's report:**
- Overview track rows are clickable, so one click opens the plate and the song.
- The Ocean plate is dressed with two rhumb roses, a big rose, the storm, rocks, "The open sea" and "two years at sea" along the incoming course.
- The slip is compact (29% height).
- **Screenshot review so far:** I checked default, motif, plate-a, plate-b, plate-c, song, overlay, ocean, troy, troy-b and troy-b-sel. Every collision I found has been fixed except the ones under "Still open" below.
- The Ocean plate is dressed as open water, with "The open sea", rhumb roses, a big rose, the storm with rain, rocks, and "two years at sea" written along the incoming course.
- The slip is compact.
## Left to do (checklist)
- [ ] **Look at the last batch.** It was rebuilt and shot, but I had not looked at it yet. The files are under `screenshots/12-vellum-atlas-`:
- `default`, `song`, `troy-song`, `plate-a`, `ocean`, `overlay-plate` and `plate-b-plain`.
- **Check that:**
- the thread rows now start just under the story-time labels and none is clipped by the slip on the Cyclops plate (7 themes) or the Troy plate;
- the overview "a year passes" now sits under the loop at port 5;
- the B key pennant icon renders;
- the overlay plate's ship tag and Sail-here popover are clear of titles.
- [ ] **Shoot the required set with the final names:** `default`, `motif` (`?motif=polyphemus`), `plate-a`, `plate-b` and `plate-c` (`?saga=cyclops&motif=polyphemus&motifs=a|b|c`), `song` (`?song=survive`), `overlay` and `ocean` (`?saga=ocean`). Delete the extras I made, or list them as extra: `troy`, `troy-b`, `troy-b-sel`, `troy-song`, `ocean-b`, `overlay-plate` and `plate-b-plain`.
- [ ] Check that the credits footer is fully visible in every state. It was visible in all the shots so far.
- [ ] Run `bun test` (not yet run this session) and `bun run typecheck`.
- [ ] Replace this file with the final report: what was built, what works, what doesn't, the screenshots, and a one-paragraph comparison of A/B/C.
### Fixes in this session
## Exact next step
Run `bash <scratchpad>/rebuild.sh`, where the scratchpad is `/tmp/claude-1000/-home-user-epic-the-musical-timeline/fb650f6d-47a0-47e4-8f6b-197d02417f3b/scratchpad/`. It builds to `r3-12/` and restarts only the 4112 server. Then run `bash <scratchpad>/shots.sh <name> "<query>" ...` and open the PNGs.
- The overview's "a year passes" note sits right under Troy's loop at port 5 instead of floating low.
- The overview's "two years at sea" note no longer crosses the course between ports 9 and 10.
- On the Ocean plate, the storm moved down and left so it no longer collides with the "Key to the general chart" caption.
- On the overlay plate, the ship moved left of the port so its mast no longer overlaps the "Survive" title.
- The overlay's "Sail here" popover now sits below the port's story-time caption instead of covering it.
- I re-checked these, and they are fine: no thread row is clipped by the slip on the Cyclops (7 themes) or Troy plates, the pennant icon in the B key renders, and the credits footer is fully visible in every shot.
## Gotchas
- A new build needs a server restart, because the asset hashes change. `rebuild.sh` kills only the PID listening on :4112.
- `rm -rf` on the outdir was denied by permissions, so just build over it.
- Plate vertical budget (viewBox 1100×700): ROUTE_Y is 312, and a new year drops the course by 30. The slip top sits at about y 483. Threads use `THREAD_STEP` 13, so 7 rows must end by y 470.
- `docs/design/002-direction-round-notes.md` shows as modified in `git status`. I did not edit it; it was probably changed by the coordinator or by the notes rule.
## Screenshots (1440×900)
## Early impressions of A/B/C (to firm up)
- **A** reads best as a system and carries 10's identity. Its band is busy on plates with 7 themes.
- **B** is the calmest at rest and charming. The current only reads once a theme is picked, and the meaning of a pennant colour needs the legend.
- **C** is the cleanest and most "navigator's note"-like, but shows nothing until you pick a theme.
Required:
- `screenshots/12-vellum-atlas-default.png`: the general chart.
- `screenshots/12-vellum-atlas-motif.png`: the general chart with `?motif=polyphemus`.
- `screenshots/12-vellum-atlas-plate-a.png`, `-plate-b.png`, `-plate-c.png`: the Cyclops plate with `?saga=cyclops&motif=polyphemus&motifs=a|b|c`.
- `screenshots/12-vellum-atlas-song.png`: `?song=survive`, the plate with the slip open.
- `screenshots/12-vellum-atlas-overlay.png`: `?overlay=1`.
- `screenshots/12-vellum-atlas-ocean.png`: `?saga=ocean`.
Extra:
- `screenshots/12-vellum-atlas-troy-song.png`: the Troy plate with a slip and 5 thread rows.
- `screenshots/12-vellum-atlas-overlay-plate.png`: the overlay on the Cyclops plate, showing the ship and the "You are here" tag.
- `screenshots/12-vellum-atlas-overlay-sail.png`: the overlay with the "Sail here" popover (`?overlay=1&song=remember-them`).
## What works
- The structure reads instantly: general chart, then plate, then song. The plate furniture carries the atlas metaphor well, and 10's vellum makes it feel like one object rather than a UI.
- With the land at the top, the slip, the threads and the scale never fight the island.
- The Ocean plate no longer looks empty. It reads as a deliberate stretch of open water.
- The overlay reuses the same chart. The ship, the "You are here" tag and "Sail here" all read clearly on the plates.
## What doesn't (or is weak)
- **On the Cyclops plate, A packs 7 thread rows** into about 90 px of plate. The faded labels are small (about 9 px on screen) and low-contrast at rest. That is fine as texture, but too small for reading.
- **With the slip open, the lower plate (the scale of story time) is hidden.** The threads stay visible, but the bottom of the plate is lost. The lower area is also fairly empty on plates without a slip.
- **The "Sail here" popover can cover thread labels**, for example on the Polyphemus port. It is transient, so this is acceptable for a spike.
- **On the overview, the motif halo around the storm overlaps the "two years at sea" note** slightly.
- **This is desktop 1440×900 only.** It was not tested at other sizes or with a screen reader beyond the basic labels and keys.
## A / B / C, honestly
**A (threads)** is the only one that works as a *system*. At a glance you see which themes run through a plate, where they enter and where they carry on, and it keeps 10's identity. The cost is density: with 7 themes the band becomes a striped ribbon whose labels are too small, and it competes with the course. **B (pennants)** is the most charming and the calmest at rest, and it looks like it belongs on a portolan. But a pennant's colour means nothing without the key, and the linking current only appears once you pick a theme, so B shows *which* themes are at a port better than how they *travel*. **C (ink only)** is the cleanest and the most "navigator's note"-like, and it is lovely once a theme is picked. At rest it shows nothing, so the chart never invites you to explore themes. My recommendation is **A as the default with B's restraint**: A already draws only the themes that play on the current plate, but a busy plate like Cyclops still needs more vertical room or lighter, slower rows. Borrow C's hand-lettered ink notes for the selected theme's part names.
## Rerun
Build and serve: `bun build src/server.ts --target=bun --production --outdir <scratchpad>/r3-12`, then
`cd <scratchpad>/r3-12 && PORT=4112 bun server.js`. Open `http://localhost:4112/mockups/12-vellum-atlas/`.
+8 -5
View File
@@ -258,10 +258,10 @@ function drawGeneral(root: SVGElement, mini = false) {
if (g <= 0) return;
const note = g === 1 ? "a year passes" : `${g === 2 ? "two" : g} years at sea`;
// Troy's year passes on the loop below port 5; the long crossing is written on open water.
if (song.sagaId === "troy") txt(root, 410, 630, note, "time-note", { "text-anchor": "middle" });
if (song.sagaId === "troy") txt(root, 410, 578, note, "time-note", { "text-anchor": "middle" });
else {
const a = OV_PORTS[i - 1]!, b = OV_PORTS[i]!;
txt(root, (a.x + b.x) / 2 - 4, (a.y + b.y) / 2 + 34, note, "time-note", { "text-anchor": "middle" });
txt(root, (a.x + b.x) / 2 - 22, (a.y + b.y) / 2 + 24, note, "time-note", { "text-anchor": "middle" });
}
});
@@ -344,7 +344,7 @@ function plateDressing(root: SVGElement, sagaId: string, L: InsetLayout) {
rhumbs(root, 190, 540);
rhumbs(root, 960, 150);
txt(root, 545, 172, "The open sea", "plate-sea-name", { "text-anchor": "middle" });
storm(root, 840, 232, 1.0);
storm(root, 830, 284, 1.0);
rock(root, 420, 540, 18, 9);
rock(root, 446, 556, 9, 13);
rock(root, 880, 470, 22, 3);
@@ -459,7 +459,7 @@ function drawInset(root: SVGElement, sagaId: string) {
const at = L.ports.find((p) => p.song.id === state.shipAt);
if (at) {
const lines = wrap(at.song.title, 15).length;
ship(root, at.x - 34, at.y + 1, `You are here: ${at.song.title}`, -22 - (lines - 1) * 22 - 25 - 24 + 1);
ship(root, at.x - 58, at.y + 1, `You are here: ${at.song.title}`, -22 - (lines - 1) * 22 - 25 - 24 + 1);
}
}
}
@@ -633,7 +633,10 @@ function sailPopover(song: Song) {
const host = plate.getBoundingClientRect();
pop = h("div", "sail-pop", undefined, plate);
pop.style.left = `${box.left + box.width / 2 - host.left}px`;
pop.style.top = `${box.top - host.top + 34}px`;
// Sit below the port's story-time caption, so the popover never covers it.
const times = [...(g.parentElement?.querySelectorAll(".port-time") ?? [])].map((e) => e.getBoundingClientRect().bottom);
const below = Math.max(box.bottom, ...times);
pop.style.top = `${below - host.top + 8}px`;
h("p", "sp-title", song.title, pop);
h("p", "sp-when", song.storyTime.label, pop);
if (song.id === state.shipAt) {