Uh oh!
There was an error while loading. Please reload this page.
feat(landing): v5 landing, back as a PR to fix before it ships again - #586
feat(landing): v5 landing, back as a PR to fix before it ships again#586AndresL230 wants to merge 4 commits into
Conversation
Reverts 9f34454 (#584), which pulled the v5 marketing landing off main. The tree is byte-identical to 5b1a240, main's state immediately before the revert: the landing-v5/ components, lib/landing/ engine + hero3d rig, the five companion pages, the v4 retirement, and the #568 drag-field e2e journey. Lives here as an open PR so the landing can be fixed before it goes back onto main / production. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Deploying with |
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs | frontend-staging | 20eefd1 | Commit Preview URL Branch Preview URL | Aug 28 2026, 02:23 AM |
Ports the hero from `Sapling Landing.html`, the later Claude Design export. The wordmark lockup is unchanged; what moved: - The 01/02/03 Ingest/Map/Recall keys are gone. The bottom band is now three columns holding the info box (left), the scroll cue (centre) and an empty spacer (right). The spacer is load bearing: it balances the info box so the cue lands on the viewport centre line, not the centre of the content. - The info box moved from the right edge to the left. - The cue reads SCROLL TO EXPLORE, flanked by two arrows, the second offset 0.28s so the pair reads as a fall rather than a blink. - Both CTAs grew to 16px/30px and 16px/27px at 16.5px. - The lede is 500 weight on #2A3B32 rather than regular on #33443B. Splits the veil into two knobs. The source packs three gradients into two elements, but they do different jobs: the bottom band is a legibility floor for the info box and cue and has faded out by half height, while the rim and the two panel radials are what sit on top of the WebGL cards. Scaling them together meant the cards could not be cleared without also thinning the text backing. `sceneWash` is held at 0.3, which drops the heaviest veil over any card from 0.84 to ~0.25; `wash` stays at full strength. Drops the two `.hero-keys` rules from globals.css, whose selector no longer exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3wrhrFAfwkY1Zd13GL5QM
The three acts recomputed their progress from scroll position every frame, so scrolling back up ran them in reverse: the graph un-assembled, chips flew back into the document, the carousel spun backwards. `actPeak` now latches the furthest point each act reached, so progress only advances and scrolling up holds the played state. That alone made a second problem obvious. Each act's extra height is nothing but scrub runway — 360vh on act 1, 220vh on act 2, 240vh on act 3 — and once latched it drives nothing, so getting back out meant grinding through eight screens of frozen scenery. `foldActs` cuts a section to one viewport and takes the same distance off the scroll position. The fold is seamless from any position because of how sticky behaves. While pinned, the child sits at the viewport top for every scrollY in [top, top + h - vh], so cutting to one viewport and pulling scrollY back to `top` leaves it pixel-identical. Past the act the shrink instead cancels the upward shift of everything below; above it nothing on screen moves. One expression covers all three, and clamping at zero makes the third a no-op. The smoothed scroll passes shift too, or the next frame reads a 360vh delta and either lerps through it or trips the `jumping` bypass. Two triggers, and between them upward scroll is never pinned: the act finished, or the reader is scrolling up inside one they have started. The second strands a half-played act at whatever progress it reached, because the runway that would finish it is exactly what gets cut — the intended trade, since scrolling up out of a scene is a decision to leave it. Skipped while explore mode is active: it holds the reader inside act 1 on purpose, and resizing the section there would move the page out from under the graph. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3wrhrFAfwkY1Zd13GL5QM
Replaces the `[data-reveal]` attribute scan in `useLanding` with a `FadeIn` component under `components/landing/anim`. Same motion, same 0.12 threshold; the difference is that a block declares its own entrance where it is written instead of opting into a page-wide querySelectorAll on a 900ms interval. One shared IntersectionObserver backs every instance. Also fixes a latent flash: the scan set `opacity:0` in an effect after paint, so a revealed block could show before hiding itself. `FadeIn` renders visible and hides in a layout effect, before paint. Styles are written straight to the node rather than held in React state. That is what this component is — there is no state the rest of the tree can observe, the hide must land before paint, and routing it through useState means a synchronous set inside a layout effect, i.e. a cascading render on mount for every block on the page. Three paths never hide, because stranding real copy at `opacity:0` is a worse failure than an un-animated heading: no IntersectionObserver, reduced motion, and no-JS (first render is visible, so server markup stays readable). Migrates all seven existing reveal sites and adds fades to the ActIngest and ActTutor headings. The engine owns exactly six attributes — [data-cap], [data-tick], [data-tcap], [data-panel], [data-ingest-tile], [data-chip] — and no FadeIn wraps any of them; ActTutor's stops short of its [data-tcap] captions. ActGraph gets none: both its headings ARE captions. FeatureLab gets none either: it is a fixed modal with its own panelFade entrance, never scrolled into view. `data-*` passthrough is not decoration — DragField welds its cluster tracks to [data-drag-anchor], and the FAQ column is both an anchor and a reveal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3wrhrFAfwkY1Zd13GL5QM
The v5 marketing landing, pulled off
mainin #584 and offproductionin #585, back as an open PR so it can be fixed before it ships again.What this is
A single re-apply commit: the revert of #584's squash (
9f34454c). The tree is byte-identical to5b1a240d—mainas it stood immediately before the revert — so this carries exactly what #524 (47 commits) and #568 (the drag-field e2e journey) put onmain, and nothing else:src/components/landing-v5/— Hero, IntroOverlay, Navbar, the three Acts, FeatureLab + the eight lab demos, Gallery, Journal, Faq, Closing, BetaModal, DragFieldsrc/lib/landing/— the scroll/physics engine (engine/sim.ts+ tests, ambient, flip, graph, marquee, plant) and thehero3d/WebGL panel rigsrc/components/companion/CompanionShell.tsx+ the five public pages the nav links to (/faq,/gallery,/news,/team,/wiki), and the/aboutportglobals.css— the.landing-dctoken scope;lib/api.ts— the beta-signup clientmarketing/surfaces, bands, and graph demoe2e/landing-drag-field.spec.ts(replacinglanding-graph.spec.ts), the v5public-seo.spec.tsassertions, and the matchingeslint-suppressions.jsonbaselineThe original 47-commit history stays reachable through #524's merge commit on
main; this PR is the revert-of-the-revert, somainkeeps a linear story.Status
Not ready to merge as-is — this is the starting point for the landing fix. Push fixes onto this branch.
Getting it back to production
productionis on the pre-#576 v4 landing again. Once the fix lands here and onmain, re-cut the frontend-only cherry the way #576 did (or take it with the nextmake promote).🤖 Generated with Claude Code