Skip to content
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/ens-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/eth-global.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 0 additions & 21 deletions public/eth-logo.svg

This file was deleted.

205 changes: 164 additions & 41 deletions src/app/(public)/components/features-section.tsx
Original file line number Diff line number Diff line change
@@ -1,84 +1,207 @@
import { CheckCircle, DollarSign, Shield, Sparkles, Users } from 'lucide-react'
'use client'

import {
ArrowRight,
Globe,
Mail,
PieChart,
Rocket,
ShieldCheck,
Zap,
} from 'lucide-react'
import { motion, useScroll, useTransform } from 'motion/react'
import * as React from 'react'

import { cn } from '@/lib/utils'

interface Feature {
icon: React.ReactNode
title: string
description: string
highlight: string
}

const features: Feature[] = [
{
icon: <Sparkles className="text-primary h-6 w-6" />,
icon: <Mail className="h-6 w-6" />,
title: 'No wallet? No problem',
description:
"Start with just an email. We'll create an embedded wallet for you and upgrade to self-custody when you're ready.",
highlight: 'Embedded Wallets',
},
{
icon: <DollarSign className="text-primary h-6 w-6" />,
title: 'Transparent revenue splits',
icon: <Globe className="h-6 w-6" />,
title: 'Your .eth domain',
description:
'Set revenue percentages once. Every payment automatically splits between treasury and owners on-chain.',
'Professional ENS names that work as domains, wallets, and identities. Own your name forever.',
highlight: 'Onchain Identity',
},
{
icon: <Shield className="text-primary h-6 w-6" />,
icon: <ShieldCheck className="h-6 w-6" />,
title: 'Multi-sig security',
description:
'Enterprise-grade protection with Safe multisig wallets. Multiple signatures required for critical decisions.',
highlight: 'Treasury Safe',
},
{
icon: <Users className="text-primary h-6 w-6" />,
title: 'Your .eth domain',
icon: <Zap className="h-6 w-6" />,
title: 'Gasless transactions',
description:
'Professional ENS names that work as domains, wallets, and identities. Own your name forever.',
"No need to buy crypto to get started. We cover gas fees for email users until you're ready to self-custody.",
highlight: 'Sponsored Gas',
},
{
icon: <CheckCircle className="text-primary h-6 w-6" />,
title: 'Gasless transactions',
icon: <PieChart className="h-6 w-6" />,
title: 'Transparent revenue splits',
description:
"No need to buy crypto to get started. We cover gas fees for email users until you're ready to self-custody.",
'Set revenue percentages once. Every payment automatically splits between treasury and owners on-chain.',
highlight: 'Smart Splits',
},
{
icon: <Sparkles className="text-primary h-6 w-6" />,
icon: <Rocket className="h-6 w-6" />,
title: 'Built for scale',
description:
'From MVP to IPO, our infrastructure grows with you. Add team members, adjust splits, upgrade security.',
highlight: 'Growth Ready',
},
]

export function FeaturesSection() {
const containerRef = React.useRef<HTMLDivElement>(null)
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ['start 20%', 'end 80%'],
})

const height = useTransform(scrollYProgress, [0, 1], ['0%', '100%'])

