Skip to content

feat(landing): rebuild landing page into GMX's nine-section structure (GF3-002) - #616

Merged
IbrahimIjai merged 3 commits into
SO4-Markets:mainfrom
0xMegie:isisue-510
Aug 25, 2026
Merged

feat(landing): rebuild landing page into GMX's nine-section structure (GF3-002)#616
IbrahimIjai merged 3 commits into
SO4-Markets:mainfrom
0xMegie:isisue-510

Conversation

@0xMegie

@0xMegie 0xMegie commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Closes #510

Rebuilds / section-by-section to mirror GMX's Home page, consuming the theme
tokens GF3-001 landed. Structure only — placeholder copy and visuals throughout,
all marked TODO(GF3-003) so the finishing work is greppable.

Spec: docs/gf_3/002_landing_page.md · Theme: docs/gf_3/001_theme_update.md
GMX reference: gmx-io/gmx-interface @ e27759a, landing/src/pages/Home/

What changed

apps/web/src/ui/landing/* is replaced wholesale. The old
hero/stats/features/markets/how-it-works/infrastructure/final-cta/footer set is
gone; nine components now compose from apps/web/src/routes/index.tsx in GMX's
order:

Section Notes
HeaderMenu Fixed nav, desktop links, burger → full-screen mobile menu, btn-landing "Open app" → /trade
HeroSection 100px display headline with rotating-word slot, "Trade now" CTA, subheadline, 3-stat row
FeatureGrid Six rounded-20 cards, lg:grid-cols-3 lg:grid-rows-3, one bg-blue-400, one col-span-2 CTA
LaunchSection Light band (pure white) — chain launcher grid
LiquiditySection Light band (#F4F5F9) — live total + pool cards with hover lift
SponsorsSection Light band — logo card row
ProgramCards Two program cards over the glow treatment
FaqSection Accordion, no JS height measurement
RoadmapSection Horizontal quarter timeline, completed/upcoming states
SocialSection Marquee skeleton, community stats, newsletter form, footer link row

There is no separate footer component — SocialSection ends with the footer
link row, matching GMX.

Design tokens

packages/ui/src/styles/globals.css gains landing-scoped additions only —
nothing existing was modified:

  • --radius-8/12/20 — the app-wide --radius is 0 by design (sharp corners);
    the landing look needs a rounded scale, so these are namespaced rather than
    touching --radius-sm/md/lg/xl.
  • --text-12/14/16/18/24/28/30 — sizes the spec calls for that the app scale
    didn't need yet.
  • --animate-title-in/out keyframes for the hero word rotation.
  • --color-gmx-sponsors-border / --color-gmx-card-shadow — replacing two
    hexes the spec had inline, so check:tokens stays clean.

Accessibility

  • FAQ uses the shared @workspace/ui/components/accordion, which already
    implements GMX's exact grid-rows: 0fr → 1fr expand (no JS measurement) and
    brings aria-controls / aria-labelledby / role="region" / focus rings.
  • Roadmap scroller is tabIndex={0} with role="group" + aria-label and
    a visible focus outline — it was pointer-only otherwise, since a scroll
    container is only arrow-key scrollable once focused.
  • Mobile menu is role="dialog" + aria-modal, locks body scroll, and traps
    Tab within the panel (Escape-to-close was already inherited from
    useMobileMenu).

Bug fixed along the way

The header wrapped SiteLogo — which renders its own <a href="/"> — in a
second anchor. Nested <a> is invalid HTML and it was failing hydration for
the whole landing route
, discarding the SSR tree and re-rendering on the
client. Console errors on / went from three to zero. Also swapped
Button render={<Link/>} for a styled Link, since "Open app" navigates and
Base UI warns that the pattern strips native button semantics.

Testing

Full gate passing: bun lint, bun typecheck, bun run check:tokens,
bun run test, bun run test:coverage, bun run build.

Visual-regression baselines for / regenerated (4 files: dark/light ×
desktop/mobile). Two new e2e specs:

  • e2e/landing-responsive.spec.ts — 768px and 1440px, the widths acceptance
    names that design-system-visual.spec.ts didn't cover, scoped to / so no
    other route's baselines change. Each width gets a screenshot baseline plus a
    hard "no horizontal overflow" assertion.
  • e2e/landing-a11y-check.spec.ts — asserts the three keyboard/focus criteria
    above rather than leaving them to manual review.

11/11 landing e2e tests pass across three consecutive runs.

design-system-visual.spec.ts now installs a paused page.clock in
beforeEach. Playwright's animations: "disabled" freezes CSS animations but
not JS timers, so the hero's rotation interval could advance mid-screenshot and
flake; reducedMotion: "reduce" doesn't help because this Chrome Headless Shell
build reflects it in neither matchMedia() nor CSS @media (verified directly).

Reviewer notes — deliberate deviations

  1. The rotating word does not use framer-motion. The issue names
    AnimatePresence explicitly. The repo has zero JS animation dependencies, so
    this is CSS keyframes (y: 98→0→−98, 0.25s ease-in-out, 2.5s cycle) driven by
    a React interval. Visually equivalent; not a line-for-line port of
    AnimatedTitle.tsx. Happy to add the dependency if spec fidelity wins.
  2. Stats show - permanently. useLandingStats returns all-null — SO4 has
    no aggregate stats endpoint, and usePoolsData is still a static stub. The
    "no layout shift when values arrive" criterion is therefore unverifiable
    today; the stat values reserve no explicit width yet.
  3. The liquidity heading reads "- in liquidity" while loading. Faithful to
    GMX's own loading state, but it reads like a bug in an 80px display heading.
  4. Social, footer, and docs links are href="#". Real URLs weren't sourced;
    the newsletter form has a placeholder handler and no endpoint.

Items 2–4 are arguably GF3-003 territory but are called out so they aren't a
surprise in review.

Out of scope (GF3-003)

Final copy, real partner/tweet content, recreated image assets, and pixel-perfect
parity polish. 15 TODO(GF3-003) markers mark every placeholder.

- Add LiquiditySection component to display liquidity stats and pool cards.
- Remove Markets and Nav components as part of the redesign.
- Introduce NewsletterForm for email subscriptions.
- Create PoolCard for displaying individual pool information.
- Add ProgramCards for showcasing trading and developer programs.
- Implement Quarter and RoadmapSection for displaying project milestones.
- Add SocialSection with a newsletter form and social stats.
- Create SocialSlider for displaying community testimonials.
- Introduce SponsorsSection to highlight ecosystem partners.
- Remove Stats and Ticker components as they are no longer needed.
- Add useLandingStats hook for managing landing page statistics.
- Implement utility functions for formatting numbers and currencies.
- Update global CSS with new styles for landing page components.
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

@0xMegie is attempting to deploy a commit to the Ijai's projects Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
interface-web Ready Ready Preview Aug 25, 2026 7:51am

@IbrahimIjai

Copy link
Copy Markdown
Contributor

The FAQ implementation doesn't appear to match the accessibility notes in the PR description. FaqItem is using a custom button + div toggle rather than the shared Accordion, so aria-controls, aria-labelledby, and role="region" aren't actually present. Could we either switch this to the shared Accordion or add the appropriate ARIA relationship to the custom implementation? Everything else looks reasonable for the GF3-002 scope.

@IbrahimIjai
IbrahimIjai merged commit 2ef3922 into SO4-Markets:main Aug 25, 2026
5 checks passed
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.

GF3-002: Rebuild the landing page structure to match GMX

2 participants