fix: 五站双模式色彩系统(浅/深各 10 组合全部可读)+ 硬编码色清零

- 五站各定义完整浅色+深色两套 token(background/foreground/card/secondary/
  muted/border/input/primary/ring),data-theme 挂 <html>(覆盖全部路由),
  .dark 由 next-themes 切换按钮驱动;devai-tools 默认深色(env 可配)
- 根因修复:data-theme 双重挂载(html + AuthLayout/ThemeChrome)导致
  auth 子树被浅色 token 覆盖、深色不可读 —— 只保留 html 一处
- FormShell 硬编码色清零:gradient 白卡片→bg-card、minimal 白底/灰输入/
  紫按钮→token、editorial 纸白/neutral→token、terminal 深色内联→token
  (深浅自动适配,形态保持)
- FormLabel 硬编码 #9393A3 → text-muted-foreground
- 修复 data-theme double-mount 后 label 深字深底不可读(用户报告的问题)
- 回归:10 组合(5 站×浅深)label 对比度全部达标;五站 mock 登录全部 OK
This commit is contained in:
AI Directory Platform
2026-09-10 03:39:19 +00:00
parent 3fddde470b
commit 442ce3a003
19 changed files with 223 additions and 279 deletions
+8
View File
@@ -23,6 +23,7 @@ const SITES_ROOT = path.join(REPO_ROOT, "sites");
// ==================================================================== // ====================================================================
const SITES = { const SITES = {
"ai-stack": { "ai-stack": {
themeId: "ai-stack",
authVariant: "glass", authVariant: "glass",
themeClass: "site-ai-stack", themeClass: "site-ai-stack",
brandZh: { brandZh: {
@@ -93,6 +94,7 @@ const SITES = {
}, },
}, },
launchai: { launchai: {
themeId: "launchai",
authVariant: "gradient", authVariant: "gradient",
themeClass: "site-launchai", themeClass: "site-launchai",
brandZh: { brandZh: {
@@ -161,6 +163,7 @@ const SITES = {
}, },
}, },
"the-ai-ledger": { "the-ai-ledger": {
themeId: "the-ai-ledger",
authVariant: "editorial", authVariant: "editorial",
themeClass: "site-the-ai-ledger", themeClass: "site-the-ai-ledger",
brandZh: { brandZh: {
@@ -230,6 +233,7 @@ const SITES = {
}, },
}, },
"devai-tools": { "devai-tools": {
themeId: "devai-tools",
authVariant: "terminal", authVariant: "terminal",
themeClass: "site-devai-tools", themeClass: "site-devai-tools",
brandZh: { brandZh: {
@@ -297,6 +301,7 @@ const SITES = {
}, },
}, },
findai: { findai: {
themeId: "findai",
authVariant: "minimal", authVariant: "minimal",
themeClass: "site-findai", themeClass: "site-findai",
brandZh: { brandZh: {
@@ -782,6 +787,9 @@ NEXT_PUBLIC_APP_NAME="${site.brand.name}"
# 登录页品牌模板(分栏侧栏颜色与标语) # 登录页品牌模板(分栏侧栏颜色与标语)
NEXT_PUBLIC_AUTH_ACCENT="${site.accent}" NEXT_PUBLIC_AUTH_ACCENT="${site.accent}"
NEXT_PUBLIC_AUTH_VARIANT="${site.authVariant}" NEXT_PUBLIC_AUTH_VARIANT="${site.authVariant}"
# 站点主题标识(<html data-theme>)与默认深浅(light | dark,用户可切换)
NEXT_PUBLIC_THEME_ID="${site.themeId}"
NEXT_PUBLIC_DEFAULT_THEME="${site.defaultTheme}"
NEXT_PUBLIC_AUTH_BRAND_TAGLINE="${site.brand.tagline}" NEXT_PUBLIC_AUTH_BRAND_TAGLINE="${site.brand.tagline}"
# 开发阶段免邮箱验证(生产置 false 发送真实验证邮件) # 开发阶段免邮箱验证(生产置 false 发送真实验证邮件)
DEV_SKIP_EMAIL_VERIFY="true" DEV_SKIP_EMAIL_VERIFY="true"
+1 -1
View File
@@ -94,7 +94,7 @@ const FormLabel = React.forwardRef<
<Label <Label
ref={ref} ref={ref}
className={cn( className={cn(
"text-[#9393A3] pb-0 text-sm", "text-muted-foreground pb-0 text-sm",
error && "text-destructive", error && "text-destructive",
className className
)} )}
@@ -61,7 +61,7 @@ export function SocialAuthButtons({
const loading = isLoading || mockLoading !== null; const loading = isLoading || mockLoading !== null;
const btnClass = const btnClass =
"flex w-full items-center justify-center gap-2.5 rounded-lg border border-border bg-background px-4 py-2.5 text-[0.95rem] font-medium text-foreground transition-colors hover:bg-secondary/60 disabled:opacity-50"; "flex w-full items-center justify-center gap-2.5 rounded-lg border border-border bg-transparent px-4 py-2.5 text-[0.95rem] font-medium text-foreground transition-colors hover:bg-secondary/60 disabled:opacity-50";
return ( return (
<div className="flex w-full flex-col gap-2.5"> <div className="flex w-full flex-col gap-2.5">
@@ -85,7 +85,7 @@ export function FormShell<TFieldValues extends FieldValues>({
if (variant === "glass") { if (variant === "glass") {
return ( return (
<Form {...form}> <Form {...form}>
<div className="relative flex min-h-screen w-full items-center justify-center overflow-hidden bg-[linear-gradient(160deg,hsl(224_60%_12%),hsl(224_55%_22%)_60%,hsl(210_45%_30%))] px-4 py-12"> <div className="dark relative flex min-h-screen w-full items-center justify-center overflow-hidden bg-[linear-gradient(160deg,hsl(224_60%_12%),hsl(224_55%_22%)_60%,hsl(210_45%_30%))] px-4 py-12">
<div className="pointer-events-none absolute -left-40 -top-40 h-96 w-96 rounded-full bg-blue-400/10 blur-3xl" /> <div className="pointer-events-none absolute -left-40 -top-40 h-96 w-96 rounded-full bg-blue-400/10 blur-3xl" />
<div className="pointer-events-none absolute -bottom-40 -right-40 h-96 w-96 rounded-full bg-indigo-400/10 blur-3xl" /> <div className="pointer-events-none absolute -bottom-40 -right-40 h-96 w-96 rounded-full bg-indigo-400/10 blur-3xl" />
<div className="relative w-full max-w-md rounded-2xl border border-white/15 bg-white/[0.08] p-8 shadow-2xl backdrop-blur-xl sm:p-10"> <div className="relative w-full max-w-md rounded-2xl border border-white/15 bg-white/[0.08] p-8 shadow-2xl backdrop-blur-xl sm:p-10">
@@ -118,7 +118,7 @@ export function FormShell<TFieldValues extends FieldValues>({
className="relative flex min-h-screen w-full items-center justify-center px-4 py-12" className="relative flex min-h-screen w-full items-center justify-center px-4 py-12"
style={{ background: `linear-gradient(140deg, hsl(${accent}) 0%, hsl(28 90% 55%) 100%)` }} style={{ background: `linear-gradient(140deg, hsl(${accent}) 0%, hsl(28 90% 55%) 100%)` }}
> >
<div className="w-full max-w-md rounded-3xl bg-white p-8 shadow-[0_24px_70px_rgba(0,0,0,0.25)] sm:p-10"> <div className="w-full max-w-md rounded-3xl bg-card p-8 shadow-[0_24px_70px_rgba(0,0,0,0.25)] sm:p-10">
<div className="mb-7 flex items-center gap-2.5"> <div className="mb-7 flex items-center gap-2.5">
<span <span
className="flex h-10 w-10 items-center justify-center rounded-2xl text-lg font-bold text-white" className="flex h-10 w-10 items-center justify-center rounded-2xl text-lg font-bold text-white"
@@ -134,7 +134,7 @@ export function FormShell<TFieldValues extends FieldValues>({
{socialSlot} {socialSlot}
{children} {children}
{errorBox} {errorBox}
{submitBtn(`w-full rounded-2xl py-3.5 text-base font-bold text-white transition hover:opacity-90 disabled:opacity-60`)} {submitBtn("w-full rounded-2xl bg-primary py-3.5 text-base font-bold text-primary-foreground transition hover:opacity-90 disabled:opacity-60")}
</form> </form>
{footerNode} {footerNode}
</div> </div>
@@ -146,18 +146,18 @@ export function FormShell<TFieldValues extends FieldValues>({
/* ================= 3. The AI Ledger:报纸头版 + 下划线输入 ================= */ /* ================= 3. The AI Ledger:报纸头版 + 下划线输入 ================= */
if (variant === "editorial") { if (variant === "editorial") {
const lineInput = const lineInput =
"w-full border-0 border-b-2 border-neutral-300 bg-transparent px-0 py-2 text-lg font-serif text-neutral-900 placeholder:text-neutral-400 focus:border-neutral-900 focus:outline-none rounded-none"; "auth-input w-full border-0 border-b-2 bg-transparent px-0 py-2 text-lg font-serif text-foreground placeholder:text-muted-foreground focus:outline-none rounded-none";
return ( return (
<Form {...form}> <Form {...form}>
<div className="min-h-screen w-full bg-[hsl(42_45%_97%)] px-4 py-10 font-serif text-neutral-900"> <div className="min-h-screen w-full bg-background px-4 py-10 text-foreground">
<div className="mx-auto max-w-xl"> <div className="mx-auto max-w-xl">
{/* 报头 */} {/* 报头 */}
<div className="border-y-[3px] border-double border-neutral-900 py-3 text-center"> <div className="border-y-[3px] border-double border-foreground py-3 text-center">
<p className="text-[10px] uppercase tracking-[0.35em] text-neutral-500"> <p className="text-[10px] uppercase tracking-[0.35em] text-muted-foreground">
{new Date().toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" })} {new Date().toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" })}
</p> </p>
<h1 className="mt-1 text-4xl font-black tracking-tight">{brand}</h1> <h1 className="mt-1 text-4xl font-black tracking-tight">{brand}</h1>
<p className="mt-1 text-[10px] uppercase tracking-[0.35em] text-neutral-500">{tagline}</p> <p className="mt-1 text-[10px] uppercase tracking-[0.35em] text-muted-foreground">{tagline}</p>
</div> </div>
<h2 className="mt-10 text-center text-2xl font-bold">{title}</h2> <h2 className="mt-10 text-center text-2xl font-bold">{title}</h2>
@@ -165,11 +165,11 @@ export function FormShell<TFieldValues extends FieldValues>({
{socialSlot} {socialSlot}
{children} {children}
{errorBox} {errorBox}
{submitBtn("w-full border-2 border-neutral-900 bg-neutral-900 py-3 text-sm font-bold uppercase tracking-[0.2em] text-white transition hover:bg-transparent hover:text-neutral-900 disabled:opacity-60")} {submitBtn("w-full border-2 border-foreground bg-foreground py-3 text-sm font-bold uppercase tracking-[0.2em] text-background transition hover:bg-transparent hover:text-foreground disabled:opacity-60")}
</form> </form>
{footerNode} {footerNode}
</div> </div>
<div className="mx-auto mt-12 max-w-xl border-t border-neutral-300 pt-4 text-center text-[10px] uppercase tracking-[0.3em] text-neutral-400"> <div className="mx-auto mt-12 max-w-xl border-t border-border pt-4 text-center text-[10px] uppercase tracking-[0.3em] text-muted-foreground">
© {new Date().getFullYear()} {brand} © {new Date().getFullYear()} {brand}
</div> </div>
</div> </div>
@@ -180,28 +180,27 @@ export function FormShell<TFieldValues extends FieldValues>({
/* ================= 4. DevAI.tools:深色终端窗口 ================= */ /* ================= 4. DevAI.tools:深色终端窗口 ================= */
if (variant === "terminal") { if (variant === "terminal") {
const termInput = const termInput =
"w-full rounded border border-emerald-500/30 bg-black/50 px-3 py-2.5 font-mono text-sm text-emerald-100 placeholder:text-emerald-100/30 focus:border-emerald-400/70 focus:outline-none rounded-md"; "auth-input w-full rounded-md border border-border bg-card px-3 py-2.5 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:border-primary/70 focus:outline-none";
const termLabel = "mb-1 block font-mono text-xs text-emerald-500/80";
return ( return (
<Form {...form}> <Form {...form}>
<div className="flex min-h-screen w-full items-center justify-center bg-[hsl(220_25%_7%)] px-4 py-12"> <div className="flex min-h-screen w-full items-center justify-center bg-background px-4 py-12">
<div className="w-full max-w-lg overflow-hidden rounded-lg border border-emerald-500/20 bg-[hsl(220_25%_9%)] shadow-[0_0_40px_rgba(16,185,129,0.06)]"> <div className="w-full max-w-lg overflow-hidden rounded-lg border border-primary/20 bg-card shadow-[0_0_40px_rgba(16,185,129,0.06)]">
{/* 终端标题栏 */} {/* 终端标题栏 */}
<div className="flex items-center gap-2 border-b border-emerald-500/15 bg-black/40 px-4 py-3"> <div className="flex items-center gap-2 border-b border-border bg-secondary/60 px-4 py-3">
<span className="h-3 w-3 rounded-full bg-red-500/80" /> <span className="h-3 w-3 rounded-full bg-red-500/80" />
<span className="h-3 w-3 rounded-full bg-yellow-500/80" /> <span className="h-3 w-3 rounded-full bg-yellow-500/80" />
<span className="h-3 w-3 rounded-full bg-emerald-500/80" /> <span className="h-3 w-3 rounded-full bg-emerald-500/80" />
<span className="ml-3 font-mono text-xs text-emerald-100/50">{brand.toLowerCase()} — auth</span> <span className="ml-3 font-mono text-xs text-muted-foreground">{brand.toLowerCase()} — auth</span>
</div> </div>
<div className="p-7"> <div className="p-7">
<p className="font-mono text-sm text-emerald-400/90"> <p className="font-mono text-sm text-primary/90">
<span className="text-emerald-600">$</span> {brand.toLowerCase()} auth --login <span className="text-primary/50">$</span> {brand.toLowerCase()} auth --login
</p> </p>
<form onSubmit={form.handleSubmit(onSubmit)} className="mt-6 space-y-5"> <form onSubmit={form.handleSubmit(onSubmit)} className="mt-6 space-y-5">
{socialSlot} {socialSlot}
{children} {children}
{errorBox} {errorBox}
{submitBtn("w-full rounded-md bg-emerald-500 py-3 font-mono text-sm font-bold text-black transition hover:bg-emerald-400 disabled:opacity-60")} {submitBtn("w-full rounded-md bg-primary py-3 font-mono text-sm font-bold text-primary-foreground transition hover:opacity-90 disabled:opacity-60")}
</form> </form>
{footerNode} {footerNode}
</div> </div>
@@ -214,25 +213,25 @@ export function FormShell<TFieldValues extends FieldValues>({
/* ================= 5. findai:纯白极简居中 ================= */ /* ================= 5. findai:纯白极简居中 ================= */
if (variant === "minimal") { if (variant === "minimal") {
const softInput = const softInput =
"w-full rounded-2xl border border-transparent bg-neutral-100 px-5 py-4 text-base text-foreground placeholder:text-neutral-400 focus:border-violet-300 focus:bg-white focus:outline-none focus:ring-4 focus:ring-violet-500/10 transition rounded-2xl"; "auth-input w-full rounded-2xl border border-transparent bg-muted px-5 py-4 text-base text-foreground placeholder:text-muted-foreground focus:border-primary/40 focus:outline-none focus:ring-4 focus:ring-primary/10 transition";
return ( return (
<Form {...form}> <Form {...form}>
<div className="flex min-h-screen w-full flex-col items-center justify-center bg-white px-4 py-12"> <div className="flex min-h-screen w-full flex-col items-center justify-center bg-background px-4 py-12">
<span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-violet-600 text-xl font-bold text-white"> <span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-primary text-xl font-bold text-primary-foreground">
{initial} {initial}
</span> </span>
<h1 className="mt-6 text-3xl font-bold tracking-tight text-foreground">{brand}</h1> <h1 className="mt-6 text-3xl font-bold tracking-tight text-foreground">{brand}</h1>
<p className="mt-2 text-sm text-neutral-400">{tagline}</p> <p className="mt-2 text-sm text-muted-foreground">{tagline}</p>
<div className="mt-10 w-full max-w-sm"> <div className="mt-10 w-full max-w-sm">
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4"> <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
{socialSlot} {socialSlot}
{children} {children}
{errorBox} {errorBox}
{submitBtn("w-full rounded-2xl bg-violet-600 py-4 text-base font-semibold text-white transition hover:bg-violet-700 disabled:opacity-60")} {submitBtn("w-full rounded-2xl bg-primary py-4 text-base font-semibold text-primary-foreground transition hover:opacity-90 disabled:opacity-60")}
</form> </form>
{footerNode} {footerNode}
</div> </div>
<p className="mt-16 text-xs text-neutral-300">{brand} — search, ranked by people</p> <p className="mt-16 text-xs text-muted-foreground/60">{brand} — search, ranked by people</p>
</div> </div>
</Form> </Form>
); );
+1 -5
View File
@@ -48,11 +48,7 @@ export async function SiteChrome({
const footerGroups = footerGroupsRaw ?? config.footerGroups; const footerGroups = footerGroupsRaw ?? config.footerGroups;
return ( return (
<div <div className={config.themeClass} style={config.cssVars as React.CSSProperties}>
data-theme={config.id}
className={config.themeClass}
style={config.cssVars as React.CSSProperties}
>
<ThemeHeader <ThemeHeader
brand={brand} brand={brand}
navItems={navItems} navItems={navItems}
+4
View File
@@ -36,6 +36,10 @@ export interface SiteConfig {
themeClass?: string; themeClass?: string;
/** 登录页布局变体:五站五种形态 */ /** 登录页布局变体:五站五种形态 */
authVariant?: "glass" | "gradient" | "editorial" | "terminal" | "minimal" | "split"; authVariant?: "glass" | "gradient" | "editorial" | "terminal" | "minimal" | "split";
/** 站点主题标识(<html data-theme>,与 globals.css 的 token 组对应) */
themeId?: string;
/** 默认深浅主题(light | dark,用户可通过模式切换按钮更改) */
defaultTheme?: "light" | "dark";
/** 中文品牌文案(导航/页脚/hero/搜索占位) */ /** 中文品牌文案(导航/页脚/hero/搜索占位) */
brandZh?: { brandZh?: {
name?: string; name?: string;
+3 -20
View File
@@ -3,26 +3,9 @@
/** /**
* # 组件 AuthLayout * # 组件 AuthLayout
* 说明:认证页容器。布局职责在 FormShell(六种布局变体); * 说明:认证页容器。布局职责在 FormShell(六种布局变体);
* 这里注入 data-theme(由 NEXT_PUBLIC_AUTH_VARIANT 映射), * data-theme 由 <html>(locale layout)统一注入,此处不再重复挂载,
* 使输入框/标签/按钮的站点主题化样式(globals.css)在 auth 路由组生效。 * 避免子树覆盖 html 的深浅 token 组合。
*/ */
const VARIANT_THEME: Record<string, string> = {
glass: "ai-stack",
gradient: "launchai",
editorial: "the-ai-ledger",
terminal: "devai-tools",
minimal: "findai",
split: "ai-stack",
};
export function AuthLayout({ children }: { children: React.ReactNode }) { export function AuthLayout({ children }: { children: React.ReactNode }) {
const variant = process.env.NEXT_PUBLIC_AUTH_VARIANT || "glass"; return <div className="min-h-screen w-full">{children}</div>;
return (
<div
data-theme={VARIANT_THEME[variant] ?? "ai-stack"}
className="min-h-screen w-full"
>
{children}
</div>
);
} }
+6 -2
View File
@@ -32,7 +32,11 @@ export default async function LocaleLayout({
return ( return (
<ViewTransitions> <ViewTransitions>
<html lang={locale} suppressHydrationWarning> <html
lang={locale}
suppressHydrationWarning
data-theme={process.env.NEXT_PUBLIC_THEME_ID || "ai-stack"}
>
<body <body
className={cn( className={cn(
GeistSans.className, GeistSans.className,
@@ -46,7 +50,7 @@ export default async function LocaleLayout({
attribute="class" attribute="class"
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
defaultTheme="light" defaultTheme={process.env.NEXT_PUBLIC_DEFAULT_THEME || "light"}
> >
<NextIntlClientProvider locale={locale} messages={messages}> <NextIntlClientProvider locale={locale} messages={messages}>
{children} {children}
+155 -225
View File
@@ -121,52 +121,112 @@ html {
} }
/* ============================================================ /* ============================================================
五站视觉签名(Site Identity Layers) 五站设计系统 —— 双模式(浅色 / 深色)完整色彩 token + 形态层
每个网站一套独立设计语言:字体 / 底色 / 圆角 / 边框 / 按钮形态 data-theme 由站点环境变量注入 <html>;.dark 由 next-themes 切换
由 SiteChrome 的 data-theme 驱动,仅作用于主题表现层
============================================================ */ ============================================================ */
/* ---------- 1. AI Stack(classic):深蓝专业 SaaS ---------- /* ---------- 1. AI Stack:深蓝专业(浅:白底蓝主色 / 深:海军蓝) ---------- */
密度较高、细边框、轻阴影、蓝色主色 */
[data-theme="ai-stack"] { [data-theme="ai-stack"] {
--primary: 224 64% 33%; --primary: 224 64% 33%;
--primary-foreground: 0 0% 100%; --primary-foreground: 0 0% 100%;
--ring: 224 64% 33%; --ring: 224 64% 33%;
--radius: 0.625rem;
} }
[data-theme="ai-stack"] .rounded-xl, [data-theme="ai-stack"].dark {
[data-theme="ai-stack"] .rounded-2xl { --background: 224 45% 10%;
border-radius: 0.625rem; --foreground: 210 30% 94%;
--card: 224 40% 13%;
--secondary: 223 35% 17%;
--muted: 223 35% 16%;
--muted-foreground: 215 20% 68%;
--border: 222 28% 22%;
--input: 222 28% 22%;
--primary: 224 70% 62%;
--primary-foreground: 224 50% 10%;
--ring: 224 70% 62%;
} }
[data-theme="ai-stack"] .group.relative.rounded-xl { [data-theme="ai-stack"] .rounded-xl { border-radius: 0.625rem; }
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); [data-theme="ai-stack"] .hero-dark {
background: linear-gradient(180deg, hsl(224 55% 12%) 0%, hsl(224 50% 20%) 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.7); }
[data-theme="ai-stack"] .hero-dark input {
background: white;
border-color: transparent;
color: hsl(224 40% 15%);
}
[data-theme="ai-stack"] .hero-dark input::placeholder { color: hsl(220 15% 55%); }
[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"] .group.relative {
border-left: 3px solid transparent;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
[data-theme="ai-stack"] .group.relative:hover {
border-left-color: hsl(var(--primary));
box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08);
} }
/* ---------- 2. LaunchAI(product):暖橙活力社区 ---------- /* ---------- 2. LaunchAI:暖橙社区(浅:暖白橙 / 深:深棕橙) ---------- */
暖白底、胶囊按钮、大圆角卡片、橙色主色 */
[data-theme="launchai"] { [data-theme="launchai"] {
--primary: 16 85% 53%; --primary: 16 85% 50%;
--primary-foreground: 0 0% 100%; --primary-foreground: 0 0% 100%;
--background: 30 55% 97%; --background: 30 55% 97%;
--secondary: 28 50% 92%; --secondary: 28 50% 92%;
--ring: 16 85% 53%; --ring: 16 85% 50%;
--radius: 1.1rem;
} }
[data-theme="launchai"] .bg-background { [data-theme="launchai"].dark {
background-color: hsl(var(--background)); --background: 20 30% 8%;
--foreground: 30 40% 92%;
--card: 20 25% 11%;
--secondary: 20 22% 15%;
--muted: 20 22% 14%;
--muted-foreground: 28 15% 66%;
--border: 22 20% 20%;
--input: 22 20% 20%;
--primary: 20 90% 56%;
--ring: 20 90% 56%;
} }
[data-theme="launchai"] .rounded-xl { border-radius: 1.1rem; } [data-theme="launchai"] h1, [data-theme="launchai"] h2 { letter-spacing: -0.02em; }
[data-theme="launchai"] .rounded-2xl { border-radius: 1.4rem; } [data-theme="launchai"] .hero-launch {
[data-theme="launchai"] h1, [data-theme="launchai"] h2 { background: linear-gradient(135deg, hsl(16 90% 48%) 0%, hsl(26 90% 52%) 100%);
letter-spacing: -0.02em; }
[data-theme="launchai"].dark .hero-launch {
background: linear-gradient(135deg, hsl(16 80% 38%) 0%, hsl(26 80% 42%) 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% 46%);
} }
/* ---------- 3. The AI Ledger(editorial):报纸编辑风 ---------- /* ---------- 3. The AI Ledger:报纸(浅:纸白墨黑 / 深:炭黑米白) ---------- */
纸白底、衬线字体、直角、黑主色、无阴影、粗黑分隔 */
[data-theme="the-ai-ledger"] { [data-theme="the-ai-ledger"] {
--primary: 24 10% 12%; --primary: 24 10% 12%;
--primary-foreground: 40 40% 98%; --primary-foreground: 40 40% 98%;
--background: 42 45% 97%; --background: 42 45% 97%;
--border: 30 10% 82%; --foreground: 24 10% 12%;
--radius: 0px; --border: 30 10% 80%;
--radius: 1px;
}
[data-theme="the-ai-ledger"].dark {
--background: 30 8% 9%;
--foreground: 40 30% 92%;
--card: 30 8% 12%;
--secondary: 30 6% 15%;
--muted: 30 6% 14%;
--muted-foreground: 40 15% 65%;
--border: 35 10% 26%;
--primary: 40 30% 92%;
--primary-foreground: 30 10% 10%;
} }
[data-theme="the-ai-ledger"] { [data-theme="the-ai-ledger"] {
font-family: Georgia, "Times New Roman", "Noto Serif SC", serif; font-family: Georgia, "Times New Roman", "Noto Serif SC", serif;
@@ -175,45 +235,47 @@ html {
[data-theme="the-ai-ledger"] h2, [data-theme="the-ai-ledger"] h2,
[data-theme="the-ai-ledger"] h3 { [data-theme="the-ai-ledger"] h3 {
font-family: Georgia, "Times New Roman", "Noto Serif SC", serif; 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-full,
[data-theme="the-ai-ledger"] .rounded-xl, [data-theme="the-ai-ledger"] .rounded-xl,
[data-theme="the-ai-ledger"] .rounded-2xl, [data-theme="the-ai-ledger"] .rounded-2xl,
[data-theme="the-ai-ledger"] .rounded-lg { [data-theme="the-ai-ledger"] .rounded-lg { border-radius: 1px; }
border-radius: 1px;
}
[data-theme="the-ai-ledger"] .shadow, [data-theme="the-ai-ledger"] .shadow,
[data-theme="the-ai-ledger"] .shadow-sm, [data-theme="the-ai-ledger"] .shadow-sm,
[data-theme="the-ai-ledger"] .shadow-lg { [data-theme="the-ai-ledger"] .shadow-lg { box-shadow: none; }
box-shadow: none; [data-theme="the-ai-ledger"] header { border-bottom: 3px double hsl(var(--border)); }
} [data-theme="the-ai-ledger"] .hero-mast p:first-of-type {
[data-theme="the-ai-ledger"] .bg-primary, text-transform: uppercase;
[data-theme="the-ai-ledger"] .hover\:bg-primary { letter-spacing: 0.35em;
background-color: hsl(24 10% 12%); font-size: 11px;
}
[data-theme="the-ai-ledger"] header .rounded-lg {
border-radius: 1px;
} }
[data-theme="the-ai-ledger"] .group.relative:hover h3 { text-decoration: underline; text-underline-offset: 3px; }
/* ---------- 4. DevAI.tools(niche):深色终端 ---------- /* ---------- 4. DevAI.tools:终端(深:默认深色 / 浅:日间终端) ---------- */
深色底、等宽字体、绿色主色、代码面板感 */
[data-theme="devai-tools"] { [data-theme="devai-tools"] {
--primary: 150 60% 38%;
--primary-foreground: 0 0% 100%;
--background: 150 20% 97%;
--foreground: 200 25% 15%;
--card: 0 0% 100%;
--secondary: 150 15% 92%;
--muted: 150 15% 92%;
--muted-foreground: 200 15% 40%;
--border: 150 15% 82%;
--ring: 150 60% 38%;
}
[data-theme="devai-tools"].dark {
--background: 220 25% 7%; --background: 220 25% 7%;
--foreground: 210 20% 92%; --foreground: 210 20% 92%;
--primary: 150 60% 45%; --card: 220 25% 9%;
--primary-foreground: 220 25% 7%;
--secondary: 220 20% 13%; --secondary: 220 20% 13%;
--muted: 220 20% 13%; --muted: 220 20% 13%;
--muted-foreground: 215 15% 62%; --muted-foreground: 215 15% 62%;
--border: 218 18% 17%; --border: 218 18% 17%;
--input: 218 18% 17%;
--primary: 150 60% 45%;
--primary-foreground: 220 25% 7%;
--ring: 150 60% 45%; --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"] h1,
[data-theme="devai-tools"] h2, [data-theme="devai-tools"] h2,
@@ -222,166 +284,50 @@ html {
font-family: ui-monospace, "SF Mono", Menlo, monospace; font-family: ui-monospace, "SF Mono", Menlo, monospace;
letter-spacing: -0.01em; letter-spacing: -0.01em;
} }
[data-theme="devai-tools"] .bg-background, [data-theme="devai-tools"].dark {
background-image: repeating-linear-gradient(
0deg,
hsl(150 60% 45% / 0.015) 0px,
hsl(150 60% 45% / 0.015) 1px,
transparent 1px,
transparent 3px
);
}
[data-theme="devai-tools"] .group.relative { [data-theme="devai-tools"] .group.relative {
background-color: hsl(220 25% 9%); border: 1px solid hsl(var(--border));
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
[data-theme="devai-tools"].dark .group.relative:hover {
border-color: hsl(150 60% 45% / 0.5);
box-shadow: 0 0 24px hsl(150 60% 45% / 0.06);
} }
[data-theme="devai-tools"] .rounded-xl { border-radius: 0.5rem; }
[data-theme="devai-tools"] .text-primary { color: hsl(150 60% 45%); }
/* ---------- 5. findai(minimal):极简紫 ---------- /* ---------- 5. findai:极简(浅:纯白紫 / 深:深紫黑) ---------- */
纯白、无边框卡片、细分隔、紫罗兰、大留白 */
[data-theme="findai"] { [data-theme="findai"] {
--primary: 262 65% 52%; --primary: 262 65% 52%;
--primary-foreground: 0 0% 100%; --primary-foreground: 0 0% 100%;
--ring: 262 65% 52%; --ring: 262 65% 52%;
} }
[data-theme="findai"].dark {
--background: 262 30% 7%;
--foreground: 260 30% 92%;
--card: 262 25% 10%;
--secondary: 262 20% 14%;
--muted: 262 20% 13%;
--muted-foreground: 260 15% 66%;
--border: 262 18% 20%;
--ring: 262 65% 60%;
--primary: 262 80% 64%;
}
[data-theme="findai"] .group.relative { [data-theme="findai"] .group.relative {
border-color: transparent; border-color: transparent;
box-shadow: none; box-shadow: none;
transition: background-color 0.15s ease; transition: background-color 0.15s ease;
} }
[data-theme="findai"] .group.relative:hover { [data-theme="findai"] .group.relative:hover { background-color: hsl(var(--muted)); }
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 { [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); box-shadow: 0 0 0 6px hsl(var(--primary) / 0.08), 0 8px 30px hsl(var(--primary) / 0.1);
border-color: hsl(262 65% 52% / 0.4); border-color: hsl(var(--primary) / 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%);
} }
/* ============================================================ /* ============================================================
@@ -392,7 +338,7 @@ html {
[data-theme="the-ai-ledger"] .auth-input { [data-theme="the-ai-ledger"] .auth-input {
border-radius: 0; border-radius: 0;
border: 0; border: 0;
border-bottom: 2px solid hsl(24 10% 70%); border-bottom: 2px solid hsl(var(--border));
background: transparent; background: transparent;
font-family: Georgia, "Times New Roman", serif; font-family: Georgia, "Times New Roman", serif;
font-size: 1.05rem; font-size: 1.05rem;
@@ -400,56 +346,43 @@ html {
padding-right: 0; padding-right: 0;
} }
[data-theme="the-ai-ledger"] .auth-input:focus { [data-theme="the-ai-ledger"] .auth-input:focus {
border-bottom-color: hsl(24 10% 12%); border-bottom-color: hsl(var(--foreground));
box-shadow: none; box-shadow: none;
} }
[data-theme="the-ai-ledger"] form button[type="submit"], [data-theme="the-ai-ledger"] form button[type="submit"],
[data-theme="the-ai-ledger"] form .rounded-lg { [data-theme="the-ai-ledger"] form .rounded-lg { border-radius: 1px; }
border-radius: 1px;
}
[data-theme="the-ai-ledger"] form label {
font-family: Georgia, serif;
letter-spacing: 0.02em;
}
/* DevAI.tools:终端等宽输入 */ /* DevAI.tools:终端等宽输入 */
[data-theme="devai-tools"] .auth-input { [data-theme="devai-tools"] .auth-input {
border-radius: 0.375rem; border-radius: 0.375rem;
border: 1px solid hsl(150 60% 45% / 0.3); border: 1px solid hsl(var(--border));
background: rgba(0, 0, 0, 0.45); background: hsl(var(--card));
font-family: ui-monospace, "SF Mono", Menlo, monospace; font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
[data-theme="devai-tools"].dark .auth-input {
color: hsl(150 40% 88%); color: hsl(150 40% 88%);
border-color: hsl(150 60% 45% / 0.3);
background: rgba(0, 0, 0, 0.45);
} }
[data-theme="devai-tools"] .auth-input::placeholder { [data-theme="devai-tools"].dark .auth-input::placeholder { color: hsl(150 30% 50% / 0.4); }
color: hsl(150 30% 50% / 0.4); [data-theme="devai-tools"].dark .auth-input:focus {
}
[data-theme="devai-tools"] .auth-input:focus {
border-color: hsl(150 60% 45% / 0.7); border-color: hsl(150 60% 45% / 0.7);
box-shadow: 0 0 0 3px hsl(150 60% 45% / 0.1); box-shadow: 0 0 0 3px hsl(150 60% 45% / 0.1);
} }
[data-theme="devai-tools"] form label { [data-theme="devai-tools"] form label { font-size: 0.8rem; }
[data-theme="devai-tools"].dark form label {
font-family: ui-monospace, Menlo, monospace; font-family: ui-monospace, Menlo, monospace;
font-size: 0.75rem; font-size: 0.75rem;
color: hsl(150 40% 60% / 0.85); color: hsl(150 40% 60% / 0.85);
} }
[data-theme="devai-tools"] form .rounded-lg {
border-radius: 0.375rem;
border-color: hsl(150 60% 45% / 0.25);
background: rgba(0, 0, 0, 0.3);
}
/* findai:大圆角浅灰底输入 */ /* findai:大圆角浅灰输入 */
[data-theme="findai"] .auth-input { [data-theme="findai"] .auth-input {
border-radius: 1rem; border-radius: 1rem;
background: hsl(0 0% 96%); background: hsl(0 0% 96%);
} }
[data-theme="findai"] .auth-input:focus { [data-theme="findai"].dark .auth-input { background: hsl(var(--card)); }
background: white; [data-theme="findai"] .auth-input:focus { background: hsl(var(--background)); }
box-shadow: 0 0 0 4px hsl(262 65% 52% / 0.1);
}
[data-theme="findai"] form .rounded-lg {
border-radius: 1rem;
}
/* LaunchAI:大圆角输入 */ /* LaunchAI:大圆角输入 */
[data-theme="launchai"] .auth-input { [data-theme="launchai"] .auth-input {
@@ -457,6 +390,3 @@ html {
padding-top: 0.75rem; padding-top: 0.75rem;
padding-bottom: 0.75rem; padding-bottom: 0.75rem;
} }
[data-theme="launchai"] form .rounded-lg {
border-radius: 0.875rem;
}
+3
View File
@@ -15,6 +15,9 @@ NEXT_PUBLIC_APP_NAME="AI Stack"
# 登录页品牌模板(分栏侧栏颜色与标语) # 登录页品牌模板(分栏侧栏颜色与标语)
NEXT_PUBLIC_AUTH_ACCENT="222 47% 11%" NEXT_PUBLIC_AUTH_ACCENT="222 47% 11%"
NEXT_PUBLIC_AUTH_VARIANT="glass" NEXT_PUBLIC_AUTH_VARIANT="glass"
# 站点主题标识(<html data-theme>)与默认深浅(light | dark,用户可切换)
NEXT_PUBLIC_THEME_ID="ai-stack"
NEXT_PUBLIC_DEFAULT_THEME="undefined"
NEXT_PUBLIC_AUTH_BRAND_TAGLINE="The professional AI tools directory — ranked by the community." NEXT_PUBLIC_AUTH_BRAND_TAGLINE="The professional AI tools directory — ranked by the community."
# 开发阶段免邮箱验证(生产置 false 发送真实验证邮件) # 开发阶段免邮箱验证(生产置 false 发送真实验证邮件)
DEV_SKIP_EMAIL_VERIFY="true" DEV_SKIP_EMAIL_VERIFY="true"
+1
View File
@@ -2,6 +2,7 @@ import type { SiteConfig } from "@/kit/types";
// AI Stack —— 独立站点的全部品牌/导航/页脚配置 // AI Stack —— 独立站点的全部品牌/导航/页脚配置
export const siteConfig: SiteConfig = { export const siteConfig: SiteConfig = {
"themeId": "ai-stack",
"authVariant": "glass", "authVariant": "glass",
"themeClass": "site-ai-stack", "themeClass": "site-ai-stack",
"brandZh": { "brandZh": {
+3
View File
@@ -15,6 +15,9 @@ NEXT_PUBLIC_APP_NAME="DevAI.tools"
# 登录页品牌模板(分栏侧栏颜色与标语) # 登录页品牌模板(分栏侧栏颜色与标语)
NEXT_PUBLIC_AUTH_ACCENT="150 60% 30%" NEXT_PUBLIC_AUTH_ACCENT="150 60% 30%"
NEXT_PUBLIC_AUTH_VARIANT="terminal" NEXT_PUBLIC_AUTH_VARIANT="terminal"
# 站点主题标识(<html data-theme>)与默认深浅(light | dark,用户可切换)
NEXT_PUBLIC_THEME_ID="devai-tools"
NEXT_PUBLIC_DEFAULT_THEME="undefined"
NEXT_PUBLIC_AUTH_BRAND_TAGLINE="AI tools for developers — curated, tested, ranked by the community." NEXT_PUBLIC_AUTH_BRAND_TAGLINE="AI tools for developers — curated, tested, ranked by the community."
# 开发阶段免邮箱验证(生产置 false 发送真实验证邮件) # 开发阶段免邮箱验证(生产置 false 发送真实验证邮件)
DEV_SKIP_EMAIL_VERIFY="true" DEV_SKIP_EMAIL_VERIFY="true"
+1
View File
@@ -2,6 +2,7 @@ import type { SiteConfig } from "@/kit/types";
// DevAI.tools —— 独立站点的全部品牌/导航/页脚配置 // DevAI.tools —— 独立站点的全部品牌/导航/页脚配置
export const siteConfig: SiteConfig = { export const siteConfig: SiteConfig = {
"themeId": "devai-tools",
"authVariant": "terminal", "authVariant": "terminal",
"themeClass": "site-devai-tools", "themeClass": "site-devai-tools",
"brandZh": { "brandZh": {
+3
View File
@@ -15,6 +15,9 @@ NEXT_PUBLIC_APP_NAME="findai"
# 登录页品牌模板(分栏侧栏颜色与标语) # 登录页品牌模板(分栏侧栏颜色与标语)
NEXT_PUBLIC_AUTH_ACCENT="260 70% 52%" NEXT_PUBLIC_AUTH_ACCENT="260 70% 52%"
NEXT_PUBLIC_AUTH_VARIANT="minimal" NEXT_PUBLIC_AUTH_VARIANT="minimal"
# 站点主题标识(<html data-theme>)与默认深浅(light | dark,用户可切换)
NEXT_PUBLIC_THEME_ID="findai"
NEXT_PUBLIC_DEFAULT_THEME="undefined"
NEXT_PUBLIC_AUTH_BRAND_TAGLINE="The minimal AI tool search engine." NEXT_PUBLIC_AUTH_BRAND_TAGLINE="The minimal AI tool search engine."
# 开发阶段免邮箱验证(生产置 false 发送真实验证邮件) # 开发阶段免邮箱验证(生产置 false 发送真实验证邮件)
DEV_SKIP_EMAIL_VERIFY="true" DEV_SKIP_EMAIL_VERIFY="true"
+1
View File
@@ -2,6 +2,7 @@ import type { SiteConfig } from "@/kit/types";
// findai —— 独立站点的全部品牌/导航/页脚配置 // findai —— 独立站点的全部品牌/导航/页脚配置
export const siteConfig: SiteConfig = { export const siteConfig: SiteConfig = {
"themeId": "findai",
"authVariant": "minimal", "authVariant": "minimal",
"themeClass": "site-findai", "themeClass": "site-findai",
"brandZh": { "brandZh": {
+3
View File
@@ -15,6 +15,9 @@ NEXT_PUBLIC_APP_NAME="LaunchAI"
# 登录页品牌模板(分栏侧栏颜色与标语) # 登录页品牌模板(分栏侧栏颜色与标语)
NEXT_PUBLIC_AUTH_ACCENT="16 85% 55%" NEXT_PUBLIC_AUTH_ACCENT="16 85% 55%"
NEXT_PUBLIC_AUTH_VARIANT="gradient" NEXT_PUBLIC_AUTH_VARIANT="gradient"
# 站点主题标识(<html data-theme>)与默认深浅(light | dark,用户可切换)
NEXT_PUBLIC_THEME_ID="launchai"
NEXT_PUBLIC_DEFAULT_THEME="undefined"
NEXT_PUBLIC_AUTH_BRAND_TAGLINE="Discover and upvote today's AI products." NEXT_PUBLIC_AUTH_BRAND_TAGLINE="Discover and upvote today's AI products."
# 开发阶段免邮箱验证(生产置 false 发送真实验证邮件) # 开发阶段免邮箱验证(生产置 false 发送真实验证邮件)
DEV_SKIP_EMAIL_VERIFY="true" DEV_SKIP_EMAIL_VERIFY="true"
+1
View File
@@ -2,6 +2,7 @@ import type { SiteConfig } from "@/kit/types";
// LaunchAI —— 独立站点的全部品牌/导航/页脚配置 // LaunchAI —— 独立站点的全部品牌/导航/页脚配置
export const siteConfig: SiteConfig = { export const siteConfig: SiteConfig = {
"themeId": "launchai",
"authVariant": "gradient", "authVariant": "gradient",
"themeClass": "site-launchai", "themeClass": "site-launchai",
"brandZh": { "brandZh": {
+3
View File
@@ -15,6 +15,9 @@ NEXT_PUBLIC_APP_NAME="The AI Ledger"
# 登录页品牌模板(分栏侧栏颜色与标语) # 登录页品牌模板(分栏侧栏颜色与标语)
NEXT_PUBLIC_AUTH_ACCENT="36 70% 40%" NEXT_PUBLIC_AUTH_ACCENT="36 70% 40%"
NEXT_PUBLIC_AUTH_VARIANT="editorial" NEXT_PUBLIC_AUTH_VARIANT="editorial"
# 站点主题标识(<html data-theme>)与默认深浅(light | dark,用户可切换)
NEXT_PUBLIC_THEME_ID="the-ai-ledger"
NEXT_PUBLIC_DEFAULT_THEME="undefined"
NEXT_PUBLIC_AUTH_BRAND_TAGLINE="Independent journalism on AI tools, with a community-ranked directory." NEXT_PUBLIC_AUTH_BRAND_TAGLINE="Independent journalism on AI tools, with a community-ranked directory."
# 开发阶段免邮箱验证(生产置 false 发送真实验证邮件) # 开发阶段免邮箱验证(生产置 false 发送真实验证邮件)
DEV_SKIP_EMAIL_VERIFY="true" DEV_SKIP_EMAIL_VERIFY="true"
+1
View File
@@ -2,6 +2,7 @@ import type { SiteConfig } from "@/kit/types";
// The AI Ledger —— 独立站点的全部品牌/导航/页脚配置 // The AI Ledger —— 独立站点的全部品牌/导航/页脚配置
export const siteConfig: SiteConfig = { export const siteConfig: SiteConfig = {
"themeId": "the-ai-ledger",
"authVariant": "editorial", "authVariant": "editorial",
"themeClass": "site-the-ai-ledger", "themeClass": "site-the-ai-ledger",
"brandZh": { "brandZh": {