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:
@@ -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"
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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,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>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
Reference in New Issue
Block a user