feat(website): the compatibility band becomes an airport diagram - #1080
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
blove
enabled auto-merge (squash)
September 9, 2026 02:12
Contributor
The band keeps the pre-ATC treatment: three hairline-separated groups, twelve integrations as 14px names beside 17px marks, plus a footer link and a disclaimer. It becomes a full-bleed aviation-yellow FAA-style airport diagram, where the chart vocabulary carries the argument that the group labels and the aside paragraph were carrying as prose. Verifying against /docs/choosing-an-adapter shaped the design twice: there are exactly two adapters, not three equal-weight groups; and Threadplane never talks to a model provider at all, so those five marks move outside the neat line rather than sitting at integration weight. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Six tasks: the geometry module and its unit spec, the plate, the styles, the phone form, an in-browser overflow spec, and a verification gate. The overflow spec is not optional ceremony. Designing this section surfaced four separate collisions that only an eye caught — gate numbers over package labels, a taxiway drawn through the main terminal, sub-labels rendering outside a 26px concourse, and the scale bar on top of runway 09R. Eyes do not scale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t it means Review follow-ups on the geometry module, all naming/derivation/guards — no coordinate moves except B6's width. FIELD now actually bounds the drawing. It was decoupled: widening APRON_B past the viewBox left all 8 tests green, because nothing compared a structure to FIELD at all. A new test contains MAIN, both concourses, both aprons, both runways, all three taxiways and every stand's rotated extent. ROW1/ROW2 are renamed to what they hold: `box` was the stand's centre y (`standCy`), `name` the callsign's baseline (`labelY`). A new per-row ordering assertion catches a box slid down onto its own label — a visibly broken plate that the old suite passed. CONCOURSES carries the row, the apron and `gatesAbove`, so "A is the up row" is stated once instead of re-encoded in the spec's local table, in the ROW1/ ROW2 names and again in the component to come. The stub, apron, gate-span and gate-count tests now loop over it. B6's width becomes `round(s * WIDE_RATIO)` = 20, not the hand-typed 30 that was 2.5:1 under a comment stating 1.67. The sizing test now asserts the property (every gate has s > 0; any `w` is > s and on the ratio) instead of listing B6 by name, so a second wordmark can join without a red suite. Also: the apron test uses the stand's true rotated half-extent, since each stand counter-rotates about its own centre; the margin band (provider row, scale bar, north arrow) is guarded against the neat line and the view the way architecture-diagram.spec.ts guards its model strip; PLANE_PATH's duplication of ui/PlaneMark.tsx is enforced by reading that file rather than asserted in a comment; `MAIN.x1 < CONC.x0` is strict, since equality means zero-length connectors; and LINK_A_Y/LINK_B_Y must fall inside both the terminal's and their concourse's y span. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Task 1's code review renamed ROW.box/ROW.name to standCy/labelY and moved the row, apron and gates-side pairing onto CONCOURSES, so the component code in task 2 now loops CONCOURSES instead of restating which row goes with which concourse. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
WIDE_RATIO had no coverage: B6's `w` was computed as `B6_H * WIDE_RATIO`, so the spec's `w ~= s * WIDE_RATIO` check compared the constant with itself and could not fail. Setting WIDE_RATIO to 2.5 left all 12 tests green while stretching the AWS wordmark at gate B6 and in the provider row. Write both of B6's numbers as literals like every other value in the table (the derived B6_H is gone; `w` is still 20), and add a test that reads the wordmark's own viewBox off disk and holds WIDE_RATIO to it. The literal `w` makes the ratio check compare two independent values, and the new test pins the ratio to something outside the module. Also close the CONCOURSES single-sourcing at the spec boundary: the field bounds list is built from CONCOURSES instead of naming the boxes by hand, and LINK_A_Y / LINK_B_Y join the table as `link` so the connector test stops re-pairing them itself. A third concourse now gets its box, apron and link checked the moment it is declared. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Code review of task 2 found the band would have had no accessible content on desktop at all: the plate is decorative and the five provider names live only in the stack, so display:none removed them from the tree entirely. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lly tested
review fixes on 474f085f:
- the SVG is aria-hidden, not role="presentation". presentation is not
inherited, so every <text> on the plate ("09L", "2000 FT") still reached
the accessibility tree as unnamed chart noise while the provider names,
which exist only in the HTML stack, were the band's real content.
- the plate had no test at all: swapping <Plate /> for an empty <figure />
left 6 of 7 specs green. A stand per gate and a concourse per adapter are
now asserted against the tables.
- the name test is scoped to .airport-stack. Unscoped, getAllByText also
matched the SVG's own <text>, so deleting the accessible list would have
left half of it passing. Same for the concourse test, which matched only
the plate.
- the CTA test asserts the [data-cta] hook; the copy and the href belong to
AdapterGuideLink.spec.tsx.
- PROVIDERS carries the optional `w` the gate table already has, so the
component no longer asks whether a filename ends in bedrock.svg to know a
mark is a wordmark. The spec's two sizing tests walk both tables, which is
the coverage the margin row never had.
- Row and Runway are exported from the data module instead of derived in the
component from the two constants that happen to exist today.
- the x tick loop bounds on the frame it decorates, like the y loop.
Two intended one-unit shifts: the Bedrock wordmark is 33 wide rather than
33.4 (its x moves 0.2), and each vertical tick moves 8 units right, from
88..968 to 96..976 — still inside the neat line.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Removing aria-hidden from the SVG passed all 21 tests — the one contract the previous commit exists to establish was the one with no guard. role="presentation" does not inherit to descendants, so the plate's own text leaked to screen readers while the provider names, which live only in the stack, would have gone missing. Also starts both graticule loops at the frame they decorate; the x loop had been moved and the y loop left behind. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…form Replaces the `.compatibility-*` block with the airport-diagram styles: the plate's airfield, buildings, stands and margin furniture, plus the head, footer and the CTA rule that `AdapterGuideLink` needs because it replaces its className rather than appending to it. The yellow ground is load-bearing rather than decoration — every mark on the plate is a dark logo drawn for a light ground, which is why they render bare with no chip. Two values carry the diagram's meaning with no legend: partner stands are white, the main terminal is ink. `.airport-stack` is the band's only accessible content: the plate is aria-hidden and the five model-provider names exist nowhere else. So it is VISUALLY hidden on desktop with the `.stage-skip` idiom (absolute + 1px + clip-path) and never `display: none` — taking it out of the tree would leave the section empty to a screen reader. Under 768px the plate is hidden instead and the same gate table renders as an HTML list, the `.arch-stack` precedent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The label's knockout plate covers only the line above it, so hatch strokes ran straight through the glyphs of @threadplane/langgraph. A painted-under halo cuts the hatch per glyph, which beats widening the plate: the plate is sized by a font-metric estimate, so anything depending on it breaks silently when the type changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Designing the compatibility band surfaced four label collisions that only a human eye caught: gate numbers over package labels, a taxiway drawn through the main terminal, sub-labels rendering outside a 26px concourse, and the scale bar on top of runway 09R. Eyes do not scale. This measures the rendered plate against lib/airport-diagram.ts so the next one fails a check instead of shipping. Six checks, each one of those four generalised: concourse type stays inside the building that names it; the concourse name plate — sized by a font-metric estimate, so nothing else holds it to reality — actually backs its label; every mark sits inside its stand; no two text runs on the plate overlap; no pavement crosses the main terminal; chart furniture and the off-airport row stay in the margin below the neat line. Counts come first. Every measurement walks a NodeList, and a walk over an empty list passes, so an unrendered plate would otherwise report no issues at all. Overlap between elements that do not share a coordinate system is the one comparison that cannot use getBBox directly: the airfield sits at a heading and each stand counter-rotates about its own centre, so an axis-aligned bound around tilted type reports collisions that are not there. Those transform each bbox's four corners into the plate's user space and separate the quads properly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nx mangles the -- passthrough into 'unknown option --_=<spec>', so both task 5 steps failed before playwright even started. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…at it claims Final-review pass over the compatibility airport diagram. The plate was unreadable between 768px and ~1000px. `.ap-svg` is `width: 100%`, so the 1000-unit drawing scales with its container: at a 768px viewport that container is ~707px, the plate renders at 0.71, and callsigns land at 6.0px with gate ids at 5.3px. The HTML gate list now takes over at `max-width: 1023px` rather than 767px, so tablets get the readable list instead of a shrunken chart — not a sideways scroll, which the spec rules out for this band. A new e2e case at 900px proves it, and fails against the old breakpoint. Three guards that could not see their own subject: - The band's whole accessibility rests on `.airport-stack` being hidden visually (clip-path) and never with `display: none` — the plate is aria-hidden, so the five provider names and the "never talks to them" claim exist nowhere else in the DOM. Nothing asserted it. A style contract now pins the desktop rule, positively and negatively. - The "never talks to them" test read `container.textContent` unscoped, so the aria-hidden plate satisfied it. Deleting the stack's off-airport label left all ten tests green while the claim vanished from the phone form. It is scoped to `.airport-stack` now, like its neighbour. - The off-airport row itself was uncounted, and the e2e's margin check walks a NodeList that passes when empty. Deleting the whole provider row left both suites green. The counts sit beside the other `toHaveCount` assertions. `MS AGENT FWK` is an abbreviation a 38px stand forces, but it was also what the phone list and every screen reader got. `Gate.long` carries the whole name; the plate keeps the short one. Also: the chart id lost a double space, the spec doc's field extents and B6 size now match the code, `TPL` is recorded as a real assigned IATA code the way `AL-0059` was, and four plate fills stop hardcoding `--color-ink` / `--color-signal` as literals. Every rendered colour is unchanged — verified in the browser. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
blove
force-pushed
the
blove/homepage-compatibility-redesign-8ae4db
branch
from
September 9, 2026 02:18
21fe386 to
ea9f7cb
Compare
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The compatibility band was split out of the dark proof band in #1067 and kept the pre-ATC treatment: three hairline-separated groups, twelve integrations as 14px names beside 17px marks, a footer link and a disclaimer. It becomes a full-bleed aviation-yellow FAA-style airport diagram, where the chart vocabulary carries the argument the group labels and the aside paragraph were carrying as prose.
<chat>— Threadplane@threadplane/langgraph/@threadplane/ag-uiTwo values carry the whole meaning with no legend: white is somebody else's, ink is ours.
Verifying against
/docs/choosing-an-adaptershaped the design twice. There are exactly two adapters, not three equal-weight groups. And Threadplane never talks to a model provider at all — the adapters call your LangGraph or AG-UI endpoint — so those five marks moved outside the neat line rather than sitting at integration weight. The wording is deliberately "never talks to them", never "never sees it": never-sees is a data claim the docs do not support, the same shape as the three claims #1067 had to kill.The yellow ground is load-bearing, not decoration. Every mark here is a dark logo drawn for a light ground (Anthropic
#181818, CrewAI and Pydantic#111827, LangGraph#1C3C3C), so on aviation yellow they render bare with no chips — which is exactly why they were invisible on the dark band before the split.Spec:
docs/superpowers/specs/2026-09-08-compatibility-airport-diagram-design.mdPlan:
docs/superpowers/plans/2026-09-08-compatibility-airport-diagram.mdWhat the guards are for
Designing this surfaced four label collisions that only an eye caught — gate numbers over package labels, a taxiway drawn through the main terminal, sub-labels rendering outside a 26px concourse, the scale bar on top of runway 09R. Eyes do not scale, so
e2e/home-airport.spec.tsmeasures every rendered text run and mark against the structure that owns it, in viewBox units.Review found several assertions that passed vacuously and are now mutation-proven: a gate 120 units outside the viewBox once passed every geometry test; deleting the plate once left 6 of 7 unit tests green;
WIDE_RATIOwas checked against a value derived from itself and is now tied tobedrock.svg's ownviewBox.Two real defects were caught before shipping.
role="presentation"does not inherit to descendants, so the plate leaked runway ids and taxiway letters to screen readers. Anddisplay: noneon the phone stack would have left the band with no accessible content on desktop, since the provider names live only there — the stack is now visually hidden via the repo's existing.stage-skipclip-path idiom, andstyle-contracts.spec.tspins that so a future cleanup cannot silently revert it.The narrow-viewport breakpoint is 1023px, not the usual 767px, and that is measured: at a 768px viewport the plate scaled to 0.71 and put callsigns at 6.0px.
Test Plan
npx nx test websitegreen on the rebased treenpx nx lint website— 0 errorsnpx playwright test --config=apps/website/playwright.config.ts e2e/home-airport.spec.ts e2e/website.spec.ts— 39 passed, including homepage spine orderclip-path), tablet and phone show the gate list, plate hidden🤖 Generated with Claude Code