Skip to content

fix: prevent two-pages-in-one layout bug on root and onboarding#24

Merged
timothylee58 merged 1 commit into
mainfrom
claude/funny-johnson-bVave
May 25, 2026
Merged

fix: prevent two-pages-in-one layout bug on root and onboarding#24
timothylee58 merged 1 commit into
mainfrom
claude/funny-johnson-bVave

Conversation

@timothylee58

@timothylee58 timothylee58 commented May 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • Root page hydration fix: Added mounted guard so SSR and the initial client render both show the same loading spinner (matching gradient background). This eliminates the flash/snap where a returning user would briefly see both the spinner and the onboarding overlay stacked.
  • GuestOnboardingFlow backdrop: Wrapped AnimatePresence in a persistent fixed inset-0 z-50 div that always shows the gradient background. Step motion-divs now use absolute inset-0 inside this backdrop — during transitions the step content can animate with opacity: 0 without punching a transparent hole that reveals the body background underneath.
  • ConversationalOnboarding full-screen: All phases (questions, scan, pet, loading, result) now use fixed inset-0 z-50 instead of min-h-screen in normal flow. This covers the TopBar and BottomNav from the (app) layout on the /onboarding route, so users no longer see the onboarding questionnaire and the app navigation chrome stacked on the same screen.

Test plan

  • Visit https://bajet-buddy.netlify.app as a first-time user — see only the loading spinner briefly, then a clean slide-in of the onboarding questions (no stacked pages)
  • Visit as a returning user who hasn't finished onboarding — same clean transition (no hydration flash)
  • Navigate to /onboarding directly — TopBar and BottomNav are covered; the questionnaire fills the full screen
  • Complete all 5 questions → bank statement step transitions cleanly without background flash
  • Analyzing → persona reveal transition is smooth

https://claude.ai/code/session_017cLXjZu6kkjXRf2BemMPpp


Generated by Claude Code


Summary by cubic

Fixes the “two pages stacked” bug on the root and /onboarding routes by making loading and onboarding screens full-screen and consistent across SSR and client render. Removes hydration flash and background bleed during step transitions.

  • Bug Fixes
    • Root page: added a mounted guard so SSR and client both show the same spinner/gradient; no brief stack of spinner + onboarding for returning users.
    • GuestOnboardingFlow: added a persistent fixed inset-0 z-50 backdrop; steps render as absolute inset-0 to stop background peeking during AnimatePresence transitions.
    • ConversationalOnboarding: all phases use fixed inset-0 z-50 to fully cover TopBar/BottomNav on /onboarding.

Written for commit a00bb04. Summary will update on new commits. Review in cubic

- Root page: add `mounted` guard so SSR and initial client render both
  show the loading spinner (same background gradient), eliminating the
  hydration-mismatch flash where the spinner and onboarding overlay
  briefly stack on returning users
- GuestOnboardingFlow: wrap AnimatePresence in a persistent fixed
  inset-0 backdrop so step transitions never expose the body background
  through the opacity-0 initial animation state; steps switch to
  `absolute inset-0` inside the shared backdrop
- ConversationalOnboarding: all phases now use `fixed inset-0 z-50` so
  the onboarding experience at /onboarding fully covers the (app)
  layout's TopBar and BottomNav, removing the visual of two stacked
  screens

https://claude.ai/code/session_017cLXjZu6kkjXRf2BemMPpp
@netlify

netlify Bot commented May 25, 2026

Copy link
Copy Markdown

Deploy Preview for bajet-buddy ready!

Name Link
🔨 Latest commit a00bb04
🔍 Latest deploy log https://app.netlify.com/projects/bajet-buddy/deploys/6a144f9aa0de4f0007baca8f
😎 Deploy Preview https://deploy-preview-24--bajet-buddy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
bajet-buddy a00bb04 May 25 2026, 01:33 PM

@timothylee58
timothylee58 marked this pull request as ready for review May 25, 2026 13:34
@timothylee58
timothylee58 merged commit e59c7b8 into main May 25, 2026
6 of 7 checks passed

@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 refactors the onboarding flow and root page to improve layout consistency and handle hydration. Key changes include the introduction of a shared LoadingSpinner and background constant, as well as updating onboarding containers to use fixed positioning. Feedback focuses on ensuring mobile responsiveness by adding overflow-y-auto to various containers and removing justify-center where it might cause content clipping at the top of the viewport when overflowing.


