Skip to content

enhance: modernize landing page feature and workflow sections#440

Open
vv-verse wants to merge 1 commit into
GitMetricsLab:mainfrom
vv-verse:feat/premium-features-ui
Open

enhance: modernize landing page feature and workflow sections#440
vv-verse wants to merge 1 commit into
GitMetricsLab:mainfrom
vv-verse:feat/premium-features-ui

Conversation

@vv-verse
Copy link
Copy Markdown

@vv-verse vv-verse commented May 22, 2026

Summary

This PR modernizes key landing page sections with improved layouts, refined card designs, enhanced workflow visualization, and better dark mode consistency to create a more premium SaaS-style experience.

Closes #439


Sections Improved

Powerful Features

  • Refined card sizing and proportions
  • Improved typography hierarchy
  • Enhanced spacing and layout balance
  • Modernized visual styling
  • Improved responsiveness and consistency

How It Works

  • Improved workflow visualization between steps
  • Enhanced animated connector line
  • Fixed dark mode visual inconsistencies
  • Improved glow and interaction effects
  • Better visual continuity across cards

UI/UX Enhancements

Area Improvement
Card Design Cleaner proportions and spacing
Visual Hierarchy Improved readability and structure
Dark Mode Better glow visibility and consistency
Workflow Animation Smoother and clearer process flow
Responsiveness Improved section balance on different screen sizes
SaaS Styling More modern and premium appearance

Design Direction

  • Modern SaaS-inspired UI
  • Cleaner workflow communication
  • Subtle glow and lighting effects
  • Improved interaction feedback
  • Better visual consistency across sections

Testing

  • Verified layout in light mode
  • Verified layout in dark mode
  • Verified responsive behavior
  • Verified workflow connector visibility
  • No new runtime errors introduced

Screenshots

Before :

image image

After :

final.github.mp4

Summary by CodeRabbit

  • New Features
    • Added animated feature cards with interactive 3D tilt effects and staggered reveal animations
    • Redesigned "How It Works" section with animated step cards and visual connector animations for improved responsive presentation
    • Enhanced fullscreen layout styling behavior

Review Change Stack

@netlify
Copy link
Copy Markdown

netlify Bot commented May 22, 2026

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit 82b6d36
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a10e438373f950008d6a6b5
😎 Deploy Preview https://deploy-preview-440--github-spy.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.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

App.tsx main layout is updated to handle fullscreen state with separate flex configurations. Features.tsx is rewritten with animated 3D-tilting cards driven by mouse position tracking. HowItWorks.tsx is refactored from theme-context styling to Framer Motion with responsive desktop/mobile connector bubbles and animated step cards.

Changes

Landing Page UI and Animation Enhancements

Layer / File(s) Summary
Main layout fullscreen handling
src/App.tsx
Main element className template conditionally applies centered flex layout (flex flex-1 justify-center items-center) when fullscreen, or flex-grow with background colors (bg-gray-50 dark:bg-gray-800) in normal mode.
Features section animated cards with 3D tilt hover
src/components/Features.tsx
Features data array defined with per-card icon, title, description, and Tailwind styling tokens; motion animation variants added for container staggering and card reveal. New internal FeatureCard component uses motion values and transforms to implement spring-smoothed 3D tilt (rotateX/rotateY) tracked from mouse position, toggling glow/accent overlays on hover. Animated section renders header, decorative dot grid and blob backgrounds, and staggered grid of FeatureCard instances.
HowItWorks section animated steps with responsive connectors
src/components/HowItWorks.tsx
Steps data model created with step numbers, icons, and per-step styling/animation colors; motion animation variants added for container and card reveal. Two new helper components (ArrowBubble for horizontal desktop connectors, DownArrowBubble for vertical mobile connectors) render SVG arrows with viewport-triggered animations. New StepCard component applies animated hover behavior with border/shadow mutations and icon transforms (rotate/scale on hover). Refactored HowItWorks main render removes ThemeContext usage, applies gradient background, and maps steps into flex-row layout with horizontal arrow connectors on desktop or stacked layout with vertical connectors on mobile.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • GitMetricsLab/github_tracker#230: Both PRs modify src/components/Features.tsx's feature-card implementation, updating the features configuration and card JSX logic to drive hover styling and layout behavior.
  • GitMetricsLab/github_tracker#239: Both PRs significantly modify src/components/HowItWorks.tsx's step data structure, rendering, and connector/card UI.
  • GitMetricsLab/github_tracker#269: Both PRs modify src/App.tsx's main element layout logic, adjusting className handling for fullscreen state detection and flex/background class switching.

Poem

