feat(web): rebuild web with Astro 6 + React 19 + Tailwind 4
Replace static HTML website with Astro SSG framework: - Astro 6 + React 19 (client islands) + Tailwind CSS 4 + shadcn/ui - i18n: zh/zh_Hant/en with URL prefix routing - Pages: Landing, Features, Pricing, About, Privacy, Terms (3 locales) - Responsive full-width layout with scroll reveal animations - Cyber gradient theme with particle effects inspired by Kimi - Features page: alternating layout with hexagram illustrations - Legal pages: markdown rendering with side info card - Language switcher preserves current page path - Assets shared via symlinks to web/design/assets/ (no duplication) Tech decisions documented in .trellis/spec/web/index.md Task: .trellis/tasks/05-08-web-astro-react-tailwind-shadcn-ui
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@keyframes fade-in-up {
|
||||
from { opacity: 0; transform: translateY(24px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes slide-in-left {
|
||||
from { opacity: 0; transform: translateX(-40px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes slide-in-right {
|
||||
from { opacity: 0; transform: translateX(40px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
|
||||
@keyframes scale-in {
|
||||
from { opacity: 0; transform: scale(0.95); }
|
||||
to { opacity: 1; transform: scale(1); }
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
|
||||
@keyframes glow-pulse {
|
||||
0%, 100% { opacity: 0.12; }
|
||||
50% { opacity: 0.2; }
|
||||
}
|
||||
|
||||
@keyframes particle-drift {
|
||||
0% { transform: translate(0, 0); }
|
||||
25% { transform: translate(10px, -20px); }
|
||||
50% { transform: translate(-5px, -40px); }
|
||||
75% { transform: translate(15px, -20px); }
|
||||
100% { transform: translate(0, 0); }
|
||||
}
|
||||
|
||||
/* Reveal animations */
|
||||
.reveal { opacity: 0; will-change: transform, opacity; }
|
||||
.reveal.visible { animation: fade-in-up 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
|
||||
|
||||
.reveal-left { opacity: 0; will-change: transform, opacity; }
|
||||
.reveal-left.visible { animation: slide-in-left 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
|
||||
|
||||
.reveal-right { opacity: 0; will-change: transform, opacity; }
|
||||
.reveal-right.visible { animation: slide-in-right 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
|
||||
|
||||
.reveal-scale { opacity: 0; will-change: transform, opacity; }
|
||||
.reveal-scale.visible { animation: scale-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
|
||||
|
||||
.reveal.visible.stagger-1 { animation-delay: 0.1s; }
|
||||
.reveal.visible.stagger-2 { animation-delay: 0.2s; }
|
||||
.reveal.visible.stagger-3 { animation-delay: 0.3s; }
|
||||
.reveal.visible.stagger-4 { animation-delay: 0.4s; }
|
||||
.reveal.visible.stagger-5 { animation-delay: 0.5s; }
|
||||
.reveal.visible.stagger-6 { animation-delay: 0.6s; }
|
||||
|
||||
/* Cyber gradient */
|
||||
.cyber-gradient {
|
||||
background: linear-gradient(135deg, #8B5CF6 0%, #A78BFA 50%, #C084FC 100%);
|
||||
}
|
||||
|
||||
.cyber-glow {
|
||||
box-shadow: 0 0 20px rgba(139, 92, 246, 0.35), 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Purple glow backgrounds */
|
||||
.glow-bg {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.glow-bg::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -10%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(ellipse at center, rgba(139, 92, 246, 0.15) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
animation: glow-pulse 6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.glow-bg-wide::before {
|
||||
width: 1200px;
|
||||
height: 800px;
|
||||
}
|
||||
|
||||
/* Floating particles (pure CSS) */
|
||||
.particle {
|
||||
position: absolute;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background: rgba(139, 92, 246, 0.4);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.particle:nth-child(1) { top: 20%; left: 15%; animation: particle-drift 8s ease-in-out infinite; }
|
||||
.particle:nth-child(2) { top: 40%; left: 75%; animation: particle-drift 12s ease-in-out infinite 1s; width: 3px; height: 3px; }
|
||||
.particle:nth-child(3) { top: 60%; left: 30%; animation: particle-drift 10s ease-in-out infinite 2s; width: 5px; height: 5px; }
|
||||
.particle:nth-child(4) { top: 30%; left: 55%; animation: particle-drift 9s ease-in-out infinite 3s; }
|
||||
.particle:nth-child(5) { top: 70%; left: 85%; animation: particle-drift 11s ease-in-out infinite 4s; width: 3px; height: 3px; }
|
||||
.particle:nth-child(6) { top: 50%; left: 10%; animation: particle-drift 7s ease-in-out infinite 5s; width: 2px; height: 2px; }
|
||||
.particle:nth-child(7) { top: 15%; left: 65%; animation: particle-drift 13s ease-in-out infinite 2s; }
|
||||
.particle:nth-child(8) { top: 80%; left: 45%; animation: particle-drift 8s ease-in-out infinite 6s; width: 3px; height: 3px; }
|
||||
|
||||
/* Connection lines between particles */
|
||||
.particle-lines {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
background-image:
|
||||
radial-gradient(circle at 15% 20%, rgba(139, 92, 246, 0.06) 0%, transparent 40%),
|
||||
radial-gradient(circle at 75% 40%, rgba(139, 92, 246, 0.04) 0%, transparent 35%),
|
||||
radial-gradient(circle at 30% 60%, rgba(139, 92, 246, 0.05) 0%, transparent 38%);
|
||||
}
|
||||
|
||||
/* Hexagram lines */
|
||||
.hex-yang {
|
||||
width: 9rem;
|
||||
height: 6px;
|
||||
border-radius: 9999px;
|
||||
background: linear-gradient(135deg, #8B5CF6, #C084FC);
|
||||
}
|
||||
|
||||
.hex-yin {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.hex-yin > div {
|
||||
width: 3.5rem;
|
||||
height: 6px;
|
||||
border-radius: 9999px;
|
||||
background: rgba(139, 92, 246, 0.4);
|
||||
}
|
||||
|
||||
/* Feature card hover */
|
||||
.feature-card {
|
||||
transition: all 0.5s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
.feature-card:hover {
|
||||
transform: translateY(-4px);
|
||||
border-color: rgba(139, 92, 246, 0.25);
|
||||
box-shadow: 0 8px 30px rgba(139, 92, 246, 0.1);
|
||||
}
|
||||
|
||||
/* Smooth scroll */
|
||||
html { scroll-behavior: smooth; }
|
||||
|
||||
/* Reduced motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.reveal, .reveal-left, .reveal-right, .reveal-scale { opacity: 1; transform: none; animation: none; }
|
||||
.particle { animation: none; }
|
||||
.glow-bg::before { animation: none; }
|
||||
html { scroll-behavior: auto; }
|
||||
}
|
||||
Reference in New Issue
Block a user