Skip to content

feat: add BackgroundTile component and it's colours in design system#322

Open
reach2saksham wants to merge 5 commits intoAOSSIE-Org:new-designfrom
reach2saksham:feat/background-tile
Open

feat: add BackgroundTile component and it's colours in design system#322
reach2saksham wants to merge 5 commits intoAOSSIE-Org:new-designfrom
reach2saksham:feat/background-tile

Conversation

@reach2saksham
Copy link

@reach2saksham reach2saksham commented Mar 7, 2026

Description

Adds a new BackgroundTile UI component, an animated wave canvas that reacts to scroll and wheel events, freezing in place when scrolling stops.

Fixes #291

Type of change

New file: components/ui/BackgroundTile.tsx

  • Canvas-based animated wave line that activates on scroll/wheel input
  • Wave freezes in its current shape when scrolling stops (does not return to flat)
  • Smooth amplitude lerp on start (fast rise, no decay on stop) to avoid jitter
  • Configurable height via heightVh prop (defaults to 50vh)
  • Line color driven by --line-color CSS variable, with light/dark mode support via global CSS tokens
  • DPR-aware canvas sizing via ResizeObserver
  • RAF loop only runs while scrolling — idle cost is zero
  • Random wave phase/frequency values scoped inside useRef to prevent SSR hydration mismatch

Updated: globals.css

Added --tile-bg, --tile-stroke, --line-color token to both light and dark mode in RGB format for better opacity control.

  • New feature (non-breaking change which adds functionality)
  • New release (version bump, release preparation)
  • UI/UX update (design changes, interface improvements)

How Has This Been Tested?

Checked logs and next for error. No errors have been found:

backgroundtile.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

    • Added an animated, responsive background tile component with interactive wave effects that respond to scroll and wheel and stops gracefully.
  • Style

    • Introduced theme-aware CSS variables for tile background, stroke, and line color.
    • Tweaked navigation background rendering for light/dark modes and updated page layout to use responsive horizontal margins.

@coderabbitai
Copy link

coderabbitai bot commented Mar 7, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5b8bb81e-5877-4b94-b139-228ad5849073

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds theme-aware CSS tokens for tile visuals and a new client-side BackgroundTile React component that renders a responsive, animated canvas waveform with scroll/wheel-driven amplitude controls; adjusts page layout margins for responsive spacing.

Changes

Cohort / File(s) Summary
Theme / globals.css
src/app/[locale]/globals.css
Added tile-related CSS custom properties (--tile-bg, --tile-stroke, --line-color) in root and .dark blocks; minor formatting/newline adjustments; adjusted navigation background token syntax.
Background Tile component
src/components/ui/BackgroundTile.tsx
New client-side React component: canvas-based animated waveform using ResizeObserver, DPR scaling, requestAnimationFrame loop, wheel/scroll-driven amplitude targets, MutationObserver for theme color, and full cleanup on unmount. Review animation loop, event handling, and observers.
Page integration / layout
src/app/[locale]/page.tsx
Updated container spacing from p-24 to responsive margins (mx-4 sm:mx-8 lg:mx-16 xl:mx-48) to accommodate the tile placement; no other functional changes.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Page as Page
    participant Tile as BackgroundTile
    participant RO as ResizeObserver
    participant Canvas as Canvas

    User->>Page: opens page / scrolls / wheel
    Page->>Tile: mount (attach listeners)
    Tile->>RO: observe container/canvas
    RO-->>Tile: size change event
    Tile->>Canvas: set DPR & resize, draw frame
    User->>Tile: wheel/scroll -> update amp target
    Tile->>Tile: start/stop RAF loop (animation)
    Tile->>Canvas: render waveform frames (requestAnimationFrame)
    User-->>Tile: input stops -> amplitude decays -> stop loop
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

new-design

Suggested reviewers

  • M4dhav

Poem

🐰 I sketched a ripple on a quiet tile,
It breathes with scrolls and shimmers after a while,
From light to dark it sways and sighs,
A canvas wave beneath the skies,
Hop, hover, hum — the page wears a smile.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive Implementation addresses core animation and component creation but light mode fade-out effect and Figma design specifics are not clearly documented. Verify that light mode fade-out animation and staged color transitions from Figma are fully implemented; confirm theme transitions match design specifications.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately summarizes the main changes: adding a BackgroundTile component and design system color tokens.
Out of Scope Changes check ✅ Passed All changes (BackgroundTile component, design tokens, responsive margins) are directly related to implementing the animated tile component.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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
Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 7, 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

@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: 5

🤖 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]/globals.css:
- Around line 40-43: The CSS variable --tile-bg uses invalid rgba() syntax with
three components; update the declaration for --tile-bg to use a valid color
function (either change rgba(227, 226, 246) to rgb(227, 226, 246) for an opaque
color or add an alpha channel like rgba(227, 226, 246, 1)). Ensure --tile-bg is
corrected alongside the existing --tile-stroke and --line-color variables so all
color values use valid CSS color syntax.
- Around line 73-76: The dark-mode CSS variables --tile-bg, --tile-stroke, and
--line-color use invalid/ambiguous rgba() syntax; update them to the corrected
color-function form used elsewhere (e.g., include an explicit alpha or use the
modern slash syntax) so they parse consistently in dark mode—for example replace
rgba(30, 29, 28) with a proper value like rgba(30,29,28,1) or rgb(30 29 28 / 1),
and similarly ensure --tile-stroke and --line-color include their alpha channels
correctly (e.g., rgba(80,80,80,0.5) and rgba(0,0,0,0.2)).

In `@src/components/ui/BackgroundTile.tsx`:
- Line 1: The BackgroundTile component uses browser-only APIs (window, document,
ResizeObserver, requestAnimationFrame) but is currently a Server Component; add
the Next.js App Router client directive by inserting "use client" as the very
first line of src/components/ui/BackgroundTile.tsx so the component (and its
useEffect/useRef hooks) run on the client; ensure the directive precedes imports
and keep existing imports and hooks (useEffect, useRef) unchanged.
- Line 77: The per-frame call to getComputedStyle in BackgroundTile.tsx (the
line setting ctx.strokeStyle =
getComputedStyle(document.documentElement).getPropertyValue("--line-color").trim())
causes unnecessary work; cache the computed "--line-color" once (e.g., in a ref
or component state) and use that cached value when painting each frame, and
refresh the cache only when the theme changes (detect via a theme prop, a
MutationObserver on document.documentElement attributes, or a theme change
event) so you avoid calling getComputedStyle inside the animation/render loop.
- Around line 146-148: The canvas currently registers a duplicate wheel listener
causing onWheel to fire twice; remove the redundant
canvas.addEventListener("wheel", onWheel, { passive: true }) registration (or
alternatively modify the canvas handler to call event.stopPropagation()) so only
one wheel handler runs; update any initialization/cleanup code that references
the canvas wheel listener (e.g., where onWheel is added/removed) to avoid double
timeouts and ensure only the window-level onWheel is used.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ae26f369-b133-45cb-97d2-a7d48a1ac9ef

📥 Commits

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

📒 Files selected for processing (2)
  • src/app/[locale]/globals.css
  • src/components/ui/BackgroundTile.tsx

Comment on lines +40 to +43
/* Background Tile Colors */
--tile-bg: rgba(227, 226, 246);
--tile-stroke: rgba(80, 80, 80, 0.1);
--line-color: rgba(0, 0, 0, 0.05);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Invalid rgba() syntax — missing alpha value.

rgba(227, 226, 246) provides only 3 values but rgba() requires 4 (r, g, b, a). This will cause the property to be ignored or produce unexpected results. Use rgb() for opaque colors or add the alpha channel.

🐛 Proposed fix
   /* Background Tile Colors */
-  --tile-bg: rgba(227, 226, 246);
+  --tile-bg: rgb(227, 226, 246);
   --tile-stroke: rgba(80, 80, 80, 0.1);
   --line-color: rgba(0, 0, 0, 0.05);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/* Background Tile Colors */
--tile-bg: rgba(227, 226, 246);
--tile-stroke: rgba(80, 80, 80, 0.1);
--line-color: rgba(0, 0, 0, 0.05);
/* Background Tile Colors */
--tile-bg: rgb(227, 226, 246);
--tile-stroke: rgba(80, 80, 80, 0.1);
--line-color: rgba(0, 0, 0, 0.05);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`[locale]/globals.css around lines 40 - 43, The CSS variable
--tile-bg uses invalid rgba() syntax with three components; update the
declaration for --tile-bg to use a valid color function (either change rgba(227,
226, 246) to rgb(227, 226, 246) for an opaque color or add an alpha channel like
rgba(227, 226, 246, 1)). Ensure --tile-bg is corrected alongside the existing
--tile-stroke and --line-color variables so all color values use valid CSS color
syntax.

Comment on lines +73 to +76
/* Background Tile Colors */
--tile-bg: rgba(30, 29, 28);
--tile-stroke: rgba(80, 80, 80, 0.5);
--line-color: rgba(0, 0, 0, 0.2);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Same rgba() syntax issue in dark mode.

Apply the same fix here for consistency.

🐛 Proposed fix
   /* Background Tile Colors */
-  --tile-bg: rgba(30, 29, 28);
+  --tile-bg: rgb(30, 29, 28);
   --tile-stroke: rgba(80, 80, 80, 0.5);
   --line-color: rgba(0, 0, 0, 0.2);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/* Background Tile Colors */
--tile-bg: rgba(30, 29, 28);
--tile-stroke: rgba(80, 80, 80, 0.5);
--line-color: rgba(0, 0, 0, 0.2);
/* Background Tile Colors */
--tile-bg: rgb(30, 29, 28);
--tile-stroke: rgba(80, 80, 80, 0.5);
--line-color: rgba(0, 0, 0, 0.2);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/`[locale]/globals.css around lines 73 - 76, The dark-mode CSS
variables --tile-bg, --tile-stroke, and --line-color use invalid/ambiguous
rgba() syntax; update them to the corrected color-function form used elsewhere
(e.g., include an explicit alpha or use the modern slash syntax) so they parse
consistently in dark mode—for example replace rgba(30, 29, 28) with a proper
value like rgba(30,29,28,1) or rgb(30 29 28 / 1), and similarly ensure
--tile-stroke and --line-color include their alpha channels correctly (e.g.,
rgba(80,80,80,0.5) and rgba(0,0,0,0.2)).

@reach2saksham
Copy link
Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 7, 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

@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

🤖 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]/page.tsx:
- Around line 13-19: The Home component imports BackgroundTile but never uses
it; either render <BackgroundTile /> inside the Home JSX (e.g., alongside or
wrapping the current div in the Home function) so the tile appears, or remove
the unused BackgroundTile import until you wire it into the page; update the
Home component to include BackgroundTile (or delete its import) and ensure any
required props or classNames are passed when rendering.

In `@src/components/ui/BackgroundTile.tsx`:
- Around line 49-57: The ResizeObserver's setSize function resets the canvas
bitmap (canvas.width/height and ctx.setTransform) but doesn't redraw, leaving
the tile blank until user input; update setSize (used by ResizeObserver and
called once at mount) to call the component's render() after resizing so the
line is immediately redrawn — locate the setSize function and the
ro.observe(canvas) usage along with the render() function and add a render()
invocation at the end of setSize so the canvas is repainted after any
resize/orientation change.
- Around line 97-101: The stroke uses a single flat color (ctx.strokeStyle =
lineColorRef.current) which cannot produce the required light-mode
transition/fade; replace the flat strokeStyle with a CanvasGradient created via
ctx.createLinearGradient(...) (or createRadialGradient if appropriate), add
color stops that use lineColorRef.current and a transparent/alpha-reduced
variant for the fade, assign that gradient to ctx.strokeStyle, and ensure you
recompute the gradient whenever canvas size, path bounds, or theme/mode changes
(where lineColorRef.current is used) before calling ctx.stroke().
- Around line 151-164: onWheel and onScroll conflict because onScroll always
sets ampRef.current = 0.55, overwriting the wheel-computed amplitude; modify the
handlers so wheel input is preferred for a short window: either consolidate both
into a single helper (e.g., handleUserScroll(amplitude)) that sets ampRef, calls
startLoop and resets stopTimer, and have onWheel call it with the
velocity-derived amplitude while onScroll only calls it if no recent wheel event
occurred; alternatively set a flag/lastWheelTime inside onWheel (and clear it
after ~80ms) and make onScroll no-op when that flag/window is active; ensure you
still call startLoop and manage stopTimer/stopLoop in the shared helper to avoid
duplicate logic (references: onWheel, onScroll, ampRef, startLoop, stopTimer,
stopLoop).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 43ef376f-cc8e-4da0-8769-c142cd7dc164

📥 Commits

Reviewing files that changed from the base of the PR and between adb56b3 and f3bb348.

📒 Files selected for processing (3)
  • src/app/[locale]/globals.css
  • src/app/[locale]/page.tsx
  • src/components/ui/BackgroundTile.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/[locale]/globals.css

@reach2saksham
Copy link
Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 7, 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.

@reach2saksham
Copy link
Author

@CodeRabbit review

@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 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

@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: 1

🤖 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/ui/BackgroundTile.tsx`:
- Around line 9-12: BackgroundTileProps declares heightVh but the BackgroundTile
component never uses it; update the BackgroundTile component to accept heightVh
(default 50) and apply it to the tile container (e.g., via an inline style or
computed class) so the tile height is set to `${heightVh}vh` instead of relying
on h-full; reference the prop name heightVh and the interface
BackgroundTileProps when making the change and ensure the same fix is applied to
the other instance noted (lines ~195-206) so both components honor the heightVh
prop.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bd357857-a322-433d-953e-c0542df3ac29

📥 Commits

Reviewing files that changed from the base of the PR and between d217bf5 and bcd47b4.

📒 Files selected for processing (1)
  • src/components/ui/BackgroundTile.tsx

Comment on lines +9 to +12
interface BackgroundTileProps {
/** Height of the tile in viewport height units. Defaults to 50. */
heightVh?: number;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

The heightVh prop is defined but never applied.

The interface documents heightVh as controlling tile height in viewport units (default 50), but the component never uses this value. The container relies on h-full from parent sizing instead.

🐛 Proposed fix to apply the height prop
   return (
     <div
       style={{
         background:   "var(--tile-bg, `#1a1a1a`)",
         border:       "0.8px solid var(--tile-stroke, rgba(255,255,255,0.08))",
         borderRadius: "24px",
-        width:        "100%",
+        height:       `${heightVh}vh`,
         overflow:     "hidden",
         position:     "relative",
       }}
-      className="w-full h-full"
+      className="w-full"
     >

Also applies to: 195-206

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

In `@src/components/ui/BackgroundTile.tsx` around lines 9 - 12,
BackgroundTileProps declares heightVh but the BackgroundTile component never
uses it; update the BackgroundTile component to accept heightVh (default 50) and
apply it to the tile container (e.g., via an inline style or computed class) so
the tile height is set to `${heightVh}vh` instead of relying on h-full;
reference the prop name heightVh and the interface BackgroundTileProps when
making the change and ensure the same fix is applied to the other instance noted
(lines ~195-206) so both components honor the heightVh prop.

@reach2saksham
Copy link
Author

@M4dhav This PR is ready to be merged from my side.

@reach2saksham reach2saksham added enhancement New feature or request new-design labels Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request new-design

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant