Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
103 changes: 103 additions & 0 deletions app/components/landing/CliCommand.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
'use client';

import * as React from 'react';
import { CopyButton } from '@/components/animate-ui/components/buttons/copy';
import { cn } from '@/lib/utils';
import { motion, AnimatePresence } from 'motion/react';

interface CliCommandProps {
className?: string;
}

export function CliCommand({ className }: CliCommandProps) {
const [step, setStep] = React.useState<1 | 2>(1);
const timerRef = React.useRef<NodeJS.Timeout | null>(null);

const commandText = step === 1 ? 'npm i create-flutterinit' : 'npx create-flutterinit';

const resetToStepOne = React.useCallback(() => {
setStep(1);
}, []);

const startResetTimer = React.useCallback(() => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
timerRef.current = setTimeout(resetToStepOne, 8000); // Reset to step 1 after 8 seconds
}, [resetToStepOne]);

React.useEffect(() => {
return () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
};
}, []);

const handleCopiedChange = React.useCallback((copied: boolean) => {
if (copied) {
if (step === 1) {
setStep(2);
}
startResetTimer();
}
}, [step, startResetTimer]);

return (
<div className={cn(
"pointer-events-auto inline-flex items-center gap-3 pl-4 pr-2 py-1.5 rounded-full bg-white border border-zinc-200/80 shadow-[0_2px_12px_-3px_rgba(0,0,0,0.05)] hover:border-zinc hover:shadow-[0_4px_20px_-4px_rgba(99,102,241,0.15)] transition-all duration-300 select-none",
className
)}>
{/* Terminal Icon */}
<svg
className="w-3.5 h-3.5 text-zinc-400 shrink-0"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
strokeLinejoin="round"
>
<polyline points="4 17 10 11 4 5" />
<line x1="12" y1="19" x2="20" y2="19" />
</svg>

{/* CLI Tag */}
<span className="text-[10px] font-extrabold tracking-wider uppercase px-1.5 py-0.5 rounded-md bg-zinc-100 text-zinc-500 scale-90 select-none">
CLI
</span>

{/* Command Text with Animation */}
<div className="relative flex items-center select-all">
<AnimatePresence mode="wait" initial={false}>
<motion.code
key={step}
initial={{ y: 8, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
exit={{ y: -8, opacity: 0 }}
transition={{ duration: 0.18, ease: 'easeInOut' }}
className="font-mono text-[13px] font-semibold text-zinc-800 tracking-tight leading-none pt-px pr-1 whitespace-nowrap block"
>
{commandText}
</motion.code>
</AnimatePresence>
</div>

{/* Separator */}
<div className="w-px h-3.5 bg-zinc-200" />

{/* Copy Button */}
<CopyButton
content={commandText}
onCopiedChange={handleCopiedChange}
variant="ghost"
size="xs"
className="rounded-full text-zinc-400 hover:text-zinc-600 hover:bg-zinc-100"
aria-label={`Copy CLI command step ${step}`}
title={`Copy CLI command step ${step}`}
/>
</div>
);
}


58 changes: 56 additions & 2 deletions app/components/landing/GitHubStars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,50 @@ async function getStars() {
}
}

export async function GitHubStars() {
export async function GitHubStars({ variant = 'default' }: { variant?: 'default' | 'sm' }) {
const stars = await getStars();

if (variant === 'sm') {
return (
<Link
href="https://github.com/Arjun544/flutter_init"
target="_blank"
rel="noopener noreferrer"
className="group relative flex items-center gap-2 h-9 px-3 rounded-lg bg-white border border-zinc-200 shadow-[0_2px_8px_-3px_rgba(0,0,0,0.05)] hover:border-primary/30 hover:shadow-[0_4px_12px_-3px_rgba(0,0,0,0.08)] hover:shadow-primary/5 hover:scale-[1.01] transition-all duration-200 overflow-hidden"
>
<div className="flex items-center gap-1.5">
<HugeiconsIcon
icon={GithubIcon}
size={16}
className="text-zinc-900 group-hover:text-primary transition-colors duration-200"
/>
<span className="text-xs font-semibold text-zinc-700 group-hover:text-primary transition-colors">
GitHub
</span>
</div>

<div className="h-3 w-px bg-zinc-200" />

<div className="flex items-center gap-1 px-1.5 py-0.5 rounded-md bg-zinc-50 border border-zinc-100 group-hover:bg-primary/5 group-hover:border-primary/20 transition-all duration-200">
<HugeiconsIcon
icon={StarIcon}
size={12}
className="text-zinc-400 group-hover:text-primary transition-all duration-200"
/>
<span className="text-xs font-bold font-mono text-zinc-600 group-hover:text-primary transition-colors">
{stars.toLocaleString()}
</span>
</div>

{/* Subtle glow effect on hover */}
<div className="absolute inset-0 rounded-lg bg-primary/0 group-hover:bg-primary/5 transition-colors duration-200 -z-10" />

{/* Animated background shine */}
<div className="absolute -inset-x-20 top-0 h-full w-20 bg-linear-to-r from-transparent via-white/30 to-transparent -skew-x-12 -translate-x-full group-hover:translate-x-[400%] transition-transform duration-1000 ease-in-out" />
</Link>
);
}

return (
<Link
href="https://github.com/Arjun544/flutter_init"
Expand Down Expand Up @@ -61,7 +102,20 @@ export async function GitHubStars() {
);
}

export function GitHubStarsSkeleton() {
export function GitHubStarsSkeleton({ variant = 'default' }: { variant?: 'default' | 'sm' }) {
if (variant === 'sm') {
return (
<div className="flex items-center gap-2.5 h-9 px-3 rounded-lg bg-white border border-zinc-200 shadow-[0_2px_8px_-3px_rgba(0,0,0,0.05)] w-[120px] animate-pulse">
<div className="flex items-center gap-1.5">
<div className="w-4 h-4 rounded-full bg-zinc-100" />
<div className="w-10 h-3 bg-zinc-100 rounded" />
</div>
<div className="h-3 w-px bg-zinc-200" />
<div className="w-10 h-5 bg-zinc-50 border border-zinc-100 rounded-md animate-pulse" />
</div>
);
}

return (
<div className="flex items-center gap-4 h-14 px-6 rounded-2xl bg-white border border-zinc-200 shadow-[0_8px_25px_-5px_rgba(0,0,0,0.05)] w-full sm:w-auto animate-pulse">
<div className="flex items-center">
Expand Down
77 changes: 46 additions & 31 deletions app/components/landing/HeroSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,72 @@ import { Button } from '@/components/ui/button';
import { ArrowRight01Icon } from '@hugeicons/core-free-icons';
import { HugeiconsIcon } from '@hugeicons/react';
import Link from 'next/link';
import { Suspense } from 'react';
import { GitHubStars, GitHubStarsSkeleton } from './GitHubStars';
import { CliCommand } from './CliCommand';
import { MobileNodePattern } from './MobileNodePattern';
import { NodePattern } from './NodePattern';
import { cn } from '@/lib/utils';
import { KineticText } from '@/components/ui/kinetic-text';
import { HexagonBackground } from '@/components/animate-ui/components/backgrounds/hexagon';
import { BorderBeam } from '@/components/ui/border-beam'

export function HeroSection() {
return (
<section className="relative w-full min-h-screen flex items-center justify-center overflow-hidden bg-white">
{/* Premium background grid - softer and atmospheric */}
<div
className="absolute inset-0 bg-[linear-gradient(to_right,#8080800a_1px,transparent_1px),linear-gradient(to_bottom,#8080800a_1px,transparent_1px)] bg-size-[64px_64px]"
style={{
maskImage: 'linear-gradient(to_bottom, black 10%, transparent 80%)',
WebkitMaskImage: 'linear-gradient(to_bottom, black 10%, transparent 80%)'
{/* Hexagon grid — aria-hidden overlay, same pattern as talkfolio Hero */}
<HexagonBackground
aria-hidden
className="pointer-events-none absolute inset-0 z-0 bg-transparent"
hexagonSize={72}
hexagonMargin={0}
hexagonStroke={1}
hexagonProps={{
className: cn(
'pointer-events-auto',
'before:bg-zinc-400/10 before:opacity-100',
'after:bg-white',
'hover:before:bg-zinc-300/40 hover:before:duration-0',
'hover:after:bg-zinc-50 hover:after:duration-0',
),
}}
/>

{/* Subtle radial center glow */}
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_0%,rgba(var(--primary-rgb),0.02)_0%,transparent_70%)]" />
{/* Soft radial centre glow */}
<div className="pointer-events-none absolute inset-0 z-1 bg-[radial-gradient(ellipse_80%_60%_at_50%_-10%,rgba(0,0,0,0.03)_0%,transparent_70%)]" />

{/* Bottom fade scrim so hexagons dissolve into the next section */}
<div
aria-hidden
className="pointer-events-none absolute inset-x-0 bottom-0 z-2 h-48"
style={{ background: 'linear-gradient(to top, #fff 15%, transparent)' }}
/>

<div className="relative z-10 w-full max-w-7xl mx-auto px-6 md:px-12 flex flex-col items-center text-center pt-16">

<div className="relative z-10 w-full max-w-7xl mx-auto px-6 md:px-12 flex flex-col items-center text-center pt-8">
{/* Clean Pill Badge */}
<Link
href="https://github.com/Arjun544/flutter_init"
target="_blank"
rel="noopener noreferrer"
className="group mt-4 mb-8 inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white shadow-[0_2px_10px_-4px_rgba(0,0,0,0.1)] border border-zinc-200/80 hover:border-primary/40 hover:shadow-[0_4px_15px_-5px_hsl(var(--primary)/0.2)] transition-all duration-300 cursor-pointer"
>
<span className="flex h-2 w-2 rounded-full bg-primary animate-pulse" />
<span className="text-[13px] font-semibold tracking-wide text-zinc-900">Open Source</span>
<div className="w-px h-3.5 bg-zinc-200 mx-1" />
<span className="text-[13px] font-medium text-zinc-500 group-hover:text-primary transition-colors">Contribute on GitHub &rarr;</span>
</Link>

{/* CLI Command Pill */}
<BorderBeam size="md" colorVariant="colorful" className="mt-20 mb-8">
<CliCommand />
</BorderBeam>

{/* Ultra-sharp Typography */}
<h1 className="text-5xl mt-10 sm:text-7xl md:text-[5rem] lg:text-[6rem] font-medium text-primary leading-[0.95] mb-6 max-w-5xl mx-auto relative z-20">
<span className="font-bold">Architect</span> <br className="hidden sm:block" />
<span className="text-zinc-400">your <span className="font-bold text-primary">Flutter</span> app.</span>
<KineticText as="span" text="Architect" className="pointer-events-auto font-bold" /> <br className="hidden sm:block" />
<span className="text-zinc-400">your{' '}
<KineticText
as="span"
text="Flutter"
className="pointer-events-auto font-bold text-primary"
/>{' '}app.
</span>
</h1>

<p className="max-w-xl text-[1.1rem] sm:text-[1.25rem] text-zinc-500 mb-12 font-medium leading-relaxed tracking-tight">
Scaffold your entire Flutter app with your preferred state management, routing, and utilities.
</p>

{/* Sleek Action Buttons */}
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 sm:gap-5 w-full sm:w-auto relative z-30">
<Button asChild size="lg" className="h-14 px-8 text-[1.05rem] font-semibold tracking-wide rounded-2xl bg-zinc-950 text-white shadow-[0_8px_25px_-5px_rgba(0,0,0,0.3)] hover:bg-zinc-800 hover:scale-[1.02] hover:shadow-[0_15px_35px_-5px_rgba(0,0,0,0.4)] transition-all duration-300 sm:w-auto group border border-zinc-800">
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 sm:gap-5 w-full sm:w-auto">
<Button asChild size="lg" className="h-14 px-6 text-md md:text-md font-semibold tracking-wide rounded-2xl bg-zinc-950 text-white shadow-[0_8px_25px_-5px_rgba(0,0,0,0.3)] hover:bg-zinc-800 hover:scale-[1.02] hover:shadow-[0_15px_35px_-5px_rgba(0,0,0,0.4)] transition-all duration-300 sm:w-auto group border border-zinc-800">
<Link href="/create">
Start Generating
<div className="ml-3 flex items-center justify-center w-6 h-6 rounded-full bg-zinc-800 group-hover:bg-zinc-700 transition-colors">
Expand All @@ -60,10 +79,6 @@ export function HeroSection() {
</div>
</Link>
</Button>

<Suspense fallback={<GitHubStarsSkeleton />}>
<GitHubStars />
</Suspense>
</div>
{/* Branching Visual Nodes - Now taking visual priority at the top */}
<div className="hidden sm:block w-full">
Expand Down
Loading
Loading