Anarlog web 前端设计系统实现:Tailwind @theme 语义令牌、CTA 模式与组件组织规范
Anarlog web 前端设计系统实现Tailwind theme 语义令牌、CTA 模式与组件组织规范【免费下载链接】anarlogOpen source Granola AI Alternative项目地址: https://gitcode.com/GitHub_Trending/hy/anarlogAnarlog开源的 Granola 替代品的营销站点与应用门户apps/web是一套基于 TanStack Start Tailwind CSS v4 的前端。本文基于 apps/web/AGENTS.md 完整展开其设计系统约定所有视觉令牌如何集中定义在 src/styles.css 的theme块中、组件中禁止硬编码色值的规则如何落地、CTA 按钮的标准写法以及组件目录的组织方式——读完后你可以按仓库既有规范为新页面添加 UI而不破坏整体品牌一致性。1. 本地环境准备用 Infisical 导出 .envAGENTS.md 开头给出的第一条实操是指令web 应用的环境变量不是手写.env而是从 Infisical 密钥管理按 dev 环境导出为 dotenv 格式infisical export \ --envdev \ --secret-overridingfalse \ --formatdotenv \ --output-fileapps/web/.env \ --projectId87dad7b5-72a6-4791-9228-b3b86b169db1 \ --path/anarlog/web参数说明参数作用--envdev只导出 dev 环境命名的密钥不混入生产值--secret-overridingfalse若本地已有同名.env条目则不覆盖保留本地调试值--formatdotenv输出为.env可直接 source 的键值对格式--output-fileapps/web/.env直接落到 web 应用的 Vite 默认读取位置--projectId/--path定位 Infisical 项目内anarlog/web路径下的密钥子树这套变量最终由 src/env.ts 统一校验服务端侧要求SUPABASE_URL、STRIPE_SECRET_KEY、LOOPS_KEY等生产环境必填项requiredInProd辅助函数在开发期自动降为可选客户端侧则以VITE_为前缀暴露VITE_APP_URLdev 默认http://localhost:3000、VITE_API_URLdev 默认http://localhost:3001生产默认https://api.anarlog.so等且 CI 环境跳过校验。也就是说 Infisical 导出只是“取数”环节取值合法性仍由 env.ts 的 zod schema 把关。2. 设计令牌的唯一事实来源src/styles.css的theme块AGENTS.md 的核心约定只有一条但极其严格所有视觉令牌都位于src/styles.css的theme块内。组件中永远不要使用硬编码的 hex 值——一律引用令牌。对照 src/styles.csstheme块第 12–81 行确实按“Typography / Layout / Animations / Colors: greys / backgrounds / foreground / borders / brand / Shadows”分组声明了全部自定义属性文件末尾再以一组工具类.surface、.text-color、.border-color-brand等见 styles.css把令牌映射为可复用 class。品牌层面的完整取值与使用规则另见 apps/web/BRAND.md它是“单一事实来源”的姊妹文档而 AGENTS.md 给出的是面向 Agent/开发者的速查表。2.1 颜色令牌语义层AGENTS.md 给出的颜色令牌表完整继承令牌值用途--color-page#f2f1ef页面/画布背景bg-page--color-surface#ffffff卡片、面板、弹窗背景.surface--color-surface-subtlevar(--grey-100)弱化的表面变体.surface-subtle--color-fgvar(--grey-900)主要文字.text-color--color-fg-muted#57534e次要/正文文字.text-color-muted--color-fg-subtlevar(--color-border)占位符、禁用态、图标--color-bordervar(--grey-500)默认边框.border-color-brand--color-border-subtlevar(--grey-300)发丝线/结构性边框.border-color-subtle--color-border-brightoklch(0.5959 0.0333 78.6)强调边框.border-color-bright--color-brand-dark#57534e选中态、强调bg-brand-dark--brand-yellowoklch(0.9484 0.0672 90.6)Hero/页脚暖色晕染.brand-yellow从源码结构看这张表描述的是“语义令牌”层真正落地时大量语义令牌并不直接写死颜色而是var()引用底层 oklch 灰色阶--grey-900~--grey-100styles.css因此改一处灰色阶即可整体平移明暗。需要注意两处细节--color-fg-muted的当前实现styles.css 中实际写为var(--grey-500)oklch(0.7782 0.0018 67.8)而非表格中的#57534e。这说明文档表格是“契约值”、CSS 是运行值二者以 CSS 为准做微调引用时仍应只用令牌名不要复制具体数值。shadcn 语义垫片styles.css 额外定义了--color-foreground: var(--color-fg)与--color-muted-foreground: var(--color-fg-secondary)注释解释这是为共享包如anlg/pricing的 PlanFeatureList中 shadcn 风格令牌提供兼容映射否则那些文本会渲染成近黑色而不是站点的暖灰色系。2.2 一个刻意缺席的令牌没有--color-brandAGENTS.md 特别注明不存在--color-brand令牌CTA 使用from-stone-600 to-stone-500Tailwind 的 stone 渐变而不是自定义令牌。这避免了“看到 brand 字样就去找--color-brand结果找不到”的常见误用——主按钮的深色渐变直接复用 Tailwind 内置 stone 色阶。这一点在组件源码中得到多处印证例如home-page/pricing-section.tsxbg-linear-to-t from-stone-600 to-stone-500 text-whiteroutes/_view/app/switch-plan.tsxrounded-full bg-linear-to-t from-stone-600 to-stone-500 text-white shadow-md ...shared-note-chat-panel.tsx同模式 transition-opacity hover:opacity-902.3 阴影令牌用阴影模拟描边是该设计系统的一个小 trickAGENTS.md 给出两个阴影令牌令牌用途--shadow-ring1px 轮廓描边效果.border-around——层叠场景下优先于border--shadow-ring-left仅左边缘 1px 轮廓对应实现styles.css--shadow-ring: 0 0 0 1px var(--color-border); --shadow-ring-left: -1px 0 0 1px var(--color-border);“优先于 border”的原因box-shadow不参与盒模型布局多个元素堆叠如卡片列表、分割面板时不会产生 border 宽度导致的 1px 错位.border-around { box-shadow: var(--shadow-ring); }工具类见 styles.css。3. 字体排印四个 font 令牌的分工AGENTS.md 定义的字体分工完整继承工具类字体适用范围font-sansGeist全部正文、标签、导航链接font-monoGeist Monoh1/h2 标题、按钮文案、代码font-serifFraunces编辑体强调、装饰性时刻font-serif2Instrument Serif斜体编辑体点缀这套分工与 BRAND.md 的字体表一致塑造出“手写笔记本 等宽结构”的编辑感。需要指出的是从当前源码结构看styles.css 的--font-sans实际声明为system-ui系统字体栈、--font-mono为ui-monospace栈另有两个手写体令牌--font-handCaveat与--font-signaturePatrick Hand用于笔记式装饰博客正文标题.blog-prose h2即使用var(--font-hand)见 styles.css。也就是说文档描述的是品牌意图而运行中的字栈在源码层做了系统字体回退——具体字体以 CSS 变量当前值为准。theme块还顺带声明了布局断点--breakpoint-laptop: 72rem、--breakpoint-wide: 87.5rem与两个动画令牌ios-opacity-spin、anarlog-dancing-stick同属“只在这里定义、组件只引用”的约定范围。4. CTA 按钮的标准写法AGENTS.md 给出了主/次两种 CTA 的完整 class 串可直接复制主 CTAstone 渐变非自定义令牌bg-linear-to-t from-stone-600 to-stone-500 rounded-full text-white;次 CTA / ghost表面 边框border border-neutral-200 bg-white rounded-lg text-neutral-700;两处细节值得注意渐变方向是to-t自下而上由深到浅主按钮普遍是rounded-full胶囊形次按钮是rounded-lg方形视觉上主次分明。次 CTA 使用 Tailwind 内置neutral-*而非语义令牌这与 BRAND.md 的用法规则吻合“neutral-*与stone-*在组件中作为回退出现但品牌面向的 UI 以语义令牌优先”。仓库内可检索到至少 5 处主 CTA 与该模式逐字一致pricing-section.tsx、switch-plan.tsx、billing.tsx、shared-note-chat-panel.tsx、-integration-ui.tsx说明这是一条被严格执行的约定而不是纸面建议。5. 组件目录结构与演进约定AGENTS.md 描述的src/components/目标布局src/components/ admin/ # 内部管理工具 mdx/ # MDX 渲染组件 notepad/ # Notepad 功能演示 sections/ # 页面级营销分区 transcription/ # 转写功能演示 *.tsx # 扁平根层 — 布局、导航、共享组件并附上一条工作习惯“大多数组件当前都平铺在根层。当你修改某个文件时考虑把它移到合适的子文件夹。”从源码结构看当前仓库中该目录以扁平.tsx文件为主shared-note-*.tsx、site-footer.tsx、error-page.tsx等并新增了home-page/子目录承载首页营销分区——即文档描述的sections/思路已部分落地而admin/、mdx/等目录可推断是待整理或阶段性存在的目标分类。实操含义是改动根层组件文件时顺手归类不要等到目录彻底失控。6. 速查改 web 前端 UI 前该看哪些文件场景先看加颜色/阴影/字体src/styles.css 的theme块L12–81禁止组件内写死 hex品牌用法规则与完整调色板BRAND.md按钮/CTA第 4 节两条标准 class 串检索from-stone-600找既有范例环境变量Infisical 导出命令 src/env.ts 的 zod schema组件归位AGENTS.md 第 5 节目录约定一句话总结该文档的设计哲学视觉决策全部收敛到theme里的少数几个语义令牌组件层只做“引用”这一种动作CTA、字体、阴影、目录结构各有唯一标准写法。任何新功能只要沿用令牌名和标准 class 串就能自动继承 Anarlog 的暖灰 oklch 品牌观感且未来调色只需改一处 CSS。【免费下载链接】anarlogOpen source Granola AI Alternative项目地址: https://gitcode.com/GitHub_Trending/hy/anarlog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →