> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibestrap.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 自定义

> 你要改什么、在哪改、什么不该动——集中在三个文件。

90% 的自定义集中在三个文件：`src/config/site.ts`、`src/app/globals.css`、
`messages/{en,zh}.json`。剩下是换 logo SVG、改邮件模板、重排营销 block。本页是地图。

## `siteConfig.ui` 的快速开关

两个预制开关，不写一行 CSS——专门针对那些"AI 现场改容易出错"的跨切面场景：

```ts theme={null}
ui: {
  theme: 'cream' as 'cream' | 'white' | 'ash',
  // cream  —— 暖米黄编辑纸感（默认；Loops / Resend / Clerk 同款）
  // white  —— 纯白临床（Stripe / Linear / Vercel 同款）
  // ash    —— 冷灰蓝通透（Apple / Bolt 同款）

  navStyle: 'underline-fade' as
    | 'tone'              // Stripe / Resend —— 仅字色变深
    | 'underline-fade'    // Notion / Loops —— 下划线渐入（默认）
    | 'pill'              // Linear / Vercel —— 圆角填充背景
    | 'underline-appears' // NYT —— hover 瞬间出下划线
    | 'split',            // v0 —— hover 是 pill，active 仅字深
}
```

主题类定义在 `src/app/globals.css`；nav recipe 在
`src/components/layout/nav-styles.ts`（每个 preset 标注了参考站点）。
新增 preset 直接在文件里加一项，TypeScript 联合类型自动收窄。

## AI 自定义

Vibestrap 故意**少**做预制。Hero、价格卡、footer、按钮 variant、卡片样式
这种块级改动，**AI 现场生成**比维护一套 preset 系统更快。

