Skip to content

feat: add responsive hero section with scroll-based animation and smooth interaction#351

Open
reach2saksham wants to merge 4 commits intoAOSSIE-Org:new-designfrom
reach2saksham:feat/hero-section-with-scroll-animation
Open

feat: add responsive hero section with scroll-based animation and smooth interaction#351
reach2saksham wants to merge 4 commits intoAOSSIE-Org:new-designfrom
reach2saksham:feat/hero-section-with-scroll-animation

Conversation

@reach2saksham
Copy link
Copy Markdown

@reach2saksham reach2saksham commented Mar 27, 2026

Description

Fixes #289

This PR introduces the Hero section for the redesigned landing page, featuring scroll-based animations and a visually engaging, fully responsive layout.

What has been introduced in this PR

  • lens-provider.tsx: Lenis is a lightweight, robust, and performant smooth scroll library, often described as being approximately 2 kb gzipped.
  • Hero.tsx: The whole layout of the hero-section
  • HeroVisual.tsx: This part incorporates imports of the assets and introduces a complete flexible scroll logic
  • hand.webp: Asset
  • phone.webp: Asset

Changes done in this PR

  • page.tsx: Remove the placeholder texts and importing Hero Section with a standardised margins
  • layout.tsx: Importing and Wrapping the Lenis
  • global.css: Lenis smooth scroll handling integration

##Implementation Details

  • Animation progress is calculated based on the viewport position
  • requestAnimationFrame is used for smooth updates
  • Interpolation (lerp) is applied to avoid abrupt transitions
  • Lenis is used to normalize scroll behavio
  • Layout is optimized to avoid repaint-heavy operations

Additional Info

  • User Agentic OS Detection has not been implemented yet because of the absence of an Appstore link.
  • The scroll animation has been completed till the second section.
  • To keep it clean, the i18n and l10n parts of this are currently in the Hero.tsx file itself. They can be cleanly put into their respective JSON after the Navbar has been completed.
  • The mobile mockup is currently kept the same and will be updated in the later stages when the mockups are finalised.

Please delete options that are not relevant.

  • Bug fix (non-breaking CHANGE which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g. code style improvements, linting)
  • Documentation update
  • New release (version bump, release preparation)
  • UI/UX update (design changes, interface improvements)
  • CI/CD & Tooling (workflow, build, or dev tool changes)
  • Dependency update (package upgrades or deprecation fixes)

How Has This Been Tested?

  • Thoroughly tested on all the device viewports.
  • Cross-checked the performance via dev tools and Lighthouse.
  • Ensured no errors are created throughout the process, and there is no cumulative layout shifts.

Please include screenshots below if applicable.

Recording.2026-03-27.173957.mp4

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings

Maintainer Checklist

Summary by CodeRabbit

  • New Features

    • App-wide smooth scrolling provider integrated.
    • New Hero landing section with animated visuals, responsive typography, and mobile-optimized download link.
    • Home page updated to showcase the new Hero layout.
  • Style

    • Added CSS to support smooth-scrolling behavior and viewport-aware layout/spacing.
  • Chores

    • Added lenis smooth-scrolling dependency.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

Warning

Rate limit exceeded

@reach2saksham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 55 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 0 minutes and 55 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 12bb1be5-c6af-477f-b3ee-fddfda2e0a6e

📥 Commits

Reviewing files that changed from the base of the PR and between e01f161 and 0ae0429.

📒 Files selected for processing (1)
  • src/components/home/HeroVisuals.tsx
📝 Walkthrough

Walkthrough

Adds Lenis smooth-scrolling (dependency, CSS, provider) and integrates it into the root layout; replaces the previous home content with a new Hero component and introduces Hero and HeroVisuals client components that implement viewport-driven scroll animations and responsive visuals.

Changes

Cohort / File(s) Summary
Dependency Manifest
package.json
Added lenis (^1.3.21). next-themes was removed and re-added with same version (no net change).
Global CSS
src/app/[locale]/globals.css
Added Lenis-related rules (html.lenis, .lenis.lenis-smooth, .lenis.lenis-stopped) to control scroll-behavior and overflow while Lenis is active/stopped.
Lenis Provider
src/components/providers/lenis-provider.tsx
New client-side provider that creates a Lenis instance on mount, drives lenis.raf via requestAnimationFrame, and destroys/cleans up on unmount.
Layout & Page
src/app/[locale]/layout.tsx, src/app/[locale]/page.tsx
Inserted LenisProvider into root layout (wrapping main content). Replaced the previous centered title/subtitle home layout with a tall wrapper rendering the new Hero component.
Hero UI
src/components/home/Hero.tsx
New client-side Hero component: responsive heading/subheadline, maintained-by external link with SVG, mobile-only download CTA, and positioned container for visuals with animation-friendly classes.
Hero Visuals & Animation
src/components/home/HeroVisuals.tsx
New HeroVisuals component: mobile-aware rendering, matchMedia-driven isMobile, desktop RAF loop that reads bounding rect, computes normalized progress, and mutates DOM refs (hand opacity, phone transform/rotation) with proper cleanup.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant Lenis as Lenis (Smooth Scroll)
    participant HeroVisuals as HeroVisuals (Component)
    participant DOM

    Browser->>Lenis: native scroll input
    Lenis->>Browser: interpolated scroll position (raf)
    Browser->>HeroVisuals: requestAnimationFrame tick
    HeroVisuals->>HeroVisuals: read getBoundingClientRect()
    HeroVisuals->>HeroVisuals: compute normalized progress
    HeroVisuals->>DOM: set hand opacity
    HeroVisuals->>DOM: set phone transform/rotation
    DOM-->>Browser: paint frame
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • M4dhav

Poem

🐰 Hop, hop — a smoother scroll takes flight,
Lenis hums softly through day and night,
A hand and phone in a gentle spin,
The hero wakes as pixels grin,
I twitch my nose and cheer—what a sight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding a responsive hero section with scroll-based animation and smooth interaction, which is the core focus of the PR.
Linked Issues check ✅ Passed All major coding requirements from issue #289 are implemented: hero layout matching design, scroll-based animation with layered elements (hand fade, mobile translate/rotate), viewport triggering, cross-browser support, and responsive design.
Out of Scope Changes check ✅ Passed All changes are directly scoped to #289: hero component structure, HeroVisuals animation, Lenis provider for smooth scrolling, CSS updates, and dependency addition are all within the stated objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@reach2saksham
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
src/app/[locale]/page.tsx (1)

14-14: Unused useTranslations hook.

The t variable is declared but never used since the Hero component uses hardcoded TEXT constants. This can be removed to reduce bundle size and avoid confusion.

Proposed cleanup
 'use client';

-import { useTranslations } from 'next-intl';
 import { Hero } from '@/components/home/Hero';

-import dynamic from 'next/dynamic';
-
-// const LanguageSwitcher = dynamic(() => import('@/components/ui/LanguageSwitcher'), {
-//   ssr: false,
-// });
-

 export default function Home() {
-  const t = useTranslations('Home');
   return (
     <div className="flex h-[400vh] flex-col mx-4 sm:mx-8 lg:mx-16 xl:mx-48 ">
       <Hero />
     </div>
   );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`[locale]/page.tsx at line 14, Remove the unused i18n hook usage:
delete the call to useTranslations and the unused variable t in the page
component (the symbol t from useTranslations('Home')), since Hero currently
renders hardcoded TEXT constants; update any imports to remove useTranslations
if it's no longer referenced and ensure the Hero usage remains unchanged to
avoid introducing regressions.
src/components/home/Hero.tsx (1)

6-12: Good i18n preparation pattern, but consider connecting to existing translations.

The TEXT constants are well-structured for future internationalization. However, the page.tsx already imports useTranslations('Home'), suggesting translations may already exist. Consider connecting these constants to the translation system now rather than using hardcoded strings.

If translations exist, connect them
// In Hero.tsx, accept translations as props or use the hook directly
import { useTranslations } from 'next-intl';

export function Hero() {
  const t = useTranslations('Home');
  
  return (
    <section ...>
      <h1>{t('headline')}</h1>
      {/* etc */}
    </section>
  );
}

This would require adding the corresponding keys to your messages/{locale}.json files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/home/Hero.tsx` around lines 6 - 12, The TEXT const in Hero.tsx
is hardcoded but page.tsx already uses useTranslations('Home'), so update the
Hero component to use the translation hook or accept translated strings as props
instead of TEXT: inside the Hero component (or its props) call
useTranslations('Home') (or receive t/home keys from page.tsx) and replace
references to TEXT.headline, TEXT.subHeadline, TEXT.maintainedBy, and
TEXT.orgName with t('headline'), t('subHeadline'), t('maintainedBy'),
t('orgName'); also add the corresponding keys to your messages/{locale}.json
files and remove or deprecate the TEXT constant.
src/components/home/HeroVisuals.tsx (1)

73-91: Consider if both mobile images need priority loading.

Both hand and phone images have priority={true}, which preloads them in the document head. On mobile, this is likely acceptable since the hero is above the fold. However, if there are other priority images on the page, this may contend for bandwidth.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/home/HeroVisuals.tsx` around lines 73 - 91, The two next/image
usages in the HeroVisuals component (the Image rendering hand.webp and the Image
rendering phone.webp) both set priority which preloads both resources; remove or
relax one of them so only the most critical above-the-fold image uses priority
to avoid bandwidth contention (e.g., keep priority on the primary hero visual
and remove priority from the secondary phone image, or conditionally set
priority based on screen size/SSR detection inside HeroVisuals). Locate the two
Image elements (hand.webp and phone.webp) and update the priority prop
accordingly so only one Image has priority or implement a small conditional to
set priority only for the main hero image.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/`[locale]/layout.tsx:
- Around line 95-101: Navbar's scroll reads and handlers are incompatible with
Lenis; instead either move Navbar out of LenisProvider or expose the Lenis
instance via context so Navbar can use Lenis APIs. Update LenisProvider to
create and provide the Lenis instance (e.g., via a LenisContext and a useLenis
hook) and in Navbar replace window.scrollY/scroll event usage and
window.scrollTo with lenis?.on('scroll', ...) subscriptions and
lenis?.scrollTo(0); ensure Lenis is cleaned up on unmount and guard Navbar logic
for null lenis.

In `@src/components/home/HeroVisuals.tsx`:
- Around line 28-66: The RAF loop in the useEffect (animate function) never
stops; capture the requestAnimationFrame id (e.g., let rafId) when calling
requestAnimationFrame(animate), return a cleanup function from the useEffect
that calls cancelAnimationFrame(rafId) and also cancels the loop when isMobile
becomes true or the component unmounts; ensure the cleanup clears any running
animation started by animate and avoid further state/DOM updates to sectionRef,
handRef, and phoneRef after cancellation.
- Around line 17-25: Change isMobile to start as an "unknown" value and render a
shared skeleton until the client measurement runs: initialize state as
useState<boolean | null>(null) (instead of false), keep the useEffect with
checkMobile() that sets true/false, and in the HeroVisuals render return a
neutral skeleton/loading placeholder when isMobile === null so the server and
first-client render match; reference the isMobile/setIsMobile state, the
checkMobile function, and the existing useEffect to implement this.

In `@src/components/providers/lenis-provider.tsx`:
- Around line 12-21: The RAF loop started by requestAnimationFrame(raf) inside
the raf(time: number) function is never cancelled on unmount; store the
animation frame id when scheduling (the value returned by requestAnimationFrame)
and call cancelAnimationFrame in the cleanup along with lenis.destroy(); update
the raf scheduling so you assign the handle (e.g., let rafId =
requestAnimationFrame(raf)) and then in the returned cleanup callback call
cancelAnimationFrame(rafId) before or after calling lenis.destroy().

---

Nitpick comments:
In `@src/app/`[locale]/page.tsx:
- Line 14: Remove the unused i18n hook usage: delete the call to useTranslations
and the unused variable t in the page component (the symbol t from
useTranslations('Home')), since Hero currently renders hardcoded TEXT constants;
update any imports to remove useTranslations if it's no longer referenced and
ensure the Hero usage remains unchanged to avoid introducing regressions.

In `@src/components/home/Hero.tsx`:
- Around line 6-12: The TEXT const in Hero.tsx is hardcoded but page.tsx already
uses useTranslations('Home'), so update the Hero component to use the
translation hook or accept translated strings as props instead of TEXT: inside
the Hero component (or its props) call useTranslations('Home') (or receive
t/home keys from page.tsx) and replace references to TEXT.headline,
TEXT.subHeadline, TEXT.maintainedBy, and TEXT.orgName with t('headline'),
t('subHeadline'), t('maintainedBy'), t('orgName'); also add the corresponding
keys to your messages/{locale}.json files and remove or deprecate the TEXT
constant.

In `@src/components/home/HeroVisuals.tsx`:
- Around line 73-91: The two next/image usages in the HeroVisuals component (the
Image rendering hand.webp and the Image rendering phone.webp) both set priority
which preloads both resources; remove or relax one of them so only the most
critical above-the-fold image uses priority to avoid bandwidth contention (e.g.,
keep priority on the primary hero visual and remove priority from the secondary
phone image, or conditionally set priority based on screen size/SSR detection
inside HeroVisuals). Locate the two Image elements (hand.webp and phone.webp)
and update the priority prop accordingly so only one Image has priority or
implement a small conditional to set priority only for the main hero image.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2bcfb88-572d-42ef-9989-67ec9da14fb7

📥 Commits

Reviewing files that changed from the base of the PR and between f3df55f and 959cdf5.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • package.json
  • public/assets/mockups/hand.webp
  • public/assets/mockups/phone.webp
  • src/app/[locale]/globals.css
  • src/app/[locale]/layout.tsx
  • src/app/[locale]/page.tsx
  • src/components/home/Hero.tsx
  • src/components/home/HeroVisuals.tsx
  • src/components/providers/lenis-provider.tsx

Comment thread src/app/[locale]/layout.tsx Outdated
Comment thread src/components/home/HeroVisuals.tsx Outdated
Comment thread src/components/home/HeroVisuals.tsx Outdated
Comment thread src/components/providers/lenis-provider.tsx
…keeping Navbar out of lenis and lenis provider memory leak fix
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/home/HeroVisuals.tsx`:
- Around line 50-59: The desktop phone animation is missing the depth/scale
phase: compute a scale factor (e.g., phoneScale derived from current and clamped
to desired min/max) and a Z translate (phoneTranslateZ derived from current to
simulate depth) and include both in the transform for phoneRef.current; update
the transform in the block that sets phoneRef.current.style.transform (and the
analogous block around lines 133-139) to use translate3d(x, y, z) rotate(...)
scale(phoneScale) so the phone both moves in Z and scales during the entrance;
keep handRef logic unchanged. Ensure you reference phoneRef,
phoneTranslateX/phoneTranslateY, phoneRotate and add phoneScale/phoneTranslateZ
variables when implementing.
- Around line 21-23: The JS breakpoint in checkMobile currently uses 768px which
mismatches Tailwind's sm (640px); update checkMobile (or replace it) to use
window.matchMedia with the same Tailwind breakpoint (e.g.
matchMedia("(max-width: 639px)") or matchMedia("(min-width: 640px)") logic) so
isMobile aligns with Tailwind's sm breakpoint, and ensure the resize/matchMedia
listener added via window.addEventListener or mediaQuery.addEventListener is
cleaned up on unmount; locate the checkMobile function, the isMobile state, and
the window.addEventListener call to implement this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 16666809-f55e-4d1d-933d-492a281253b8

📥 Commits

Reviewing files that changed from the base of the PR and between 959cdf5 and 69c9969.

📒 Files selected for processing (3)
  • src/app/[locale]/layout.tsx
  • src/components/home/HeroVisuals.tsx
  • src/components/providers/lenis-provider.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/[locale]/layout.tsx
  • src/components/providers/lenis-provider.tsx

Comment thread src/components/home/HeroVisuals.tsx Outdated
Comment on lines +21 to +23
const checkMobile = () => setIsMobile(window.innerWidth < 768);
checkMobile();
window.addEventListener("resize", checkMobile);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Tailwind screen definitions =="
configs="$(fd 'tailwind\.config\.(js|cjs|mjs|ts)$' -HI . || true)"
if [ -z "$configs" ]; then
  echo "No tailwind config found; verify whether the repo is using Tailwind defaults."
else
  while IFS= read -r file; do
    [ -z "$file" ] && continue
    echo "--- $file ---"
    rg -n "screens|sm|md" "$file"
  done <<< "$configs"
fi

echo
echo "== Hero breakpoint usage =="
rg -n 'window\.innerWidth <|sm:|md:' src/components/home/HeroVisuals.tsx src/components/home/Hero.tsx

Repository: AOSSIE-Org/Resonate-Website

Length of output: 1792


🌐 Web query:

Tailwind CSS default sm breakpoint screen width

💡 Result:

The default Tailwind CSS sm breakpoint is 40rem (640px).

Citations:


Align the responsive breakpoints: JS uses 768px while Tailwind defaults to sm: 640px.

Between 640px–768px, Tailwind applies sm: styles but the JS threshold keeps isMobile true, causing misaligned layout and potential jumping after checkMobile() runs. Use a shared breakpoint constant or matchMedia to sync JS and Tailwind behavior.

Affects lines: 21, 75, 82, 113

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/home/HeroVisuals.tsx` around lines 21 - 23, The JS breakpoint
in checkMobile currently uses 768px which mismatches Tailwind's sm (640px);
update checkMobile (or replace it) to use window.matchMedia with the same
Tailwind breakpoint (e.g. matchMedia("(max-width: 639px)") or
matchMedia("(min-width: 640px)") logic) so isMobile aligns with Tailwind's sm
breakpoint, and ensure the resize/matchMedia listener added via
window.addEventListener or mediaQuery.addEventListener is cleaned up on unmount;
locate the checkMobile function, the isMobile state, and the
window.addEventListener call to implement this change.

Comment thread src/components/home/HeroVisuals.tsx Outdated
Comment on lines +50 to +59
const phoneRotate = current * -10;
const phoneTranslateX = Math.min(current * (vw * 0.28), maxTranslateX);
const phoneTranslateY = current * 1000;

if (handRef.current) {
handRef.current.style.opacity = `${handOpacity}`;
}

if (phoneRef.current) {
phoneRef.current.style.transform = `translate3d(${phoneTranslateX}px, ${phoneTranslateY}px, 0) rotate(${phoneRotate}deg)`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The desktop phone animation still misses the scale/depth phase from issue #289.

Line 59 keeps the Z component fixed at 0 and only applies translate/rotate, and there is no scale() term anywhere in the desktop branch. The linked hero spec calls for a drop/scale-to-fit entrance, so this is still a 2D move rather than the requested depth animation.

Also applies to: 133-139

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/home/HeroVisuals.tsx` around lines 50 - 59, The desktop phone
animation is missing the depth/scale phase: compute a scale factor (e.g.,
phoneScale derived from current and clamped to desired min/max) and a Z
translate (phoneTranslateZ derived from current to simulate depth) and include
both in the transform for phoneRef.current; update the transform in the block
that sets phoneRef.current.style.transform (and the analogous block around lines
133-139) to use translate3d(x, y, z) rotate(...) scale(phoneScale) so the phone
both moves in Z and scales during the entrance; keep handRef logic unchanged.
Ensure you reference phoneRef, phoneTranslateX/phoneTranslateY, phoneRotate and
add phoneScale/phoneTranslateZ variables when implementing.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

No the scaling has been removed after discussion and iteration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/home/HeroVisuals.tsx`:
- Around line 42-82: The desktop animation useEffect currently runs whenever
isMobile === false; detect the user preference by querying
window.matchMedia('(prefers-reduced-motion: reduce)').matches at the top of the
effect (or use a helper) and if true, skip starting the RAF loop and instead set
the static end-state styles on phoneRef and handRef (the same styles the
animation would produce at rest) so the visual is rendered without motion;
modify the effect that defines animate (and the one at lines ~121-165) to
short-circuit before requestAnimationFrame when prefersReducedMotion is true,
and ensure you still clean up any rafId and do not call requestAnimationFrame in
that case (references: useEffect, isMobile, sectionRef, handRef, phoneRef,
animate, getMarginX).
- Around line 42-82: The RAF loop in useEffect (animate, rafId, current, target,
sectionRef, handRef, phoneRef) currently requeues unconditionally; change it to
gate the loop with an intersection/scroll activity flag and stop rescheduling
when the animation has settled. Add an IntersectionObserver (or reuse a
scroll/lenis flag) to track isIntersecting, compute target as before, then only
call requestAnimationFrame(animate) when isIntersecting OR Math.abs(target -
current) > EPSILON (e.g. 0.001); if both false, cancelAnimationFrame(rafId) and
don't set a new rafId. Also ensure the observer is cleaned up in the effect
cleanup and that rafId is canceled when isMobile changes. This keeps
getBoundingClientRect/style writes off when off-screen and stops the perpetual
RAF once current ≈ target.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ebcd69b8-a81c-40ef-a938-af56856bd854

📥 Commits

Reviewing files that changed from the base of the PR and between 69c9969 and e01f161.

📒 Files selected for processing (1)
  • src/components/home/HeroVisuals.tsx

Comment thread src/components/home/HeroVisuals.tsx Outdated
@reach2saksham
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant