fix: page

This commit is contained in:
Oleg Proskurin 2025-12-03 15:08:36 +07:00
parent 7588817803
commit 21ac410780
5 changed files with 235 additions and 108 deletions

View File

@ -10,17 +10,18 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"react": "19.1.0",
"react-dom": "19.1.0",
"@banatie/database": "workspace:*",
"lucide-react": "^0.400.0",
"next": "15.5.4",
"@banatie/database": "workspace:*"
"react": "19.1.0",
"react-dom": "19.1.0"
},
"devDependencies": {
"typescript": "^5",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4"
"tailwindcss": "^4",
"typescript": "^5"
}
}

View File

@ -45,6 +45,15 @@ body {
}
}
@keyframes gradient-rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.animate-gradient {
background-size: 200% 200%;
animation: gradient-shift 3s ease infinite;

View File

@ -0,0 +1,55 @@
interface AnimatedGradientBorderProps {
children: React.ReactNode;
className?: string;
}
const gradientStyle: React.CSSProperties = {
background: `conic-gradient(
from 0deg,
rgba(99, 102, 241, 0.3),
rgba(139, 92, 246, 0.8),
rgba(236, 72, 153, 0.6),
rgba(34, 211, 238, 0.8),
rgba(99, 102, 241, 0.3)
)`,
filter: 'blur(40px)',
};
const glowStyle: React.CSSProperties = {
background: `conic-gradient(
from 0deg,
rgba(99, 102, 241, 0.1),
rgba(139, 92, 246, 0.4),
rgba(236, 72, 153, 0.3),
rgba(34, 211, 238, 0.4),
rgba(99, 102, 241, 0.1)
)`,
filter: 'blur(15px)',
};
export const AnimatedGradientBorder = ({
children,
className = '',
}: AnimatedGradientBorderProps) => {
return (
<div className={`relative p-10 rounded-xl isolate ${className}`}>
<div
className="absolute -inset-16 pointer-events-none"
style={{
maskImage: 'radial-gradient(ellipse closest-side at center, black 0%, black 50%, transparent 100%)',
WebkitMaskImage: 'radial-gradient(ellipse closest-side at center, black 0%, black 50%, transparent 100%)',
}}
>
<div
className="absolute inset-[-52%] opacity-60 -z-10 animate-[gradient-rotate_4s_linear_infinite]"
style={glowStyle}
/>
<div
className="absolute inset-[-50%] z-0 animate-[gradient-rotate_4s_linear_infinite]"
style={gradientStyle}
/>
</div>
<div className="relative z-10 bg-[#0a0612] rounded-[10px]">{children}</div>
</div>
);
};

View File

@ -1,6 +1,7 @@
'use client';
import { useState } from 'react';
import { AnimatedGradientBorder } from './components/AnimatedGradientBorder';
import {
Zap,
Globe,
@ -42,12 +43,6 @@ import {
const customStyles = `
@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@500;600;700&display=swap');
@property --form-angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
.gradient-text {
background: linear-gradient(90deg, #818cf8 0%, #c084fc 25%, #f472b6 50%, #c084fc 75%, #818cf8 100%);
background-size: 200% 100%;
@ -63,47 +58,6 @@ const customStyles = `
100% { background-position: 100% 50%; }
}
.email-form-wrapper {
position: relative;
max-width: 28rem;
margin: 0 auto;
padding: 2px;
border-radius: 12px;
background: linear-gradient(#0a0612, #0a0612) padding-box,
conic-gradient(from var(--form-angle),
rgba(99, 102, 241, 0.3),
rgba(139, 92, 246, 0.8),
rgba(236, 72, 153, 0.6),
rgba(34, 211, 238, 0.8),
rgba(99, 102, 241, 0.3)
) border-box;
animation: form-glow-rotate 4s linear infinite;
}
.email-form-wrapper::before {
content: '';
position: absolute;
inset: -2px;
border-radius: 14px;
background: conic-gradient(from var(--form-angle),
rgba(99, 102, 241, 0.1),
rgba(139, 92, 246, 0.4),
rgba(236, 72, 153, 0.3),
rgba(34, 211, 238, 0.4),
rgba(99, 102, 241, 0.1)
);
filter: blur(15px);
opacity: 0.6;
z-index: -1;
animation: form-glow-rotate 4s linear infinite;
}
@keyframes form-glow-rotate {
to {
--form-angle: 360deg;
}
}
.beta-dot {
animation: beta-dot-delay 20s linear forwards, beta-dot-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) 20s infinite;
}
@ -138,12 +92,30 @@ const customStyles = `
function BackgroundBlobs() {
const blobs = [
{ className: 'w-[600px] h-[600px] top-[-200px] right-[-100px]', gradient: 'rgba(139, 92, 246, 0.3)' },
{ className: 'w-[500px] h-[500px] top-[800px] left-[-150px]', gradient: 'rgba(99, 102, 241, 0.25)' },
{ className: 'w-[400px] h-[400px] top-[1600px] right-[-100px]', gradient: 'rgba(236, 72, 153, 0.2)' },
{ className: 'w-[550px] h-[550px] top-[2400px] left-[-200px]', gradient: 'rgba(34, 211, 238, 0.15)' },
{ className: 'w-[450px] h-[450px] top-[3200px] right-[-150px]', gradient: 'rgba(139, 92, 246, 0.25)' },
{ className: 'w-[500px] h-[500px] top-[4000px] left-[-100px]', gradient: 'rgba(99, 102, 241, 0.2)' },
{
className: 'w-[600px] h-[600px] top-[-200px] right-[-100px]',
gradient: 'rgba(139, 92, 246, 0.3)',
},
{
className: 'w-[500px] h-[500px] top-[800px] left-[-150px]',
gradient: 'rgba(99, 102, 241, 0.25)',
},
{
className: 'w-[400px] h-[400px] top-[1600px] right-[-100px]',
gradient: 'rgba(236, 72, 153, 0.2)',
},
{
className: 'w-[550px] h-[550px] top-[2400px] left-[-200px]',
gradient: 'rgba(34, 211, 238, 0.15)',
},
{
className: 'w-[450px] h-[450px] top-[3200px] right-[-150px]',
gradient: 'rgba(139, 92, 246, 0.25)',
},
{
className: 'w-[500px] h-[500px] top-[4000px] left-[-100px]',
gradient: 'rgba(99, 102, 241, 0.2)',
},
];
return (
@ -164,7 +136,8 @@ function HeroGlow() {
<div
className="absolute top-0 left-1/2 -translate-x-1/2 w-full max-w-[1200px] h-[600px] pointer-events-none"
style={{
background: 'radial-gradient(ellipse at center top, rgba(99, 102, 241, 0.2) 0%, rgba(139, 92, 246, 0.1) 30%, transparent 70%)',
background:
'radial-gradient(ellipse at center top, rgba(99, 102, 241, 0.2) 0%, rgba(139, 92, 246, 0.1) 30%, transparent 70%)',
}}
/>
);
@ -246,7 +219,9 @@ function HeroSection() {
: 'bg-indigo-500/15 border border-indigo-500/30 text-indigo-300'
}`}
>
<badge.icon className={`w-4 h-4 ${badge.variant === 'cyan' ? 'text-cyan-400' : 'text-indigo-400'}`} />
<badge.icon
className={`w-4 h-4 ${badge.variant === 'cyan' ? 'text-cyan-400' : 'text-indigo-400'}`}
/>
{badge.text}
</span>
))}
@ -277,13 +252,17 @@ function ApiExampleSection() {
<div className="bg-black/50 border border-indigo-500/20 rounded-lg p-4 font-mono text-sm overflow-x-auto mb-4">
<div className="text-gray-500 mb-2"># Generate an image</div>
<span className="text-cyan-400">curl</span> <span className="text-gray-300">-X POST https://api.banatie.app/v1/generate \</span>
<span className="text-cyan-400">curl</span>{' '}
<span className="text-gray-300">-X POST https://api.banatie.app/v1/generate \</span>
<br />
<span className="text-gray-300 ml-4">-H</span> <span className="text-green-400">&quot;Authorization: Bearer $API_KEY&quot;</span>{' '}
<span className="text-gray-300 ml-4">-H</span>{' '}
<span className="text-green-400">&quot;Authorization: Bearer $API_KEY&quot;</span>{' '}
<span className="text-gray-300">\</span>
<br />
<span className="text-gray-300 ml-4">-d</span>{' '}
<span className="text-green-400">&apos;{`{"prompt": "modern office interior, natural light"}`}&apos;</span>
<span className="text-green-400">
&apos;{`{"prompt": "modern office interior, natural light"}`}&apos;
</span>
</div>
<div className="bg-black/50 border border-indigo-500/20 rounded-lg p-4 font-mono text-sm overflow-x-auto">
@ -291,11 +270,15 @@ function ApiExampleSection() {
<span className="text-gray-300">{'{'}</span>
<br />
<span className="text-purple-400 ml-4">&quot;url&quot;</span>
<span className="text-gray-300">:</span> <span className="text-green-400">&quot;https://cdn.banatie.app/img/a7x2k9.png&quot;</span>
<span className="text-gray-300">:</span>{' '}
<span className="text-green-400">
&quot;https://cdn.banatie.app/img/a7x2k9.png&quot;
</span>
<span className="text-gray-300">,</span>
<br />
<span className="text-purple-400 ml-4">&quot;enhanced_prompt&quot;</span>
<span className="text-gray-300">:</span> <span className="text-green-400">&quot;A photorealistic modern office...&quot;</span>
<span className="text-gray-300">:</span>{' '}
<span className="text-green-400">&quot;A photorealistic modern office...&quot;</span>
<span className="text-gray-300">,</span>
<br />
<span className="text-purple-400 ml-4">&quot;generation_time&quot;</span>
@ -348,8 +331,12 @@ function ProblemSolutionSection() {
return (
<section className="py-20 px-6">
<div className="max-w-6xl mx-auto">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">Why developers choose Banatie</h2>
<p className="text-gray-400 text-center mb-16 max-w-2xl mx-auto">Stop fighting your image workflow. Start building.</p>
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">
Why developers choose Banatie
</h2>
<p className="text-gray-400 text-center mb-16 max-w-2xl mx-auto">
Stop fighting your image workflow. Start building.
</p>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-6">
{problems.map((item, i) => (
@ -390,11 +377,14 @@ function PromptUrlsSection() {
<Sparkles className="w-6 h-6 text-cyan-400" />
</div>
<div>
<span className="inline-block px-3 py-1 bg-cyan-500/20 text-cyan-300 text-xs rounded-full mb-2">Unique</span>
<span className="inline-block px-3 py-1 bg-cyan-500/20 text-cyan-300 text-xs rounded-full mb-2">
Unique
</span>
<h2 className="text-2xl font-bold mb-2">Prompt URLs Images via HTML</h2>
<p className="text-gray-400">
Put a prompt in your <code className="text-cyan-300 bg-black/30 px-1 rounded">img src</code> and get a real image. No API calls. No
JavaScript. Just HTML.
Put a prompt in your{' '}
<code className="text-cyan-300 bg-black/30 px-1 rounded">img src</code> and get a
real image. No API calls. No JavaScript. Just HTML.
</p>
</div>
</div>
@ -402,15 +392,22 @@ function PromptUrlsSection() {
<div className="bg-black/50 border border-indigo-500/20 rounded-lg p-4 font-mono text-sm overflow-x-auto">
<span className="text-gray-500">&lt;!-- Write this --&gt;</span>
<br />
<span className="text-purple-400">&lt;img</span> <span className="text-cyan-300">src</span>=
<span className="text-green-400">&quot;https://cdn.banatie.app/gen?p=modern office interior&quot;</span>{' '}
<span className="text-purple-400">&lt;img</span>{' '}
<span className="text-cyan-300">src</span>=
<span className="text-green-400">
&quot;https://cdn.banatie.app/gen?p=modern office interior&quot;
</span>{' '}
<span className="text-purple-400">/&gt;</span>
<br />
<br />
<span className="text-gray-500">&lt;!-- Get this: production-ready image, cached, CDN-delivered --&gt;</span>
<span className="text-gray-500">
&lt;!-- Get this: production-ready image, cached, CDN-delivered --&gt;
</span>
</div>
<p className="text-gray-500 text-sm mt-4">Perfect for static sites, prototypes, and AI coding agents that generate HTML.</p>
<p className="text-gray-500 text-sm mt-4">
Perfect for static sites, prototypes, and AI coding agents that generate HTML.
</p>
</div>
</div>
</section>
@ -438,8 +435,12 @@ function HowItWorksSection() {
return (
<section className="py-20 px-6">
<div className="max-w-6xl mx-auto">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">Your prompt. Your control. Production-ready.</h2>
<p className="text-gray-400 text-center mb-16 max-w-2xl mx-auto">We handle the complexity so you can focus on building.</p>
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">
Your prompt. Your control. Production-ready.
</h2>
<p className="text-gray-400 text-center mb-16 max-w-2xl mx-auto">
We handle the complexity so you can focus on building.
</p>
<div className="max-w-4xl mx-auto">
<div className="grid md:grid-cols-4 gap-4 mb-8">
@ -491,42 +492,48 @@ function KeyFeaturesSection() {
icon: AtSign,
iconColor: 'text-pink-400',
title: 'Reference Images',
description: 'Use @aliases to maintain style consistency across your project. Reference up to 3 images per generation.',
description:
'Use @aliases to maintain style consistency across your project. Reference up to 3 images per generation.',
isUnique: false,
},
{
icon: GitBranch,
iconColor: 'text-purple-400',
title: 'Flows',
description: 'Chain generations, iterate on results, build image sequences with @last and @first references.',
description:
'Chain generations, iterate on results, build image sequences with @last and @first references.',
isUnique: false,
},
{
icon: Palette,
iconColor: 'text-yellow-400',
title: '7 Style Templates',
description: 'Same prompt, different styles. Photorealistic, illustration, minimalist, product, comic, sticker, and more.',
description:
'Same prompt, different styles. Photorealistic, illustration, minimalist, product, comic, sticker, and more.',
isUnique: false,
},
{
icon: Globe,
iconColor: 'text-green-400',
title: 'Instant CDN Delivery',
description: 'Every image gets production-ready URL. No upload, no optimization, no hosting setup needed.',
description:
'Every image gets production-ready URL. No upload, no optimization, no hosting setup needed.',
isUnique: false,
},
{
icon: SlidersHorizontal,
iconColor: 'text-blue-400',
title: 'Output Control',
description: 'Control aspect ratio, dimensions, and format. From square thumbnails to ultra-wide banners.',
description:
'Control aspect ratio, dimensions, and format. From square thumbnails to ultra-wide banners.',
isUnique: false,
},
{
icon: Link,
iconColor: 'text-cyan-400',
title: 'Prompt URLs',
description: 'Generate images via URL parameters. Put prompt in img src, get real image. Built-in caching.',
description:
'Generate images via URL parameters. Put prompt in img src, get real image. Built-in caching.',
isUnique: true,
},
];
@ -534,8 +541,12 @@ function KeyFeaturesSection() {
return (
<section className="py-20 px-6">
<div className="max-w-6xl mx-auto">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">Built for real development workflows</h2>
<p className="text-gray-400 text-center mb-16 max-w-2xl mx-auto">Everything you need to integrate AI images into your projects.</p>
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">
Built for real development workflows
</h2>
<p className="text-gray-400 text-center mb-16 max-w-2xl mx-auto">
Everything you need to integrate AI images into your projects.
</p>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{features.map((feature, i) => (
@ -552,7 +563,11 @@ function KeyFeaturesSection() {
</div>
<div className="flex items-center gap-2 mb-2">
<h3 className="font-semibold text-lg">{feature.title}</h3>
{feature.isUnique && <span className="px-2 py-0.5 bg-cyan-500/20 text-cyan-300 text-xs rounded">Unique</span>}
{feature.isUnique && (
<span className="px-2 py-0.5 bg-cyan-500/20 text-cyan-300 text-xs rounded">
Unique
</span>
)}
</div>
<p className="text-gray-400 text-sm">{feature.description}</p>
</div>
@ -581,7 +596,9 @@ function IntegrationsSection() {
<section className="py-20 px-6">
<div className="max-w-6xl mx-auto text-center">
<h2 className="text-3xl md:text-4xl font-bold mb-4">Works with your tools</h2>
<p className="text-gray-400 mb-12 max-w-2xl mx-auto">Use what fits your workflow. All methods, same capabilities.</p>
<p className="text-gray-400 mb-12 max-w-2xl mx-auto">
Use what fits your workflow. All methods, same capabilities.
</p>
<div className="flex flex-wrap justify-center gap-4 mb-8">
{tools.map((tool, i) => (
@ -599,12 +616,15 @@ function IntegrationsSection() {
<div className="max-w-2xl mx-auto mt-8 p-4 bg-slate-900/60 border border-indigo-500/15 backdrop-blur-[10px] rounded-lg">
<p className="text-sm text-gray-400">
<strong className="text-white">Banatie Lab</strong> Official web interface for Banatie API. Generate images, build flows, browse your
gallery, and explore all capabilities with ready-to-use code snippets.
<strong className="text-white">Banatie Lab</strong> Official web interface for Banatie
API. Generate images, build flows, browse your gallery, and explore all capabilities
with ready-to-use code snippets.
</p>
</div>
<p className="text-gray-500 text-sm mt-6">Perfect for Claude Code, Cursor, and any AI-powered workflow.</p>
<p className="text-gray-500 text-sm mt-6">
Perfect for Claude Code, Cursor, and any AI-powered workflow.
</p>
</div>
</section>
);
@ -625,11 +645,14 @@ function ShapeTheFutureSection() {
<div className="relative my-[60px]">
<section className="shape-future bg-[#2a2a2a] relative z-[2]">
<div className="relative z-[6] py-[60px] px-10 text-center max-w-[700px] mx-auto">
<h2 className="shape-future-title text-5xl font-semibold text-[#f5f5f5] mb-4 leading-tight">Shape the future of Banatie</h2>
<h2 className="shape-future-title text-5xl font-semibold text-[#f5f5f5] mb-4 leading-tight">
Shape the future of Banatie
</h2>
<p className="text-[1.05rem] text-[#a0a0a0] mb-6 leading-relaxed">
We&apos;re building this for developers like you. Early adopters get direct influence on our roadmap suggest features, vote on
priorities, and help us build exactly what you need.
We&apos;re building this for developers like you. Early adopters get direct influence on
our roadmap suggest features, vote on priorities, and help us build exactly what you
need.
</p>
<div className="flex flex-wrap gap-6 justify-center text-[0.95rem] text-[#888]">
@ -666,10 +689,30 @@ function GeminiSection() {
];
const capabilities = [
{ icon: Type, title: 'Perfect Text Rendering', description: 'Legible text in images — logos, diagrams, posters. What other models still struggle with.' },
{ icon: Brain, title: 'Native Multimodal', description: 'Understands text AND images in one model. Not a text model + image model bolted together.' },
{ icon: Target, title: 'Precise Prompt Following', description: 'What you ask is what you get. No artistic "interpretation" that ignores your instructions.' },
{ icon: Image, title: 'Professional Realism', description: 'Photorealistic output that replaces stock photos. Not fantasy art — real, usable images.' },
{
icon: Type,
title: 'Perfect Text Rendering',
description:
'Legible text in images — logos, diagrams, posters. What other models still struggle with.',
},
{
icon: Brain,
title: 'Native Multimodal',
description:
'Understands text AND images in one model. Not a text model + image model bolted together.',
},
{
icon: Target,
title: 'Precise Prompt Following',
description:
'What you ask is what you get. No artistic "interpretation" that ignores your instructions.',
},
{
icon: Image,
title: 'Professional Realism',
description:
'Photorealistic output that replaces stock photos. Not fantasy art — real, usable images.',
},
];
return (
@ -683,8 +726,9 @@ function GeminiSection() {
<h2 className="text-2xl md:text-3xl font-bold">Powered by Google Gemini</h2>
</div>
<p className="text-gray-400 max-w-2xl mx-auto">
We chose Gemini because it&apos;s the only model family that combines native multimodal understanding with production-grade image
generation. Two models, optimized for different needs.
We chose Gemini because it&apos;s the only model family that combines native
multimodal understanding with production-grade image generation. Two models, optimized
for different needs.
</p>
</div>
@ -702,7 +746,8 @@ function GeminiSection() {
</div>
</div>
<p className="text-gray-400 text-sm mb-4">
Optimized for speed and iteration. Perfect for rapid prototyping and high-volume generation.
Optimized for speed and iteration. Perfect for rapid prototyping and high-volume
generation.
</p>
<ul className="space-y-2 text-sm">
{flashFeatures.map((feature, i) => (
@ -728,7 +773,8 @@ function GeminiSection() {
</div>
</div>
<p className="text-gray-400 text-sm mb-4">
Maximum quality and creative control. For production assets and professional workflows.
Maximum quality and creative control. For production assets and professional
workflows.
</p>
<ul className="space-y-2 text-sm">
{proFeatures.map((feature, i) => (
@ -745,7 +791,9 @@ function GeminiSection() {
{/* Shared Capabilities */}
<div className="border-t border-yellow-500/20 pt-8">
<h4 className="text-center font-semibold mb-6 text-gray-300">Why Gemini outperforms competitors</h4>
<h4 className="text-center font-semibold mb-6 text-gray-300">
Why Gemini outperforms competitors
</h4>
<div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
{capabilities.map((cap, i) => (
<div key={i} className="text-center p-4">
@ -762,7 +810,8 @@ function GeminiSection() {
{/* #1 Ranking Note */}
<p className="text-center text-gray-500 text-sm mt-8">
<Award className="w-4 h-4 inline mr-1 text-yellow-400" />
Gemini 2.5 Flash Image ranked #1 on LMArena for both text-to-image and image editing (August 2025)
Gemini 2.5 Flash Image ranked #1 on LMArena for both text-to-image and image editing
(August 2025)
</p>
</div>
</div>
@ -796,7 +845,8 @@ function FinalCtaSection() {
<div
className="absolute top-0 left-0 right-0 h-0.5 pointer-events-none"
style={{
background: 'linear-gradient(90deg, transparent 0%, rgba(34, 211, 238, 0.3) 25%, rgba(34, 211, 238, 0.6) 50%, rgba(34, 211, 238, 0.3) 75%, transparent 100%)',
background:
'linear-gradient(90deg, transparent 0%, rgba(34, 211, 238, 0.3) 25%, rgba(34, 211, 238, 0.6) 50%, rgba(34, 211, 238, 0.3) 75%, transparent 100%)',
}}
/>
@ -804,12 +854,15 @@ function FinalCtaSection() {
<div
className="absolute inset-0 opacity-50 pointer-events-none"
style={{
backgroundImage: 'radial-gradient(circle at 20% 50%, rgba(34, 211, 238, 0.15) 0%, transparent 40%), radial-gradient(circle at 80% 50%, rgba(34, 211, 238, 0.1) 0%, transparent 35%)',
backgroundImage:
'radial-gradient(circle at 20% 50%, rgba(34, 211, 238, 0.15) 0%, transparent 40%), radial-gradient(circle at 80% 50%, rgba(34, 211, 238, 0.1) 0%, transparent 35%)',
}}
/>
<div className="relative z-10 max-w-3xl mx-auto text-center">
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-6 text-white">Ready to build?</h2>
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold mb-6 text-white">
Ready to build?
</h2>
<p className="text-cyan-100/70 text-lg md:text-xl mb-10 max-w-2xl mx-auto">
Join developers waiting for early access. We&apos;ll notify you when your spot is ready.
</p>
@ -822,7 +875,9 @@ function FinalCtaSection() {
<ArrowRight className="w-5 h-5 transition-transform group-hover:translate-x-[5px]" />
</button>
<p className="text-cyan-200/50 text-sm mt-8">No credit card required Free to start Cancel anytime</p>
<p className="text-cyan-200/50 text-sm mt-8">
No credit card required Free to start Cancel anytime
</p>
</div>
</section>
);

View File

@ -196,6 +196,9 @@ importers:
'@banatie/database':
specifier: workspace:*
version: link:../../packages/database
lucide-react:
specifier: ^0.400.0
version: 0.400.0(react@19.1.0)
next:
specifier: 15.5.4
version: 15.5.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@ -9192,6 +9195,10 @@ snapshots:
dependencies:
react: 18.3.1
lucide-react@0.400.0(react@19.1.0):
dependencies:
react: 19.1.0
magic-string@0.30.19:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5