🐰 With cards that tilt and dance in place,
And arrows flowing through the space,
We blur the lines, we blur the light,
Till every hover shines so bright—
A SaaS-y glow, a modern grace! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The title 'enhance: modernize landing page feature and workflow sections' clearly summarizes the main changes of modernizing landing page sections with improved layouts and animations.
Description check ✅ Passed The description provides a clear summary, references the linked issue, lists specific improvements to Features and HowItWorks sections, includes testing verification, and provides before/after screenshots.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #439: modernizes the Features section with refined cards and animations, enhances HowItWorks with improved workflow visualization and dark mode fixes, and implements Framer Motion animations throughout.
Out of Scope Changes check ✅ Passed All changes are in scope: App.tsx layout adjustment supports the styling improvements, Features.tsx receives full animation and card design overhaul, and HowItWorks.tsx gets workflow visualization enhancements as required by issue #439.

✏️ 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.

Copy link
Copy Markdown
Contributor

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/Features.tsx`:
- Around line 123-139: The two glow divs in Features.tsx use the non-existent
Tailwind token "duration-400" (see the className values on the absolute glow
divs with "transition-opacity duration-400"); replace "duration-400" with a
valid token such as "duration-300" or "duration-500" or, if you need exactly
400ms and your Tailwind setup allows arbitrary values, use "duration-[400ms]" so
the hover fade timing is actually applied.

In `@src/components/HowItWorks.tsx`:
- Around line 261-289: The mapped fragments need top-level keys and the mobile
mapping has a redundant motion wrapper; replace the anonymous fragments in both
steps.map() calls with keyed containers (e.g., use <React.Fragment
key={step.number}> or a keyed div) so the fragment itself has a key, and in the
mobile branch remove the extra <motion.div variants={cardVariants}> since
StepCard already receives variants={cardVariants}; instead render StepCard
directly (with the key on the fragment/container) and keep DownArrowBubble keyed
as before (references: steps.map, StepCard, ArrowBubble, DownArrowBubble,
cardVariants, motion.div).
🪄 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: ea37c18c-9f18-4fc9-aa96-63572aef6326

📥 Commits

Reviewing files that changed from the base of the PR and between 9d34c19 and 82b6d36.

📒 Files selected for processing (3)
  • src/App.tsx
  • src/components/Features.tsx
  • src/components/HowItWorks.tsx

Comment on lines +123 to +139
{/* Strong ambient glow on hover */}
<div
className="absolute inset-0 rounded-2xl pointer-events-none transition-opacity duration-400"
style={{
opacity: hovered ? 1 : 0,
background: `radial-gradient(ellipse at 50% 0%, rgba(${feature.glow},0.22) 0%, transparent 60%)`,
}}
/>

{/* Bottom glow puddle */}
<div
className="absolute -bottom-6 left-1/2 -translate-x-1/2 w-3/4 h-12 rounded-full pointer-events-none transition-opacity duration-400 blur-xl"
style={{
opacity: hovered ? 0.5 : 0,
background: `rgba(${feature.glow}, 0.35)`,
}}
/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate Tailwind config
echo "== Tailwind config files =="
ls -1 tailwind.config.* 2>/dev/null || true
ls -1 **/tailwind.config.* 2>/dev/null || true

# Search for duration-400 usage across the repo
echo "== occurrences of 'duration-400' =="
rg -n "duration-400" . || true

# Inspect Tailwind transitionDuration configuration (if tailwind.config exists)
for f in $(ls -1 tailwind.config.* 2>/dev/null || true); do
  echo "== transitionDuration in $f =="
  rg -n "transitionDuration|duration" "$f" || true
done

# Show tailwind version from package.json (best-effort)
echo "== tailwind version in package.json =="
if [ -f package.json ]; then
  cat package.json | rg -n "\"tailwindcss\"|tailwindcss" || true
fi

# Inspect the referenced file section for exact class usage
echo "== src/components/Features.tsx excerpt around duration-400 =="
sed -n '100,160p' src/components/Features.tsx 2>/dev/null || true

Repository: GitMetricsLab/github_tracker

Length of output: 2864


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== tailwind.config.js =="
wc -l tailwind.config.js
sed -n '1,200p' tailwind.config.js

echo "== transitionDuration matches (if any) in tailwind.config.js =="
rg -n "transitionDuration|extend.*transitionDuration|duration" tailwind.config.js || true

Repository: GitMetricsLab/github_tracker

Length of output: 520


Use a valid Tailwind duration token for these hover fades

duration-400 won’t be generated here (Tailwind config has no transitionDuration override), so the intended 400ms timing won’t apply.

Proposed fix
-        className="absolute inset-0 rounded-2xl pointer-events-none transition-opacity duration-400"
+        className="absolute inset-0 rounded-2xl pointer-events-none transition-opacity duration-[400ms]"
@@
-        className="absolute -bottom-6 left-1/2 -translate-x-1/2 w-3/4 h-12 rounded-full pointer-events-none transition-opacity duration-400 blur-xl"
+        className="absolute -bottom-6 left-1/2 -translate-x-1/2 w-3/4 h-12 rounded-full pointer-events-none transition-opacity duration-[400ms] blur-xl"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Features.tsx` around lines 123 - 139, The two glow divs in
Features.tsx use the non-existent Tailwind token "duration-400" (see the
className values on the absolute glow divs with "transition-opacity
duration-400"); replace "duration-400" with a valid token such as "duration-300"
or "duration-500" or, if you need exactly 400ms and your Tailwind setup allows
arbitrary values, use "duration-[400ms]" so the hover fade timing is actually
applied.

Comment on lines +261 to +289
{steps.map((step, i) => (
<>
<div key={step.number} className="flex-1 min-w-0 flex flex-col">
<StepCard step={step} className="flex-1" />
</div>
{i < steps.length - 1 && (
<ArrowBubble key={`arrow-${i}`} color={step.arrowColor} />
)}
</>
))}
</motion.div>

{/* Mobile: stacked cards + down arrows */}
<motion.div
className="flex flex-col md:hidden gap-0"
variants={containerVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-50px' }}
>
{steps.map((step, i) => (
<>
<motion.div key={step.number} variants={cardVariants}>
<StepCard step={step} />
</motion.div>
{i < steps.length - 1 && (
<DownArrowBubble key={`down-${i}`} color={step.arrowColor} />
)}
</>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and display the relevant section of HowItWorks.tsx
FILE="src/components/HowItWorks.tsx"
if [ ! -f "$FILE" ]; then
  echo "Missing file: $FILE"
  exit 1
fi

# Show lines around 240-320 (includes the provided 261-289 region)
nl -ba "$FILE" | sed -n '230,320p'

Repository: GitMetricsLab/github_tracker

Length of output: 116


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check how Fragment is currently handled in this file (if imported or used)
FILE="src/components/HowItWorks.tsx"
rg -n "import\s+\{[^}]*Fragment[^}]*\}" "$FILE" || true
rg -n "\bFragment\b" "$FILE" || true

# Check StepCard / motion usage within the file for variants/ownership
rg -n "StepCard|cardVariants|variants=\{cardVariants\}|ArrowBubble|DownArrowBubble|motion\.div" "$FILE"

Repository: GitMetricsLab/github_tracker

Length of output: 966


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="src/components/HowItWorks.tsx"
sed -n '120,170p' "$FILE"

Repository: GitMetricsLab/github_tracker

Length of output: 1901


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="src/components/HowItWorks.tsx"
sed -n '240,310p' "$FILE"

Repository: GitMetricsLab/github_tracker

Length of output: 2229


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="src/components/HowItWorks.tsx"
# Check if Fragment is already imported/used
rg -n "import\s+\{[^}]*Fragment|Fragment\s*[,)>]" "$FILE" || true

Repository: GitMetricsLab/github_tracker

Length of output: 54


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="src/components/HowItWorks.tsx"
sed -n '1,80p' "$FILE"

Repository: GitMetricsLab/github_tracker

Length of output: 2837


Key the mapped wrapper elements and remove the redundant mobile motion wrapper.

  • Both steps.map() branches return anonymous <>...</> fragments; React needs a key on the top-level fragment (inner keys don’t cover the fragment itself).
  • In the mobile branch, StepCard already applies variants={cardVariants}, so the extra <motion.div variants={cardVariants}> duplicates the entrance animation.
Proposed fix
+import { Fragment } from 'react';
 import { motion } from 'framer-motion';
@@
-          {steps.map((step, i) => (
-            <>
-              <div key={step.number} className="flex-1 min-w-0 flex flex-col">
+          {steps.map((step, i) => (
+            <Fragment key={step.number}>
+              <div className="flex-1 min-w-0 flex flex-col">
                 <StepCard step={step} className="flex-1" />
               </div>
               {i < steps.length - 1 && (
                 <ArrowBubble key={`arrow-${i}`} color={step.arrowColor} />
               )}
-            </>
+            </Fragment>
           ))}
@@
-          {steps.map((step, i) => (
-            <>
-              <motion.div key={step.number} variants={cardVariants}>
-                <StepCard step={step} />
-              </motion.div>
+          {steps.map((step, i) => (
+            <Fragment key={step.number}>
+              <StepCard step={step} />
               {i < steps.length - 1 && (
                 <DownArrowBubble key={`down-${i}`} color={step.arrowColor} />
               )}
-            </>
+            </Fragment>
           ))}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/HowItWorks.tsx` around lines 261 - 289, The mapped fragments
need top-level keys and the mobile mapping has a redundant motion wrapper;
replace the anonymous fragments in both steps.map() calls with keyed containers
(e.g., use <React.Fragment key={step.number}> or a keyed div) so the fragment
itself has a key, and in the mobile branch remove the extra <motion.div
variants={cardVariants}> since StepCard already receives
variants={cardVariants}; instead render StepCard directly (with the key on the
fragment/container) and keep DownArrowBubble keyed as before (references:
steps.map, StepCard, ArrowBubble, DownArrowBubble, cardVariants, motion.div).

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.

🚀 Feature: [Enhancement] Improve landing page feature and workflow sections UI/UX

1 participant