Skip to content

Rebuild Ridgeline on the mobile surface (Phase 30 slice G) - #240

Merged
vicmaster merged 5 commits into
masterfrom
phase-30-slice-g
Nov 1, 2026
Merged

vicmaster merged 5 commits into
masterfrom
phase-30-slice-g

Conversation

@vicmaster

Copy link
Copy Markdown
Owner

Phase 30 slice G, the last slice. The phase began with a phone screen, "Ridgeline — Today", that had been hand-built in 93 nodes and scored 100/100 without a single mobile check running. This PR rebuilds that screen on the finished phase, through the real tools, and keeps the rebuild as a test. The re-run also surfaced two render defects that the gate could not see, and this PR fixes them.

The re-run

test-ridgeline.ts drives the MCP server over stdio and follows the spec's path:

  1. canvas_create({ type: "mobile" }).
  2. generate_design_system, with seed #277350 and the soft personality.
  3. apply_structure("dashboard"), which stamps dashboard-mobile.
  4. canvas_set_genre("data"). The honest-content tell's own suggestion names this genre for a fitness screen's own figures.
  5. One batch_design batch.

The batch has no autofix, builds no device chrome by hand, and changes no rules.

Result
Nodes 33 (the hand-built screen had 93, counted the same way)
canvas_evaluate, fast mode 100/100, READY TO PRESENT, three info findings (APCA advisories on secondary text in the dark theme)
canvas_evaluate, detailed mode 100/100, READY TO PRESENT, the same three info findings
Dark-theme contrast findings none. A negative control proves the dark check is live: making dark secondary text match its surface produces dark errors.
canvas_stress, all five default perturbations CLEAN, with 20 designed truncations (info)
mobile-handbuilt-target 0
surface.rulesOn all six mobile rules plus mobile-artboard

Every tap target is a primitive: the bell is a nav-bar action, the four quick actions and "See all" are buttons, the runs are list rows, and the tabs and the start-run action are tab-bar items. The status bar, nav bar, tab bar and home indicator are the primitives.

The test also fails if the design system's fonts fall back, because a fallback face changes the glyph widths that every verdict above is measured on. It runs in the full tier.

The screen differs from the hand-built one in three places:

  • The quick actions are a two-by-two grid of buttons rather than a row of four icon tiles. Four labelled 44px buttons don't fit one 358px row.
  • The "FM" avatar is not rebuilt, because the nav bar has no avatar slot.
  • The notification badge is not rebuilt, because nav-bar actions carry no badge.

Two render fixes the re-run needed (approved before building)

Large type on a phone rendered at 60%.

  • The renderer scales any font size of 24px or more against a fixed 1440 design width. On a 390 artboard, $title (33px) rendered at 20px, smaller than the 21px card title, and $heading (27px) rendered at 16px, smaller than the 17px body. The rebuilt screen's headline figure read smaller than a card heading.
  • Font sizes now scale against the root's own width, so a size renders as authored on its artboard and still shrinks on narrower viewports.
  • A 1440 canvas emits exactly the CSS it did before, including in breakpoint renders.
  • Padding keeps the 1440 reference, because the slice C safe-area rules model it.
  • One visible change for existing work: a web canvas that isn't 1440 wide now renders its large type at the authored size. For example, a 32px heading on a 1280 page used to render at 28.4px. This belongs in the release notes.

Chart tick labels stretched with the plot.

  • The chart's SVG stretches to fill its box, and its tick labels were SVG text inside it. On a width: "100%" chart in a phone card the labels came out squashed to about half their width.
  • They are now HTML labels over the chart, at 11px at any width.
  • Each x label has its own slot: its bar on a bar chart with one label per bar, otherwise the room halfway to the nearest labelled tick on each side. A label truncates with an ellipsis inside its slot, so dense labels never overlap or run past the plot.
  • Empty labels skip their tick and leave the room to their neighbours. The docs now say to label every other tick on a narrow line chart.

A fix that followed from the font change

canvas_sync_from_url with a viewport override renders the imported page in a document as wide as the canvas root. Without this, the two sides scaled large type against different widths, and an in-sync page reported drift.

Docs

  • README's screenshot_responsive paragraph and GUIDELINES' font-size and chart bullets describe the new behaviour.
  • The batch_design docstring's chart line covers label slots.
  • VISION ticks slice G and closes Phase 30.
  • The spec gains slice G's build contract and an "As built" block, which records each departure, every verifier finding, and what changed because of it.

Testing

  • New test-ridgeline.ts (full tier) and test-fluid-type.ts (no browser).
  • New checks in test-chart.ts and test-sync-drift.ts.
  • The full tier passes 116 of 117. The failure is test-text-props.ts, which hung in Chrome past the runner's timeout; it passes on its own in 3.5s. The same one-off hang happened in slice E.
  • Verification ran in two rounds:
    • Round 1 used four agents: spec conformance, a render-fix adversary, a mutation pass and the docs steward. Their findings changed the test (the greeting and home indicator restored, and the assertions tightened), the label layout, and the sync render.
    • Round 2 used one agent on the fix diff. It found that half-step end slots truncated "Jan" and "Dec" on a fully labelled phone line chart, and that a 100% root synced above 1440 drifted. Both are fixed.
  • The round-2 fixes were proven red on the previous commit and green after. No agent re-verified them. The sync change is a one-line pass-through in the tool handler. test-sync-drift.ts mirrors that handler rather than calling it, so the sync fix is verified by reading only.

On a 390 phone artboard every size >= 24px rendered at 60% of authored, measured against a fixed
1440, so titles and headings drew under the body. Chart tick labels were SVG text inside a plot that
stretches to its box, so a 100%-wide chart squashed or widened them.
Verify round 1: unsquashed month labels overlapped on a phone-width chart, and a sync at a viewport
narrower than the canvas scaled type against different widths on each side.
Verify round 2: half-step end slots truncated Jan and Dec on a fully labelled phone line chart, and a
100% root synced above 1440 got a 1440 imported document.
@vicmaster
vicmaster merged commit ab78edc into master Nov 1, 2026
3 checks passed
@vicmaster
vicmaster deleted the phase-30-slice-g branch November 1, 2026 23:12
@vicmaster vicmaster mentioned this pull request Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant