feat(marketing): add Features and FAQ sections to homepage#472
feat(marketing): add Features and FAQ sections to homepage#472
Conversation
Add two new sections to the marketing site homepage: - Features section with alternating text/image layout showcasing parallel agents, CLI compatibility, and git worktree isolation - FAQ section with Onlook-style two-column layout, custom accordion with plus icon, and smooth Framer Motion animations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughAdds two marketing sections (FeaturesSection and FAQSection) with multiple demo components, updates marketing page layout and content, introduces a mesh-gradient integration change (stripe-gradient) and a new preset-icons export/typings surface in the UI package, and adjusts several layout style classes. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ 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 |
There was a problem hiding this comment.
The main functional issue is that FeatureImage is currently hardcoded to always render a placeholder, so real feature screenshots can never display. The alternating layout uses direction: rtl (lg:direction-rtl), which is brittle and can introduce unintended RTL side effects; ordering alone is sufficient. The FAQ accordion is missing basic ARIA semantics and removes focus outlines without adding an accessible focus style, which degrades keyboard/screen-reader usability.
Summary of changes
What changed
- Added a new marketing Features section (
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx) with:- Alternating text/image rows driven by a local
FEATURESdata array. - Framer Motion entrance animations per section/row.
- A
FeatureImagecomponent that currently renders a placeholder instead of the providedimageSrc.
- Alternating text/image rows driven by a local
- Added a new FAQ section (
apps/marketing/src/app/components/FAQSection/FAQSection.tsx) with:- Two-column layout (sticky title on desktop + accordion on the right).
- Custom accordion rows using
AnimatePresence+motion.divheight/opacity transitions. - Local
FAQ_ITEMScontent.
- Export barrels for both components (
components/FAQSection/index.ts,components/FeaturesSection/index.ts). - Updated the homepage (
apps/marketing/src/app/page.tsx) to renderFeaturesSectionafterVideoSectionandFAQSectionbeforeCTASection.
| function FeatureImage({ src, alt }: { src?: string; alt: string }) { | ||
| // Check if image exists by trying to load it - for now show placeholder | ||
| // Replace with actual images when available | ||
| const showPlaceholder = true; | ||
|
|
||
| return ( | ||
| <div className="relative w-full aspect-[4/3] rounded-2xl overflow-hidden bg-muted border border-border"> | ||
| {!showPlaceholder && src ? ( | ||
| <Image | ||
| src={src} | ||
| alt={alt} | ||
| fill | ||
| className="object-cover" | ||
| sizes="(max-width: 768px) 100vw, 50vw" | ||
| /> | ||
| ) : ( | ||
| <div className="absolute inset-0 flex items-center justify-center"> | ||
| <div className="text-muted-foreground/40 text-sm font-mono"> | ||
| Screenshot | ||
| </div> | ||
| </div> | ||
| )} | ||
| </div> |
There was a problem hiding this comment.
FeatureImage is hardcoded to always show the placeholder (const showPlaceholder = true;). That means the imageSrc values in FEATURES will never render, and this can easily ship accidentally since everything “works” visually.
Also, the comment claims it “checks if image exists by trying to load it”, but there is no such logic, so the code and comment disagree.
Suggestion
Make placeholder behavior explicit and data-driven instead of permanently enabled. For example, render the image when src is provided and keep a fallback when it isn’t:
function FeatureImage({ src, alt }: { src?: string; alt: string }) {
return (
<div className="relative w-full aspect-[4/3] rounded-2xl overflow-hidden bg-muted border border-border">
{src ? (
<Image
src={src}
alt={alt}
fill
className="object-cover"
sizes="(max-width: 768px) 100vw, 50vw"
/>
) : (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-muted-foreground/40 text-sm font-mono">Screenshot</div>
</div>
)}
</div>
);
}If you need “not-yet-available” placeholders, consider setting imageSrc to undefined for those features until assets exist (or gate with an env flag). Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this change.
| <motion.div | ||
| key={feature.title} | ||
| className={`grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-16 items-center ${ | ||
| isReversed ? "lg:direction-rtl" : "" | ||
| }`} | ||
| initial={{ opacity: 0, y: 40 }} |
There was a problem hiding this comment.
Using lg:direction-rtl to reverse the layout is risky:
directionis not a standard Tailwind utility by default, so this likely relies on a plugin/custom config and can silently do nothing in other contexts.direction: rtlcan have side effects beyond layout ordering (text direction, punctuation/number rendering, etc.).
You already set lg:order-* on the children, so the direction toggle is redundant at best and harmful at worst.
Suggestion
Drop the lg:direction-rtl approach and rely purely on ordering (or use lg:flex-row-reverse if you switch to flex). Minimal change:
className="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-16 items-center"since you already have:
- text:
lg:order-2/lg:order-1 - image:
lg:order-1/lg:order-2
Reply with "@CharlieHelps yes please" if you'd like me to add a commit that removes lg:direction-rtl and keeps the alternating layout intact.
| <div className="border-b border-border"> | ||
| <button | ||
| type="button" | ||
| onClick={onToggle} | ||
| className="group flex w-full items-center justify-between py-6 text-left transition-all outline-none" | ||
| > | ||
| <span className="text-base sm:text-lg font-medium text-foreground pr-4"> | ||
| {item.question} | ||
| </span> | ||
| <HiPlus | ||
| className={`h-5 w-5 shrink-0 text-muted-foreground transition-transform duration-200 ${ | ||
| isOpen ? "rotate-45" : "" | ||
| }`} | ||
| /> | ||
| </button> | ||
| <AnimatePresence initial={false}> | ||
| {isOpen && ( | ||
| <motion.div | ||
| initial={{ height: 0, opacity: 0 }} | ||
| animate={{ height: "auto", opacity: 1 }} | ||
| exit={{ height: 0, opacity: 0 }} | ||
| transition={{ duration: 0.2, ease: "easeInOut" }} | ||
| className="overflow-hidden" | ||
| > | ||
| <p className="pb-6 text-base text-muted-foreground leading-relaxed pr-12"> | ||
| {item.answer} | ||
| </p> | ||
| </motion.div> | ||
| )} | ||
| </AnimatePresence> |
There was a problem hiding this comment.
The accordion uses a <button> but doesn’t expose any accessibility state/relationships (aria-expanded, aria-controls, and an id on the panel). This is a real UX issue for keyboard/screen-reader users, especially since the panel is conditionally mounted/unmounted.
Also, the focus styling is fully suppressed via outline-none without providing a visible focus ring, which makes keyboard navigation much harder.
Suggestion
Add the standard ARIA attributes and restore a visible focus indicator. Example:
function FAQAccordionItem({ item, isOpen, onToggle, id }: { item: FAQItem; isOpen: boolean; onToggle: () => void; id: string }) {
return (
<div className="border-b border-border">
<button
type="button"
onClick={onToggle}
aria-expanded={isOpen}
aria-controls={`${id}-panel`}
className="group flex w-full items-center justify-between py-6 text-left transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
...
</button>
<AnimatePresence initial={false}>
{isOpen && (
<motion.div id={`${id}-panel`} role="region" aria-label={item.question} ...>
...
</motion.div>
)}
</AnimatePresence>
</div>
);
}And pass id={faq-${index}} from the map. Reply with "@CharlieHelps yes please" if you'd like me to add a commit implementing these accessibility improvements.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/marketing/src/app/components/FAQSection/FAQSection.tsx (1)
124-131: Consider using array index as the key.Using
item.questionas the key works if questions are unique, but using the array index would be more conventional and stable for static data that doesn't reorder.🔎 Optional refactor
- {FAQ_ITEMS.map((item, index) => ( + {FAQ_ITEMS.map((item, index) => ( <FAQAccordionItem - key={item.question} + key={index} item={item} isOpen={openIndex === index} onToggle={() => handleToggle(index)} /> ))}
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FAQSection/index.tsapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/FeaturesSection/index.tsapps/marketing/src/app/page.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid using any type in TypeScript - maintain type safety unless absolutely necessary
Files:
apps/marketing/src/app/components/FeaturesSection/index.tsapps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FAQSection/index.tsapps/marketing/src/app/page.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix
Files:
apps/marketing/src/app/components/FeaturesSection/index.tsapps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FAQSection/index.tsapps/marketing/src/app/page.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
**/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Files:
apps/marketing/src/app/components/FeaturesSection/index.tsapps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FAQSection/index.tsapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
**/{components,features}/**/[!.]*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
**/*.{tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use React + TailwindCSS v4 + shadcn/ui for UI development
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/page.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
**/{components,features}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
**/{components,features}/**/*.tsx: Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Use one component per file - do not combine multiple components in a single file
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
🧠 Learnings (4)
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/[!.]*.tsx : Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Applied to files:
apps/marketing/src/app/components/FeaturesSection/index.tsapps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FAQSection/index.tsapps/marketing/src/app/page.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/*.tsx : Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Applied to files:
apps/marketing/src/app/components/FeaturesSection/index.tsapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx} : Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Applied to files:
apps/marketing/src/app/components/FeaturesSection/index.tsapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to src/components/{ui,ai-elements,react-flow}/**/*.tsx : Use kebab-case single files for shadcn/ui components in src/components/ui/, src/components/ai-elements, and src/components/react-flow/ directories
Applied to files:
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
🧬 Code graph analysis (2)
apps/marketing/src/app/components/FAQSection/FAQSection.tsx (1)
apps/marketing/src/app/components/FAQSection/index.ts (1)
FAQSection(1-1)
apps/marketing/src/app/page.tsx (4)
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx (1)
FeaturesSection(67-134)apps/marketing/src/app/components/FeaturesSection/index.ts (1)
FeaturesSection(1-1)apps/marketing/src/app/components/FAQSection/FAQSection.tsx (1)
FAQSection(90-138)apps/marketing/src/app/components/FAQSection/index.ts (1)
FAQSection(1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Deploy Marketing
- GitHub Check: Deploy Docs
- GitHub Check: Deploy Web
- GitHub Check: Deploy API
- GitHub Check: Deploy Admin
- GitHub Check: Build
🔇 Additional comments (6)
apps/marketing/src/app/components/FAQSection/FAQSection.tsx (1)
7-44: LGTM! Well-structured FAQ data.The
FAQIteminterface andFAQ_ITEMSconstant are cleanly defined. The FAQ content effectively addresses key user concerns about pricing, compatibility, privacy, and differentiation.apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx (2)
6-39: LGTM! Clean feature data structure.The
Featureinterface andFEATURESarray are well-defined. OptionalimageSrcappropriately supports the placeholder pattern used inFeatureImage.
41-65: LGTM! Intentional placeholder implementation.The hardcoded
showPlaceholderflag is clearly documented as temporary. The component correctly handles both placeholder and actual image rendering with appropriate Next.js Image configuration.apps/marketing/src/app/components/FeaturesSection/index.ts (1)
1-1: LGTM! Standard barrel export.The export follows the project's component organization pattern.
Based on learnings: Applies to component structure guidelines for barrel exports.
apps/marketing/src/app/components/FAQSection/index.ts (1)
1-1: LGTM! Standard barrel export.The export follows the project's component organization pattern.
Based on learnings: Applies to component structure guidelines for barrel exports.
apps/marketing/src/app/page.tsx (1)
4-5: LGTM! Clean component integration.The new
FeaturesSectionandFAQSectioncomponents are properly imported and rendered in the appropriate sequence, matching the PR objectives.Also applies to: 17-17, 19-19
| function FAQAccordionItem({ | ||
| item, | ||
| isOpen, | ||
| onToggle, | ||
| }: { | ||
| item: FAQItem; | ||
| isOpen: boolean; | ||
| onToggle: () => void; | ||
| }) { | ||
| return ( | ||
| <div className="border-b border-border"> | ||
| <button | ||
| type="button" | ||
| onClick={onToggle} | ||
| className="group flex w-full items-center justify-between py-6 text-left transition-all outline-none" | ||
| > | ||
| <span className="text-base sm:text-lg font-medium text-foreground pr-4"> | ||
| {item.question} | ||
| </span> | ||
| <HiPlus | ||
| className={`h-5 w-5 shrink-0 text-muted-foreground transition-transform duration-200 ${ | ||
| isOpen ? "rotate-45" : "" | ||
| }`} | ||
| /> | ||
| </button> | ||
| <AnimatePresence initial={false}> | ||
| {isOpen && ( | ||
| <motion.div | ||
| initial={{ height: 0, opacity: 0 }} | ||
| animate={{ height: "auto", opacity: 1 }} | ||
| exit={{ height: 0, opacity: 0 }} | ||
| transition={{ duration: 0.2, ease: "easeInOut" }} | ||
| className="overflow-hidden" | ||
| > | ||
| <p className="pb-6 text-base text-muted-foreground leading-relaxed pr-12"> | ||
| {item.answer} | ||
| </p> | ||
| </motion.div> | ||
| )} | ||
| </AnimatePresence> | ||
| </div> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Add keyboard focus styles for accessibility.
The button removes the default outline with outline-none but doesn't provide custom focus indicators. Keyboard users won't be able to see which FAQ item is focused.
🔎 Proposed fix to add focus-visible styles
<button
type="button"
onClick={onToggle}
- className="group flex w-full items-center justify-between py-6 text-left transition-all outline-none"
+ className="group flex w-full items-center justify-between py-6 text-left transition-all outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary rounded-sm"
>🤖 Prompt for AI Agents
In apps/marketing/src/app/components/FAQSection/FAQSection.tsx around lines
46-88, the FAQ item button removes the browser focus outline (outline-none) but
lacks a custom focus indicator; update the button's className to include
accessible focus-visible styles (for example Tailwind focus-visible:ring,
focus-visible:ring-offset and focus-visible:ring-primary or similar utilities,
and/or focus-visible:outline-none only if replaced by a visible ring) so
keyboard users get a clear visible focus state, keeping current layout and
transitions intact.
Change grid breakpoint from lg (1024px) to xl (1280px) so the hero section stays in single-column layout until there's enough room for the two-column layout with ProductDemo. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add min-w-0 to ProductDemo container to allow proper shrinking in grid - Add max-w-full to ProductDemo to constrain width - Change FeaturesSection two-column grid to xl breakpoint (1280px) - Change FAQSection two-column grid to xl breakpoint (1280px) - Keep padding adjustments at lg breakpoint (1024px) for consistency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx (2)
41-65: Hardcoded placeholder prevents images from rendering.The
showPlaceholderconstant is hardcoded totrue(line 44), which means theimageSrcvalues inFEATURESwill never render. Additionally, the comment on line 42 claims to check if the image exists, but no such logic is implemented.This issue has already been identified in previous review comments by charliecreates[bot].
76-85: Remove invalid Tailwind classlg:direction-rtl.Lines 78-80 use
lg:direction-rtl, which is not a valid Tailwind CSS utility class and has no effect. The alternating layout already works correctly via thelg:order-1andlg:order-2classes on lines 88 and 104.This issue has already been identified in previous review comments by charliecreates[bot] and coderabbitai[bot].
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/SecuritySection/SecuritySection.tsxapps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/marketing/src/app/components/FAQSection/FAQSection.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid using any type in TypeScript - maintain type safety unless absolutely necessary
Files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/SecuritySection/SecuritySection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix
Files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/SecuritySection/SecuritySection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx
**/{components,features}/**/[!.]*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/SecuritySection/SecuritySection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx
**/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/SecuritySection/SecuritySection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx
**/*.{tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use React + TailwindCSS v4 + shadcn/ui for UI development
Files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/SecuritySection/SecuritySection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx
**/{components,features}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
**/{components,features}/**/*.tsx: Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Use one component per file - do not combine multiple components in a single file
Files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/SecuritySection/SecuritySection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx
🧠 Learnings (4)
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/*.{tsx,css} : Use React + TailwindCSS v4 + shadcn/ui for UI development
Applied to files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to src/components/{ui,ai-elements,react-flow}/**/*.tsx : Use kebab-case single files for shadcn/ui components in src/components/ui/, src/components/ai-elements, and src/components/react-flow/ directories
Applied to files:
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/HeroSection/HeroSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/[!.]*.tsx : Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Applied to files:
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/*.tsx : Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Applied to files:
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
🧬 Code graph analysis (1)
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx (2)
packages/ui/src/components/ai-elements/image.tsx (1)
Image(9-24)apps/marketing/src/app/components/FeaturesSection/index.ts (1)
FeaturesSection(1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Deploy Web
- GitHub Check: Deploy Docs
- GitHub Check: Deploy API
- GitHub Check: Deploy Marketing
- GitHub Check: Deploy Admin
- GitHub Check: Build
🔇 Additional comments (10)
apps/marketing/src/app/components/HeroSection/HeroSection.tsx (1)
21-31: LGTM! Breakpoint adjustments prevent layout cropping.The coordinated shift from
lg:(1024px) toxl:(1280px) breakpoints across padding, grid layout, and typography ensures the two-column layout and larger heading only activate when there's sufficient space for the ProductDemo component. This aligns with the commit message goal of preventing hero section cropping at medium screen sizes.Optionally verify that the hero section displays correctly across all viewport widths:
- Mobile (<640px): single column, smaller text
- Small/medium (640px–1279px): single column with slightly larger text
- Extra-large (≥1280px): two-column grid with full-size heading
apps/marketing/src/app/components/SecuritySection/SecuritySection.tsx (1)
39-39: LGTM!The container width update to
max-w-7xlaligns with the broader layout consistency improvements across sections in this PR.apps/marketing/src/app/components/CTASection/CTASection.tsx (1)
14-14: LGTM!Container width update maintains consistency with other sections.
apps/marketing/src/app/components/VideoSection/VideoSection.tsx (3)
8-8: LGTM!Container width update aligns with layout consistency improvements.
10-10: LGTM!Spacing adjustments improve visual hierarchy and use appropriate Tailwind utilities.
Also applies to: 16-16
33-33: LGTM!Border radius simplification aligns with the design updates in this PR.
apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx (1)
1-39: LGTM!Component structure, types, and data definitions follow React and TypeScript best practices. The Feature interface is properly typed and the FEATURES array is well-organized.
apps/marketing/src/app/components/TrustedBySection/TrustedBySection.tsx (3)
57-57: LGTM - intentional switch to custom fade overlays.The change from the built-in marquee gradient to
gradient={false}with custom overlay divs provides more control over the fade effect appearance. This is a good architectural choice, assuming the gradient classes in the overlays are corrected.
54-55: Gradient class names are correct for TailwindCSS v4.TailwindCSS v4 renamed
bg-gradient-*tobg-linear-*, sobg-linear-to-randbg-linear-to-lare the correct syntax for this version. The fade overlays will render properly.Likely an incorrect or invalid review comment.
11-23: All logo files are present at the correct paths inapps/marketing/public/logos/and the gradient syntaxbg-linear-to-randbg-linear-to-lare correct for Tailwind CSS v4 (the framework renamed these utilities from v3'sbg-gradient-to-*). The component follows coding guidelines with proper TypeScript typing, correct Next.js Image usage, and clean structure.
| <p className="text-lg sm:text-xl font-light tracking-[-0.03em] text-muted-foreground max-w-[700px]"> | ||
| We provides parallelization and better UX to enhance your Cursor, | ||
| Claude Code, OpenCode, etc. workflows. |
There was a problem hiding this comment.
Fix grammatical error in user-facing text.
Line 21 contains "We provides" which should be "We provide."
🔎 Proposed fix
<p className="text-lg sm:text-xl font-light tracking-[-0.03em] text-muted-foreground max-w-[700px]">
- We provides parallelization and better UX to enhance your Cursor,
+ We provide parallelization and better UX to enhance your Cursor,
Claude Code, OpenCode, etc. workflows.
</p>📝 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.
| <p className="text-lg sm:text-xl font-light tracking-[-0.03em] text-muted-foreground max-w-[700px]"> | |
| We provides parallelization and better UX to enhance your Cursor, | |
| Claude Code, OpenCode, etc. workflows. | |
| <p className="text-lg sm:text-xl font-light tracking-[-0.03em] text-muted-foreground max-w-[700px]"> | |
| We provide parallelization and better UX to enhance your Cursor, | |
| Claude Code, OpenCode, etc. workflows. | |
| </p> |
🤖 Prompt for AI Agents
In apps/marketing/src/app/components/VideoSection/VideoSection.tsx around lines
20 to 22, the user-facing sentence uses incorrect grammar "We provides"; update
the text to "We provide" (i.e., change "We provides parallelization..." to "We
provide parallelization...") so the subject-verb agreement is correct while
leaving the rest of the copy intact.
Changed grid-cols-[42%_58%] to grid-cols-[2fr_3fr]. Percentage-based columns don't account for the gap, causing 100% + gap to overflow. Fr units distribute available space after subtracting gaps. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/ui/src/components/mesh-gradient.tsx (1)
12-27: Remove duplicate type definition—use declarations from stripe-gradient.d.ts.The
GradientInstanceinterface duplicates the type information already declared inpackages/ui/src/types/stripe-gradient.d.ts. This violates DRY principles and can lead to type inconsistencies.🔎 Proposed fix
"use client"; import { useEffect, useId, useRef } from "react"; -import { Gradient } from "stripe-gradient"; +import type { Gradient } from "stripe-gradient"; interface MeshGradientProps { colors: readonly [string, string, string, string]; className?: string; speed?: number; } -interface GradientInstance { - initGradient: (selector: string) => void; - disconnect?: () => void; - pause?: () => void; - el?: HTMLElement | null; - conf?: { playing?: boolean }; - uniforms?: { - u_global?: { - value?: { - noiseSpeed?: { - value: number; - }; - }; - }; - }; -} - export function MeshGradient({ colors, className = "", speed = 3e-6, }: MeshGradientProps) { const canvasRef = useRef<HTMLCanvasElement>(null); const id = useId(); const canvasId = `gradient-canvas-${id.replace(/:/g, "")}`; useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; - const gradient = new Gradient() as GradientInstance; + const gradient = new Gradient(); gradient.initGradient(`#${canvasId}`);
♻️ Duplicate comments (2)
apps/marketing/src/app/components/VideoSection/VideoSection.tsx (2)
7-7: Restore vertical padding to maintain visual hierarchy.The section padding was reduced from
py-24(96px) topy-2(8px), which compresses the section dramatically and breaks visual consistency with other marketing sections.
21-22: Fix grammatical error in user-facing text."We provides" should be "We provide" to correct the subject-verb agreement.
🧹 Nitpick comments (7)
apps/marketing/src/app/components/VideoSection/VideoSection.tsx (1)
33-33: Consider whether the border radius reduction is intentional.The video container border radius was reduced from
rounded-2xl(16px) torounded(~4-8px), which is a noticeable visual change. If this was intended as part of the design refresh, no action needed. Otherwise, you may want to restorerounded-2xlfor consistency with the previous design.apps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsx (2)
74-109: Consider extractingSpinnerIconto a separate file.Per coding guidelines, components should be one per file. However, since
SpinnerIconis a small, private helper used only within this component, co-location is acceptable here.
134-140: Blinking cursor interval runs continuously.The cursor blink interval starts immediately and runs regardless of whether the component is in view or the terminal animation has completed. Consider starting the interval only after
isInViewis true and the terminal lines have finished rendering.🔎 Proposed optimization
// Blinking cursor useEffect(() => { + if (!isInView || displayedLines.length < TERMINAL_LINES.length) return; + const interval = setInterval(() => { setShowCursor((prev) => !prev); }, 530); return () => clearInterval(interval); - }, []); + }, [isInView, displayedLines.length]);apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsx (1)
12-33: Consider usingcn()utility for className composition.The component implementation is clean and well-structured. However, the className concatenation using template literals could be improved by using a
cn()utility (fromclsxorclass-variance-authority) for better handling of conditional classes and deduplication.🔎 Suggested refactor
+"use client"; + +import { MeshGradient } from "@superset/ui/mesh-gradient"; +import { cn } from "@/lib/utils"; // or wherever your cn utility is located +import type { ReactNode } from "react"; + export function FeatureDemo({ children, colors, className = "", }: FeatureDemoProps) { return ( <div - className={`relative w-full aspect-4/3 rounded-2xl overflow-hidden ${className}`} + className={cn("relative w-full aspect-4/3 rounded-2xl overflow-hidden", className)} >packages/ui/src/types/stripe-gradient.d.ts (1)
1-18: Consider making properties optional to match actual usage.The type declarations mark
el,conf, anduniformsas required properties, but the usage inmesh-gradient.tsx(lines 46, 52, 55, 61) uses optional chaining (gradient?.uniforms?.u_global...,if (gradient.pause), etc.), suggesting these properties may not always be present.🔎 Proposed type adjustment
declare module "stripe-gradient" { export class Gradient { initGradient(selector: string): void; - disconnect(): void; - pause(): void; - el: HTMLElement | null; - conf: { playing?: boolean }; - uniforms: { + disconnect?(): void; + pause?(): void; + el?: HTMLElement | null; + conf?: { playing?: boolean }; + uniforms?: { u_global?: { value?: { noiseSpeed?: { value: number; }; }; }; }; } }apps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsx (2)
96-258: Consider extracting sub-components to improve maintainability.The
IsolationDemocomponent is 162 lines long and handles multiple concerns (header, sidebar, diff content). While functional, it could benefit from extraction into smaller, focused components likeDiffHeader,DiffSidebar, andDiffContent.This would improve:
- Testability (each sub-component can be tested independently)
- Readability (clearer separation of concerns)
- Reusability (components could potentially be reused)
However, since this is a demo component used once, the current implementation is acceptable.
200-251: Nested ternaries reduce readability.Lines 200-251 contain multiple nested ternary operators for conditional className values. While functional, this pattern makes the code harder to read and maintain.
🔎 Suggested refactor using helper function
+const getLineStyles = (type: string) => { + const styles = { + bg: type === "added" ? "bg-green-500/10" : type === "removed" ? "bg-red-500/10" : "", + lineNumber: type === "added" ? "text-green-400/60" : type === "removed" ? "text-red-400/60" : "text-white/20", + marker: type === "added" ? "text-green-400" : type === "removed" ? "text-red-400" : "text-white/20", + markerChar: type === "added" ? "+" : type === "removed" ? "-" : " ", + content: type === "added" ? "text-green-300/90" : type === "removed" ? "text-red-300/90" : "text-white/60", + }; + return styles; +}; + export function IsolationDemo() { // ... existing code ... {DIFF_LINES.map((line, index) => { + const styles = getLineStyles(line.type); return ( <motion.div key={line.id} - className={`flex ${ - line.type === "added" - ? "bg-green-500/10" - : line.type === "removed" - ? "bg-red-500/10" - : "" - }`} + className={`flex ${styles.bg}`} // ... animation props ... > <span - className={`w-8 text-right pr-2 select-none ${ - line.type === "added" - ? "text-green-400/60" - : line.type === "removed" - ? "text-red-400/60" - : "text-white/20" - }`} + className={`w-8 text-right pr-2 select-none ${styles.lineNumber}`} > {index + 1} </span> <span - className={`w-4 text-center select-none ${ - line.type === "added" - ? "text-green-400" - : line.type === "removed" - ? "text-red-400" - : "text-white/20" - }`} + className={`w-4 text-center select-none ${styles.marker}`} > - {line.type === "added" - ? "+" - : line.type === "removed" - ? "-" - : " "} + {styles.markerChar} </span> <span - className={`flex-1 px-2 ${ - line.type === "added" - ? "text-green-300/90" - : line.type === "removed" - ? "text-red-300/90" - : "text-white/60" - }`} + className={`flex-1 px-2 ${styles.content}`} > {line.content} </span> </motion.div> ); })}
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (22)
apps/marketing/public/app-icons/claude.svgis excluded by!**/*.svgapps/marketing/public/app-icons/codex.svgis excluded by!**/*.svgapps/marketing/public/app-icons/cursor-agent.svgis excluded by!**/*.svgapps/marketing/public/app-icons/cursor.svgis excluded by!**/*.svgapps/marketing/public/app-icons/finder.pngis excluded by!**/*.pngapps/marketing/public/app-icons/gemini.svgis excluded by!**/*.svgapps/marketing/public/app-icons/iterm.pngis excluded by!**/*.pngapps/marketing/public/app-icons/jetbrains.svgis excluded by!**/*.svgapps/marketing/public/app-icons/opencode.svgis excluded by!**/*.svgapps/marketing/public/app-icons/sublime.svgis excluded by!**/*.svgapps/marketing/public/app-icons/terminal.pngis excluded by!**/*.pngapps/marketing/public/app-icons/vscode.svgis excluded by!**/*.svgapps/marketing/public/app-icons/warp.pngis excluded by!**/*.pngapps/marketing/public/app-icons/xcode.svgis excluded by!**/*.svgbun.lockis excluded by!**/*.lockpackages/ui/src/assets/icons/preset-icons/claude.svgis excluded by!**/*.svgpackages/ui/src/assets/icons/preset-icons/codex-white.svgis excluded by!**/*.svgpackages/ui/src/assets/icons/preset-icons/codex.svgis excluded by!**/*.svgpackages/ui/src/assets/icons/preset-icons/cursor.svgis excluded by!**/*.svgpackages/ui/src/assets/icons/preset-icons/gemini.svgis excluded by!**/*.svgpackages/ui/src/assets/icons/preset-icons/opencode-white.svgis excluded by!**/*.svgpackages/ui/src/assets/icons/preset-icons/opencode.svgis excluded by!**/*.svg
📒 Files selected for processing (21)
apps/desktop/src/renderer/assets/app-icons/preset-icons/index.tsapps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsxapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/index.tsapps/marketing/src/app/components/FeaturesSection/constants.tsapps/marketing/src/app/components/HeroSection/components/ProductDemo/ProductDemo.tsxapps/marketing/src/app/components/HeroSection/components/ProductDemo/components/MeshGradient/index.tsapps/marketing/src/app/components/VideoSection/VideoSection.tsxpackages/ui/package.jsonpackages/ui/src/assets/icons/preset-icons/index.tspackages/ui/src/components/mesh-gradient.tsxpackages/ui/src/types/stripe-gradient.d.tspackages/ui/src/types/svg.d.ts
💤 Files with no reviewable changes (1)
- apps/marketing/src/app/components/HeroSection/components/ProductDemo/components/MeshGradient/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/marketing/src/app/components/HeroSection/components/ProductDemo/ProductDemo.tsx
- apps/marketing/src/app/components/FeaturesSection/FeaturesSection.tsx
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid using any type in TypeScript - maintain type safety unless absolutely necessary
Files:
apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.tsapps/marketing/src/app/components/FeaturesSection/constants.tsapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxpackages/ui/src/types/svg.d.tsapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxpackages/ui/src/assets/icons/preset-icons/index.tspackages/ui/src/components/mesh-gradient.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxpackages/ui/src/types/stripe-gradient.d.tsapps/desktop/src/renderer/assets/app-icons/preset-icons/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix
Files:
apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.tsapps/marketing/src/app/components/FeaturesSection/constants.tsapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxpackages/ui/src/types/svg.d.tsapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxpackages/ui/src/assets/icons/preset-icons/index.tspackages/ui/src/components/mesh-gradient.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxpackages/ui/src/types/stripe-gradient.d.tsapps/desktop/src/renderer/assets/app-icons/preset-icons/index.ts
**/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Files:
apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.tsapps/marketing/src/app/components/FeaturesSection/constants.tsapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxpackages/ui/src/components/mesh-gradient.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsx
**/{components,features}/**/[!.]*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Files:
apps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxpackages/ui/src/components/mesh-gradient.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsx
**/*.{tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use React + TailwindCSS v4 + shadcn/ui for UI development
Files:
apps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxpackages/ui/src/components/mesh-gradient.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsx
**/{components,features}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
**/{components,features}/**/*.tsx: Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Use one component per file - do not combine multiple components in a single file
Files:
apps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxpackages/ui/src/components/mesh-gradient.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never import Node.js modules in renderer process or shared code - use only in main process (src/main/)
Files:
apps/desktop/src/renderer/assets/app-icons/preset-icons/index.ts
apps/desktop/src/{main,renderer,preload}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use type-safe IPC communication - define channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers
Files:
apps/desktop/src/renderer/assets/app-icons/preset-icons/index.ts
apps/desktop/**/*.{ts,tsx}
📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)
apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined insrc/lib/trpc
Use alias as defined intsconfig.jsonwhen possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from@trpc/server/observableinstead of async generators, as the library explicitly checksisObservable(result)and throws an error otherwise
Files:
apps/desktop/src/renderer/assets/app-icons/preset-icons/index.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Add UI components using npx shadcnlatest add command run in packages/ui/ directory
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/[!.]*.tsx : Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Applied to files:
apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.tsapps/marketing/src/app/components/FeaturesSection/constants.tsapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxpackages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/*.tsx : Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Applied to files:
apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxpackages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx} : Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Applied to files:
apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.tsapps/marketing/src/app/components/FeaturesSection/constants.tsapps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/index.tsapps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxpackages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/*.{tsx,css} : Use React + TailwindCSS v4 + shadcn/ui for UI development
Applied to files:
apps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxpackages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to src/components/{ui,ai-elements,react-flow}/**/*.tsx : Use kebab-case single files for shadcn/ui components in src/components/ui/, src/components/ai-elements, and src/components/react-flow/ directories
Applied to files:
apps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxpackages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/*.tsx : Use one component per file - do not combine multiple components in a single file
Applied to files:
apps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsxapps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsxpackages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix
Applied to files:
packages/ui/package.json
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Use alias as defined in `tsconfig.json` when possible
Applied to files:
packages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules in renderer process or shared code - use only in main process (src/main/)
Applied to files:
packages/ui/package.json
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/*.test.{ts,tsx} : Place tests co-located with components using .test.ts or .test.tsx naming convention
Applied to files:
packages/ui/package.json
🧬 Code graph analysis (4)
apps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsx (2)
apps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.ts (1)
OpenInDemo(1-1)packages/ui/src/components/ai-elements/image.tsx (1)
Image(9-24)
apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/FeatureDemo.tsx (1)
packages/ui/src/components/mesh-gradient.tsx (1)
MeshGradient(29-85)
apps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsx (1)
apps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.ts (1)
ParallelExecutionDemo(1-1)
packages/ui/src/assets/icons/preset-icons/index.ts (1)
apps/desktop/src/renderer/assets/app-icons/preset-icons/index.ts (3)
PresetIconSet(5-5)PRESET_ICONS(4-4)getPresetIcon(4-4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Deploy Admin
- GitHub Check: Deploy Marketing
- GitHub Check: Deploy Web
- GitHub Check: Deploy Docs
- GitHub Check: Deploy API
- GitHub Check: Build
🔇 Additional comments (22)
apps/marketing/src/app/components/VideoSection/VideoSection.tsx (1)
21-22: Verify the tool name "OpenCode" for accuracy.The text mentions "OpenCode" as one of the supported tools. However, the PR objectives reference "Codex" in the Universal CLI Support feature description. Please confirm whether "OpenCode" is correct or if this should be "Codex" or another tool name.
packages/ui/src/assets/icons/preset-icons/index.ts (3)
9-12: LGTM! Clean interface design.The
PresetIconSetinterface provides a clear, type-safe way to handle theme-specific icon variants.
22-30: LGTM! Robust icon lookup logic.The function correctly normalizes the preset name and handles missing entries by returning
undefined. The implementation is type-safe and defensive.
1-40: The package export configuration for preset-icons is already properly configured inpackages/ui/package.json. The exports field includes both"./icons/preset-icons": "./src/assets/icons/preset-icons/index.ts"and"./icons/preset-icons/*": "./src/assets/icons/preset-icons/*.svg", which enables consumers to import from@superset/ui/icons/preset-iconsas intended. No additional configuration is needed.Likely an incorrect or invalid review comment.
apps/desktop/src/renderer/assets/app-icons/preset-icons/index.ts (3)
1-5: LGTM! Clean refactoring to centralized icon system.The re-export pattern maintains backward compatibility while delegating to the shared UI package. The type export for
PresetIconSetis a good addition for consumers who need the type definition.
7-11: LGTM! Hook correctly delegates to the centralized icon system.The
usePresetIconhook properly uses the theme store and delegates to the importedgetPresetIconfunction, maintaining the same API while leveraging the shared implementation.
13-16: LGTM! Useful utility hook for theme detection.The new
useIsDarkThemehook provides a convenient way to check the current theme state. This is a good addition that promotes code reusability across the renderer.packages/ui/src/types/svg.d.ts (1)
1-4: No issues found. The SVG module declaration correctly types imports asstring, which matches the actual usage pattern inpackages/ui/src/assets/icons/preset-icons/index.tswhere SVGs are imported and exported as string values through thePresetIconSetinterface.apps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/UniversalCompatibilityDemo.tsx (1)
1-90: LGTM!The component follows the one-component-per-file guideline, uses proper barrel export structure, and implements Framer Motion animations correctly. The staggered animation delays and
useInViewwithonce: trueprovide a smooth, efficient scroll-triggered animation that only fires once.packages/ui/package.json (2)
12-14: New export paths look correctly structured.The export mappings align with the expected file locations and follow the existing pattern in the package.
71-71: Monitor maintenance status of thestripe-gradientpackage.This is a reverse engineered JavaScript library using Three.js & Vite to replicate animated Stripe gradients. The package shows a not healthy version release cadence, with the last version released a year ago. While the package is functional and appropriate for production use, consider keeping an eye on maintainer activity or having a fallback if long-term support becomes critical for your application.
apps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/ParallelExecutionDemo.tsx (1)
238-245: React key includes array index which is acceptable for static content.Since
TERMINAL_LINESis a static array that doesn't change order, using the index in the key is fine here. The additionalline.slice(0, 10)adds minimal benefit but doesn't hurt.apps/marketing/src/app/components/FeaturesSection/components/FeatureDemo/index.ts (1)
1-1: LGTM!Correct barrel export pattern per coding guidelines.
apps/marketing/src/app/components/FeaturesSection/components/ParallelExecutionDemo/index.ts (1)
1-1: LGTM!Correct barrel export pattern per coding guidelines.
apps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/index.ts (1)
1-1: LGTM!Correct barrel export pattern per coding guidelines.
apps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/index.ts (1)
1-1: LGTM!Correct barrel export pattern per coding guidelines.
apps/marketing/src/app/components/FeaturesSection/components/UniversalCompatibilityDemo/index.ts (1)
1-1: LGTM!Correct barrel export pattern per coding guidelines.
apps/marketing/src/app/components/FeaturesSection/constants.ts (1)
1-37: LGTM! Well-structured feature data.The Feature interface and FEATURES array are well-defined with proper TypeScript types. The use of readonly tuples for colors ensures type safety, and co-locating this constants file with the component follows the coding guidelines.
apps/marketing/src/app/components/FeaturesSection/components/IsolationDemo/IsolationDemo.tsx (1)
96-107: Excellent animation implementation!The use of
useInViewwith framer-motion provides a smooth, performant entrance animation that triggers when the component enters the viewport. The staggered animations for child elements (lines 169-175, 207-212) create a polished, professional effect.apps/marketing/src/app/components/FeaturesSection/components/OpenInDemo/OpenInDemo.tsx (2)
38-178: Well-structured demo component with smooth animations.The OpenInDemo component effectively demonstrates the "Open in any IDE" feature with:
- Clean window chrome styling
- Logical file tree presentation
- Well-sequenced animations using
useInView- Proper Next.js Image optimization for icons
The intentional overflow of the dropdown menu (line 145:
-right-10) creates a nice visual effect showing the menu extending beyond the window boundary.
14-27: All icon files referenced in the IDE_OPTIONS array are present in the public folder. No action needed.packages/ui/src/components/mesh-gradient.tsx (1)
45-49: No initialization callback or promise-based API available in whatamesh/stripe-gradient library.The Gradient library provides only a synchronous
initGradient()method, and documentation is acknowledged as lacking. The library offers no official initialization callback, promise-based API, or ready signal.The 100ms setTimeout workaround appears necessary given the library's design, though without access to internal source code, the exact reason for the timing requirement is unclear—it may address DOM readiness, canvas rendering synchronization, or internal state initialization. Add a comment explaining why this delay is needed to aid future maintainers.
| "use client"; | ||
|
|
||
| import { useEffect, useId, useRef } from "react"; | ||
| import { Gradient } from "stripe-gradient"; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n packages/ui/src/components/mesh-gradient.tsx | head -50Repository: superset-sh/superset
Length of output: 1494
🏁 Script executed:
#!/bin/bash
cd packages/ui/src/components
echo "=== File: mesh-gradient.tsx ==="
cat -n mesh-gradient.tsx | head -50
echo ""
echo "=== Lines 40-45 ==="
cat -n mesh-gradient.tsx | sed -n '40,45p'Repository: superset-sh/superset
Length of output: 1731
Consider using dynamic import for stripe-gradient to preserve code-splitting benefits.
The Gradient import at line 4 is currently synchronous, which includes the stripe-gradient library in your initial bundle. Since this module is only used inside a useEffect hook (lines 42-43) for lazy initialization, a dynamic import would be more beneficial:
const { Gradient } = await import("stripe-gradient");While stripe-gradient is a small ~10kb file, removing it from the critical path improves initial load time by deferring its download until the component mounts.
🤖 Prompt for AI Agents
In packages/ui/src/components/mesh-gradient.tsx around line 4, the synchronous
import of Gradient pulls stripe-gradient into the initial bundle; change this to
a dynamic import inside the effect where it's used (e.g., await
import("stripe-gradient")) and then read Gradient from the resolved module
before instantiating it; ensure the effect handles the promise lifecycle
(cancellation on unmount) and type imports are adjusted (use type-only import or
inline typing) so TypeScript stays happy while preserving code-splitting.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/marketing/src/app/components/FAQSection/FAQSection.tsx (1)
50-79: Accessibility issues remain unresolved from previous reviews.The accordion button still lacks proper ARIA attributes (
aria-expanded,aria-controls) and visible focus indicators, making it inaccessible to keyboard and screen-reader users. This issue was previously flagged in detail by other reviewers.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/marketing/src/app/components/CTASection/CTASection.tsxapps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/components/VideoSection/VideoSection.tsxapps/marketing/src/app/page.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/marketing/src/app/components/VideoSection/VideoSection.tsx
- apps/marketing/src/app/components/CTASection/CTASection.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid using any type in TypeScript - maintain type safety unless absolutely necessary
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/page.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/page.tsx
**/{components,features}/**/[!.]*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsx
**/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsx
**/*.{tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Use React + TailwindCSS v4 + shadcn/ui for UI development
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/page.tsx
**/{components,features}/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
**/{components,features}/**/*.tsx: Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Use one component per file - do not combine multiple components in a single file
Files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/{components,features}/**/[!.]*.tsx : Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export
Applied to files:
apps/marketing/src/app/components/FAQSection/FAQSection.tsxapps/marketing/src/app/page.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Deploy Web
- GitHub Check: Deploy Admin
- GitHub Check: Deploy Docs
- GitHub Check: Deploy Marketing
- GitHub Check: Deploy API
- GitHub Check: Build
🔇 Additional comments (4)
apps/marketing/src/app/components/FAQSection/FAQSection.tsx (3)
1-6: LGTM!The imports and client directive are appropriate for an interactive FAQ accordion component with animations.
7-10: LGTM!The interface definition is clean and type-safe.
84-132: LGTM!The component structure is well-organized with proper state management, responsive layout, and smooth animations. The single-item-open accordion pattern is correctly implemented, and the sticky title on larger screens provides good UX.
apps/marketing/src/app/page.tsx (1)
4-5: LGTM!The composition changes successfully integrate the new Features and FAQ sections into a logical marketing page flow. The section ordering (Hero → Video → TrustedBy → Features → FAQ → CTA) provides a well-structured user journey from initial hook to conversion.
Also applies to: 15-17
Summary
Test plan
bun run typecheck- passesbun run lint- passes🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Style
Chores
✏️ Tip: You can customize this high-level summary in your review settings.