常见的几类，[`STYLES.md` → AI swap recipes](https://github.com/xiaohu0x/vibestrap/blob/main/STYLES.md#ai-swap-recipes--single-block-customization)
准备了可复制粘贴的 prompt 模板，标明确切的文件路径和约束。打开对应
recipe，把 prompt 粘到 Claude Code / Cursor / Codex，一般 2–5 分钟落地。

可用 recipe：

* 换 **hero**（终端 demo → 居中标题 / 双栏 split / 视频背景）
* 重做 **价格卡**（单卡 → 双档 monthly+yearly / 三档对比 / slider）
* 换 **feature-card** 样式（硬边 → 软阴影 / glass / 渐变）
* 紧凑 **footer**（4 列 → 极简一行 / 大 footer + 邮件订阅）
* 重做主 **按钮**（实心 → 描边 / 渐变 / ghost）

要换整套风格（cream-mono → 暗色科技 等），看 `STYLES.md` 顶部的
7 个完整 style recipe——同一个文件的前半部分。

## 品牌

改 `src/config/site.ts` —— 中心配置：

```ts theme={null}
export const siteConfig = {
  name: 'YourProduct',
  description: '一段话的产品介绍。',
  shortDescription: '一句话的标语。',
  url: 'https://your-domain.com',
  links: {
    github: 'https://github.com/yourorg/yourrepo',
    twitter: 'https://twitter.com/yourhandle',
    contact: 'mailto:hello@your-domain.com',
  },
  mail: {
    fromName: 'YourProduct',
    supportEmail: 'support@your-domain.com',
  },
};
```

文件保持在 250 行内。重业务逻辑（定价数学、AI provider 设置）放各自模块——参考
`src/ai/pricing.ts` 的写法。

## 颜色（超出 preset 的自定义调色）

Tailwind v4 从 `src/app/globals.css` 的 `@theme` 读 token。所有颜色都是
[OKLCH](https://oklch.com)——感知均匀、色相旋转可预测、用 OKLCH 取色器复制粘贴友好。

Vibestrap 是**仅 light 模式**——没有 `.dark` 类，没有系统模式切换。
要加 dark 变体，看 dark-mode 参考文档里的 5 步加回方案。

默认 `cream` 主题：

```css theme={null}
.theme-cream {
  --background: oklch(0.96 0.012 85);   /* 暖米黄纸感 */
  --foreground: oklch(0.18 0 0);        /* 接近黑 */
  --primary: oklch(0.18 0 0);
  --primary-foreground: oklch(0.97 0.008 85);
  --accent-tech: oklch(0.55 0.2 250);   /* 电光蓝 —— logo cursor + 进度条 */
  --accent-tech-light: oklch(0.72 0.16 240);
  /* 完整定义在 globals.css */
}
```

两种自定义路径：

1. **改 preset 数值** —— 直接编辑 `globals.css` 里 `.theme-cream`（或 `.theme-white` / `.theme-ash`）的 OKLCH 值。shadcn/ui 组件按 token 名引用，改一处全部翻新。
2. **加新 preset** —— 复制一个 `.theme-*` 块改名，然后在 `siteConfig.ui.theme` 联合类型里加上新名字。TypeScript 类型自动派生。

用 OKLCH 取色器选品牌色。`--accent-tech` 跟 `--accent-tech-light` **必须一起换**——
进度条 gradient 是它俩的中间色插值。

## 字体

默认 **Geist Sans** + **Geist Mono**，在 `src/app/layout.tsx` 通过 `next/font/google` 加载：

```tsx theme={null}
import { Geist, Geist_Mono } from 'next/font/google';
const geistSans = Geist({ variable: '--font-geist-sans', subsets: ['latin'] });
const geistMono = Geist_Mono({ variable: '--font-geist-mono', subsets: ['latin'] });
```

换成任意 `next/font/google` 字体即可。把 `globals.css` 里的 `--font-sans` / `--font-mono` 同步
到对应 CSS 变量名就行——不用动 Tailwind 配置。

## 营销文案

所有页面文案在 `messages/en.json` 和 `messages/zh.json` 的 `Home` 命名空间下。两文件 key 结构
**必须**完全一致——next-intl 在 build 时对 key 漂移会报错。

```json theme={null}
"Home": {
  "hero": {
    "title": "你的 hero 标题",
    "subtitle": "你的副标题。"
  }
}
```

热更新立即生效。加新 key 时同一个 commit 里两边都加。

## Hero / features 排版

首页是一摞独立 block，在 `src/app/[locale]/(marketing)/page.tsx` 组合：

```tsx theme={null}
<Hero />
<LogoCloud />
<Features />
<UseCases />
<WhyVibestrap />
<Quickstart />
<Pricing />
<FAQ />
<NewsletterCard />
<CTA />
```

任意重排或删除。每个 block 是 `src/components/blocks/` 里自包含的组件，从
`messages/{locale}.json` 读文案——跨边界不需要 prop 传递。

## 定价

`siteConfig` 里有两套独立的定价面：

**Vibestrap 自身的定价**（你卖给买家的）：

```ts theme={null}
product: {
  standardPriceCents: 9900,        // $99
  promo: { active: true, priceCents: 4900 }, // $49 限时
}
```

切 `promo.active` 在两档之间翻转。hero、pricing block、checkout 都读 `activePriceCents()`，
改一处全联动。

**下游 app 示例定价**（买家给自己用户展示的 4 档样板：一次性打折 / 一次性正价 / 月付订阅 / 年付订阅）：

```ts theme={null}
demoPlans: [
  { id: 'lifetime_promo',    type: 'one_time',    priceCents:  4900, priceIdEnv: 'STRIPE_PRICE_VIBESTRAP_PROMO',    creditsGranted:   1000 },
  { id: 'lifetime_standard', type: 'one_time',    priceCents:  9900, priceIdEnv: 'STRIPE_PRICE_VIBESTRAP_STANDARD', creditsGranted:   1000 },
  { id: 'pro_monthly',       type: 'subscription', interval: 'monthly', priceCents:  999, priceIdEnv: 'STRIPE_PRICE_PRO_MONTHLY', creditsGranted:  1000 },
  { id: 'pro_yearly',        type: 'subscription', interval: 'yearly',  priceCents: 9900, priceIdEnv: 'STRIPE_PRICE_PRO_YEARLY',  creditsGranted: 12000 },
]
```

会以 2×2 网格渲染在 `/settings/credits`，展示 4 种常见定价模式。买家产品收什么价，就把价格、env 名、积分发放数都换成自己的。

## Logo

默认 header 和 footer 用 `lucide-react` 的 `Sparkles` 图标。两处都换：

```tsx theme={null}
// src/components/layout/header.tsx
import { Sparkles } from 'lucide-react';
// → 换成你自己的 SVG 组件或 <Image src="/logo.svg" .../>
<Sparkles className="size-5 text-primary" />
```

同一处改在 `src/components/layout/footer.tsx`。OG 图换 `public/og.png`（1200x630，PNG 或 JPG）。

## 邮件模板

React Email 模板在 `src/mail/templates/`：

* `verify-email.tsx` —— 注册验证。
* `welcome.tsx` —— 验证完毕后发。
* `forgot-password.tsx` —— 密码重置链接。

像普通 React 组件一样改。品牌信息（`siteConfig.name`、`siteConfig.mail.supportEmail`）已经接上。
email-dev 脚本上线前的本地预览：触发 auth 流，看 dev 控制台的渲染输出。

## 加 locale

1. 在 `src/config/site.ts` 加 locale 代码：
   ```ts theme={null}
   i18n: { defaultLocale: 'en', locales: ['en', 'zh', 'ja'] }
   ```
2. 建 `messages/ja.json`，key 结构镜像 `en.json`。
3. 文档若要上线，每篇 `*.zh.mdx` 都翻一份 `*.ja.mdx`。
4. 完事。URL 自动变成 `/ja/...`。

## 另见

* [配置](/zh/configuration) —— 每个 `siteConfig` 字段。
* [架构](/zh/architecture) —— block、主题、provider 怎么串起来。
* [Env 参考](/zh/env-reference) —— 控制 feature 开关的 key。
