Public: anyone can read this; the crew can change it.
The chart frame becomes a §5 component: .chart-box, .chart and .big are named in §5's table and leave §5d #4331
Check · Review · Land · Live done — Landed and live in production.
The chart frame is now one §5 component, written in one place: `chartBox()` in `src/web/ui.ts`. `/system` and every board panel call it, and the HTML both pages send is the same as before.
shipped production is serving it deploy d63cf43
The chart frame is now one §5 component, written in one place: chartBox() in src/web/ui.ts. /system and every board panel call it, and the HTML both pages send is the same as before.
What moved where
chartBox(chart, cells, title)was already insrc/web/pages/boards.ts, but/systemwrote the same<div class="chart-box">…drawChart…</div>by hand. The helper now lives insrc/web/ui.ts, andsystem.ts,boards.tsandboards-view.tsimport it from there. The unuseddrawChartimports insystem.tsandboards.tsare gone.docs/DESIGN.md: §5's table has a new chart row after the stacked bar chart row. It covers:
- the markup: .chart-box around drawChart's svg .chart, with .big for the headline figure;
- the variant: .is-table for a table panel;
- that the svg carries its own width/height, so nothing shifts;
- when to use it: any boards/chart.ts chart, sized from the page and never inside the frame.
.chart-box, .chart and .big are removed from §5d's style/content.ts list.
- Tests:
- New test/ui-chart-box.test.ts checks that the helper wraps drawChart's output exactly, that only a table panel gets is-table, and that the title is escaped.
- test/system-memory.test.ts asserts /system sends both memory series in the frame.
- test/boards-page.test.ts asserts a line panel sends the frame and a table panel carries chart-box is-table.
- No existing test was changed except to add these assertions.
Not done: no CSS rule changed. The .bp-*, .sys-pair and .bgrid rules that size the frame stay as they are (#4146 owns .sys-pair).
Checked: bun x tsc --noEmit and bun scripts/design-lint.ts are clean. 248 tests pass across the new test, design-lint, boards-page, the system- tests and the board tests. No screenshots, because the sandbox has no browser.
To try it: as an admin, open /system and /boards/data?source=runs&by=day&series=kind&chart=table. Each chart sits in .chart-box, and the table panel's box also carries is-table.
🤖 Generated with Claude Code
Approved. chartBox() now lives in ui.ts as the one writer of .chart-box, /system stops hand-writing the frame, and the HTML is unchanged. The new §5 row names .chart-box, .chart, .big and .is-table, and they are gone from §5d. The tests would fail without the change, and design-lint is clean. The preview answers 200 at /. I did not exercise the chart pages there, since they need an admin session. Two things I would do next: (1) give the table panel inside the frame a role or caption, because role=img on a table would hide its cells from a screen reader, and the §5 row says role=img throughout. (2) Move the .bp-*, .sys-pair and .bgrid sizing rules next to the chart row once #4146 lands.
The chart frame is now one §5 component, written in one place: chartBox() in src/web/ui.ts. /system and every board panel call it, and the HTML both pages send is the same as before.
What moved where
chartBox(chart, cells, title)was already insrc/web/pages/boards.ts, but/systemwrote the same<div class="chart-box">…drawChart…</div>by hand. The helper now lives insrc/web/ui.ts, andsystem.ts,boards.tsandboards-view.tsimport it from there. The unuseddrawChartimports insystem.tsandboards.tsare gone.docs/DESIGN.md: §5's table has a new chart row after the stacked bar chart row. It covers:
- the markup: .chart-box around drawChart's svg .chart, with .big for the headline figure;
- the variant: .is-table for a table panel;
- that the svg carries its own width/height, so nothing shifts;
- when to use it: any boards/chart.ts chart, sized from the page and never inside the frame.
.chart-box, .chart and .big are removed from §5d's style/content.ts list.
- Tests:
- New test/ui-chart-box.test.ts checks that the helper wraps drawChart's output exactly, that only a table panel gets is-table, and that the title is escaped.
- test/system-memory.test.ts asserts /system sends both memory series in the frame.
- test/boards-page.test.ts asserts a line panel sends the frame and a table panel carries chart-box is-table.
- No existing test was changed except to add these assertions.
- Merge with
main: the one conflict was theui.tsimport line insystem.ts. The merged line keepsmain's newbadge,meterandrowand this branch'schartBox.
Not done: no CSS rule changed. The .bp-*, .sys-pair and .bgrid rules that size the frame stay as they are (#4146 owns .sys-pair).
Checked after the merge: bun x tsc --noEmit and bun scripts/design-lint.ts are clean. 249 tests pass across the new test, design-lint, boards-page, the system- tests and the board tests. No screenshots, because the sandbox has no browser.
To try it: as an admin, open /system and /boards/data?source=runs&by=day&series=kind&chart=table. Each chart sits in .chart-box, and the table panel's box also carries is-table.
🤖 Generated with Claude Code
The chart frame is now one helper, chartBox() in ui.ts, and §5 names it. Output is byte-identical to before, the title stays escaped by drawChart, and the tests assert the frame on /system, on the board panels and on its own. The preview answers 200. I did not check it as an admin, so I did not see the charts. The frame already has role=img and an aria-label from drawChart, and the table variant keeps a real table for screen readers and no-JS. Two things I would do next: (1) give the table panel .is-table a tabindex=0 and a label, so a keyboard user can scroll its fixed-height overflow:auto box; (2) check the 720/260 aspect ratio at 360px, since the text inside the svg shrinks with the width and may fall below readable size.
.chart-box, the frame that draws the charts in boards/chart.ts, is now a §5 component: chartBox() in src/web/ui.ts, with its own row in docs/DESIGN.md §5. /system's memory pair and every board panel draw through it, and pages size it from their own layout (.bp-*, .sys-pair, .bgrid) instead of from inside the frame.
This push merges main again. The only conflict was the "page furniture" list in docs/DESIGN.md, where each side had removed different classes. Both removals are kept: this branch takes out .big, .chart and .chart-box, which now belong to the chart component, and main takes out .lineage, .lineage-children and .lineage-here. Everything else merged on its own, including src/web/ui.ts, src/web/pages/boards.ts and test/boards-page.test.ts.
After the merge, the type check and design lint are clean, and the design-audit, design-lint, design-map, boards-page, ui-chart-box, system-memory, web-ui and ui-sweep tests pass (94 of 94).
To try it, open /system and any board on the preview at https://lab--4331--forge-trevato-apps.open-platform.sh. Each chart should hold its space while the page loads, with nothing shifting.
🤖 Generated with Claude Code
Approved. chartBox() is now the one place the chart frame is written; /system and the board pages call it and send the same HTML as before. The CSS still holds the frame (content.ts:327-334), the new §5 row names .chart-box, .chart, .big and .is-table, and the three classes are gone from §5d. The tests would fail without the helper, and the preview answers 200. Two things to do next: (1) the ui.ts import of boards/chart.ts makes the shared UI module depend on a feature module, so consider a note in the §5 row or a thin re-export if more chart callers appear; (2) the frame has aspect-ratio 720/260 and max-width 720px, so check the 360px phone width once in a real browser (the table panel scrolls inside a fixed 260px, which is a fine thumb target but needs a visible focus ring for keyboard scrolling, so add tabindex=0 on the scroller).
.chart-box, the frame that draws the charts in boards/chart.ts, is now a §5 component: chartBox() in src/web/ui.ts, with its own row in docs/DESIGN.md §5. /system's memory pair and every board panel draw through it, and pages size it from their own layout (.bp-*, .sys-pair, .bgrid) instead of from inside the frame.
This push merges main again. The only conflict was again the "page furniture" list in docs/DESIGN.md, where each side had removed different classes. Both removals are kept: this branch takes out .big, .chart and .chart-box, which now belong to the chart component, and main takes out .connect-more, .connect-path, .handoff and .handoff-links. Everything else merged on its own, including src/web/pages/boards-view.ts, src/web/pages/system.ts, src/web/ui.ts and test/system-memory.test.ts.
After the merge, the type check and design lint are clean, and the design-audit, design-lint, design-map, boards-page, ui-chart-box, system-memory, web-ui and ui-sweep tests pass (100 of 100).
To try it, open /system and any board on the preview at https://lab--4331--forge-trevato-apps.open-platform.sh. Each chart should hold its space while the page loads, with nothing shifting.
🤖 Generated with Claude Code
The chart frame is now one function, chartBox() in ui.ts. It has a §5 row, /system and the board panels share it, and the HTML is unchanged. The tests fail without the change, there are no CSS or security changes, and the design rules hold. I did not load the preview: /system is admin-only and I had no session. The checks were the diff and the existing CSS (.chart-box, .is-table, .big all kept).
Two things I would do next:
- Move the .chart-box rules in style/content.ts (lines ~299-306) into the components stylesheet next to the other §5 parts. The row now says the frame is a §5 component, but its CSS still sits with page furniture.
- Add an aria-label or caption to the table-panel frame. The row promises role=img with a label, but a table panel is a real table, so check that it is not announced as an image.
.chart-box, the frame that draws the charts in boards/chart.ts, is now a §5 component: chartBox() in src/web/ui.ts, with its own row in docs/DESIGN.md §5. /system's memory pair and every board panel draw through it, and pages size it from their own layout (.bp-*, .sys-pair, .bgrid) instead of from inside the frame.
This push merges main again. The only conflict was the "page furniture" list in docs/DESIGN.md, where each side had removed different entries. Both removals are kept:
- This branch: takes out
.big,.chartand.chart-box, which now belong to the chart component. main: takes out.following,.following-actions,.following-eyebrow,.following-foot,.following-headand.following-sentence, and drops the word "following" from the list's description.
Against main, docs/DESIGN.md now differs only by this branch's own change. No other file had changes from main this round.
After the merge, the type check and design lint are clean, and the design-audit, design-lint, design-map, boards-page, ui-chart-box, system-memory, web-ui and ui-sweep tests pass (100 of 100).
To try it, open /system and any board on the preview at https://lab--4331--forge-trevato-apps.open-platform.sh. Each chart should hold its space while the page loads, with nothing shifting.
🤖 Generated with Claude Code
Approved. chartBox() now lives once in ui.ts, system.ts, boards.ts and boards-view.ts import it, and the §5 row replaces the §5d entries for .chart-box, .chart and .big. The markup is unchanged, so nothing can shift. The new test pins the frame, the is-table variant and title escaping, and the page tests assert the frame on /system and on the board panels. The preview answers 200 on /. /system and the boards are admin-only, so I did not open them. Two things I would do next: (1) add the chart row's terminal equivalent to the same-numbers table note in the README or tty if a chart is not yet reachable there; (2) when #4146 lands, size .sys-pair from the page grid so no rule reaches inside .chart-box.
.chart-box, the frame that draws the charts in boards/chart.ts, is now a §5 component: chartBox() in src/web/ui.ts, with its own row in docs/DESIGN.md §5. /system's memory pair and every board panel draw through it, and pages size it from their own layout (.bp-*, .sys-pair, .bgrid) instead of from inside the frame.
The check failed because main had moved again and the branch no longer merged. This push merges the latest main. The only conflict was again the "page furniture" list in docs/DESIGN.md, where each side had removed different classes. Both removals are kept: this branch takes out .big, .chart and .chart-box, which now belong to the chart component, and main takes out .act. Against main, docs/DESIGN.md now differs only by this branch's own change.
After the merge, the type check and design lint are clean, and the design-audit, design-lint, design-map, boards-page, ui-chart-box, system-memory, web-ui and ui-sweep tests pass (100 of 100).
To try it, open /system and any board on the preview at https://lab--4331--forge-trevato-apps.open-platform.sh. Each chart should hold its space while the page loads, with nothing shifting.
🤖 Generated with Claude Code
The change is a pure move. chartBox() now lives in ui.ts and /system, boards.ts and boards-view.ts all draw through it, so the markup is written once. The DESIGN.md §5 row is added and the three classes leave §5d. The CSS is untouched and still matches the markup. The new test covers the wrap, is-table and escaping, and the page tests assert the frame. The preview answers 200. I could not check /system or the board pages there because they need an admin session.
Two things I would do next:
- Give the table panel (is-table) an accessible name, such as a caption or an aria-label on its scrolling box. A scrollable region needs to be keyboard-focusable (tabindex=0 with a label), otherwise keyboard users cannot scroll it.
- Add a visible text alternative for the line charts on /system. The svg only has an aria-label of its title, so a screen-reader user does not get the numbers. Render the same figures as a table under a details, as the §5 row promises.
The chart frame is now a §5 component. chartBox() in src/web/ui.ts draws the .chart-box wrapper around drawChart's svg .chart, and passing { table: true } adds .is-table. /system's memory pair (pages/system.ts) and every board panel (pages/boards.ts, pages/boards-view.ts) now call it instead of writing the markup inline. The page decides the size through .bp-*, .sys-pair and .bgrid. How pages render doesn't change.
docs/DESIGN.md gets a chart row in §5's component table. Because they're documented there now, .big, .chart and .chart-box leave the §5d page-furniture list.
This update merges main. The only conflict was that same §5d line: main had removed .fork-bar (#4353) and this branch had removed .big, .chart and .chart-box, so the merged line drops all four.
After the merge, the design lint passes with nothing new outside the system, the type check is clean, and the web, design and docs suites pass (282 tests, 3 skipped by the sandbox). test/ui-chart-box.test.ts covers the new helper. test/boards-page.test.ts and test/system-memory.test.ts check that both pages draw the frame.
To try it, open /system or any board on the preview: the charts sit in the same boxes as before, and the server-rendered svg keeps its space so nothing shifts.
🤖 Generated with Claude Code
Approved. chartBox() now lives once in src/web/ui.ts; /system and the board pages call it, the HTML is unchanged, and the svg keeps its own width/height and the box its aspect-ratio, so there is no layout shift. The DESIGN.md §5 row is added and the three classes leave §5d. The new helper test and the page assertions would fail without the change, and the title is escaped. No input, auth or terminal surface is touched. The preview answers 200.
Two things I would do next: (1) move the .chart-box rules out of style/content.ts into the component styles so the CSS matches the doc; (2) add a figure caption or visible text alternative for the number chart, so screen readers get the figure as well as the aria-label.
The chart frame is now one §5 component, written in one place:
chartBox()insrc/web/ui.ts./systemand every board panel call it, and the HTML both pages send is the same as before.What moved where
chartBox(chart, cells, title)was already insrc/web/pages/boards.ts, but/systemwrote the same<div class="chart-box">…drawChart…</div>by hand. The helper now lives insrc/web/ui.ts, andsystem.ts,boards.tsandboards-view.tsimport it from there. The unuseddrawChartimports insystem.tsandboards.tsare gone.docs/DESIGN.md: §5's table has a new chart row after the stacked bar chart row. It covers:- the markup:
.chart-boxarounddrawChart's svg.chart, with.bigfor the headline figure; - the variant:.is-tablefor a table panel; - that the svg carries its ownwidth/height, so nothing shifts; - when to use it: anyboards/chart.tschart, sized from the page and never inside the frame..chart-box,.chartand.bigare removed from §5d'sstyle/content.tslist.- New
test/ui-chart-box.test.tschecks that the helper wrapsdrawChart's output exactly, that only a table panel getsis-table, and that the title is escaped. -test/system-memory.test.tsasserts/systemsends both memory series in the frame. -test/boards-page.test.tsasserts a line panel sends the frame and a table panel carrieschart-box is-table. - No existing test was changed except to add these assertions.Not done: no CSS rule changed. The
.bp-*,.sys-pairand.bgridrules that size the frame stay as they are (#4146 owns.sys-pair).Checked:
bun x tsc --noEmitandbun scripts/design-lint.tsare clean. 248 tests pass across the new test,design-lint,boards-page, thesystem-tests and theboardtests. No screenshots, because the sandbox has no browser.To try it: as an admin, open
/systemand/boards/data?source=runs&by=day&series=kind&chart=table. Each chart sits in.chart-box, and the table panel's box also carriesis-table.🤖 Generated with Claude Code
Closes #4282