return (
<div className="flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-background p-6 text-foreground">

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 main questions phase is missing overflow-y-auto. Since this phase contains dynamic text and multiple options, it is highly likely to overflow on mobile devices. Additionally, removing justify-center is recommended to prevent top-clipping during overflow.

Suggested change
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center overflow-y-auto bg-background p-6 text-foreground">

<AnimatePresence mode="wait">
{step === "questions" && (
<motion.div key="questions" initial={{ x: 40, opacity: 0 }} animate={{ x: 0, opacity: 1 }} exit={{ x: -40, opacity: 0 }}
className="absolute inset-0">

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 absolute inset-0 container lacks overflow-y-auto. If the OnboardingChat content exceeds the viewport height, users will be unable to scroll to see the rest of the conversation, which is a critical issue on mobile devices.

Suggested change
className="absolute inset-0">
className="absolute inset-0 overflow-y-auto">

</AnimatePresence>
{step === "statement" && (
<motion.div key="statement" initial={{ x: 40, opacity: 0 }} animate={{ x: 0, opacity: 1 }} exit={{ x: -40, opacity: 0 }}
className="absolute inset-0">

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 bank statement upload step should be scrollable to ensure that the upload button and any potential error messages remain accessible if the content overflows the screen.

Suggested change
className="absolute inset-0">
className="absolute inset-0 overflow-y-auto">


{step === "roast" && persona && (
<motion.div key="roast" initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, y: 50 }}
className="absolute inset-0">

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 persona summary can contain a significant amount of text (roast, budget breakdown, etc.). Without overflow-y-auto, this content will be cut off on smaller screens.

Suggested change
className="absolute inset-0">
className="absolute inset-0 overflow-y-auto">

if (phase === "scan") {
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">

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

Using justify-center on a container with overflow-y-auto can cause the top of the content to be clipped and unreachable if the content height exceeds the viewport. It is safer to remove justify-center and rely on padding or a wrapper to ensure the content remains accessible on smaller screens, similar to the implementation in the result phase (line 357).

Suggested change
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center overflow-y-auto bg-background p-6 text-foreground">

const SPECIES_ORDER: PetSpecies[] = ["squirrel", "fox", "raccoon", "rabbit"];
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">

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

Similar to the scan phase, combining justify-center with overflow-y-auto may lead to content clipping at the top on small devices. Removing justify-center ensures that all pet options are scrollable and visible.

Suggested change
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center overflow-y-auto bg-background p-6 text-foreground">

if (phase === "loading") {
return (
<div className="min-h-screen flex flex-col items-center justify-center bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-background p-6 text-foreground">

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

This container is missing overflow-y-auto. While the loading state is currently minimal, adding it ensures the UI doesn't break on extremely small screens or in landscape orientation.

Suggested change
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/web/components/features/onboarding/ConversationalOnboarding.tsx">

<violation number="1" location="apps/web/components/features/onboarding/ConversationalOnboarding.tsx:172">
P2: `justify-center` combined with `overflow-y-auto` on a flex column causes top content to be clipped and unreachable when content exceeds viewport height. Remove `justify-center` and rely on padding or an inner wrapper to vertically center shorter content.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

if (phase === "scan") {
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: justify-center combined with overflow-y-auto on a flex column causes top content to be clipped and unreachable when content exceeds viewport height. Remove justify-center and rely on padding or an inner wrapper to vertically center shorter content.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/components/features/onboarding/ConversationalOnboarding.tsx, line 172:

<comment>`justify-center` combined with `overflow-y-auto` on a flex column causes top content to be clipped and unreachable when content exceeds viewport height. Remove `justify-center` and rely on padding or an inner wrapper to vertically center shorter content.</comment>

<file context>
@@ -169,7 +169,7 @@ export function ConversationalOnboarding() {
   if (phase === "scan") {
     return (
-      <div className="flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground">
+      <div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">
         <div className="w-full max-w-md space-y-6">
           <motion.div
</file context>
Suggested change
<div className="fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-background p-6 text-foreground">
<div className="fixed inset-0 z-50 flex flex-col items-center overflow-y-auto bg-background p-6 text-foreground">

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.

2 participants