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:
zl-q
2026-05-09 12:11:10 +08:00
parent 04b493ed09
commit c12320cb79
72 changed files with 23855 additions and 828 deletions
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import AboutPage from '../../components/AboutPage.astro';
const locale = 'en' as const;
---
<MarketingLayout locale={locale}>
<AboutPage locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import FeaturesPage from '../../components/FeaturesPage.astro';
const locale = 'en' as const;
---
<MarketingLayout locale={locale}>
<FeaturesPage locale={locale} />
</MarketingLayout>
+13
View File
@@ -0,0 +1,13 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import Hero from '../../components/Hero.astro';
import Showcase from '../../components/Showcase.astro';
import CtaSection from '../../components/CtaSection.astro';
const locale = 'en' as const;
---
<MarketingLayout locale={locale}>
<Hero locale={locale} />
<Showcase locale={locale} />
<CtaSection locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import PricingPage from '../../components/PricingPage.astro';
const locale = 'en' as const;
---
<MarketingLayout locale={locale}>
<PricingPage locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import LegalPage from '../../components/LegalPage.astro';
const locale = 'en' as const;
---
<MarketingLayout locale={locale}>
<LegalPage locale={locale} docType="privacy_policy" />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import LegalPage from '../../components/LegalPage.astro';
const locale = 'en' as const;
---
<MarketingLayout locale={locale}>
<LegalPage locale={locale} docType="terms_of_service" />
</MarketingLayout>
+3
View File
@@ -0,0 +1,3 @@
---
return Astro.redirect('/zh/');
---
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import AboutPage from '../../components/AboutPage.astro';
const locale = 'zh' as const;
---
<MarketingLayout locale={locale}>
<AboutPage locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import FeaturesPage from '../../components/FeaturesPage.astro';
const locale = 'zh' as const;
---
<MarketingLayout locale={locale}>
<FeaturesPage locale={locale} />
</MarketingLayout>
+13
View File
@@ -0,0 +1,13 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import Hero from '../../components/Hero.astro';
import Showcase from '../../components/Showcase.astro';
import CtaSection from '../../components/CtaSection.astro';
const locale = 'zh' as const;
---
<MarketingLayout locale={locale}>
<Hero locale={locale} />
<Showcase locale={locale} />
<CtaSection locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import PricingPage from '../../components/PricingPage.astro';
const locale = 'zh' as const;
---
<MarketingLayout locale={locale}>
<PricingPage locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import LegalPage from '../../components/LegalPage.astro';
const locale = 'zh' as const;
---
<MarketingLayout locale={locale}>
<LegalPage locale={locale} docType="privacy_policy" />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import LegalPage from '../../components/LegalPage.astro';
const locale = 'zh' as const;
---
<MarketingLayout locale={locale}>
<LegalPage locale={locale} docType="terms_of_service" />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import AboutPage from '../../components/AboutPage.astro';
const locale = 'zh_Hant' as const;
---
<MarketingLayout locale={locale}>
<AboutPage locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import FeaturesPage from '../../components/FeaturesPage.astro';
const locale = 'zh_Hant' as const;
---
<MarketingLayout locale={locale}>
<FeaturesPage locale={locale} />
</MarketingLayout>
+13
View File
@@ -0,0 +1,13 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import Hero from '../../components/Hero.astro';
import Showcase from '../../components/Showcase.astro';
import CtaSection from '../../components/CtaSection.astro';
const locale = 'zh_Hant' as const;
---
<MarketingLayout locale={locale}>
<Hero locale={locale} />
<Showcase locale={locale} />
<CtaSection locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import PricingPage from '../../components/PricingPage.astro';
const locale = 'zh_Hant' as const;
---
<MarketingLayout locale={locale}>
<PricingPage locale={locale} />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import LegalPage from '../../components/LegalPage.astro';
const locale = 'zh_Hant' as const;
---
<MarketingLayout locale={locale}>
<LegalPage locale={locale} docType="privacy_policy" />
</MarketingLayout>
+8
View File
@@ -0,0 +1,8 @@
---
import MarketingLayout from '../../layouts/Marketing.astro';
import LegalPage from '../../components/LegalPage.astro';
const locale = 'zh_Hant' as const;
---
<MarketingLayout locale={locale}>
<LegalPage locale={locale} docType="terms_of_service" />
</MarketingLayout>