Conversation
Four defects observed at 375x812: a four-line 207px H1, a mobile poster sliced across its top edge, no autoplay below 768px, and Angular absent from both the H1 and the title. Records two corrections found while diagnosing: the mobile poster is a purpose-built 390x650 capture rather than a scaled desktop one, and its slicing is drift from the beat its recorder documents rather than the beat itself. Also resolves the messaging.md hero drift deliberately, keeping the category claim and adding the stack to it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Amends the spec with canvas-measured card line widths: HERO_H1_LINES stays three spans, re-split to absorb "Angular", because the array is also the line-breaking for two fixed-height card images. A two-span split measured 964px against a ~536px column. The phone fix is a font-size override plus flowing the spans inline, since the shared --text-h1 clamp floor of 48px is what renders at 375px. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
website.spec.ts hard-coded the H1 and guarded "Angular" on the eyebrow — the assertion this work inverts — and site-metadata.ts hand-duplicates the tagline in the site-wide OG alt. Neither was enumerated. Also folds the card eyebrow duplication into Task 6, gtm.md and README into Task 7, and records that nx build website needs GROWTH_FORM_POLICY=growth_v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The phone poster is a 390x650 capture displayed in a ~335px stage — about 0.86 scale, so its type is degraded. A live iframe lays out at the stage's real width, so its type renders at its designed size. Dropping the 768px autoplay floor to 0 improves legibility by construction, not just motion. The `@media (max-width: 767px)` breakpoint is now a TWO-way coupling — the 3:5 stage ratio and the <source media> — both tied to the poster's geometry. MIN_AUTOPLAY_WIDTH is no longer part of it; both comments say so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The "reclaims 90px" figure was measured against the pre-Angular copy. Against the copy that now ships, block spans make all three lines wrap, so the real pre-fix state is 6 lines / 311px and the reclaim is ~194px (~24% of the fold). Both baselines are real; the spec now names which is which rather than implying one. Also drops scrollIntoViewIfNeeded from the Task 4 phone test: the demo now sits at y=501 with 51% visible on load, so asserting the mount from a standing start is what proves the fold win. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The phone poster has opened on a backup table cut through horizontally since the approval tools became executable (#1011): that run streams a 669px result table, taller than the whole 390x650 frame, and the timeline is pinned to the bottom, so the frame's top edge landed inside it. Guard the top edge in the recorder. The clipping edge is the chat's own scroll container, not y=0, so a sliced block can still have a positive y; the guard fails when any chat-message straddles that edge and prints the measured geometry. The height budget genuinely moved and could not stay 3:5. 526 is the middle of the gap that puts the edge above the delete_backups chip, so the poster keeps the approval beat and opens on nothing sliced. The capture height, POSTER_MOBILE_W/H and .hero-demo-stage's aspect-ratio move together to 195:263 so object-fit: cover stays a no-op. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
At 390px the four-column grid wrapped the S3 path to four lines per row via word-break: break-all, making the table 583px tall. Below 480px each backup is now a two-line block — id + size, then truncated path + date — which is 268px and keeps all four values. CSS only, so one template, no resize listener, and desktop is untouched. This makes the live phone demo readable. It does NOT reframe the hero poster: the timeline is bottom-pinned, so shrinking the table moves only its top edge and its bottom stays put. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`tsconfig.app.json` includes spec files (`src/**/*.ts`) and its lib set is `["es2022", "dom"]` with no `dom.iterable`, so spreading a `NodeListOf<Element>` fails with TS2488 and breaks `nx build examples-chat-angular`. `nx test` does not typecheck, so the break was invisible there and landed in 93307be6d. Verified: without the change `nx build examples-chat-angular` exits 1 with TS2488; with it, exit 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Move the phone capture from 390x526 to 390x906 (65:151, shipped 585x1359). The timeline is bottom-pinned, so the capture height decides where the frame's top edge lands and it must fall in a gap between messages. Measured from the DOM at h=866, with the edge fixed at y=62: user prompt -54..10, list_backups table 34..388, delete_backups chip 412..455, answer 479..705. Raising h by d shifts every box down by d, so h = 928 - e for an edge position e, giving windows (449, 473), (516, 540) and (894, 918). 906 is the middle of the third: the prompt's bottom lands at 50, wholly above the edge, and the table's top at 74, clear below it. 526 framed the story but shrank the live stage: this ratio also sizes the autoplaying iframe below 768px, so the earlier budget cost the phone demo 19% of its viewport. 906 frames the whole streamed backup table AND gives the live demo more room than it has ever had. Also updates the two guards that enforce the coupling. They still asserted 3/5 and 975 -- the pre-Task-5 geometry -- so `nx test website` had been red since 017568f8e moved the source without them. The poster ships at webp quality 40, not 55: the taller capture pushed q55 to 39,016 bytes, over the 36,000-byte budget. Single-encode from one capture, q55 39,050 / q50 37,880 / q45 36,394 / q40 34,094 / q35 32,264. q40 clears the budget with ~1.9KB of headroom and is indistinguishable from q55 at 1:1 in the table's monospace text, so the budget itself is unchanged. Verified at 375x812: [data-hero-demo] top 501.4 (budget <= 530), stage 333x774, visibleFraction 0.342 against the 0.25 autoplay threshold, state "ready" with the iframe mounted. Top-edge guard confirmed non-vacuous at 906 -- with the responsive table disabled it trips with the table spanning -241..429 across the edge. 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>
Three corrections learned by running it: nx build website needs GROWTH_FORM_POLICY=growth_v1; examples-chat-angular must be BUILT, not just tested, because its tsconfig compiles specs without dom.iterable; and card:github defaults to fetching production, so regenerating before deploy captures the copy being replaced. Also scopes hero.svg into Task 7 — it claims to mirror the social cards and nothing tests that claim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The phone stage ratio moved three times on this branch and five comments still asserted a superseded value as current — including the outer comment sitting directly on the .hero-demo-stage rule, which claimed 390x650/3:5 fifteen lines above aspect-ratio: 65/151. That is the exact failure mode this branch exists to fix, so it is worth the sweep. Also drops two over-claims. The recorder header presented the taller live stage as an unambiguous win; it is not — at 375px only ~34% of the stage is ever on screen, and the honest justification for 906 is poster framing, with the live stage along for the ride because object-fit: cover is only a no-op while the ratios match. And the spec said the top-edge guard "converts a silent drift into a failing capture"; it converts it into a failing RE-RECORD, which is weaker, because nothing checks the committed poster in CI. Records why marketing/assets deliberately keeps ANGULAR in its eyebrow while the website's cards dropped it: those cards carry a blog title, not the hero H1, so the word adds information rather than repeating it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Reworks the threadplane.ai homepage hero for phone viewports. Spec:
docs/superpowers/specs/2026-09-18-mobile-above-fold-design.md.Why
Four defects, each observed directly in a browser at 375x812 against production:
<title>, only in a small low-contrast eyebrow.PostHog shows mobile median session duration at 2-3s against 6s+ on desktop, but that sample is ~41 sessions/30d and is directional only. This is justified by the defects above, not by a bounce emergency — homepage bounce has been improving steeply and is already below the sector median.
What changed
[data-hero-demo]topstate: ready<title>positioning.tsonly): H1 is nowThe open-source thread-plane for Angular agents.;HERO_EYEBROWdrops the now-duplicatedAngular ·;PRIMARY_TAGLINEgains Angular, which is what puts it in<title>and the site-wide OG defaults.--text-h1isclamp(48px, 6vw, 72px), so at 375px the clamp floor is what renders.landing.cssoverrides.hero-headingto 36px and flows.hero-heading-lineinline below 767px. Both halves are required.MIN_AUTOPLAY_WIDTH768 → 0. A live iframe lays out at the stage's real width, so this improves legibility by construction, not just motion.prefers-reduced-motionstill gates it at every width.Notable findings
8900e1886, which introduced alist_backupstable taller than the whole capture frame. Not timing drift — captures are byte-identical.nx test websitehad been red for three commits while the Playwright suite stayed green, because the stale guards assert CSS the e2e never reads.nx build examples-chat-angularcompiles spec files withoutdom.iterable, so aNodeListspread broke the build whilenx teststayed green.New guards, all mutation-tested
.hero-heading≤ 130px,[data-hero-demo]top ≤ 530px. Absolute, not relative — a relative guard passes vacuously once the thing it guards drifts, which is how both defects shipped. Verified to fail (259px / 643.94px) with the fix reverted.toEqualpin onHERO_H1_LINES, which is also the line-breaking for two fixed-height card renderers.Test plan
nx test website,nx lint website,nx build website— all exit 0nx test examples-chat-angular,nx build examples-chat-angular— exit 0nx e2e website --grep "homepage hero"— 5/5WEBSITE_E2E_MODE=production nx e2e website— 175 passed, incl. the public-copy contract gatedocs/brand/github-social-preview.pngat Settings → General → Social preview. GitHub's social preview has no API.Known open
hero-replay.jsondrift can still stale the committed poster silently.hero.svgwent stale.marketing/assetsdeliberately keepsANGULAR(its cards carry a blog title, not the hero H1) and now records why.🤖 Generated with Claude Code