Skip to content

feat(frontend): cinematic 3D landing page overhaul + page transitions#63

Merged
hoangsonww merged 3 commits into
masterfrom
feat/landing-3d-overhaul
Jun 11, 2026
Merged

feat(frontend): cinematic 3D landing page overhaul + page transitions#63
hoangsonww merged 3 commits into
masterfrom
feat/landing-3d-overhaul

Conversation

@hoangsonww

Copy link
Copy Markdown
Owner

Summary

Rebuilds the landing page around a fully procedural react-three-fiber scene (no binary assets — every shape/material/light is generated in code) and lifts every section to a cohesive, premium bar. Adds app-wide page transitions and routes the primary CTAs to sign-up.

What changed

3D scene — frontend/src/components/three/HeroExperience.js (new)

  • Distorted glowing AI core, frosted-glass "document" panels, metallic solids, Sparkles particles, Lightformer environment (no .hdr/.glb/font files).
  • Pointer parallax; prefers-reduced-motion freezes animation.
  • Limited-graphics support: WebGL capability detection → CSS fallback; React error boundary → CSS fallback; failIfMajorPerformanceCaveat: false (allows software/SwiftShader); low-power tier (fewer objects, no shadows/AA, cheaper translucent material); context-loss kept recoverable.
  • Lighter cta variant pauses its render loop when off-screen (IntersectionObserver).

Landing page — frontend/src/pages/LandingPage.js

  • Full-bleed cinematic hero → floating stats band → numbered pillars → dark spotlight → bento features → connected stepper workflow → comparison → dual auto-marquee formats → use cases → workspace/privacy → accordion FAQ → dark 3D CTA bookend.
  • Fraunces display serif + Poppins body, eyebrow labels, rounded icon tiles, refined hover.
  • Italic gradient headline padding fix (no clipped glyphs); accordion hover tint overriding the global button:hover red; tighter expanded accordion spacing.
  • "Start for free" / "Get Started" CTAs → /register.

App-wide transitions — frontend/src/App.js + frontend/src/index.css

  • Incoming page rises + fades in (0.7s); outgoing descends + fades out (0.55s). Orchestrated in AppLayout (displayLocation lags location by one exit), synced with scroll-to-top + navbar visibility, animationend + timeout-fallback swap, reduced-motion bypass.

Deps: three, @react-three/fiber@8, @react-three/drei@9 (React 18 compatible). three.js is lazy-loaded into a separate chunk.

Verification

  • npm run build — compiles clean (only a harmless @mediapipe/tasks-vision source-map warning from a drei transitive dep).
  • jest — 6 suites, 35/35 pass.
  • Manually verified desktop + mobile (no horizontal overflow), transition cycle, and CTA → /register.

🤖 Generated with Claude Code

Rebuild the landing page around a fully procedural react-three-fiber
scene (no binary assets) and bring every section up to a cohesive,
premium bar.

- HeroExperience: procedural r3f scene (distorted glowing AI core,
  frosted-glass document panels, metallic solids, Sparkles particles,
  Lightformer environment). Pointer parallax, reduced-motion safe.
  WebGL capability detection + error boundary + CSS fallback, software
  rendering allowed, and a low-power tier (fewer objects, no shadows/AA,
  cheaper materials) for limited-graphics devices. Lighter "cta" variant
  pauses its render loop when off-screen.
- LandingPage: full-bleed cinematic hero, floating stats band, numbered
  pillars, dark spotlight, bento features, connected stepper workflow,
  comparison, dual auto-marquee, use cases, workspace/privacy, accordion
  FAQ, and a dark 3D CTA bookend. Fraunces display serif + eyebrow labels
  + rounded icon tiles. Italic gradient headline padding fix; accordion
  hover tint (overrides global red) and tighter expanded spacing.
- App: app-wide page transitions (rise/fade in, descend/fade out) driven
  by AppLayout, synced with scroll-to-top and navbar visibility, with a
  reduced-motion bypass and animationend + timeout fallback.
- CTAs ("Start for free" / "Get Started") now route to /register.
- Add three, @react-three/fiber@8, @react-three/drei@9 (React 18).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 11, 2026 03:54
@netlify

netlify Bot commented Jun 11, 2026

Copy link
Copy Markdown

Deploy Preview for docuthinker-ai-app ready!

