feat: 深度设计五站视觉语言 + 语言路由修复
- 语言路由:localeDetection 关闭,/ 固定英文、/zh 固定中文,URL 决定语言 (不再按 cookie/Accept-Language 自动跳转;语言切换器显式切换不受影响) - 五站独立视觉语言(data-theme 驱动的设计系统层): · AI Stack:深蓝渐变 Hero + 统计条 + 卡片左色条 hover(专业 SaaS) · LaunchAI:橙色渐变 Banner + 斜切底边 + 暖白底(活力社区) · The AI Ledger:黑色报头日期条 + 衬线字体 + 直角 + 双细线 + 报纸排版(媒体) · DevAI.tools:全站深色 + 等宽字体 + 终端 Hero + 扫描线纹理 + 系统状态条(终端) · findai:纯白极简 + 紫色聚焦光圈 + 无界卡片(搜索引擎) - 修复 :first-of-type 误伤(hero 样式收敛到专用 class)
This commit is contained in:
@@ -23,6 +23,7 @@ const SITES_ROOT = path.join(REPO_ROOT, "sites");
|
||||
// ====================================================================
|
||||
const SITES = {
|
||||
"ai-stack": {
|
||||
themeClass: "site-ai-stack",
|
||||
brandZh: {
|
||||
name: "AI Stack",
|
||||
tagline: "由真实用户排名的专业 AI 工具目录。",
|
||||
@@ -91,6 +92,7 @@ const SITES = {
|
||||
},
|
||||
},
|
||||
launchai: {
|
||||
themeClass: "site-launchai",
|
||||
brandZh: {
|
||||
name: "LaunchAI",
|
||||
tagline: "发现并投票今日的 AI 新品。",
|
||||
@@ -157,6 +159,7 @@ const SITES = {
|
||||
},
|
||||
},
|
||||
"the-ai-ledger": {
|
||||
themeClass: "site-the-ai-ledger",
|
||||
brandZh: {
|
||||
name: "The AI Ledger",
|
||||
tagline: "独立 AI 报道,附社区排名目录。",
|
||||
@@ -224,6 +227,7 @@ const SITES = {
|
||||
},
|
||||
},
|
||||
"devai-tools": {
|
||||
themeClass: "site-devai-tools",
|
||||
brandZh: {
|
||||
name: "DevAI.tools",
|
||||
tagline: "面向开发者的 AI 工具——精选、实测、社区排名。",
|
||||
@@ -289,6 +293,7 @@ const SITES = {
|
||||
},
|
||||
},
|
||||
findai: {
|
||||
themeClass: "site-findai",
|
||||
brandZh: {
|
||||
name: "findai",
|
||||
tagline: "极简 AI 工具搜索引擎。",
|
||||
|
||||
@@ -4,7 +4,10 @@ import { createNavigation } from 'next-intl/navigation';
|
||||
export const routing = defineRouting({
|
||||
locales: ['en', 'zh'],
|
||||
defaultLocale: 'en',
|
||||
localePrefix: 'as-needed'
|
||||
localePrefix: 'as-needed',
|
||||
// 品牌站根路径固定默认语言(英文):不按 cookie/Accept-Language 自动跳转。
|
||||
// 中文用户通过导航语言切换器显式进入 /zh。
|
||||
localeDetection: false
|
||||
});
|
||||
|
||||
export type Locale = (typeof routing.locales)[number];
|
||||
|
||||
@@ -48,7 +48,11 @@ export async function SiteChrome({
|
||||
const footerGroups = footerGroupsRaw ?? config.footerGroups;
|
||||
|
||||
return (
|
||||
<div style={config.cssVars as React.CSSProperties}>
|
||||
<div
|
||||
data-theme={config.id}
|
||||
className={config.themeClass}
|
||||
style={config.cssVars as React.CSSProperties}
|
||||
>
|
||||
<ThemeHeader
|
||||
brand={brand}
|
||||
navItems={navItems}
|
||||
|
||||
@@ -63,7 +63,7 @@ async function ClassicHome({ locale }: { locale: string }) {
|
||||
return (
|
||||
<div className="bg-background">
|
||||
{/* Hero */}
|
||||
<section className="border-b border-border bg-gradient-to-b from-secondary/40 to-background">
|
||||
<section className="hero-dark border-b border-border">
|
||||
<div className="mx-auto max-w-7xl px-4 py-16 text-center sm:px-6 md:py-24">
|
||||
<h1 className="mx-auto max-w-3xl text-3xl font-bold tracking-tight text-foreground sm:text-4xl md:text-5xl">
|
||||
{th("title")}
|
||||
@@ -88,13 +88,28 @@ async function ClassicHome({ locale }: { locale: string }) {
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div className="mt-4 flex flex-wrap items-center justify-center gap-2 text-xs text-muted-foreground">
|
||||
<span>{t("popularLabel")}</span>
|
||||
|
||||
{/* 统计条(深色 Hero 内的白色数字) */}
|
||||
<div className="mx-auto mt-10 flex max-w-lg items-center justify-center gap-10 border-t border-white/15 pt-6">
|
||||
{[
|
||||
{ v: "1,000+", l: "AI tools" },
|
||||
{ v: "14", l: "Categories" },
|
||||
{ v: "7", l: "Rankings" },
|
||||
].map((s) => (
|
||||
<div key={s.l} className="text-center">
|
||||
<div className="text-2xl font-bold text-white">{s.v}</div>
|
||||
<div className="text-xs text-white/60">{s.l}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-2 text-xs">
|
||||
<span className="text-white/60">{t("popularLabel")}</span>
|
||||
{t.raw("popularSearches").map((q: string) => (
|
||||
<LocaleLink
|
||||
key={q}
|
||||
href={`/tools?search=${q}`}
|
||||
className="rounded-full bg-secondary px-2.5 py-1 transition-colors hover:bg-hover"
|
||||
className="rounded-full bg-white/10 px-2.5 py-1 text-white/80 transition-colors hover:bg-white/20"
|
||||
>
|
||||
{q}
|
||||
</LocaleLink>
|
||||
|
||||
@@ -59,8 +59,17 @@ async function EditorialHome({ locale }: { locale: string }) {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Masthead:黑色报头条(当日日期 + 期号),报纸头版签名 */}
|
||||
<div className="bg-foreground text-background">
|
||||
<div className="mx-auto flex max-w-4xl items-center justify-between px-4 py-2 text-[11px] uppercase tracking-[0.25em] sm:px-6">
|
||||
<span>{new Date().toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" })}</span>
|
||||
<span className="hidden sm:inline">Est. 2026</span>
|
||||
<span>Daily</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Masthead */}
|
||||
<section className="border-b border-border">
|
||||
<section className="hero-mast border-b border-border">
|
||||
<div className="mx-auto max-w-4xl px-4 py-16 text-center sm:px-6 md:py-20">
|
||||
<p className="text-xs font-medium uppercase tracking-[0.3em] text-muted-foreground">
|
||||
{t("mastheadLabel")}
|
||||
|
||||
@@ -77,6 +77,7 @@ async function MinimalHome({ locale }: { locale: string }) {
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div className="mx-auto mt-10 max-w-md border-t border-border/60 pt-5" />
|
||||
<div className="mt-6 flex flex-wrap items-center justify-center gap-2">
|
||||
{popularSearches.map((q) => (
|
||||
<LocaleLink
|
||||
|
||||
@@ -56,7 +56,13 @@ async function NicheHome({ locale }: { locale: string }) {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Terminal 风格 Hero */}
|
||||
{/* Terminal 风格 Hero + 绿色系统状态条 */}
|
||||
<div className="border-b border-border bg-background">
|
||||
<div className="mx-auto flex max-w-5xl items-center gap-2 px-4 py-2 font-mono text-[11px] text-muted-foreground sm:px-6">
|
||||
<span className="inline-block h-2 w-2 animate-pulse rounded-full bg-emerald-500" />
|
||||
system: online · 1,000+ tools indexed · updated hourly
|
||||
</div>
|
||||
</div>
|
||||
<section className="border-b border-border bg-[hsl(var(--secondary))]/40">
|
||||
<div className="mx-auto max-w-5xl px-4 py-14 sm:px-6 md:py-20">
|
||||
<div className="mx-auto max-w-2xl overflow-hidden rounded-xl border border-border bg-background shadow-sm">
|
||||
|
||||
@@ -115,7 +115,7 @@ async function ProductHome({ locale }: { locale: string }) {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Hero:今日发布 */}
|
||||
<section className="border-b border-border bg-gradient-to-b from-primary/5 to-background">
|
||||
<section className="hero-launch border-b border-border bg-gradient-to-b from-primary/5 to-background">
|
||||
<div className="mx-auto max-w-5xl px-4 py-12 text-center sm:px-6 md:py-16">
|
||||
<h1 className="text-2xl font-extrabold tracking-tight text-foreground sm:text-4xl">
|
||||
{th("title")}
|
||||
|
||||
@@ -32,6 +32,8 @@ export interface SiteConfig {
|
||||
seo?: Record<string, { title: string; description: string }>;
|
||||
/** 品牌强调色 HSL 三元组(登录页分栏模板) */
|
||||
accent?: string;
|
||||
/** 站点视觉签名 class(挂载在站点外壳根元素,驱动全站差异化样式) */
|
||||
themeClass?: string;
|
||||
/** 中文品牌文案(导航/页脚/hero/搜索占位) */
|
||||
brandZh?: {
|
||||
name?: string;
|
||||
|
||||
@@ -119,3 +119,267 @@ html {
|
||||
.animate-drawer-in {
|
||||
animation: bu-drawer-in 0.18s ease-out;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
五站视觉签名(Site Identity Layers)
|
||||
每个网站一套独立设计语言:字体 / 底色 / 圆角 / 边框 / 按钮形态
|
||||
由 SiteChrome 的 data-theme 驱动,仅作用于主题表现层
|
||||
============================================================ */
|
||||
|
||||
/* ---------- 1. AI Stack(classic):深蓝专业 SaaS ----------
|
||||
密度较高、细边框、轻阴影、蓝色主色 */
|
||||
[data-theme="ai-stack"] {
|
||||
--primary: 224 64% 33%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--ring: 224 64% 33%;
|
||||
}
|
||||
[data-theme="ai-stack"] .rounded-xl,
|
||||
[data-theme="ai-stack"] .rounded-2xl {
|
||||
border-radius: 0.625rem;
|
||||
}
|
||||
[data-theme="ai-stack"] .group.relative.rounded-xl {
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||
}
|
||||
|
||||
/* ---------- 2. LaunchAI(product):暖橙活力社区 ----------
|
||||
暖白底、胶囊按钮、大圆角卡片、橙色主色 */
|
||||
[data-theme="launchai"] {
|
||||
--primary: 16 85% 53%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--background: 30 55% 97%;
|
||||
--secondary: 28 50% 92%;
|
||||
--ring: 16 85% 53%;
|
||||
}
|
||||
[data-theme="launchai"] .bg-background {
|
||||
background-color: hsl(var(--background));
|
||||
}
|
||||
[data-theme="launchai"] .rounded-xl { border-radius: 1.1rem; }
|
||||
[data-theme="launchai"] .rounded-2xl { border-radius: 1.4rem; }
|
||||
[data-theme="launchai"] h1, [data-theme="launchai"] h2 {
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
/* ---------- 3. The AI Ledger(editorial):报纸编辑风 ----------
|
||||
纸白底、衬线字体、直角、黑主色、无阴影、粗黑分隔 */
|
||||
[data-theme="the-ai-ledger"] {
|
||||
--primary: 24 10% 12%;
|
||||
--primary-foreground: 40 40% 98%;
|
||||
--background: 42 45% 97%;
|
||||
--border: 30 10% 82%;
|
||||
--radius: 0px;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] {
|
||||
font-family: Georgia, "Times New Roman", "Noto Serif SC", serif;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] h1,
|
||||
[data-theme="the-ai-ledger"] h2,
|
||||
[data-theme="the-ai-ledger"] h3 {
|
||||
font-family: Georgia, "Times New Roman", "Noto Serif SC", serif;
|
||||
letter-spacing: -0.005em;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] .rounded-full,
|
||||
[data-theme="the-ai-ledger"] .rounded-xl,
|
||||
[data-theme="the-ai-ledger"] .rounded-2xl,
|
||||
[data-theme="the-ai-ledger"] .rounded-lg {
|
||||
border-radius: 1px;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] .shadow,
|
||||
[data-theme="the-ai-ledger"] .shadow-sm,
|
||||
[data-theme="the-ai-ledger"] .shadow-lg {
|
||||
box-shadow: none;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] .bg-primary,
|
||||
[data-theme="the-ai-ledger"] .hover\:bg-primary {
|
||||
background-color: hsl(24 10% 12%);
|
||||
}
|
||||
[data-theme="the-ai-ledger"] header .rounded-lg {
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
/* ---------- 4. DevAI.tools(niche):深色终端 ----------
|
||||
深色底、等宽字体、绿色主色、代码面板感 */
|
||||
[data-theme="devai-tools"] {
|
||||
--background: 220 25% 7%;
|
||||
--foreground: 210 20% 92%;
|
||||
--primary: 150 60% 45%;
|
||||
--primary-foreground: 220 25% 7%;
|
||||
--secondary: 220 20% 13%;
|
||||
--muted: 220 20% 13%;
|
||||
--muted-foreground: 215 15% 62%;
|
||||
--border: 218 18% 17%;
|
||||
--ring: 150 60% 45%;
|
||||
--card: 220 25% 9%;
|
||||
--popover: 220 25% 9%;
|
||||
--accent: 220 20% 15%;
|
||||
}
|
||||
[data-theme="devai-tools"] {
|
||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
[data-theme="devai-tools"] h1,
|
||||
[data-theme="devai-tools"] h2,
|
||||
[data-theme="devai-tools"] h3,
|
||||
[data-theme="devai-tools"] header .font-bold {
|
||||
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
[data-theme="devai-tools"] .bg-background,
|
||||
[data-theme="devai-tools"] .group.relative {
|
||||
background-color: hsl(220 25% 9%);
|
||||
}
|
||||
[data-theme="devai-tools"] .rounded-xl { border-radius: 0.5rem; }
|
||||
[data-theme="devai-tools"] .text-primary { color: hsl(150 60% 45%); }
|
||||
|
||||
/* ---------- 5. findai(minimal):极简紫 ----------
|
||||
纯白、无边框卡片、细分隔、紫罗兰、大留白 */
|
||||
[data-theme="findai"] {
|
||||
--primary: 262 65% 52%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--ring: 262 65% 52%;
|
||||
}
|
||||
[data-theme="findai"] .group.relative {
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
[data-theme="findai"] .group.relative:hover {
|
||||
background-color: hsl(262 40% 97%);
|
||||
}
|
||||
[data-theme="findai"] .shadow-lg {
|
||||
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
[data-theme="findai"] .rounded-full { border-radius: 999px; }
|
||||
|
||||
/* ============================================================
|
||||
深度设计层 v2 —— 每站完整的视觉语言(不只是换色)
|
||||
============================================================ */
|
||||
|
||||
/* ---------- 1. AI Stack:深蓝渐变 Hero + 统计条(专业 SaaS) ---------- */
|
||||
[data-theme="ai-stack"] .hero-dark {
|
||||
background: linear-gradient(180deg, hsl(224 60% 14%) 0%, hsl(224 55% 22%) 75%, hsl(var(--background)) 100%);
|
||||
}
|
||||
[data-theme="ai-stack"] .hero-dark h1 {
|
||||
color: white;
|
||||
}
|
||||
[data-theme="ai-stack"] .hero-dark p,
|
||||
[data-theme="ai-stack"] .hero-dark span {
|
||||
color: rgba(255, 255, 255, 0.65);
|
||||
}
|
||||
[data-theme="ai-stack"] .hero-dark input {
|
||||
background: white;
|
||||
border-color: transparent;
|
||||
}
|
||||
[data-theme="ai-stack"] .hero-dark .bg-secondary {
|
||||
background-color: rgba(255, 255, 255, 0.12);
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
[data-theme="ai-stack"] .hero-dark .bg-secondary:hover {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
[data-theme="ai-stack"] .group.relative {
|
||||
border-left: 3px solid transparent;
|
||||
transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
[data-theme="ai-stack"] .group.relative:hover {
|
||||
border-left-color: hsl(224 64% 40%);
|
||||
box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
/* ---------- 2. LaunchAI:橙色渐变 Banner + 活力大字 ---------- */
|
||||
[data-theme="launchai"] .hero-launch {
|
||||
background: linear-gradient(135deg, hsl(16 90% 50%) 0%, hsl(24 90% 55%) 100%);
|
||||
}
|
||||
[data-theme="launchai"] .hero-launch h1,
|
||||
[data-theme="launchai"] .hero-launch p {
|
||||
color: white;
|
||||
}
|
||||
[data-theme="launchai"] .hero-launch .text-muted-foreground {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
[data-theme="launchai"] .hero-launch a.bg-primary,
|
||||
[data-theme="launchai"] .hero-launch button.bg-primary {
|
||||
background: white;
|
||||
color: hsl(16 90% 50%);
|
||||
}
|
||||
[data-theme="launchai"] .border-l-4 { border-left-width: 4px; }
|
||||
[data-theme="launchai"] .group.relative:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* ---------- 3. The AI Ledger:黑色报头 + 报纸排版 ---------- */
|
||||
[data-theme="the-ai-ledger"] header {
|
||||
border-bottom: 3px double hsl(24 10% 12%);
|
||||
}
|
||||
[data-theme="the-ai-ledger"] section:first-of-type {
|
||||
border-bottom: 1px solid hsl(24 10% 12%);
|
||||
background: transparent;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] section:first-of-type h1 {
|
||||
font-size: clamp(2rem, 5vw, 3.5rem);
|
||||
font-weight: 900;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] .hero-mast p:first-of-type {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.35em;
|
||||
font-size: 11px;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] .group.relative:hover h3 {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
[data-theme="the-ai-ledger"] .rounded-full.bg-primary,
|
||||
[data-theme="the-ai-ledger"] a.bg-primary {
|
||||
border-radius: 1px;
|
||||
}
|
||||
/* 首页大标题区域居中双细线(报纸报头风格) */
|
||||
[data-theme="the-ai-ledger"] .border-b.border-border {
|
||||
border-bottom-style: double;
|
||||
border-bottom-width: 3px;
|
||||
}
|
||||
|
||||
/* ---------- 4. DevAI.tools:扫描线 + 终端霓虹 ---------- */
|
||||
[data-theme="devai-tools"] {
|
||||
background-image: repeating-linear-gradient(
|
||||
0deg,
|
||||
rgba(150, 60% 45% / 0.015) 0px,
|
||||
rgba(150, 60% 45% / 0.015) 1px,
|
||||
transparent 1px,
|
||||
transparent 3px
|
||||
);
|
||||
}
|
||||
[data-theme="devai-tools"] .group.relative {
|
||||
border: 1px solid hsl(218 18% 17%);
|
||||
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
[data-theme="devai-tools"] .group.relative:hover {
|
||||
border-color: hsl(150 60% 45% / 0.5);
|
||||
box-shadow: 0 0 0 1px hsl(150 60% 45% / 0.15), 0 0 24px hsl(150 60% 45% / 0.06);
|
||||
}
|
||||
[data-theme="devai-tools"] .rounded-xl.bg-primary {
|
||||
background-color: hsl(150 60% 45%);
|
||||
color: hsl(220 25% 7%);
|
||||
}
|
||||
[data-theme="devai-tools"] header .bg-secondary {
|
||||
background-color: hsl(220 20% 13%);
|
||||
}
|
||||
|
||||
/* ---------- 5. findai:聚焦光圈 + 无界卡片 ---------- */
|
||||
[data-theme="findai"] input:focus {
|
||||
box-shadow: 0 0 0 6px hsl(262 65% 52% / 0.08), 0 8px 30px hsl(262 65% 52% / 0.1);
|
||||
border-color: hsl(262 65% 52% / 0.4);
|
||||
}
|
||||
[data-theme="findai"] .group.relative:hover h3 {
|
||||
color: hsl(262 65% 52%);
|
||||
}
|
||||
[data-theme="findai"] .rounded-full.border {
|
||||
border-color: hsl(0 0% 90%);
|
||||
}
|
||||
|
||||
/* LaunchAI hero 斜切签名条 */
|
||||
[data-theme="launchai"] section:first-of-type::after {
|
||||
content: "";
|
||||
display: block;
|
||||
height: 18px;
|
||||
margin-top: -18px;
|
||||
background: hsl(var(--background));
|
||||
clip-path: polygon(0 100%, 100% 0, 100% 100%, 0 100%);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user