复评 P0 收尾:把「每个数字带口径」从个别页自觉升级为结构性强制。 - metrics-basis.ts:METRIC_BASES / METRIC_BASIS_NOTES + resolveMetricBasis (缺失·非法·大小写错一律回落最弱 target)+ weakestBasis(一组数字取最弱者聚合) + FORBIDDEN_PROOF_PHRASES;MetricsBasisNote 收 basis prop - 类型层 Product.metrics / DataProof / ServiceMetric / Solution.outcomes / DataMetric / about keyMetrics 全部加 basis?;9 处调用点改为 basis 驱动 - content-types.ts 新增共享 metricBasisField(select)展开进 9 处字段定义; trustSignals 有意跳过(已有自己的 source)。seed 显式声明 55 条 target - 删除字面虚构佐证:详情页「每一项指标都源自真实客户案例」、「经过实战验证」×3、 「来自真实客户的使用数据」、「经实际场景验证」;给此前完全裸奔的 3 个共享 数字渲染器(DataProofSection / detail-trust / detail-product-value)补上角注 - metrics-basis.test 3→16 例:basis 解析正控制、weakestBasis 次序、seed 全量 显式声明 + 覆盖证明(防空跑假绿)+ 禁任何条目自称 verified + 禁词全源码扫描 - 文档同源:DESIGN.md 立 The Declared-Basis Rule;PRODUCT.md 常驻禁令; CONTEXT.md 记决策并警示 admin 字段需重跑 seed 才激活 边界:CMS 字段定义存 ContentModel.fields(DB 内 JSON),basis 下拉须重跑 seed 才会出现在 admin 表单;本次 DB 与 seed 数据值零改动,渲染端对缺 basis 兜底 target。 Gates: type-check 0 · jest 1594/132 · contrast 7/7 · headings 10/10 lint 0e/128w(与 stash 基线逐行比对,零新增告警)
243 lines
15 KiB
Markdown
243 lines
15 KiB
Markdown
---
|
||
name: Novalon Website
|
||
description: 数字化转型咨询公司的可审计宣言 — Bain 式深红陈述、数据先行、零编造信任语法
|
||
colors:
|
||
cinnabar: "#C41E3A"
|
||
cinnabar-deep: "#A01830"
|
||
cinnabar-ember: "#E04A68"
|
||
cinnabar-blush: "#FEF2F4"
|
||
crimson-veil: "#8B1530"
|
||
cinnabar-light: "#F87171"
|
||
ink: "#0A0E14"
|
||
ink-rise: "#0F1419"
|
||
ink-pillar: "#151B23"
|
||
paper: "#FFFFFF"
|
||
mist: "#F8FAFC"
|
||
slate-cool: "#F1F5F9"
|
||
graphite: "#334155"
|
||
graphite-soft: "#475569"
|
||
haze: "#64748B"
|
||
hairline: "#EEF2F7"
|
||
rule: "#CBD5E1"
|
||
typography:
|
||
display:
|
||
fontFamily: "Geist Sans, PingFang SC, Hiragino Sans GB, Microsoft YaHei, sans-serif"
|
||
fontSize: "clamp(2.25rem, 5vw + 1rem, 6rem)"
|
||
fontWeight: 900
|
||
lineHeight: 0.92
|
||
letterSpacing: "-0.03em"
|
||
headline:
|
||
fontFamily: "Geist Sans, PingFang SC, Microsoft YaHei, sans-serif"
|
||
fontSize: "clamp(1.875rem, 2vw + 1rem, 3.75rem)"
|
||
fontWeight: 800
|
||
lineHeight: 0.95
|
||
letterSpacing: "-0.02em"
|
||
title:
|
||
fontFamily: "Geist Sans, PingFang SC, Microsoft YaHei, sans-serif"
|
||
fontSize: "1.25rem–1.5rem"
|
||
fontWeight: 700
|
||
lineHeight: 1.35
|
||
body:
|
||
fontFamily: "Geist Sans, PingFang SC, Microsoft YaHei, sans-serif"
|
||
fontSize: "1rem"
|
||
fontWeight: 400
|
||
lineHeight: 1.65
|
||
label:
|
||
fontFamily: "Geist Sans, PingFang SC, Microsoft YaHei, sans-serif"
|
||
fontSize: "0.8125rem"
|
||
fontWeight: 500
|
||
lineHeight: 1.4
|
||
letterSpacing: "0.08em–0.15em"
|
||
mono:
|
||
fontFamily: "Geist Mono, SFMono-Regular, Menlo, monospace"
|
||
fontSize: "0.75rem"
|
||
fontWeight: 400
|
||
letterSpacing: "0.2em"
|
||
rounded:
|
||
xs: "3px"
|
||
sm: "6px"
|
||
md: "8px"
|
||
lg: "12px"
|
||
xl: "18px"
|
||
2xl: "24px"
|
||
full: "9999px"
|
||
spacing:
|
||
xs: "4px"
|
||
sm: "8px"
|
||
md: "16px"
|
||
lg: "24px"
|
||
xl: "32px"
|
||
2xl: "48px"
|
||
3xl: "64px"
|
||
4xl: "96px"
|
||
5xl: "128px"
|
||
6xl: "192px"
|
||
components:
|
||
cta-primary:
|
||
backgroundColor: "{colors.cinnabar}"
|
||
textColor: "{colors.paper}"
|
||
rounded: "{rounded.full}"
|
||
padding: "16px 40px"
|
||
cta-primary-hover:
|
||
backgroundColor: "{colors.cinnabar-deep}"
|
||
cta-secondary:
|
||
textColor: "{colors.ink}"
|
||
rounded: "{rounded.full}"
|
||
padding: "16px 40px"
|
||
cta-dark:
|
||
textColor: "#F8FAFC"
|
||
rounded: "{rounded.full}"
|
||
padding: "16px 40px"
|
||
card-bain:
|
||
backgroundColor: "{colors.paper}"
|
||
rounded: "{rounded.lg}"
|
||
padding: "24px"
|
||
input-field:
|
||
backgroundColor: "{colors.paper}"
|
||
rounded: "{rounded.sm}"
|
||
size: "height 44px"
|
||
badge-pill:
|
||
backgroundColor: "{colors.cinnabar-blush}"
|
||
textColor: "{colors.cinnabar}"
|
||
rounded: "{rounded.full}"
|
||
---
|
||
|
||
# Design System: Novalon Website
|
||
|
||
## Overview
|
||
|
||
**Creative North Star: "The Crimson Ledger · 可审计的宣言"**
|
||
|
||
Novalon 的界面是一份可以逐条审计的经营宣言。它模仿顶级咨询公司(Bain 系)的陈述方式:先给答案,再给论证 —— 巨型黑体断言占据首屏,三条实测数字紧随其后,朱砂红只落在结论、行动与强调上。整个系统的情绪是「沉稳、精致、可信赖」:不是高高在上的专家,而是坐下来一起想办法的同行者。
|
||
|
||
第二支柱是「诚实语法」:不虚构案例、不伪造数据。未发布的内容明说「内测中 / 首批共创 / 敬请期待」,每个数字带来源角注。这份克制本身被当作差异化资产,视觉系统配合它:宁可有大面积留白与「暂未发布」,不放一张假图、一句空话。
|
||
|
||
深色模式不是附属品而是一等公民:主题由 `html[data-theme]` 驱动,仅覆盖 CSS 变量,每个文字令牌附带实测对比度注释(全部达 WCAG AA),品牌红走「底色 / 文字」双通道以保证反色后仍达标。
|
||
|
||
**Key Characteristics:**
|
||
- 答案先行的宣言 Hero,按页型分三档音量:首页全幅宣言 / hub 紧凑引言 / 信任页降档宣言
|
||
- 朱砂红是「结论电压」:每页 ≥3 处触达点、面积 ≤10%
|
||
- 柔和阴影分层替代硬边框分界;细发线(1px)只做区域呼吸线
|
||
- 明暗双主题逐令牌审校,对比度实测值写进代码注释
|
||
- 动效 180–280ms、ease-ink 曲线、reduced-motion 全链路守卫
|
||
|
||
## Colors
|
||
|
||
中性色是纸与墨的冷调 slate 系,全部色彩张力由一个声音承担 —— 朱砂。
|
||
|
||
### Primary
|
||
- **Cinnabar Signal 朱砂信号** (`{colors.cinnabar}` #C41E3A): 品牌红。CTA 填充、标题关键词下划线、active 导航下划线、数据数字、卡片顶部 2px 红条、hover 焦点环。
|
||
- **Cinnabar Deep** (`{colors.cinnabar-deep}` #A01830): 品牌红 hover 态。
|
||
- **Cinnabar Ember** (`{colors.cinnabar-ember}` #E04A68): 亮部变体,用于装饰性强调。
|
||
- **Cinnabar Blush** (`{colors.cinnabar-blush}` #FEF2F4): 红底最浅层,badge 背景、错误提示底。
|
||
- **Crimson Veil** (`{colors.crimson-veil}` #8B1530): 深红全幅区块背景(Bain 式引述区/CTA 区),其上文字用 #F8FAFC。
|
||
|
||
### Neutral
|
||
- **Ink** (`{colors.ink}` #0A0E14): 近黑的冷墨。主文字、深色页底、描边按钮文字。暗黑模式下语义整体反转(ink 变浅、paper 变深),但「深色区块」类令牌(`--color-dark-*`、overlay、footer)显式引用、不随反色。
|
||
- **Ink Rise / Ink Pillar** (`{colors.ink-rise}` / `{colors.ink-pillar}`): 暗黑模式的两级深底。
|
||
- **Paper** (`{colors.paper}` #FFFFFF): 主底与卡片底。
|
||
- **Mist** (`{colors.mist}` #F8FAFC): 交替 section 底、次级面。
|
||
- **Slate Cool** (`{colors.slate-cool}` #F1F5F9): 三级底、hover 底。
|
||
- **Graphite** (`{colors.graphite}` #334155): 正文次级文字(AA 达标)。
|
||
- **Haze** (`{colors.haze}` #64748B): 辅助文字与占位符下限(4.76:1);更浅的 `--color-text-hint` #7C8CA5 仅允许出现在 ≥24px 装饰大字。
|
||
- **Hairline** (`{colors.hairline}` #EEF2F7): 卡片描边、gap-px 网格线 —— 刻意淡到近乎不可见,分界交给阴影。
|
||
- **Rule** (`{colors.rule}` #CBD5E1): 可见分隔线、次级边框。
|
||
|
||
### Functional
|
||
- success/warning/error/info 各带「本体 + 文字专用」双令牌(如 `--color-success` 仅 3.30:1,正文必须用 `--color-success-text` #15803D)。错误色直接复用品牌红。
|
||
|
||
### 编码辅色(非装饰)
|
||
蓝/青/琥珀/紫/青柠/玫红/靛 7 个 accent 仅用于服务与行业编码(图标底、solution 卡 accent),一律 12% 软底变体成对出现。**它们永远不组合成渐变,也不承担全局氛围。**
|
||
|
||
### Named Rules
|
||
**The One Voice Rule.** 一屏之内,色彩主张只允许朱砂一个声音发言;accent 编码色是分类标签,不是情绪表达。
|
||
**The Two-Channel Red Rule.** 底色用 `--color-brand`(暗黑不翻),文字用 `--color-brand-ink`(暗黑翻至 #F87171)。合并成一条是 bug 的源头——红底白字按钮与深底红字要同时达标。
|
||
**The Ledger Budget Rule.** 品牌红触达每页 ≥3 处、面积 ≤10%。红色稀缺才值钱。
|
||
|
||
## Typography
|
||
|
||
**Display/Body Font:** Geist Sans(本地 woff2,next/font),中文逐字符回退 PingFang SC / 微软雅黑
|
||
**Label/Mono Font:** Geist Mono(编号、digest、eyebrow 英文装饰位)
|
||
**Legacy Exception:** `--font-brand` 楷体(STKaiti/KaiTi)仅存于遗留页 `/about/brand`,**新页面禁用**。
|
||
|
||
**Character:** 无衬线黑体的极端粗细跨度(400 正文 ↔ 900 断言)就是层级本身;中文靠字族回退保持现代感,不用书法制造「文化氛围」。
|
||
|
||
### Hierarchy
|
||
- **Display** (900, 3rem→6rem 经 `--font-size-7xl` 变量随断点放大, leading 0.92–0.95, tracking -0.03em): 首屏宣言本体,第二行常染品牌红或加红下划线。注意:本项目 fontSize 在 `theme.extend` 中自定义到 7xl(≥1024px 时 6rem),Tailwind 默认 `text-8xl` 与它同值(6rem)——历史遗留的 `xl:text-8xl` 是无效层级,子页 Hero 已全部移除。
|
||
- **Headline** (800/900, 1.875rem→3.75rem, leading ~0.95): Section 标题。
|
||
- **Title** (600–700, 1.125–1.5rem): 卡片标题。
|
||
- **Body** (400, 1rem/1.0625rem, leading 1.65–1.85): 正文;`text-text-secondary` 为默认灰度。
|
||
- **Label** (500, 0.8125rem, tracking 0.08–0.15em, 可 uppercase): eyebrow、badge、导航眉标。
|
||
- **Mono Caption** (0.75rem, tracking 0.2em uppercase): 编号、digest、技术注记。
|
||
|
||
### Named Rules
|
||
**The Answer-First Rule.** 标题写结论断言,不写问句或口号铺垫;紧随其后的数字条是证据。
|
||
**The -0.04em Floor.** 追踪最紧 -0.04em(现用最紧 -0.03em);display 不超过 6rem。
|
||
**The 10px Floor.** 10–11px 大写 tracking 微标签(eyebrow、digest、case 分类签)是 Bain 账本风的有意下限,全站保留、不上坡;绝对像素字号不得 <10px,由 `src/lib/constants/font-floor.test.ts` 机械守卫禁止再引入(rem 因 18px 根字号歧义不纳入)。
|
||
**The Declared-Basis Rule.** 凡以大数字样式呈现的指标必须声明口径 `basis: target | team-history | verified`(单一真源 `src/lib/constants/metrics-basis.ts`),渲染端据此自动附角注;缺失或非法一律按最弱的 `target`(「目标口径,非既成结果」)处理,宁可多标注也不裸奔。聚合时取一组数字里最弱的那个。禁止任何「数字源自真实客户案例 / 经过实战验证」式佐证文案——本站 2026-01 成立、零公开客户案例,该措辞由 `metrics-basis.test.ts` 全源码扫描拦截。
|
||
|
||
## Layout
|
||
|
||
12 列网格心智(`--grid-columns: 12`),容器上限 1360px(`--container-max`),水平内边距 16→40px 随断点。Mobile First,Tailwind 默认断点(sm 640 / md 768 / lg 1024 / xl 1280)。
|
||
|
||
- 纵向节奏:section 默认 `--section-padding-y` = 96px(`py-20 md:py-28` 一族),呼吸区 `section-breathing` 128→192px,数据密集区 `section-compact` 48→64px。
|
||
- Bain 式不对称栅格是主力构图:`asymmetric-wide-narrow` 5fr/3fr、`asymmetric-narrow-wide` 3fr/5fr、`asymmetric-three` 2fr/1fr/1fr(lg 起生效)。
|
||
- 卡片密集区用 gap-px + 发线底色(`bg-border-primary`)的无缝网格,而非卡片间留大缝。
|
||
- Section 背景在 Paper ↔ Mist 间交替,上下以 1px 发线收边;深色/深红区块作为全幅打断。
|
||
- Hero 四档音量(2026-09-19 layout+distill 定型,critique 复评补第四档):**首页** `min-h-[90vh]`+粒子场,全站唯一全幅宣言档;**hub 目录页**(products/solutions/services)与**叶子详情**(service-detail)为紧凑引言:无 min-h、`py-16 sm:py-20 lg:py-28`、标题封顶 `lg:text-6xl xl:text-7xl`,其下重复的 Hero 数据条已删;**信任页**(about/team)`min-h-[60vh]`、`lg:py-40`、标题封顶 `lg:text-7xl`,保留宣言气场与 CMS 驱动数据条;**独立内容页**(cases `70vh` / news `75vh` / methodology `60vh` / product-detail·solution-detail `80vh`)允许中等音量引言,但**转化页不得用**——/contact 已改紧凑档(无 min-h、`py-16 sm:py-20 lg:py-28`,表单回到首屏视野)。/about/brand 为遗产豁免(90vh,随页面退役一并处理)。
|
||
|
||
## Elevation & Depth
|
||
|
||
分层靠「几乎看不见的边框 + 真实柔和的阴影」完成:`--color-border-primary` 被刻意软化到 #EEF2F7,卡片默认 `--shadow-sm`/card-shadow 贴地,hover 升至 `--card-shadow-hover` 并 translateY(-4px)。阴影全部从墨色 rgba(10,14,20,α) 取用,不用纯黑。
|
||
|
||
### Shadow Vocabulary
|
||
- **xs–xl 层级带** (`0 1px 1px α0.03` → `0 24px 56px α0.1`): 微边界 → 卡片 → 下拉 → 模态 → 全屏浮层。
|
||
- **Brand Halo** (`0 6px 24px rgba(196,30,58,0.22)`,hover 加深至 0.32): 仅 CTA/品牌强调元素的有色阴影。
|
||
- **Inset / Glow** (`inset 0 2px 4px`; `0 0 40px rgba(196,30,58,0.15)`): 凹陷输入与慎用光晕。
|
||
|
||
### Named Rules
|
||
**The Quiet Border Rule.** 边框只负责「有没有」,深度全部交给阴影;禁止用重边框线做层级。
|
||
|
||
## Shapes
|
||
|
||
柔边体系:徽章/焦点元素 3px、按钮/输入 6px、卡片/弹窗 8px、大卡 12px(`--card-border-radius`)、英雄卡 18px、全屏弹窗 24px;CTA 与 badge 一律全圆角 pill。特色几何:区块顶/底 0.5–2px 朱砂条带、`corner-frame` L 形角框(16px 红色直角)、`clip-slant` 斜切(Accenture 遗产,仅装饰带使用)。卡片在 1px 淡边框与阴影之间只声明一次 elevation(边框为 hairline 级)。
|
||
|
||
## Components
|
||
|
||
### Buttons(CTAButton,全站行动召唤)
|
||
- **Shape:** 全圆角 pill(rounded-full),内置 ArrowRight 箭头签名,hover 位移 translate-x。
|
||
- **Primary:** 朱砂填充 + 白字(16px 40px),hover 转 Cinnabar Deep;**Secondary:** 墨色 20% 描边透明底;**Dark:** 深色区块专用浅描边;**Inline:** 透明小箭头文字链,用于卡内「了解更多」。
|
||
- 交互 Button(ui/button.tsx)另带 6 档 size 与 ripple,触控下限 44×44px。
|
||
|
||
### Cards / Containers(bain-card)
|
||
- **Corner Style:** 12px 柔边;**Background:** Paper;**Border:** 1px hairline;**Shadow:** card-shadow → hover 抬升 4px + card-shadow-hover;内边距 24px(大 40px)。
|
||
|
||
### Inputs / Fields
|
||
- Paper 底、hairline 描边、6px 圆角、44px 高;focus 转 `border-brand/50`;标签常驻(placeholder 仅作示例);错误文案内联于字段下。
|
||
|
||
### Navigation
|
||
- 白色 sticky 头部,active 项朱砂下划线;桌面 hover 展开 mega dropdown(分组 + 描述 + 状态 badge);移动端汉堡 + 底部 tab bar 双轨(在办:收敛为一套);skip-link 常驻。
|
||
|
||
### 数据条(Stats Strip)
|
||
- 3 项为宜:数字用 display 级 font-black + `tabular-nums` + 品牌红,label 用小灰字。这是「答案先行」的结构件,但仅在数据不被本页其它区域重复时放置(首页成果带、信任页 Hero);hub 页 Hero 的数据条因与下方网格逐字重复已移除。
|
||
|
||
### Badge / 状态签
|
||
- Pill,12% 软底或 blush 底 + 品牌/编码色文字 + 20% 同色描边;「内测中 / 敬请期待」等诚实状态以此呈现。
|
||
|
||
## Do's and Don'ts
|
||
|
||
### Do:
|
||
- **Do** 让每个 section 以可验证的陈述开场,数据、来源角注跟上(The Answer-First Rule)。
|
||
- **Do** 新文字令牌落地前先在代码注释写实测对比度比值(沿现制度:如 5.74:1、AA 判定)。
|
||
- **Do** 用 `text-brand-ink` 写红色文字、`bg-brand` 做红色填充,永不混用(双通道)。
|
||
- **Do** 入场动效统一 ease-ink `cubic-bezier(0.22,1,0.36,1)`、180–280ms,stagger 用 `--stagger-*` 令牌;reduced-motion 时退为静态。
|
||
- **Do** 未发布内容使用 `ContentUnavailableState`(带导航出口),空/错/成功态永远给出下一步。
|
||
|
||
### Don't:
|
||
- **Don't** 用多色渐变、玻璃拟态或彩色光晕制造「科技感」;科技感到数字和排版为止。
|
||
- **Don't** 在新页面使用楷体 `--font-brand`(例外遗产,仅 /about/brand)。
|
||
- **Don't** 把内容入场做成 spring 回弹(`--ease-spring*` 死令牌已于 2026-09-19 polish 批次删除;原则保留,防止回归)。
|
||
- **Don't** 用 `--color-text-hint` (#7C8CA5) 写正文/占位符(仅 ≥24px 装饰大字)。
|
||
- **Don't** 虚构案例、客户 logo、产品截图;宁可用 badge 承认「内测中」。
|
||
- **Don't** 让 CTA 文案自由发挥:预约动作全站统一「预约咨询」。
|