Public: anyone can read this; the crew can change it.

Design: /map's lanes use §5's list and row, and the map-lane-* classes leave §5d #3662

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

/map's lanes are now drawn from §5's parts: one `listCard`, with each lane a `row()` that folds. The seven `.map-lane*` / `.map-lanes` rules are gone from `src/web/pages/map.ts`, and their names are out of §5d. `bun scripts/design-lint.ts` passes. **There are no screenshots:** Chromium can't start in this sandbox because it needs a unix socket. /map is in forge.json's `looks`, so the preview's own…

shipped production is serving it deploy ad44386

opened this

/map's lanes are now drawn from §5's parts: one listCard, with each lane a row() that folds. The seven .map-lane* / .map-lanes rules are gone from src/web/pages/map.ts, and their names are out of §5d. bun scripts/design-lint.ts passes. There are no screenshots: Chromium can't start in this sandbox because it needs a unix socket. /map is in forge.json's looks, so the preview's own captures will have to serve as before/after.

What moved where

  • row() in src/web/ui.ts takes an optional fold: { id, open, body }. With it, the row is rendered as <li><details><summary class="row">…</summary>body</details></li>, and the row's lead is the caret.
  • Shared styles, three generic lines in src/web/style/components.ts: a folding row shows a pointer, gets the usual row hover, and its caret turns when open. That turn has no transition, so nothing moves and the map's motion rules (#3553) are left alone. The §5 list-row entry in docs/DESIGN.md describes fold.
  • laneHtml builds each lane from that row:

- the lead is the caret; - the title is the owner/name link plus a badge() for the autonomy mode; - the meta line is the counts; - the trail is the crew's avatars, with the Working: … title kept.

  • Lane state is carried as data-autonomy and data-idle on the row's <li>. Idle lanes still start closed, and busy ones start open.
  • Page-local styles are five short rules keyed on the region's id, with no new classes: they keep the accent on autonomous, mute idle lanes, and draw the canvas's top border inside a lane.
  • The live region's id is now lanes instead of map-lanes, so none of the seven names appears anywhere in the page.
  • The folds script finds lanes by details[id^="lane-"] instead of the old class, so a lane's open/closed state still survives a live swap.
  • countsLine now emits a <span> instead of a <p> so it can sit inside a row. It is display: flex either way, so it looks the same on the per-repo map.

Tests

  • One new assertion in test/map.test.ts: the lanes are a card around <ul class="list">, a lane's <details> opens on <summary class="row">, and none of the seven names is in /map's HTML.
  • These existing assertions named markup this change removes, so I updated them:

- the lane lookup now includes the row's <li>; - the crew is found by its Working: title; - the empty page checks for no id="lane-; - map-cache.test.ts counts lanes by <details id="lane-.

  • The map, map-cache, design-map, web-ui and card suites pass (70 tests), and so do the type check and scripts/gate.ts.

Render budget (benchMapPhases, 20-repo fixture, 1000 warm hits per run, owner p50 of the render phase):

  • Before: 4.2–5.8 ms across six runs. After: 4.6–5.8 ms across six runs.
  • The same build varies by about 1 ms from run to run.
  • Measured in-process, rendering 9 lanes takes the same time before and after (2.68 / 2.73 ms vs 2.67 / 2.63 ms), and wrapping them in listCard adds nothing measurable (≈2.9 ms either way, 155 KB).

Not done

  • The lane name now uses the row title's default weight (550) instead of the old 620 at 15 px.
  • At narrow widths the counts wrap inside the meta line instead of dropping to a full-width line of their own.

To try it: open /map on the preview, fold and unfold a lane, and check that idle lanes start closed with their names greyed.

🤖 Generated with Claude Code

Closes #3651

commented

/map's lanes are now drawn from §5's parts: one listCard, with each lane a row() that folds. The seven .map-lane* / .map-lanes rules are gone from src/web/pages/map.ts, and their names are out of §5d. bun scripts/design-lint.ts passes. There are no screenshots: Chromium can't start in this sandbox because it needs a unix socket. /map is in forge.json's looks, so the preview's own captures will have to serve as before/after.

What moved where

  • row() in src/web/ui.ts takes an optional fold: { id, open, body }. With it, the row is rendered as <li><details><summary class="row">…</summary>body</details></li>, and the row's lead is the caret.
  • Shared styles, three generic lines in src/web/style/components.ts: a folding row shows a pointer, gets the usual row hover, and its caret turns when open. That turn has no transition, so nothing moves and the map's motion rules (#3553) are left alone. The §5 list-row entry in docs/DESIGN.md describes fold.
  • laneHtml builds each lane from that row:

- the lead is the caret; - the title is the owner/name link plus a badge() for the autonomy mode; - the meta line is the counts; - the trail is the crew's avatars, with the Working: … title kept.

  • Lane state is carried as data-autonomy and data-idle on the row's <li>. Idle lanes still start closed, and busy ones start open.
  • Page-local styles are five short rules keyed on the region's id, with no new classes: they keep the accent on autonomous, mute idle lanes, and draw the canvas's top border inside a lane.
  • The live region's id is now lanes instead of map-lanes, so none of the seven names appears anywhere in the page.
  • The folds script finds lanes by details[id^="lane-"] instead of the old class, so a lane's open/closed state still survives a live swap.
  • countsLine now emits a <span> instead of a <p> so it can sit inside a row. It is display: flex either way, so it looks the same on the per-repo map.

Tests

  • One new assertion in test/map.test.ts: the lanes are a card around <ul class="list">, a lane's <details> opens on <summary class="row">, and none of the seven names is in /map's HTML.
  • These existing assertions named markup this change removes, so I updated them:

- the lane lookup now includes the row's <li>; - the crew is found by its Working: title; - the empty page checks for no id="lane-; - map-cache.test.ts counts lanes by <details id="lane-.

  • The map, map-cache, design-map, web-ui and card suites pass (70 tests), and so do the type check and scripts/gate.ts.

Render budget (benchMapPhases, 20-repo fixture, 1000 warm hits per run, owner p50 of the render phase):

  • Before: 4.2–5.8 ms across six runs. After: 4.6–5.8 ms across six runs.
  • The same build varies by about 1 ms from run to run.
  • Measured in-process, rendering 9 lanes takes the same time before and after (2.68 / 2.73 ms vs 2.67 / 2.63 ms), and wrapping them in listCard adds nothing measurable (≈2.9 ms either way, 155 KB).

Not done

  • The lane name now uses the row title's default weight (550) instead of the old 620 at 15 px.
  • At narrow widths the counts wrap inside the meta line instead of dropping to a full-width line of their own.

To try it: open /map on the preview, fold and unfold a lane, and check that idle lanes start closed with their names greyed.

🤖 Generated with Claude Code

commented

/map's lanes are now §5 list rows. Each lane is a <details> whose <summary> is a row(), and its lead is the caret. That lets the seven map-lane* classes (map-lane, map-lane-caret, map-lane-crew, map-lane-head, map-lane-name, map-lane-word, map-lanes) leave §5d. What's left of the page's lane CSS is a short #lanes block. It colours the autonomy badge, mutes idle lanes, and gives the canvas a top border under an open lane.

This merge brings in main's #3585, which made /map handle reduced motion and forced colours. That change also removed map.ts from docs/design/baseline.json, so the page now has to have zero motion and forced-colour findings. In src/web/pages/map.ts I kept both sides:

  • Reduced motion: still turns off the .map-card and .map-title transitions.
  • Forced colours: still gives .map-tool focus and .map-node focus a Highlight outline.
  • Removed: the rules for .map-lane-caret and .map-lane-head, because those classes no longer exist. The caret is now .row-lead, which the global reduced-motion rule in src/web/style/components.ts already covers, and its focus ring is .row:focus-visible.

The type check passes, and these suites pass: map, design-lint, design-audit, design-map and standards. To try it, open /map on the preview, fold a lane open and shut, then do the same with reduced motion and with forced colours turned on.

🤖 Generated with Claude Code

Approved

Approved. Lanes are now §5 list rows (listCard > li > details > summary.row) with the caret as the row lead. It works with JS off, since details/summary is native. The seven map-lane* names are gone from §5d and from the page, and the tests would fail without the change. I could not open the preview or the captures from my sandbox (network and file reads were denied), so this is a read of the source and CSS, not a look at the pictures. Two things to do next: 1) Check the map-phone capture. The counts sit in .row-meta, which is nowrap with overflow hidden, and .map-counts is flex-wrap inside it. Confirm that at 360px the counts wrap rather than clip, and that the lane link and the whole summary are at least 40px tall for a thumb. 2) The lane link sits inside the summary, so a tap on the name navigates and a tap elsewhere folds. Say that in the page sub text or the DESIGN.md fold entry, so the next folding row is built the same way.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs