feat: add nebula clouds and meteor effects to pricing and docs pages, unify header style with homepage
Docker Build / Build and Push Docker Image (push) Failing after 1m37s

This commit is contained in:
2026-06-15 01:26:15 +08:00
parent c450214d78
commit c42757f9af
2 changed files with 222 additions and 10 deletions
+125 -9
View File
@@ -250,16 +250,47 @@ export function Docs() {
return (
<PublicLayout showMainContainer={false}>
<div className='mx-auto w-full max-w-6xl px-6 pt-20 pb-12'>
{/* Page header */}
<div className='mb-8 text-center'>
<h1 className='text-2xl font-bold tracking-tight sm:text-3xl text-foreground'>
{t('Documentation')}
</h1>
<p className='mt-2 text-muted-foreground'>
{t('Everything you need to integrate and manage your API gateway')}
</p>
<div className='relative overflow-hidden'>
{/* Background effects matching home page */}
<div
aria-hidden
className='pointer-events-none absolute inset-0 opacity-[0.03] dark:opacity-[0.04]'
style={{
backgroundImage:
'radial-gradient(circle, var(--primary) 0.5px, transparent 0.5px)',
backgroundSize: '24px 24px',
}}
/>
<div
aria-hidden
className='pointer-events-none absolute inset-0'
style={{
background:
'radial-gradient(ellipse 60% 50% at 50% -10%, oklch(0.55 0.15 240 / 0.06) 0%, transparent 70%)',
}}
/>
{/* Drifting nebula clouds */}
<div aria-hidden className='pointer-events-none absolute inset-0 overflow-hidden'>
<div className='nebula-cloud nebula-cloud-1' />
<div className='nebula-cloud nebula-cloud-2' />
</div>
{/* Shooting stars */}
<div aria-hidden className='pointer-events-none absolute inset-0 overflow-hidden'>
<div className='meteor meteor-1' />
<div className='meteor meteor-2' />
<div className='meteor meteor-3' />
</div>
<div className='relative mx-auto w-full max-w-6xl px-6 pt-20 pb-12'>
{/* Page header */}
<div className='mb-8 text-center'>
<h1 className='text-[clamp(1.75rem,4vw,2.5rem)] leading-tight font-bold tracking-[-0.025em] text-foreground'>
{t('Documentation')}
</h1>
<p className='mx-auto mt-2 max-w-lg text-[15px] leading-relaxed text-muted-foreground'>
{t('Everything you need to integrate and manage your API gateway')}
</p>
</div>
{/* Three-column layout */}
<div className='flex gap-8'>
@@ -403,6 +434,91 @@ export function Docs() {
</aside>
</div>
</div>
<style>{`
.nebula-cloud {
position: absolute;
border-radius: 50%;
filter: blur(80px);
opacity: 0;
animation: nebula-drift 20s ease-in-out infinite;
}
.dark .nebula-cloud { filter: blur(100px); }
.nebula-cloud-1 {
width: 500px; height: 500px;
top: -10%; left: -5%;
background: radial-gradient(circle, oklch(0.78 0.15 210 / 0.07) 0%, transparent 70%);
animation-duration: 25s;
}
.dark .nebula-cloud-1 {
background: radial-gradient(circle, oklch(0.78 0.15 210 / 0.10) 0%, transparent 70%);
}
.nebula-cloud-2 {
width: 400px; height: 400px;
top: 20%; right: -8%;
background: radial-gradient(circle, oklch(0.70 0.12 260 / 0.05) 0%, transparent 70%);
animation-duration: 30s;
animation-delay: -8s;
}
.dark .nebula-cloud-2 {
background: radial-gradient(circle, oklch(0.70 0.12 260 / 0.08) 0%, transparent 70%);
}
@keyframes nebula-drift {
0%, 100% { opacity: 0.3; transform: translate(0, 0) scale(1); }
25% { opacity: 0.7; transform: translate(40px, -20px) scale(1.05); }
50% { opacity: 0.5; transform: translate(-20px, 30px) scale(0.95); }
75% { opacity: 0.8; transform: translate(20px, 10px) scale(1.02); }
}
.meteor {
position: absolute;
width: 1.5px;
height: 0;
border-radius: 999px;
animation: meteor-fall linear infinite;
opacity: 0;
will-change: transform, opacity, height;
}
.meteor::before {
content: '';
position: absolute;
top: 0; left: 50%;
transform: translateX(-50%);
width: 3px; height: 3px;
border-radius: 50%;
background: oklch(0.85 0.12 210 / 0.9);
box-shadow: 0 0 4px 1px oklch(0.78 0.15 210 / 0.5), 0 0 12px 3px oklch(0.78 0.15 210 / 0.2);
}
.dark .meteor::before {
width: 4px; height: 4px;
background: oklch(0.90 0.15 210 / 0.95);
box-shadow: 0 0 6px 2px oklch(0.78 0.15 210 / 0.6), 0 0 20px 6px oklch(0.78 0.15 210 / 0.25), 0 0 40px 10px oklch(0.78 0.15 210 / 0.08);
}
.meteor::after {
content: '';
position: absolute;
top: 3px; left: 0;
width: 100%;
border-radius: 999px;
background: linear-gradient(to bottom, oklch(0.78 0.15 210 / 0.6) 0%, oklch(0.78 0.15 210 / 0.3) 20%, oklch(0.78 0.15 210 / 0.08) 60%, transparent 100%);
}
.dark .meteor::after {
background: linear-gradient(to bottom, oklch(0.78 0.15 210 / 0.7) 0%, oklch(0.78 0.15 210 / 0.35) 15%, oklch(0.78 0.15 210 / 0.1) 50%, transparent 100%);
}
.meteor-1 { left: 15%; top: -2%; animation-duration: 1.8s; animation-delay: 3s; }
.meteor-2 { left: 50%; top: -2%; animation-duration: 1.6s; animation-delay: 10s; }
.meteor-3 { left: 80%; top: -2%; animation-duration: 2.0s; animation-delay: 18s; }
@keyframes meteor-fall {
0% { height: 0; opacity: 0; transform: translateY(0) translateX(0) rotate(220deg); }
8% { opacity: 1; }
20% { height: 100px; opacity: 0.9; }
50% { height: 160px; opacity: 0.5; }
80% { height: 60px; opacity: 0.15; }
100% { height: 0; opacity: 0; transform: translateY(700px) translateX(-200px) rotate(220deg); }
}
@media (prefers-reduced-motion: reduce) {
.nebula-cloud, .meteor { animation: none !important; opacity: 0 !important; }
}
`}</style>
</PublicLayout>
)
}
+97 -1
View File
@@ -168,7 +168,7 @@ export function Pricing() {
return (
<PublicLayout showMainContainer={false}>
<div className='relative'>
<div className='relative overflow-hidden'>
{/* Background effects matching home page */}
<div
aria-hidden
@@ -187,6 +187,17 @@ export function Pricing() {
'radial-gradient(ellipse 60% 50% at 50% -10%, oklch(0.55 0.15 240 / 0.06) 0%, transparent 70%)',
}}
/>
{/* Drifting nebula clouds */}
<div aria-hidden className='pointer-events-none absolute inset-0 overflow-hidden'>
<div className='nebula-cloud nebula-cloud-1' />
<div className='nebula-cloud nebula-cloud-2' />
</div>
{/* Shooting stars */}
<div aria-hidden className='pointer-events-none absolute inset-0 overflow-hidden'>
<div className='meteor meteor-1' />
<div className='meteor meteor-2' />
<div className='meteor meteor-3' />
</div>
<PageTransition className='relative mx-auto w-full max-w-6xl px-6 pt-20 pb-12'>
{/* Header */}
@@ -304,6 +315,91 @@ export function Pricing() {
/>
)}
</PageTransition>
<style>{`
.nebula-cloud {
position: absolute;
border-radius: 50%;
filter: blur(80px);
opacity: 0;
animation: nebula-drift 20s ease-in-out infinite;
}
.dark .nebula-cloud { filter: blur(100px); }
.nebula-cloud-1 {
width: 500px; height: 500px;
top: -10%; left: -5%;
background: radial-gradient(circle, oklch(0.78 0.15 210 / 0.07) 0%, transparent 70%);
animation-duration: 25s;
}
.dark .nebula-cloud-1 {
background: radial-gradient(circle, oklch(0.78 0.15 210 / 0.10) 0%, transparent 70%);
}
.nebula-cloud-2 {
width: 400px; height: 400px;
top: 20%; right: -8%;
background: radial-gradient(circle, oklch(0.70 0.12 260 / 0.05) 0%, transparent 70%);
animation-duration: 30s;
animation-delay: -8s;
}
.dark .nebula-cloud-2 {
background: radial-gradient(circle, oklch(0.70 0.12 260 / 0.08) 0%, transparent 70%);
}
@keyframes nebula-drift {
0%, 100% { opacity: 0.3; transform: translate(0, 0) scale(1); }
25% { opacity: 0.7; transform: translate(40px, -20px) scale(1.05); }
50% { opacity: 0.5; transform: translate(-20px, 30px) scale(0.95); }
75% { opacity: 0.8; transform: translate(20px, 10px) scale(1.02); }
}
.meteor {
position: absolute;
width: 1.5px;
height: 0;
border-radius: 999px;
animation: meteor-fall linear infinite;
opacity: 0;
will-change: transform, opacity, height;
}
.meteor::before {
content: '';
position: absolute;
top: 0; left: 50%;
transform: translateX(-50%);
width: 3px; height: 3px;
border-radius: 50%;
background: oklch(0.85 0.12 210 / 0.9);
box-shadow: 0 0 4px 1px oklch(0.78 0.15 210 / 0.5), 0 0 12px 3px oklch(0.78 0.15 210 / 0.2);
}
.dark .meteor::before {
width: 4px; height: 4px;
background: oklch(0.90 0.15 210 / 0.95);
box-shadow: 0 0 6px 2px oklch(0.78 0.15 210 / 0.6), 0 0 20px 6px oklch(0.78 0.15 210 / 0.25), 0 0 40px 10px oklch(0.78 0.15 210 / 0.08);
}
.meteor::after {
content: '';
position: absolute;
top: 3px; left: 0;
width: 100%;
border-radius: 999px;
background: linear-gradient(to bottom, oklch(0.78 0.15 210 / 0.6) 0%, oklch(0.78 0.15 210 / 0.3) 20%, oklch(0.78 0.15 210 / 0.08) 60%, transparent 100%);
}
.dark .meteor::after {
background: linear-gradient(to bottom, oklch(0.78 0.15 210 / 0.7) 0%, oklch(0.78 0.15 210 / 0.35) 15%, oklch(0.78 0.15 210 / 0.1) 50%, transparent 100%);
}
.meteor-1 { left: 15%; top: -2%; animation-duration: 1.8s; animation-delay: 2s; }
.meteor-2 { left: 50%; top: -2%; animation-duration: 1.6s; animation-delay: 9s; }
.meteor-3 { left: 80%; top: -2%; animation-duration: 2.0s; animation-delay: 16s; }
@keyframes meteor-fall {
0% { height: 0; opacity: 0; transform: translateY(0) translateX(0) rotate(220deg); }
8% { opacity: 1; }
20% { height: 100px; opacity: 0.9; }
50% { height: 160px; opacity: 0.5; }
80% { height: 60px; opacity: 0.15; }
100% { height: 0; opacity: 0; transform: translateY(700px) translateX(-200px) rotate(220deg); }
}
@media (prefers-reduced-motion: reduce) {
.nebula-cloud, .meteor { animation: none !important; opacity: 0 !important; }
}
`}</style>
</div>
</PublicLayout>
)