return (
<section id="features" className="bg-card/30 relative py-24">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-16 text-center">
<h2 className="text-foreground mb-6 text-3xl font-bold md:text-5xl">
Everything you need to
<span className="text-primary"> build unstoppable</span>
</h2>
<p className="text-muted-foreground mx-auto max-w-2xl text-xl">
From idea to IPO, all the infrastructure you need for a transparent,
decentralized business
</p>
<section
id="features"
ref={containerRef}
className="bg-background relative overflow-hidden py-24 md:py-32"
>
{/* Dynamic Background */}
<div className="pointer-events-none absolute inset-0 -z-10 overflow-hidden">
<div className="absolute top-0 left-0 -translate-x-1/2 translate-y-[-20%] opacity-20 blur-[100px]">
<div className="bg-primary h-[600px] w-[600px] rounded-full mix-blend-screen" />
</div>
<div className="absolute right-0 bottom-0 translate-x-1/2 translate-y-[20%] opacity-20 blur-[100px]">
<div className="bg-accent h-[600px] w-[600px] rounded-full mix-blend-screen" />
</div>
<div className="absolute inset-0 bg-[linear-gradient(to_right,var(--border)_1px,transparent_1px),linear-gradient(to_bottom,var(--border)_1px,transparent_1px)] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_50%,#000_70%,transparent_100%)] bg-[size:4rem_4rem] opacity-[0.05]" />
</div>

<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{features.map((feature, index) => (
<div key={index} className="group relative">
<div className="from-primary/20 to-accent/20 absolute inset-0 rounded-2xl bg-gradient-to-r opacity-25 blur transition-opacity group-hover:opacity-40"></div>
<div className="bg-card border-border hover:border-primary/50 relative rounded-2xl border p-8 transition-all duration-300">
<div className="bg-primary/10 mb-6 flex h-12 w-12 items-center justify-center rounded-2xl">
{feature.icon}
</div>
<h3 className="text-foreground mb-4 text-xl font-semibold">
{feature.title}
</h3>
<p className="text-muted-foreground leading-relaxed">
{feature.description}
</p>
</div>
</div>
))}
<div className="relative z-10 mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="mb-24 text-center">
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
>
<h2 className="text-foreground mb-6 text-4xl leading-tight font-bold tracking-tighter md:text-5xl lg:text-6xl">
The complete{' '}
<span className="animate-gradient-x bg-gradient-to-r from-pink-500 via-purple-500 to-indigo-500 bg-clip-text text-transparent">
onchain OS
</span>
</h2>
<p className="text-muted-foreground mx-auto max-w-2xl text-xl">
A unified platform for your company&apos;s entire lifecycle. From
day one to IPO.
</p>
</motion.div>
</div>

<div className="relative mx-auto max-w-5xl">
{/* Vertical Timeline Line (Desktop Center / Mobile Left) */}
<div className="bg-border/40 absolute top-0 bottom-0 left-8 w-[2px] md:left-1/2 md:-ml-px" />

<motion.div
style={{ height }}
className="from-primary via-accent to-primary absolute top-0 left-8 w-[2px] origin-top bg-gradient-to-b md:left-1/2 md:-ml-px"
/>

<div className="space-y-12 md:space-y-24">
{features.map((feature, index) => (
<FeatureNode key={index} feature={feature} index={index} />
))}
</div>
</div>
</div>
</section>
)
}

function FeatureNode({ feature, index }: { feature: Feature; index: number }) {
const isEven = index % 2 === 0

return (
<div
className={cn(
'relative flex items-center md:justify-between',
isEven ? 'md:flex-row' : 'md:flex-row-reverse'
)}
>
{/* Node Point */}
<div className="border-background bg-foreground shadow-primary/20 absolute left-8 z-20 -ml-[11px] flex h-[22px] w-[22px] items-center justify-center rounded-full border-[3px] shadow-lg md:left-1/2 md:-ml-[11px]">
<div className="bg-background h-2 w-2 rounded-full" />
</div>

{/* Content Card */}
<motion.div
initial={{ opacity: 0, x: isEven ? -30 : 30 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true, margin: '-10% 0px -10% 0px' }}
transition={{ duration: 0.5, delay: 0.1 }}
className={cn('ml-20 md:ml-0 md:w-[45%]', 'group relative')}
>
{/* Connector Line (Horizontal) */}
<div
className={cn(
'bg-border/50 absolute top-1/2 hidden h-px w-8 md:block',
isEven ? '-right-8' : '-left-8'
)}
/>
{/* Mobile Connector */}
<div className="bg-border/50 absolute top-8 -left-12 h-px w-12 md:hidden" />

<div className="group/card border-border/50 bg-card/30 hover:border-primary/30 relative overflow-hidden rounded-2xl border p-6 backdrop-blur-xl transition-all duration-300 hover:-translate-y-1 hover:shadow-xl md:p-8">
{/* Hover Glow */}
<div className="from-primary/10 to-accent/10 absolute -inset-px -z-10 bg-gradient-to-r opacity-0 blur-xl transition-opacity duration-500 group-hover/card:opacity-100" />

{/* Icon Box */}
<div className="from-primary/10 to-accent/10 border-primary/20 text-primary mb-5 inline-flex h-12 w-12 items-center justify-center rounded-xl border bg-gradient-to-br shadow-sm transition-transform duration-300 group-hover/card:scale-110 group-hover/card:rotate-3">
{feature.icon}
</div>

<div className="space-y-3">
<div className="flex items-center gap-3">
<span className="text-primary/80 text-xs font-bold tracking-wider uppercase">
Step 0{index + 1}
</span>
Comment on lines +180 to +182
Copy link

Choose a reason for hiding this comment

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

style: String template Step 0{index + 1} creates Step 01, Step 02 etc - consider using Step ${index + 1} for cleaner numbering

Suggested change
<span className="text-primary/80 text-xs font-bold tracking-wider uppercase">
Step 0{index + 1}
</span>
<span className="text-primary/80 text-xs font-bold tracking-wider uppercase">
Step {index + 1}
</span>

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/(public)/components/features-section.tsx
Line: 180:182

Comment:
**style:** String template `Step 0{index + 1}` creates `Step 01`, `Step 02` etc - consider using `Step ${index + 1}` for cleaner numbering

```suggestion
              <span className="text-primary/80 text-xs font-bold tracking-wider uppercase">
                Step {index + 1}
              </span>
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

<div className="bg-border/50 h-px flex-1" />
</div>

<h3 className="text-foreground text-xl font-bold tracking-tight md:text-2xl">
{feature.title}
</h3>

<p className="text-muted-foreground text-base leading-relaxed md:text-lg">
{feature.description}
</p>
</div>

{/* Interactive Arrow */}
<div className="text-primary mt-5 flex -translate-x-2 items-center text-sm font-medium opacity-0 transition-all duration-300 group-hover/card:translate-x-0 group-hover/card:opacity-100">
<span className="mr-2">{feature.highlight}</span>
<ArrowRight className="h-4 w-4" />
</div>
</div>
</motion.div>

{/* Spacer for the other side (desktop only) */}
<div className="hidden md:block md:w-[45%]" />
</div>
)
}
69 changes: 46 additions & 23 deletions src/app/(public)/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,61 @@
import Image from 'next/image'
import Link from 'next/link'

import { ChainLogo } from '@/components/ui/chain-logo'

export function Footer() {
return (
<footer className="border-border bg-card/50 border-t py-12">
<footer className="border-border bg-card/50 border-t py-12 backdrop-blur-sm">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="flex flex-col items-center justify-between md:flex-row">
<Link href="/" className="flex items-center space-x-2 py-5">
<Image
src="/logo.svg"
width={35}
height={35}
alt="StartUpChain Logo"
/>
<span className="text-foreground text-3xl font-normal tracking-widest">
StartUpChain
</span>
</Link>
<div className="text-muted-foreground flex items-center space-x-6 text-sm">
{/*<a href="#" className="hover:text-foreground transition-colors">
<div className="flex flex-col items-center justify-between gap-8 md:flex-row">
<div className="flex flex-col items-center md:items-start">
<Link href="/" className="flex items-center space-x-2">
<ChainLogo width={40} height={40} className="text-primary" />
<span className="text-foreground text-2xl font-bold tracking-tight">
StartupChain
</span>
</Link>
<p className="text-muted-foreground mt-2 text-sm">
The onchain operating system for modern companies.
</p>
</div>

<div className="text-muted-foreground flex flex-wrap items-center justify-center gap-6 text-sm md:justify-end">
<Link
href="#privacy"
className="hover:text-primary transition-colors"
>
Privacy
</a>
<a href="#" className="hover:text-foreground transition-colors">
</Link>
<Link
href="#terms"
className="hover:text-primary transition-colors"
Comment on lines +24 to +31
Copy link

Choose a reason for hiding this comment

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

logic: These hash fragment links (#privacy, #terms) will not navigate to actual pages and may confuse users

Suggested change
href="#privacy"
className="hover:text-primary transition-colors"
>
Privacy
</a>
<a href="#" className="hover:text-foreground transition-colors">
</Link>
<Link
href="#terms"
className="hover:text-primary transition-colors"
<Link
href="/privacy"
className="hover:text-primary transition-colors"
>
Privacy
</Link>
<Link
href="/terms"
className="hover:text-primary transition-colors"

Are there actual Privacy and Terms pages that should be linked, or should these be removed for now?

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/(public)/components/footer.tsx
Line: 24:31

Comment:
**logic:** These hash fragment links (#privacy, #terms) will not navigate to actual pages and may confuse users

```suggestion
              <Link
              href="/privacy"
              className="hover:text-primary transition-colors"
            >
              Privacy
            </Link>
            <Link
              href="/terms"
              className="hover:text-primary transition-colors"
```

 Are there actual Privacy and Terms pages that should be linked, or should these be removed for now?

How can I resolve this? If you propose a fix, please make it concise.

>
Terms
</a>
<a href="#" className="hover:text-foreground transition-colors">
</Link>
<a
href="https://twitter.com"
target="_blank"
rel="noopener noreferrer"
className="hover:text-primary transition-colors"
>
Twitter
</a>*/}
<a href="#" className="hover:text-foreground transition-colors">
</a>
<a
href="https://discord.com"
target="_blank"
rel="noopener noreferrer"
className="hover:text-primary transition-colors"
>
Discord
</a>

</div>
</div>

<div className="border-border/50 text-muted-foreground mt-8 border-t pt-8 text-center text-sm md:text-left">
<p>
&copy; {new Date().getFullYear()} StartupChain. All rights reserved.
</p>
</div>
</div>
</footer>
)
Expand Down
Loading
Loading