feat: revamp landing page with interactive components and unified nav (#251)#315
Conversation
- Split monolithic landing page into section components - Add smooth scroll animations and micro-interactions - Implement orbit animations, BYOM pipeline, services showcase - Improve typography hierarchy and spacing - Fix auth forms with proper titles and branding - Remove redundant 'Back to Home' button from signup - Fully responsive across mobile, tablet, and desktop - Mobile hamburger menu support
geturbackend#251) - Add BorderGlow, Hyperspeed, and MagicBento components - Refactor hero section: centered layout with Hyperspeed background - Replace services grid with MagicBento card component - Add unified glassmorphism nav with active states - Update Pricing page to use shared nav and mobile overlay - Add gsap, three, postprocessing dependencies - Polish animations and visual effects across landing page
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
💤 Files with no reviewable changes (1)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds three new reusable visual components ( ChangesVisual Component Library and Landing Page Revamp
Auth Pages and Pricing Navigation Polish
Sequence Diagram(s)sequenceDiagram
participant Browser as Browser
participant LandingPage as LandingPage
participant Hyperspeed as Hyperspeed (Three.js)
participant MagicBento as MagicBento
participant BorderGlow as BorderGlow
participant GlobalSpotlight as GlobalSpotlight
Browser->>LandingPage: mount
LandingPage->>Hyperspeed: render in hero section
Hyperspeed->>Hyperspeed: load SMAA assets → init App → tick()
LandingPage->>MagicBento: render APP_SERVICES cards
MagicBento->>GlobalSpotlight: mount (if enableSpotlight + !isMobile)
MagicBento->>BorderGlow: render each card
Browser->>GlobalSpotlight: mousemove
GlobalSpotlight->>BorderGlow: set --glow-intensity per card distance
Browser->>BorderGlow: onPointerMove
BorderGlow->>BorderGlow: compute --edge-proximity, --cursor-angle → update DOM style
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
LGTM |
|
@coderabbitai |
|
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
apps/web-dashboard/src/pages/LandingPage/index.jsx (3)
772-774:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd ARIA metadata to the mobile menu toggle button.
The toggle button has no accessible name/state. Add
aria-label,aria-expanded, andaria-controlsso screen readers can operate it correctly.🤖 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 `@apps/web-dashboard/src/pages/LandingPage/index.jsx` around lines 772 - 774, The mobile menu toggle button with className "mobile-menu-btn" lacks accessibility attributes required by screen readers. Add the aria-label attribute to provide an accessible name describing the button's purpose, add the aria-expanded attribute bound to the isMobileMenuOpen state to indicate whether the menu is open or closed, and add the aria-controls attribute that references the ID of the mobile menu element being toggled. These attributes will enable screen reader users to understand and operate the button correctly.
1284-1290:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse semantic buttons for FAQ toggles (keyboard + ARIA).
The FAQ trigger is a clickable
div, which is not keyboard-accessible by default. Use a<button>witharia-expanded/aria-controls.Proposed fix
-<div className="faq-question" onClick={() => toggleFaq(index)}> +<button + type="button" + className="faq-question" + onClick={() => toggleFaq(index)} + aria-expanded={openFaqIndex === index} + aria-controls={`faq-answer-${index}`} +> <span>{faq.q}</span> {openFaqIndex === index ? <ChevronUp size={20} color="`#666`" /> : <ChevronDown size={20} color="`#666`" />} -</div> +</button> {openFaqIndex === index && ( - <div className="faq-answer">{faq.a}</div> + <div id={`faq-answer-${index}`} className="faq-answer">{faq.a}</div> )}🤖 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 `@apps/web-dashboard/src/pages/LandingPage/index.jsx` around lines 1284 - 1290, The FAQ trigger element with className "faq-question" uses a non-semantic div instead of a button, which lacks keyboard accessibility and screen reader support. Replace the div element with a button element, add an aria-expanded attribute that reflects the open state (true when openFaqIndex === index, false otherwise), add an aria-controls attribute pointing to a unique ID of the associated answer section (faq-answer), and assign that ID to the answer div container. Keep the onClick handler with toggleFaq(index) on the button element to maintain the toggle functionality.
694-700:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFix broken mobile “Features” anchor target.
Line 696 links to
#features, but there is no element withid="features"in this page. The mobile menu item is currently non-functional.Proposed fix
-<a href="`#features`" onClick={() => setIsMobileMenuOpen(false)} ...>Features</a> +<a href="`#client-services`" onClick={() => setIsMobileMenuOpen(false)} ...>Features</a>🤖 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 `@apps/web-dashboard/src/pages/LandingPage/index.jsx` around lines 694 - 700, The mobile menu item with href="`#features`" in the mobile-menu-overlay section references an anchor point that does not exist on the page. Locate the Features section element in the LandingPage component and add the id="features" attribute to the appropriate container element that should serve as the target for this anchor link. This will make the mobile navigation link functional when clicked.
🧹 Nitpick comments (1)
apps/web-dashboard/src/index.css (1)
815-819: ⚡ Quick winUse theme tokens for the auth card surface.
These hardcoded colors bypass your existing light/dark token system. Switching to variables keeps this component consistent with the rest of the design system.
♻️ Suggested change
.auth-form-card { width: 100%; padding: 2rem; - border: 1px solid rgba(255,255,255,0.06); + border: 1px solid var(--color-glass-card-border); border-radius: 16px; - background: rgba(255,255,255,0.02); + background: var(--color-glass-card-bg); box-shadow: 0 24px 48px -12px rgba(0,0,0,0.4); }🤖 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 `@apps/web-dashboard/src/index.css` around lines 815 - 819, The auth card surface styling uses hardcoded RGBA color values for border, background, and box-shadow instead of theme tokens, which prevents proper light/dark mode theming. Replace the hardcoded rgba(255,255,255,0.06) border color, rgba(255,255,255,0.02) background color, and the rgba(0,0,0,0.4) box-shadow value with corresponding CSS custom properties or theme variables from your existing token system to ensure consistency across the design system and support dynamic theme switching.
🤖 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 `@apps/web-dashboard/src/components/BorderGlow/BorderGlow.css`:
- Around line 61-84: Remove the empty lines before certain CSS declarations in
the BorderGlow.css file to comply with Stylelint's declaration-empty-line-before
rule. Specifically, eliminate the blank lines that appear before the mask-image
declaration (after opacity), before the mask-image declaration in the
.border-glow-card > .edge-light block (after z-index), and before the final
opacity declaration. Ensure all declarations within each CSS rule block are
properly spaced according to your Stylelint configuration without unnecessary
empty lines between them.
In `@apps/web-dashboard/src/components/BorderGlow/BorderGlow.jsx`:
- Around line 39-49: The `animateValue` function starts delayed animations using
setTimeout and requestAnimationFrame but provides no way to cancel them, leaving
orphaned callbacks running when the component unmounts or props change rapidly.
Modify `animateValue` to return a cancel function that clears the setTimeout and
cancels any pending requestAnimationFrame calls by storing the frame ID. Then
update the effect around line 109 that calls `animateValue` multiple times to
collect the returned cancel functions and invoke all of them in the effect's
cleanup function to properly clean up animations when the component unmounts or
dependencies change.
In `@apps/web-dashboard/src/components/Hyperspeed/Hyperspeed.css`:
- Around line 13-17: The canvas selector in Hyperspeed.css is a global selector
that will unintentionally restyle all canvas elements across the app,
potentially causing cross-page regressions. To fix this, scope the canvas
selector to only apply within the Hyperspeed component by changing the selector
from `canvas` to `#lights canvas`. This ensures that the width, height, and
display properties only affect the canvas element inside the `#lights`
container.
In `@apps/web-dashboard/src/components/Hyperspeed/Hyperspeed.jsx`:
- Around line 1168-1177: The async operation started by
loadAssets().then(myApp.init) can execute after the cleanup function has
disposed of appRef.current, causing init to run on a disposed instance. Fix this
by tracking whether the component is still mounted using a flag or ref, then in
the then callback where myApp.init is called, check that the component is still
mounted and appRef.current has not been set to null before executing init.
Alternatively, store the promise from loadAssets() and cancel it in the cleanup
function before disposing to prevent the async chain from completing after
unmount.
In `@apps/web-dashboard/src/components/MagicBento/MagicBento.css`:
- Line 10: The stylelint rule `declaration-empty-line-before` is being violated
on the line containing the `color-scheme: light dark;` declaration. Add an empty
line before the `color-scheme` declaration to comply with the stylelint
configuration and resolve the lint violation.
- Around line 1-11: The CSS custom properties and color-scheme setting are
currently defined on the global :root selector in MagicBento.css, which causes
them to leak styling behavior application-wide. Move all the variable
definitions (--hue, --sat, --white, --purple-primary, --purple-glow,
--purple-border, --border-color, --background-dark) and the color-scheme
property from the :root selector to a component-scoped selector such as
.bento-section or the appropriate container class for the MagicBento component.
This will ensure these styles only apply to the component and do not have
unintended side effects on other pages or components.
In `@apps/web-dashboard/src/components/MagicBento/MagicBento.jsx`:
- Around line 475-488: The MagicBento component has several interactive
card-related props commented out in the destructuring (enableTilt, clickEffect,
enableMagnetism, particleCount) that are being passed by callers but are never
used because the component renders BorderGlow directly instead of ParticleCard.
Uncomment these props in the function parameters and ensure they are passed to
ParticleCard component (or whichever component is responsible for rendering the
interactive cards) so that GSAP card interactions like tilt, click effects, and
magnetism can actually execute. Make sure the card rendering logic in the map
function uses the appropriate component that accepts these interactive props.
In `@apps/web-dashboard/src/pages/Pricing.jsx`:
- Line 69: The mobile menu toggle button lacks accessibility attributes required
for screen reader users. Add aria-expanded attribute to the button element that
controls the mobile menu, setting its value to the isMobileMenuOpen state
(aria-expanded={isMobileMenuOpen}), and add an aria-label attribute with a
descriptive label such as "Toggle mobile menu" to provide an accessible name for
the icon-only button. Apply these ARIA attributes to both the menu toggle button
near line 69 and the additional instance around lines 149-151.
- Around line 70-73: Replace the anchor tag elements with hash references
(Features with href="/#client-services" and Use Cases with href="/#use-cases")
with the React Router Link component to enable client-side navigation instead of
full page reloads. Change the href attributes to to attributes and convert the
<a> tags to <Link> tags while preserving all the onClick handlers and inline
styles.
---
Outside diff comments:
In `@apps/web-dashboard/src/pages/LandingPage/index.jsx`:
- Around line 772-774: The mobile menu toggle button with className
"mobile-menu-btn" lacks accessibility attributes required by screen readers. Add
the aria-label attribute to provide an accessible name describing the button's
purpose, add the aria-expanded attribute bound to the isMobileMenuOpen state to
indicate whether the menu is open or closed, and add the aria-controls attribute
that references the ID of the mobile menu element being toggled. These
attributes will enable screen reader users to understand and operate the button
correctly.
- Around line 1284-1290: The FAQ trigger element with className "faq-question"
uses a non-semantic div instead of a button, which lacks keyboard accessibility
and screen reader support. Replace the div element with a button element, add an
aria-expanded attribute that reflects the open state (true when openFaqIndex ===
index, false otherwise), add an aria-controls attribute pointing to a unique ID
of the associated answer section (faq-answer), and assign that ID to the answer
div container. Keep the onClick handler with toggleFaq(index) on the button
element to maintain the toggle functionality.
- Around line 694-700: The mobile menu item with href="`#features`" in the
mobile-menu-overlay section references an anchor point that does not exist on
the page. Locate the Features section element in the LandingPage component and
add the id="features" attribute to the appropriate container element that should
serve as the target for this anchor link. This will make the mobile navigation
link functional when clicked.
---
Nitpick comments:
In `@apps/web-dashboard/src/index.css`:
- Around line 815-819: The auth card surface styling uses hardcoded RGBA color
values for border, background, and box-shadow instead of theme tokens, which
prevents proper light/dark mode theming. Replace the hardcoded
rgba(255,255,255,0.06) border color, rgba(255,255,255,0.02) background color,
and the rgba(0,0,0,0.4) box-shadow value with corresponding CSS custom
properties or theme variables from your existing token system to ensure
consistency across the design system and support dynamic theme switching.
🪄 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: b06ad7aa-dcd1-4297-a7a7-9ea9ffd54e78
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (14)
apps/web-dashboard/package.jsonapps/web-dashboard/src/components/AuthShell.jsxapps/web-dashboard/src/components/BorderGlow/BorderGlow.cssapps/web-dashboard/src/components/BorderGlow/BorderGlow.jsxapps/web-dashboard/src/components/Hyperspeed/Hyperspeed.cssapps/web-dashboard/src/components/Hyperspeed/Hyperspeed.jsxapps/web-dashboard/src/components/MagicBento/MagicBento.cssapps/web-dashboard/src/components/MagicBento/MagicBento.jsxapps/web-dashboard/src/index.cssapps/web-dashboard/src/pages/LandingPage/index.jsxapps/web-dashboard/src/pages/LandingPage/style.cssapps/web-dashboard/src/pages/Login.jsxapps/web-dashboard/src/pages/Pricing.jsxapps/web-dashboard/src/pages/Signup.jsx
|
can u create a new issue for all these comments? @coderabbitai |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Get all review comments on PR `#315`
echo "=== PR Review Comments ==="
gh pr view 315 --repo geturbackend/urBackend --json reviews,comments
echo ""
echo "=== PR Review Thread Comments ==="
gh api repos/geturbackend/urBackend/pulls/315/comments --jq '.[] | {id: .id, body: .body, path: .path, line: .line, user: .user.login}'
echo ""
echo "=== PR Issue Comments ==="
gh api repos/geturbackend/urBackend/issues/315/comments --jq '.[] | {id: .id, body: .body, user: .user.login}'
echo ""
echo "=== PR Reviews ==="
gh api repos/geturbackend/urBackend/pulls/315/reviews --jq '.[] | {id: .id, body: .body, state: .state, user: .user.login}'Length of output: 151666 🏁 Script executed: #!/bin/bash
set -euo pipefail
gh issue create \
--repo geturbackend/urBackend \
--assignee yash-pouranik \
--title "Follow-up: Address code review findings from PR `#315` (Landing Page Revamp)" \
--body "## Overview
This issue tracks all actionable findings from the CodeRabbit review of PR `#315` (Landing Page Revamp). Addressing these will allow the changes to be merged to production safely.
> **Requested by:** `@yash-pouranik`
> **Source PR:** https://github.com/geturbackend/urBackend/pull/315
---
## 🔴 Major Issues
### 1. \`BorderGlow/BorderGlow.jsx\` — \`animateValue\` lacks cancellation (Lines 39–49, 109–128)
The \`animateValue\` function uses \`setTimeout\` + \`requestAnimationFrame\` but returns no cancel handle. Unmounting the component or rapidly changing props leaves orphaned callbacks running against stale DOM elements.
**Fix:** Make \`animateValue\` return a cancel function, and call all cancel functions in the \`useEffect\` cleanup.
---
### 2. \`Hyperspeed/Hyperspeed.jsx\` — Async init/unmount race condition (Line 1177)
\`loadAssets().then(myApp.init)\` can execute after the cleanup function has already disposed the instance, reinitializing listeners/resources on a torn-down component.
**Fix:** Track a \`cancelled\` flag in the \`useEffect\` and guard \`myApp.init()\` with it:
\`\`\`diff
+let cancelled = false;
myApp.loadAssets().then(() => {
- myApp.init();
+ if (!cancelled && !myApp.disposed) myApp.init();
});
return () => {
+ cancelled = true;
appRef.current?.dispose();
};
\`\`\`
---
### 3. \`Hyperspeed/Hyperspeed.css\` — Global \`canvas\` selector (Lines 13–17)
The bare \`canvas\` selector will restyle **all** canvas elements across the app, causing potential cross-page regressions.
**Fix:**
\`\`\`diff
-canvas {
+#lights canvas {
width: 100%;
height: 100%;
display: block;
}
\`\`\`
---
### 4. \`MagicBento/MagicBento.css\` — Global \`:root\` CSS variable leak (Lines 1–11)
CSS custom properties and \`color-scheme\` defined on \`:root\` leak styling behavior app-wide.
**Fix:** Scope them to \`.bento-section\` instead of \`:root\`, and remove \`color-scheme: light dark;\` from the component stylesheet.
---
### 5. \`MagicBento/MagicBento.jsx\` — Interactive card props never wired (Lines 475–488, 505–541)
\`enableTilt\`, \`clickEffect\`, \`enableMagnetism\`, and \`particleCount\` are accepted by callers but silently dropped — \`BorderGlow\` is rendered directly instead of \`ParticleCard\`, so GSAP interactions never execute.
**Fix:** Uncomment the props in the destructuring and wrap \`BorderGlow\` cards inside \`ParticleCard\`, forwarding the interaction props.
---
### 6. \`Pricing.jsx\` — Mobile menu toggle button missing ARIA (Line 69, Lines 149–151)
The icon-only toggle button has no accessible name or expanded-state metadata, breaking screen-reader navigation.
**Fix:**
\`\`\`diff
<button
className=\"mobile-menu-btn\"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
+ aria-label={isMobileMenuOpen ? 'Close navigation menu' : 'Open navigation menu'}
+ aria-expanded={isMobileMenuOpen}
+ aria-controls=\"pricing-mobile-menu\"
>
\`\`\`
---
### 7. \`LandingPage/index.jsx\` — Mobile menu toggle button missing ARIA (Lines 772–774)
Same issue as above — the \`.mobile-menu-btn\` in the LandingPage lacks \`aria-label\`, \`aria-expanded\`, and \`aria-controls\`.
---
### 8. \`LandingPage/index.jsx\` — Broken mobile "Features" anchor (Lines 694–700)
\`href=\"`#features`\"\` in the mobile overlay references an ID that does not exist on the page, making this nav item non-functional.
**Fix:** Change to \`href=\"`#client-services`\"\` (or add \`id=\"features\"\` to the appropriate section container).
---
### 9. \`LandingPage/index.jsx\` — FAQ toggle uses non-semantic \`<div>\` (Lines 1284–1290)
The FAQ trigger is a clickable \`<div>\`, which is not keyboard-accessible by default.
**Fix:** Replace with \`<button type=\"button\">\` and add \`aria-expanded\` / \`aria-controls\` attributes.
---
### 10. \`Pricing.jsx\` — Hash links should use \`<Link>\` not \`<a>\` (Lines 70–73)
\`<a href=\"/#client-services\">\` and \`<a href=\"/#use-cases\">\` cause full page reloads. React Router's \`<Link to=\"/#...\">\` handles these client-side.
**Fix:** Replace the \`<a>\` tags with \`<Link>\` from \`react-router-dom\`, and update the \`isInternal\` check to include hash-based paths.
---
## 🟡 Minor Issues
### 11. \`BorderGlow/BorderGlow.css\` — Stylelint \`declaration-empty-line-before\` violations (Lines 61, 63–70, 79–82, 84)
Multiple empty lines before CSS declarations violate the configured Stylelint rule, keeping lint red.
**Fix:** Remove the blank lines before \`mask-image\` and \`opacity\` declarations in the affected rule blocks.
---
### 12. \`MagicBento/MagicBento.css\` — Stylelint \`declaration-empty-line-before\` violation (Line 10)
Missing empty line before the \`color-scheme: light dark;\` declaration.
**Fix:** Add an empty line before the \`color-scheme\` declaration.
---
## 💡 Nitpick
### 13. \`src/index.css\` — Auth card uses hardcoded RGBA colors (Lines 815–819)
The \`.auth-form-card\` uses hardcoded \`rgba(255,255,255,...)\` values instead of theme tokens, bypassing the light/dark token system.
**Suggestion:** Replace with CSS custom properties (e.g., \`var(--color-glass-card-border)\`, \`var(--color-glass-card-bg)\`).
---
## Acceptance Criteria
- [ ] \`animateValue\` returns a cancel function and the \`useEffect\` calls it on cleanup
- [ ] Hyperspeed async init guarded against post-unmount execution
- [ ] \`canvas\` selector scoped to \`#lights canvas\`
- [ ] MagicBento CSS variables scoped to \`.bento-section\` instead of \`:root\`
- [ ] \`ParticleCard\` wired up with interaction props in \`MagicBento\`
- [ ] Mobile menu toggle buttons have \`aria-label\`, \`aria-expanded\`, \`aria-controls\` in both LandingPage and Pricing
- [ ] FAQ toggle replaced with semantic \`<button>\` + ARIA attributes
- [ ] Broken \`#features\` anchor fixed in LandingPage mobile menu
- [ ] Hash navigation links in Pricing use \`<Link>\` instead of \`<a>\`
- [ ] Stylelint violations fixed in \`BorderGlow.css\` and \`MagicBento.css\`
- [ ] (Optional) Auth card hardcoded colors replaced with theme tokens
"Length of output: 6376
👉 #318 It's assigned to you and includes all 13 items from the review — broken down into major issues (bugs/regressions/a11y), minor lint violations, and a nitpick — along with a checklist of acceptance criteria so you can track progress before merging to production. Here's a quick summary of the most critical ones to tackle first:
|
|
now we can safely merge this? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "=== PR `#315` status ==="
gh pr view 315 --repo geturbackend/urBackend --json state,mergeable,mergeStateStatus,headRefName,commits,title
echo ""
echo "=== Issue `#318` current body (checklist) ==="
gh issue view 318 --repo geturbackend/urBackend --json body,state,title --jq '{state: .state, title: .title, body: .body}'Length of output: 8481
Must fix before merging to prod (🔴 Major):
Once the fixes from issue |
|
i was thinking to merge this to prod and then @Siddh2024 will open follow up PR for #318 |
|
Tip For best results, initiate chat on the files or code changes.
These are 3–4 line fixes each. The rest (ARIA, broken anchor, TL;DR: Fix items |
- Fix Stylelint declaration-empty-line-before in BorderGlow.css - Add animation cancellation cleanup to BorderGlow.jsx - Scope canvas selector to #lights in Hyperspeed.css - Guard async asset-init against unmount race in Hyperspeed.jsx - Scope :root tokens to .bento-section in MagicBento.css - Wire ParticleCard props in MagicBento.jsx - Add ARIA attributes and extract inline styles in Pricing.jsx/css
Fixes #251
This PR revamps the landing page and pricing page with:
Closes #251
Summary by CodeRabbit
New Features
Bug Fixes