diff --git a/CONTEXT.md b/CONTEXT.md index dcbd8e9..2ff8850 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -46,6 +46,30 @@ Novalon 网站的**主体视觉骨架**。核心特征: 决策状态:✅ 已确认(2026-06-28 重申约束,2026-06-29 补充贯穿规则) +### 品牌色令牌的语义拆分(2026-09-04 新增 · 暗黑模式修复) + +品牌红必须区分「文字」与「底色」两种用法,二者**不能共用同一个 CSS 变量**: + +| utility | 变量 | 浅色 | 深色 | 适用 | +|---|---|---|---|---| +| `text-brand-ink` | `--color-brand-ink-rgb` | #C41E3A | **#F87171** | 品牌色**文字**:eyebrow、指标数字、标签、链接 hover | +| `bg-brand` / `border-brand` | `--color-brand-rgb` | #C41E3A | #C41E3A(**不翻转**) | 按钮底色、边框、图标填充 | +| `bg-brand-bg` | `--color-brand-bg` | #FEF2F4 | **#2A1418** | 品牌浅底块(与 `--color-error-bg` 同口径翻转) | +| `--badge-accent-text` | `--badge-accent`(组件注入) | accentColor 原色 | `color-mix(accent 45%, white)` | DetailHero 徽章:accentColor 直用作深底文字不可读(#1e3a5f 深底 1.65:1),经 CSS 变量间接引用后按主题自动适配 | + +依据(WCAG 相对亮度实测,非估算): +- 红底白字按钮 #C41E3A × #F8FAFC = **5.58:1**;若把按钮底整体换成 #E04A68 会掉到 **3.75:1** + → 所以**绝不能**整体提亮 `--color-brand` +- 深色下品牌文字取 **#F87171**:于 #0A0E14 / #0F1419 / #151B23 分别 **6.99 / 6.69 / 6.26**,全达 AA; + 且它已是深色主题 `--color-error-text` 的既有值,不引入新色值 + +例外 —— 以下场景保持 `bg-white` + `text-brand`(**不**用 brand-ink),因为它们是恒定品牌红/深色 +区块上的**白底反转元素**,白底在两主题下都不翻转:CTA 区块白底主按钮、品牌红指标块上的白底角标、 +Switch / Slider 的白底圆钮。 + +决策状态:✅ 2026-09-04 全站审计后确认(深色对比度违规 683 → 0); +✅ 2026-09-04 生产构建终验(33 路由 × 双主题 P1=0 / P3=0,剩余 P2 全为 GA 外网噪音) + ### 动效设计四原则 (Motion Design Principles) 基于 Porsche Consulting "用动效象征变革"理念,统一全站动效语言: 1. **Purposeful(有目的)**:每个动效必须服务于内容传达,不做纯装饰动效 diff --git a/src/app/(marketing)/about/about-content-v4.tsx b/src/app/(marketing)/about/about-content-v4.tsx index b7d7353..c3a6b64 100644 --- a/src/app/(marketing)/about/about-content-v4.tsx +++ b/src/app/(marketing)/about/about-content-v4.tsx @@ -70,7 +70,7 @@ function HeroSection({ data }: { data: AboutData }) {
0 ? 'mt-4 sm:mt-6' : ''}`}> {i === 1 ? ( - + {line} -
+
{metric.value}
{metric.label}
@@ -165,7 +165,7 @@ function WhoWeAreSection({ data }: { data: AboutData }) { className="lg:col-span-5" >
- 01 + 01
Why We Started @@ -194,7 +194,7 @@ function WhoWeAreSection({ data }: { data: AboutData }) { className="lg:col-span-7" >
- 02 + 02
How We Work @@ -214,7 +214,7 @@ function WhoWeAreSection({ data }: { data: AboutData }) { {value.number}
-

+

{value.title}

{value.description}

@@ -244,7 +244,7 @@ function MilestonesSection({ data }: { data: AboutData }) { className="max-w-3xl mb-16 sm:mb-20 md:mb-24" >
- 03 + 03
Where We Are Heading @@ -272,7 +272,7 @@ function MilestonesSection({ data }: { data: AboutData }) {
-
+
{milestone.year}
diff --git a/src/app/(marketing)/about/brand/brand-content.tsx b/src/app/(marketing)/about/brand/brand-content.tsx index 06aa798..8141c8f 100644 --- a/src/app/(marketing)/about/brand/brand-content.tsx +++ b/src/app/(marketing)/about/brand/brand-content.tsx @@ -80,7 +80,7 @@ export default function BrandContent() { > - + 品牌故事 @@ -99,7 +99,7 @@ export default function BrandContent() { ariaHidden />
- 以技术驱动业务增长 + 以技术驱动业务增长 {/* 数据条 */} @@ -111,7 +111,7 @@ export default function BrandContent() { > {brandStats.map((stat, i) => (
- + {stat.value} @@ -143,13 +143,13 @@ export default function BrandContent() {
- + 品牌定位

做企业数字化转型的 - 长期同行者 + 长期同行者

我们不是传统的外包服务商,而是深度嵌入客户业务的战略伙伴。 @@ -163,7 +163,7 @@ export default function BrandContent() {

-
+

{item.title}

@@ -195,7 +195,7 @@ export default function BrandContent() {

让每一家企业
- 都拥有数据驱动的 + 都拥有数据驱动
决策能力

@@ -222,7 +222,7 @@ export default function BrandContent() {

成为中国企业
- 数字化转型的 + 数字化转型
首选伙伴

@@ -242,13 +242,13 @@ export default function BrandContent() {
- + 发展历程

新起点上,每一步都 - 脚踏实地 + 脚踏实地

@@ -265,7 +265,7 @@ export default function BrandContent() {
- + {item.year} {/* text-muted 在 bg-tertiary(#F1F5F9) 上仅 4.34:1;换 text-secondary → 9.45:1 */} @@ -305,13 +305,13 @@ export default function BrandContent() {
- + 品牌实力

用实力赢得 - 每一份信任 + 每一份信任

@@ -324,7 +324,7 @@ export default function BrandContent() { ].map((item, i) => (
-
+

{item.title}

@@ -339,7 +339,7 @@ export default function BrandContent() { {/* ============ L4: CTA 品牌行动号召 ============ */}
-
+
@@ -348,7 +348,7 @@ export default function BrandContent() {

成为下一个
- 数据驱动型企业 + 数据驱动型企业

无论您处于数字化转型的哪个阶段,我们都愿意成为您的长期伙伴。 diff --git a/src/app/(marketing)/cases/cases-content-v3.tsx b/src/app/(marketing)/cases/cases-content-v3.tsx index 21becce..2f2b8f5 100644 --- a/src/app/(marketing)/cases/cases-content-v3.tsx +++ b/src/app/(marketing)/cases/cases-content-v3.tsx @@ -32,7 +32,7 @@ function CaseCard({ caseItem, index }: { caseItem: CaseStudy; index: number }) {

- + {caseItem.industry} @@ -40,15 +40,15 @@ function CaseCard({ caseItem, index }: { caseItem: CaseStudy; index: number }) {
-

+

{caseItem.title}

- - 挑战 + + 挑战

{caseItem.challenge} @@ -69,7 +69,7 @@ function CaseCard({ caseItem, index }: { caseItem: CaseStudy; index: number }) { {caseItem.metrics.slice(0, 2).map((m, i) => (

{m.value}
@@ -83,7 +83,7 @@ function CaseCard({ caseItem, index }: { caseItem: CaseStudy; index: number }) { {caseItem.client}
-
+
查看详情
@@ -143,7 +143,7 @@ export default function CasesContentV3({
{heroTitle1}
- + {heroTitle2} - + 首批客户共创中 @@ -211,7 +211,7 @@ export default function CasesContentV3({ className="text-center lg:text-left" >
{metric.value}
diff --git a/src/app/(marketing)/contact/contact-content-v3.test.tsx b/src/app/(marketing)/contact/contact-content-v3.test.tsx index 3bebb3b..c3027a5 100644 --- a/src/app/(marketing)/contact/contact-content-v3.test.tsx +++ b/src/app/(marketing)/contact/contact-content-v3.test.tsx @@ -67,7 +67,7 @@ jest.mock('@/components/ui/labeled-input', () => ({ data-testid={dataTestId || 'labeled-input'} {...props} /> - {error && {error}} + {error && {error}}
), })); @@ -88,7 +88,7 @@ jest.mock('@/components/ui/labeled-textarea', () => ({ data-testid={dataTestId || 'labeled-textarea'} {...props} /> - {error && {error}} + {error && {error}}
), })); diff --git a/src/app/(marketing)/contact/contact-content-v3.tsx b/src/app/(marketing)/contact/contact-content-v3.tsx index 536d53e..0ed5fb6 100644 --- a/src/app/(marketing)/contact/contact-content-v3.tsx +++ b/src/app/(marketing)/contact/contact-content-v3.tsx @@ -239,7 +239,7 @@ function ContactFormContent({ data }: { data: ContactData }) {
0 ? 'mt-4 sm:mt-6' : ''}`}> {i === 1 ? ( - + {line} {data.emailLabel || ''}

{emailAddress} @@ -317,12 +317,12 @@ function ContactFormContent({ data }: { data: ContactData }) {
-
{data.dayLabel || ''} - {data.hours || ''} + {data.hours || ''}
@@ -358,13 +358,13 @@ function ContactFormContent({ data }: { data: ContactData }) { {Object.keys(errors).length > 0 && (
-

+

请修正以下 {Object.keys(errors).length} 项内容: