Skip to content

feat: Railway-style interactive hero demo + /feed/more screen - #64

Open
Tar-ive wants to merge 2 commits into
mainfrom
devin/1782924768-railway-homepage
Open

feat: Railway-style interactive hero demo + /feed/more screen#64
Tar-ive wants to merge 2 commits into
mainfrom
devin/1782924768-railway-homepage

Conversation

@Tar-ive

@Tar-ive Tar-ive commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

Replaces the landing page hero with a Railway-inspired 5-tab interactive product demo and adds a new /feed/more feature hub page.

Hero Section (hero-section.tsx)

The hero now contains a dark-framed "device window" on the right that renders 5 animated mock UI panels, each telling the next chapter of the giftmaxxing user journey:

Discover → Swipe → Gift → Pool → Maxi
  • Discover: Pinterest-style grid of gift items with heart toggles
  • Swipe: Tinder-style card with swipe animation + match score
  • Gift: Wishlist with claim buttons + Maxi tip callout
  • Pool: Group gifting progress bar with contributor list + "chip in" CTA
  • Maxi: AI chat conversation with typing indicator and staggered message reveal

Tabs auto-cycle every 5s; clicking a tab resets the timer. Each panel re-mounts with a key={activeTab} cross-fade via CSS (animate-panel-in). Tab bar uses pill-style buttons matching Railway's bottom nav pattern.

Left column retains headline + CTAs but now uses the tagline "Gifting, finally figured out." with the existing word-gradient animation.

Features Section (features-section.tsx)

Rebuilt as 5 alternating FeatureBlock sections (one per tab) with:

  • Vertical connector lines between blocks (Railway's "train track" equivalent)
  • Each block: tag pill + icon, headline + accent line, description, deep-link CTA, and stacked bullet cards with hover-lift
  • First feature includes "Alternative to" competitive positioning badges (Amazon, Google Shopping, Pinterest)

More Page (/feed/more/page.tsx)

New in-app page at /feed/more serving as a feature hub:

  • User profile header with avatar, name, handle
  • 3-column stats bar (finds saved, double-buys, avg rating)
  • Core Features grid (6 cards: Feed, Swipe, Maxi, Pools, Shop, Ideas)
  • More to Explore grid (6 cards: Events, Messages, Notifications, Drops, Milestones, Recommendations)
  • Maxi CTA banner at bottom
  • Each card has icon, description, hover glow effect (card-glow CSS), and arrow reveal on hover

CSS (globals.css)

Added animate-panel-in (opacity+translateY+scale cross-fade), animate-in (staggered item entrance), and card-glow (hover gradient border) animations.

Link to Devin session: https://calhacks-promptetheus.devinenterprise.com/sessions/622c5fce32b64bff863ca8ef7a2efc41
Requested by: @Tar-ive


Open in Devin Review

Summary by CodeRabbit

  • New Features
    • Added a new “More” feed page with user profile info, quick stats, feature cards, and shortcut links.
    • Introduced a tabbed interactive demo in the landing hero with auto-rotating panels.
    • Updated the landing features section with a cleaner, card-based layout and action links.
  • Style
    • Added new motion and hover-glow effects for cards and panels across the app.

- Replace hero section with 5-tab interactive demo (Discover → Swipe → Gift → Pool → Maxi)
  showing simulated app UI with auto-cycling and click-override
- Rebuild features section with Railway-style narrative arc and connector lines
- Add /feed/more page with feature hub, quick stats, and Maxi CTA banner
- Add CSS animations for panel transitions and card hover effects

Co-Authored-By: Saksham <tarive22@gmail.com>
@Tar-ive Tar-ive self-assigned this Jul 1, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
giftmaxxing Ready Ready Preview, Comment, Open in v0 Jul 1, 2026 5:07pm

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@devin-ai-integration[bot], you've reached your PR review limit, so we couldn't start this review.

Next review available in: 3 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f302a961-87cd-4b48-a67c-4bc41059b123

📥 Commits

Reviewing files that changed from the base of the PR and between 9a13631 and f699076.

📒 Files selected for processing (2)
  • web/components/landing/features-section.tsx
  • web/components/landing/hero-section.tsx

Walkthrough

This PR adds a new /feed/more page with a user header, quick stats, and feature card grids, reworks the landing hero into a tabbed interactive demo replacing keyword rotation, replaces the features section with a bullet-based FeatureBlock layout, and adds supporting CSS keyframes/glow styles.

Changes

Feed More Page

Layer / File(s) Summary
Feature card types and data config
web/app/feed/more/page.tsx
Defines IconComponent type, FeatureCard interface, and PRIMARY_FEATURES/SECONDARY_FEATURES arrays (title/description/href/icon/color/badge).
CardGrid component and MorePage rendering
web/app/feed/more/page.tsx
Implements CardGrid for linked feature tiles and MorePage rendering user header, quick stats, feature sections, banner link, and footer nav.

Landing Page Redesign

Layer / File(s) Summary
Hero tabbed interactive demo and layout
web/components/landing/hero-section.tsx
Removes BlurWord keyword rotation; adds TabId/TABS/mock panels/PANELS map, auto-cycling timerRef state with manual restart, reworked background/CTAs/device frame, and simplified stats labels.
Feature-bullet layout and FeatureBlock animation
web/components/landing/features-section.tsx
Introduces Feature interface, FEATURES dataset, FEATURE_COLORS, and FeatureBlock with per-block IntersectionObserver visibility; replaces prior bento/particle rendering with mapped FeatureBlock list.
Animation and glow CSS support
web/app/globals.css
Adds panel-in/in keyframes, .animate-panel-in/.animate-in classes, and .card-glow hover pseudo-element effect.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant HeroSection
  participant TimerRef
  participant PANELS
  HeroSection->>TimerRef: start interval (AUTO_CYCLE_MS)
  TimerRef->>HeroSection: tick, advance activeTab
  HeroSection->>PANELS: render Panel for activeTab
  User->>HeroSection: click tab
  HeroSection->>TimerRef: restart interval
  HeroSection->>PANELS: render selected Panel
Loading
sequenceDiagram
  participant User
  participant MorePage
  participant useCurrentUser
  participant CardGrid
  User->>MorePage: navigate to /feed/more
  MorePage->>useCurrentUser: fetch current user
  useCurrentUser-->>MorePage: user avatar/name/handle
  MorePage->>CardGrid: render feature arrays
  CardGrid-->>User: linked feature tiles
Loading

Related PRs: None found.

Suggested labels: frontend, ui-enhancement

Suggested reviewers: Tar-ive

Poem

A tab spins round, discover then swipe,
Panels auto-cycle, no BlurWord hype,
Cards glow soft on hover's embrace (opacity fade-in),
More page loads with stats and a chase,
Ship it, rabbit-style — CSS keyframes in place! 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the main changes: the Railway-style interactive hero demo and the new /feed/more screen.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1782924768-railway-homepage

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.

@devin-ai-integration devin-ai-integration Bot left a comment

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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🧹 Nitpick comments (4)
web/app/feed/more/page.tsx (2)

23-23: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer lucide-react's exported LucideIcon type over typeof Search.

typeof Search works but couples the alias to whichever icon happens to be imported first (fragile indirection). lucide-react exports a canonical LucideIcon type for exactly this component-typing use case.

♻️ Suggested tightening
-type IconComponent = typeof Search;
+import type { LucideIcon } from "lucide-react";
+type IconComponent = LucideIcon;
🤖 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 `@web/app/feed/more/page.tsx` at line 23, Replace the IconComponent alias in
the feed page with lucide-react’s exported LucideIcon type instead of using
typeof Search. Update the type definition near IconComponent to import and
reference LucideIcon directly, so the component typing is decoupled from
whichever icon is imported first and stays consistent across icon swaps.

34-123: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Feature/color config overlaps with features-section.tsx's own dataset.

Per the stack context, features-section.tsx (sibling layer, same PR) maintains its own FEATURES dataset plus a FEATURE_COLORS palette for the same five product pillars (Discover/Swipe/Gift/Pool/Maxi). This file independently re-declares titles/colors/icons for an overlapping but distinct card set (hub page vs. landing feature blocks). Not a bug today, but two sources of truth for feature branding (icon/color/copy) risk drift as either evolves — consider a shared config module if these are meant to represent the same product surfaces.

🤖 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 `@web/app/feed/more/page.tsx` around lines 34 - 123, The feature card titles,
icons, and colors in PRIMARY_FEATURES and SECONDARY_FEATURES are duplicating
branding data that also exists in features-section.tsx, creating multiple
sources of truth. Move the shared product-pillar metadata into a common config
module and have both this page’s card arrays and features-section.tsx consume
it, keeping only page-specific copy or links local. Use the existing FeatureCard
shape and the PRIMARY_FEATURES/SECONDARY_FEATURES constants as the main call
sites to refactor.
web/components/landing/features-section.tsx (1)

92-99: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Observer keeps watching after visibility is already latched.

Once entry.isIntersecting fires and isVisible is set true, the observer (obs) is never unobserve/disconnect-ed until unmount, so it keeps computing intersection on every scroll for a block that will never change state again. Cheap fix: disconnect right after the first trigger.

♻️ Proposed fix
     const observer = new IntersectionObserver(
-      ([entry]) => { if (entry.isIntersecting) setIsVisible(true); },
+      ([entry]) => {
+        if (entry.isIntersecting) {
+          setIsVisible(true);
+          observer.disconnect();
+        }
+      },
       { threshold: 0.15 }
     );
🤖 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 `@web/components/landing/features-section.tsx` around lines 92 - 99, The
IntersectionObserver in the features-section component keeps observing after the
first visible state is latched, causing unnecessary work on later scrolls.
Update the useEffect callback in features-section.tsx so the observer is
disconnected or unobserved immediately after setIsVisible(true) runs for the
first intersecting entry, and keep the cleanup disconnect in place for unmount.
Refer to the useEffect, observer, and setIsVisible logic in the
landing/features-section component when making the change.
web/components/landing/hero-section.tsx (1)

447-455: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

Hard-coded third-party CDN image (external dependency, EDN risk) for the hero background.

https://cdn.midjourney.com/... is loaded via a raw <img> rather than next/image, and depends entirely on a third-party CDN outside your control. Beyond losing Next.js image optimization (responsive sizes, lazy loading, format negotiation), if that asset is ever removed/rotated by Midjourney, the hero silently falls back to display:none on error, leaving an empty background. Consider hosting the asset yourself (e.g. public/ or your own CDN) and rendering via next/image.

🤖 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 `@web/components/landing/hero-section.tsx` around lines 447 - 455, The hero
background currently depends on a hard-coded Midjourney CDN URL in the hero
section, which should be replaced with an asset you control. Update the hero
background in hero-section.tsx to use a self-hosted image (for example from
public/ or your own CDN) and render it through next/image instead of a raw img
so the component keeps optimization and doesn’t vanish if the external asset
disappears. Keep the change localized to the hero image markup and its fallback
handling.
🤖 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 `@web/app/feed/more/page.tsx`:
- Around line 194-208: The quick stat cards in the live profile header are
hardcoded placeholder values, so update the stats block in the feed page to use
real user data or clearly mark it as mock copy. Refactor the inline stats array
in the header section so it pulls from the appropriate user stats source, or
replace the current `12k+ / 0 / 4.9` values with explicit placeholder labeling.
Keep the existing card rendering structure, but ensure the data source is
dynamic or intentionally non-production.

In `@web/components/landing/hero-section.tsx`:
- Around line 549-570: The tab buttons in hero-section lose their accessible
name on small screens because the label span is hidden for inactive tabs. Update
the tab button markup in the TABS map so each button always has a persistent
accessible name, using the tab label as button text or an aria-label on the
button, and ensure the Icon in the same button is treated as decorative if
needed. Keep the visual mobile behavior, but make sure inactive tabs in
handleTabClick remain announced correctly for screen readers.

---

Nitpick comments:
In `@web/app/feed/more/page.tsx`:
- Line 23: Replace the IconComponent alias in the feed page with lucide-react’s
exported LucideIcon type instead of using typeof Search. Update the type
definition near IconComponent to import and reference LucideIcon directly, so
the component typing is decoupled from whichever icon is imported first and
stays consistent across icon swaps.
- Around line 34-123: The feature card titles, icons, and colors in
PRIMARY_FEATURES and SECONDARY_FEATURES are duplicating branding data that also
exists in features-section.tsx, creating multiple sources of truth. Move the
shared product-pillar metadata into a common config module and have both this
page’s card arrays and features-section.tsx consume it, keeping only
page-specific copy or links local. Use the existing FeatureCard shape and the
PRIMARY_FEATURES/SECONDARY_FEATURES constants as the main call sites to
refactor.

In `@web/components/landing/features-section.tsx`:
- Around line 92-99: The IntersectionObserver in the features-section component
keeps observing after the first visible state is latched, causing unnecessary
work on later scrolls. Update the useEffect callback in features-section.tsx so
the observer is disconnected or unobserved immediately after setIsVisible(true)
runs for the first intersecting entry, and keep the cleanup disconnect in place
for unmount. Refer to the useEffect, observer, and setIsVisible logic in the
landing/features-section component when making the change.

In `@web/components/landing/hero-section.tsx`:
- Around line 447-455: The hero background currently depends on a hard-coded
Midjourney CDN URL in the hero section, which should be replaced with an asset
you control. Update the hero background in hero-section.tsx to use a self-hosted
image (for example from public/ or your own CDN) and render it through
next/image instead of a raw img so the component keeps optimization and doesn’t
vanish if the external asset disappears. Keep the change localized to the hero
image markup and its fallback handling.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3f8d39fc-b606-49f4-80c4-0307dcb398ab

📥 Commits

Reviewing files that changed from the base of the PR and between dc276ef and 9a13631.

📒 Files selected for processing (4)
  • web/app/feed/more/page.tsx
  • web/app/globals.css
  • web/components/landing/features-section.tsx
  • web/components/landing/hero-section.tsx

Comment on lines +194 to +208
<div className="grid grid-cols-3 gap-3 mb-10">
{[
{ value: "12k+", label: "Finds saved" },
{ value: "0", label: "Double-buys" },
{ value: "4.9", label: "Avg rating" },
].map((stat) => (
<div
key={stat.label}
className="rounded-2xl border border-line bg-surface p-4 text-center"
>
<p className="text-2xl font-display text-ink">{stat.value}</p>
<p className="text-[10px] text-ink-faint mt-1">{stat.label}</p>
</div>
))}
</div>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the target file and nearby context.
sed -n '1,260p' web/app/feed/more/page.tsx

# Search for the stat labels/values and any related data source in the feed area.
rg -n '"12k\+|"0"|"4\.9"|Finds saved|Double-buys|Avg rating|quick stats|stats' web/app/feed -S

# Check whether this page pulls any user-specific metrics elsewhere.
rg -n 'useCurrentUser|avatar|handle|grad|rating|saved|double-buys|finds saved' web/app -S

Repository: Tar-ive/giftmaxxing

Length of output: 21839


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the file structure for the page component before reading smaller slices.
ast-grep outline web/app/feed/more/page.tsx --view expanded

# Show line numbers around the stats block only.
nl -ba web/app/feed/more/page.tsx | sed -n '180,220p'

Repository: Tar-ive/giftmaxxing

Length of output: 644


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("web/app/feed/more/page.tsx")
text = p.read_text()
for needle in ["12k+", "0", "4.9", "Finds saved", "Double-buys", "Avg rating"]:
    print(needle, text.count(needle))
PY

Repository: Tar-ive/giftmaxxing

Length of output: 216


Wire the quick stats to real user data The 12k+ / 0 / 4.9 cards read as per-user metrics under the live profile header, but they’re hardcoded. Either source them from user stats or mark them as placeholder copy.

🤖 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 `@web/app/feed/more/page.tsx` around lines 194 - 208, The quick stat cards in
the live profile header are hardcoded placeholder values, so update the stats
block in the feed page to use real user data or clearly mark it as mock copy.
Refactor the inline stats array in the header section so it pulls from the
appropriate user stats source, or replace the current `12k+ / 0 / 4.9` values
with explicit placeholder labeling. Keep the existing card rendering structure,
but ensure the data source is dynamic or intentionally non-production.

Comment thread web/components/landing/hero-section.tsx
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.

1 participant