Rework Intro page into a scroll-snapped hero with interactive map - #717
Draft
Shikhar16078 wants to merge 4 commits into
Draft
Rework Intro page into a scroll-snapped hero with interactive map#717Shikhar16078 wants to merge 4 commits into
Shikhar16078 wants to merge 4 commits into
Conversation
Replaces the old single static block (logo + welcome text + objectives, all crammed into one ~80vh container) with three full-viewport, scroll-snapped sections: a hero intro, a live interactive world map, and Common Objectives — so the landing page actually lets people explore the map immediately instead of only linking out to it from a list. - IntroScrollContainer/IntroScrollSection: the scroll-snap mechanics. Sections use min-height (not height) so overflowing content on short/ narrow viewports grows the section instead of being clipped and made unreachable by the mandatory snap. - useRevealOnScroll: new IntersectionObserver-based hook (this codebase had none) driving each section's fade/slide-in; skips the effect entirely under prefers-reduced-motion. The hero opts out of animating since it's visible on first paint — animating it risked a flash of invisible content. - useIntroSectionNav + IntroSectionNav: dot navigation and a "scroll down" chevron on the hero, since scroll-snap sections otherwise have no visible affordance telling users there's more below. Computes scroll targets from each section's actual DOM offsetTop rather than assuming uniform heights, since sections can legitimately vary (see the min-height point above). - IntroMapSection: embeds EntityMap directly with allowSidebar (required, not optional — its non-sidebar click path expects a DetailsPanel that only exists on the Data page) and progressively reveals more languages as the user zooms in (60 at rest, up to 300 at max zoom), since showing either too few or the full ~8,500-language set both looked bad. Reads EntityMap's zoom level via a new onZoomChange callback prop. - PageNavBar now publishes its real rendered height as a --navbar-height CSS var (measured, not hardcoded, since it wraps to two rows on narrow viewports) so the hero can size sections as calc(100vh - navbar). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Each row's label text and its input/button controls were laid out with ad-hoc inline-flex + margins, so the controls landed at a different horizontal position per row depending on that row's label length (and two of the four rows have no input field at all, making it worse). Switches ObjectiveList to a 3-column CSS grid (label | input-or-spacer | GO button) so every row's controls line up regardless of label length. Each Objective renders its form with display: contents so the form doesn't introduce its own box between the grid and its children, while still fully working for onSubmit/Enter-to-submit. Also gives the inputs and GO buttons a pill style consistent with the rest of the app's bordered/rounded control language instead of bare default elements. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
intro-page.png and consent-banner.png needed updating to match the reworked Intro page. The other 8 baselines (data/about/lucky-search pages, untouched by this branch) also came back with diffs when regenerated — verified via a throwaway diff against the old baselines that this is font-rendering/anti-aliasing drift between whatever environment originally produced them and the local Chromium install here (ghosted/doubled text, no layout change), not a real regression. Refreshing all of them keeps the whole suite consistent with this environment; full suite passes cleanly against the new set. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
Cloudflare Pages preview
|
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.
No linked issue — this came out of an interactive design/iteration session, not a tracked issue.
Summary: Replaces the old Intro page (a single ~80vh block with logo, welcome text, and a plain list of "Common Objectives" links) with three full-viewport, scroll-snapped sections: a hero intro, a live interactive world map, and a redesigned Common Objectives grid — so the landing page lets people explore the map immediately instead of only linking out to it.
Changes
IntroScrollContainer/IntroScrollSection) that snap section-to-section on scroll, each fading/sliding in via a newuseRevealOnScrollhook (the hero itself skips the animation since it's visible on first paint).EntityMapdirectly (pan/zoom/click-to-pin, same component the Data page uses), showing 60 languages at rest and progressively revealing up to 300 as the user zooms in, so the view is never too sparse or an overwhelming ~8,500-entity blob.PageNavBarnow publishes its real rendered height as a--navbar-heightCSS var (measured viaResizeObserver, not hardcoded, since it wraps to two rows on narrow viewports) so the hero can size sections ascalc(100vh - navbar).EntityMapgained an optionalonZoomChangecallback prop (backward compatible — the Data page's existing usage doesn't pass it) so the map section can react to zoom level.CommonObjectives.tsxwas restructured internally (grid +display: contentstrick) but its external API/usage is unchanged.Out of scope/Future work: Common Objectives' navigation still does a full page reload (
window.location.href) rather than SPA navigation — left as-is since it predates this change and wasn't part of the ask. The dot nav stays visible (fixed position) even once scrolled past the hero into the footer — minor, not fixed here.Test Plan and Screenshots
How to test the changes in this PR:
npm run dev, visit/intro. Scroll through all three sections (or use the dot nav / chevron), try the map's zoom controls and click a territory to pin it, submit a Common Objectives row via click and via Enter key, and check dark mode + a narrow/short viewport (e.g. mobile emulation) where hero content can exceed one screen.Introduction
Interactive Map
Common Objectives
Checklist
Summary
Testing
npm run lintnpm run buildnpm run testIntersectionObserverstub tosrc/tests/setupTests.tsfor the newuseRevealOnScrollhooknpm run dev-- tried out the website directlye2e/screenshots.spec.ts-snapshots/intro-page.png,consent-banner.png); full suite passesChanges
Visual changes
/intro)Data changes
Internal changes
--navbar-heightCSS var,EntityMap'sonZoomChangeprop)src/pages/intro/(mirrors the existingsrc/pages/dataviews/pattern) andsrc/shared/hooks/useRevealOnScroll.tsallowSidebaris required on the hero's map, why sections usemin-heightnotheight, whydisplay: contentsis used inCommonObjectives)Docs