Name Link
🔨 Latest commit ae2666d
🔍 Latest deploy log https://app.netlify.com/projects/docuthinker-ai-app/deploys/6a2a3324ed08660009f52135
😎 Deploy Preview https://deploy-preview-63--docuthinker-ai-app.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 19
Accessibility: 93
Best Practices: 92
SEO: 99
PWA: 80
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docuthinker-fullstack-app Ignored Ignored Jun 11, 2026 4:01am

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@hoangsonww hoangsonww self-assigned this Jun 11, 2026
Keep the background unchanged on hover (transparent) so the app-wide
button:hover red never shows and there is no hover tint at all.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hoangsonww hoangsonww added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers labels Jun 11, 2026
@hoangsonww hoangsonww added this to the v2.x.x - Enhanced Release milestone Jun 11, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a procedural 3D WebGL hero experience using React Three Fiber and adds animated page transitions to the frontend, along with associated Three.js dependencies and CSS styles. The feedback highlights three key issues: a bug in the route transition logic where query parameter or hash changes on the same pathname fail to update the rendered location; a performance bottleneck in the 3D scene where the environment map is unnecessarily re-rendered every frame; and a material configuration issue where combining transparency and physical transmission on the document panels can cause depth sorting anomalies.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread frontend/src/App.js
Comment on lines +131 to +132
useEffect(() => {
if (location.pathname === displayLocation.pathname) return undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

When the user navigates to a URL with the same pathname but different query parameters (e.g., ?tab=1 to ?tab=2) or hash, location.pathname === displayLocation.pathname evaluates to true, causing the effect to return early. Because displayLocation is never updated to the new location object, the child routes and components will not receive the updated search/hash parameters and will fail to re-render. To fix this, we should immediately update displayLocation to the new location when the pathname is the same but the location object itself has changed, bypassing the page transition.

  useEffect(() => {
    if (location.pathname === displayLocation.pathname) {
      if (location !== displayLocation) {
        setDisplayLocation(location);
      }
      return undefined;
    }

Comment on lines +337 to +340
<Environment
resolution={lowPower ? 128 : 256}
frames={reduceMotion || lowPower ? 1 : Infinity}
>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The <Environment> component is configured with frames={reduceMotion || lowPower ? 1 : Infinity}. When frames is set to Infinity, the environment map (which renders the child <Lightformer> components into a cube map) is updated every single frame. Since the lightformers in this scene are completely static and do not animate, rendering the environment map every frame is a massive and unnecessary GPU bottleneck that can cause severe frame rate drops and high power consumption. Setting frames={1} will render the environment map once on mount and reuse it, significantly improving performance.

Suggested change
<Environment
resolution={lowPower ? 128 : 256}
frames={reduceMotion || lowPower ? 1 : Infinity}
>
<Environment
resolution={lowPower ? 128 : 256}
frames={1}
>

Comment on lines +171 to +184
<meshPhysicalMaterial
color={PALETTE.panel}
transmission={0.94}
thickness={0.6}
roughness={0.12}
ior={1.4}
metalness={0}
clearcoat={1}
clearcoatRoughness={0.15}
attenuationColor={PALETTE.attenuation}
attenuationDistance={1.6}
transparent
opacity={0.92}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For transmissive materials in Three.js, setting transparent={true} and a fractional opacity alongside transmission is generally discouraged. Physical transmission handles its own transparency and refraction pass internally. Forcing the material into the transparent queue by setting transparent={true} can cause severe depth sorting issues (e.g., overlapping panels or particles like <Sparkles> rendering in the wrong order) and makes the glass look washed out. Removing transparent and opacity allows the physical transmission shader to render the frosted glass effect correctly and robustly.

          <meshPhysicalMaterial
            color={PALETTE.panel}
            transmission={0.94}
            thickness={0.6}
            roughness={0.12}
            ior={1.4}
            metalness={0}
            clearcoat={1}
            clearcoatRoughness={0.15}
            attenuationColor={PALETTE.attenuation}
            attenuationDistance={1.6}
          />

The earlier --legacy-peer-deps install left package-lock.json missing
transitive entries (@testing-library/dom, typescript, webrtc-adapter,
sdp, form-data, @types/node-fetch, aria-query), breaking `npm ci`.
Regenerated a full, consistent lockfile; `npm ci` now succeeds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hoangsonww
hoangsonww merged commit 2d05d14 into master Jun 11, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants