@tailwind base; @tailwind components; @tailwind utilities; html { background-color: var(--color-bg-primary) !important; } body { background-color: var(--color-bg-primary) !important; color: var(--color-text-primary) !important; } :root { /* === 咨询专业 · 色彩体系(浅色模式) === */ /* 墨色核心 */ --color-ink: #0A0E14; --color-ink-light: #0F1419; --color-ink-lighter: #151B23; --color-ink-rgb: 10 14 20; /* 品牌信号色:朱砂红 — Committed 色彩策略(Bain 式自信表达) */ --color-brand: #C41E3A; --color-brand-hover: #A01830; --color-brand-light: #E04A68; --color-brand-soft: rgba(196, 30, 58, 0.12); --color-brand-bg: #FEF2F4; /* Tailwind 无法对「任意值形式的裸 var()」套用 /NN 透明度修饰符(bg-[var(--color-brand-bg)] 再加 /50 编译后 0 条规则,静默失效),故底色通道也要提供 rgb 三元组,配合 tailwind.config.js 的 brand.bg = rgb(var(--color-brand-bg-rgb) / ) 让 bg-brand-bg/50 正确生成。 254 242 244 = #FEF2F4,alpha 默认 1 时与裸 var() 同色,无视觉漂移。 */ --color-brand-bg-rgb: 254 242 244; --color-brand-rgb: 196 30 58; /* 品牌「文字墨色」专用通道(text-brand-ink)。 与 --color-brand-rgb 分离的原因:--color-brand-rgb 同时服务 bg-brand / border-brand, 而红底白字按钮在深底上仍需 #C41E3A(实测 5.58:1); 一旦随主题提亮,按钮会掉到 3.75:1。故文字与底色必须走两条通道。 深色下取 #F87171(248 113 113):于 #0A0E14/#0F1419/#151B23 分别 6.99/6.69/6.26,全达 AA。 */ --color-brand-ink: #C41E3A; --color-brand-ink-rgb: 196 30 58; /* 品牌红文字通道的 hover 档:与 --color-brand-hover(底色通道)分离, 暗色下必须提亮,否则 #A01830 压在 #0A0E14 上仅 2.06:1(验收 A-12 残留项)。 */ --color-brand-ink-hover: #A01830; --color-brand-ink-hover-rgb: 160 24 48; /* 详情页 Hero badge 的 accent 文字色(accentColor 由各页 hero-themes 传入, 经 --badge-accent 自定义属性注入)。浅色 = 原色;深色 = 45% accent + 55% 白的提亮变体 —— accentColor 多为深色系(#1e3a5f 等),直接用作深底文字仅 1.65:1 */ --badge-accent-text: var(--badge-accent, var(--color-ink)); /* 品牌色深色区块(Bain 式深红背景) */ --color-brand-section: #8B1530; --color-brand-section-text: #F8FAFC; --color-brand-section-muted: rgba(248, 250, 252, 0.7); /* 辅助色:服务/行业编码 */ --color-accent-blue: #3B82F6; --color-accent-blue-soft: rgba(59, 130, 246, 0.12); --color-accent-blue-rgb: 59 130 246; --color-accent-teal: #14B8A6; --color-accent-teal-soft: rgba(20, 184, 166, 0.12); --color-accent-teal-rgb: 20 184 166; --color-accent-amber: #F59E0B; --color-accent-amber-soft: rgba(245, 158, 11, 0.12); --color-accent-amber-rgb: 245 158 11; --color-accent-purple: #8B5CF6; --color-accent-purple-soft: rgba(139, 92, 246, 0.12); --color-accent-purple-rgb: 139 92 246; --color-accent-cyan: #06B6D4; --color-accent-cyan-soft: rgba(6, 182, 212, 0.12); --color-accent-cyan-rgb: 6 182 212; --color-accent-rose: #E11D48; --color-accent-rose-soft: rgba(225, 29, 72, 0.12); --color-accent-rose-rgb: 225 29 72; --color-accent-indigo: #4F46E5; --color-accent-indigo-soft: rgba(79, 70, 229, 0.12); --color-accent-indigo-rgb: 79 70 229; /* 背景色层级 */ --color-bg-primary: #FFFFFF; --color-bg-secondary: #F8FAFC; --color-bg-secondary-rgb: 248 250 252; --color-bg-tertiary: #F1F5F9; --color-bg-section: #F8FAFC; /* 同 --color-brand-bg-rgb 的理由:bg-[var(--color-bg-section)] 再加 /60 这类写法编译后 0 条规则。 与 --color-bg-secondary-rgb 当前同值但语义不同(section ≠ secondary),故独立建三元组, 避免任一 token 调整时静默串色。248 250 252 = #F8FAFC。 */ --color-bg-section-rgb: 248 250 252; --color-bg-hover: #F1F5F9; --color-bg-elevated: #FFFFFF; --color-bg-primary-rgb: 255 255 255; /* 文字色层级 */ --color-text-primary: #0A0E14; --color-text-secondary: #334155; --color-text-secondary-rgb: 51 65 85; --color-text-tertiary: #475569; --color-text-muted: #64748B; --color-text-muted-rgb: 100 116 139; --color-text-subtle: #64748B; --color-text-placeholder: #64748B; /* 仅用于 ≥24px 大号装饰性文本(如章节序号),对白底 3.41:1,满足 AA 大字 3:1。 正文、占位符、提示文案请改用 --color-text-placeholder(4.76:1)或更深的令牌。 */ --color-text-hint: #7C8CA5; --color-text-inverse: #FFFFFF; /* 边框色层级 —— 中度软化:--color-border-primary 从 #E2E8F0 调整为 #EEF2F7(更淡), 让 20 处 gap-px bg-border-primary 网格线与所有卡片边框都自动弱化(约 50%), 与增强的卡片阴影呼应,视觉从"靠硬边分界"转为"靠阴影分层"。 */ --color-border-primary: #EEF2F7; --color-border-primary-rgb: 238 242 247; --color-border-secondary: #CBD5E1; --color-border-secondary-rgb: 203 213 225; --color-border-accent: #0A0E14; --color-border-accent-rgb: 10 14 20; --color-border-light: #F1F5F9; --color-border-light-rgb: 241 245 249; --color-border-dark: #334155; --color-border-dark-rgb: 51 65 85; --color-border-brand: #C41E3A; --color-border-brand-rgb: 196 30 58; /* 链接色 */ --color-link: #0A0E14; --color-link-hover: #C41E3A; /* 功能色 */ --color-success: #16A34A; --color-success-hover: #15803D; --color-success-bg: #F0FDF4; --color-success-rgb: 22 163 74; /* 文字专用:--color-success 仅 3.30:1,作正文色不达 AA;本值 5.02:1(于 success-bg 上 4.79:1) */ --color-success-text: #15803D; --color-warning: #D97706; --color-warning-hover: #B45309; --color-warning-bg: #FFFBEB; --color-warning-rgb: 217 119 6; /* 文字专用:--color-warning 仅 3.19:1,作正文色不达 AA;本值 5.02:1(于 warning-bg 上 4.84:1) */ --color-warning-text: #B45309; --color-error: #C41E3A; --color-error-hover: #A01830; --color-error-bg: #FEF2F4; --color-error-rgb: 196 30 58; /* 文字专用:--color-error(品牌红)在暗黑底仅 3.3:1,不达 AA;本值浅红, 暗黑模式经 html[data-theme='dark'] 覆盖(#F87171)后于暗底达 AA。 */ --color-error-text: #C41E3A; --color-info: #3B82F6; --color-info-rgb: 59 130 246; --color-info-bg: #EFF6FF; /* 文字专用:--color-info 仅 3.68:1,作正文色不达 AA;本值 6.70:1(于 info-bg 上 6.16:1) */ --color-info-text: #1D4ED8; /* 深色调性区域 */ --color-dark-bg: #0A0E14; --color-dark-bg-secondary: #0F1419; --color-dark-bg-tertiary: #151B23; --color-dark-text-primary: #F8FAFC; --color-dark-text-secondary: #CBD5E1; --color-dark-text-muted: #94A3B8; --color-dark-border: #1E293B; /* 遮罩 / 深色叠加层(dialog 背板、metric-card 深色半透明底): 语义上"永远是深色覆盖",不随暗黑模式反色 —— 故用独立 token。 */ --color-overlay: #0A0E14; --color-overlay-rgb: 10 14 20; /* 阴影系统(按层级 + 用途分类) */ /* 基础层级:几乎看不见,用于微妙的边界定义 */ --shadow-xs: 0 1px 1px rgba(10, 14, 20, 0.03); /* 轻量:卡片默认状态、输入框 */ --shadow-sm: 0 1px 3px rgba(10, 14, 20, 0.04), 0 1px 2px rgba(10, 14, 20, 0.02); /* 中等:悬浮状态、下拉菜单 */ --shadow-md: 0 4px 12px rgba(10, 14, 20, 0.06), 0 2px 4px rgba(10, 14, 20, 0.03); /* 大型:模态框、悬浮卡片 */ --shadow-lg: 0 12px 28px rgba(10, 14, 20, 0.08), 0 4px 8px rgba(10, 14, 20, 0.04); /* 超大:全屏弹窗、重要浮层 */ --shadow-xl: 0 24px 56px rgba(10, 14, 20, 0.1), 0 8px 16px rgba(10, 14, 20, 0.06); /* 品牌阴影:CTA 按钮、品牌强调元素 */ --shadow-brand: 0 6px 24px rgba(196, 30, 58, 0.22); --shadow-brand-hover: 0 8px 32px rgba(196, 30, 58, 0.32); /* 内阴影:凹陷效果、输入框聚焦 */ --shadow-inset: inset 0 2px 4px rgba(10, 14, 20, 0.04); /* 光晕阴影:发光效果(慎用) */ --shadow-glow: 0 0 40px rgba(196, 30, 58, 0.15); /* 字体系统 字族按「逐字符」回退:拉丁字母命中 Geist(无 CJK 字形), 中文自动落到后面的 PingFang SC / 微软雅黑。 var() 必须给回退值,否则 next/font 变量缺失时整条声明会失效。 */ --font-sans: var(--font-geist-sans, ui-sans-serif), "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-display: var(--font-geist-sans, ui-sans-serif), "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-mono: var(--font-geist-mono, ui-monospace), SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; --font-brand: "STKaiti", "KaiTi", "楷体", "SimKai", serif; --font-calligraphy-system: "STKaiti", "KaiTi", "楷体", "SimKai", serif; --font-serif: "Songti SC", "STSongti-SC", "Noto Serif CJK SC", "SimSun", "STSong", serif; /* 字号系统(12级排版尺度)—— Mobile First,默认移动端 */ --font-size-caption: 0.6875rem; --font-size-xs: 0.75rem; --font-size-sm: 0.875rem; --font-size-base: 1rem; --font-size-lg: 1.0625rem; --font-size-xl: 1.1875rem; --font-size-2xl: 1.25rem; --font-size-3xl: 1.5rem; --font-size-4xl: 1.875rem; --font-size-5xl: 2.25rem; --font-size-6xl: 3rem; --font-size-7xl: 3.5rem; --font-size-display: 4.5rem; /* 行高系统(与字号对应) */ --line-height-caption: 1.4; --line-height-tight: 1.15; --line-height-snug: 1.35; --line-height-normal: 1.65; --line-height-relaxed: 1.85; /* 字间距系统(按使用场景分层) */ --letter-spacing-tighter: -0.03em; /* 展示标题,不低于 -0.04em 地板 */ --letter-spacing-tight: -0.02em; --letter-spacing-normal: 0; --letter-spacing-wide: 0.03em; --letter-spacing-wider: 0.06em; --letter-spacing-widest: 0.12em; --letter-spacing-eyebrow: 0.12em; /* 减小,避免过宽追踪 */ /* 段落间距 */ --paragraph-spacing: 1.25em; --paragraph-spacing-loose: 1.75em; /* 间距系统 */ --spacing-xs: 0.25rem; --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 1.5rem; --spacing-xl: 2rem; --spacing-2xl: 3rem; --spacing-3xl: 4rem; --spacing-4xl: 6rem; --spacing-5xl: 8rem; --spacing-6xl: 12rem; /* 圆角系统(按用途分类)—— 中度软化:4→6/6→8/10→12/14→18, 让"硬边"卡片语言变为"柔边",与增强的卡片阴影呼应。 注意:SM/MD/LG 同步联动大量 Tailwind 圆角类,全局生效。 */ --radius-xs: 3px; /* 极小:标签、徽章 */ --radius-sm: 6px; /* 小:按钮、输入框 */ --radius-md: 8px; /* 中:卡片、弹窗 */ --radius-lg: 12px; /* 大:大型卡片、容器 */ --radius-xl: 18px; /* 特大:英雄卡片、特色模块 */ --radius-2xl: 24px; /* 超大:全屏弹窗、大型容器 */ --radius-3xl: 32px; /* 巨大:展示卡片 */ --radius-full: 9999px; /* 圆形:头像、圆形按钮 */ /* 过渡系统(按时长分级) */ --transition-instant: 100ms; --transition-fast: 180ms; --transition-normal: 280ms; --transition-slow: 450ms; --transition-slower: 700ms; --transition-gentle: 1000ms; /* 缓动曲线(按性格分类) */ /* 标准:通用入场、状态变化(最常用) */ --ease-standard: cubic-bezier(0.4, 0, 0.2, 1); /* 减速:元素入场(快速开始,轻柔结束) */ --ease-decelerate: cubic-bezier(0, 0, 0.2, 1); /* 加速:元素退场(轻柔开始,快速结束) */ --ease-accelerate: cubic-bezier(0.4, 0, 1, 1); /* 锐利:精确、专业的感觉(数据变化、指标跳动) */ --ease-sharp: cubic-bezier(0.65, 0, 0.35, 1); /* 水墨:柔和、有呼吸感(背景过渡、光晕变化) */ --ease-ink: cubic-bezier(0.22, 1, 0.36, 1); /* ease-out 别名:默认使用水墨曲线(Porsche 风格:快速开始,缓慢结束) */ --ease-out: cubic-bezier(0.22, 1, 0.36, 1); /* 动效延迟序列(错落动效用)—— 已删除:--stagger-xs…xl 此前零消费者。 全站 stagger 全部由 framer-motion 以「秒」为单位的数值驱动 (transition.delay / variants.staggerChildren),CSS 自定义属性无法被 transition.delay 读取(除非物质化 getComputedStyle),故令牌在此形同虚设。 唯一事实来源改为 JS:src/components/ui/scroll-reveal.tsx(StaggerReveal 默认 staggerDelay = 0.05)与 page-transition.tsx。 取值区间按 CONTEXT.md「动效设计四原则」4:子元素 stagger 30–60ms、 Section 间 stagger 100–150ms。 */ /* 容器宽度 */ --container-max: 1360px; --container-padding: 1rem; /* === 组件令牌层(Component Tokens)=== */ /* 按钮 */ --btn-height-sm: 2.25rem; --btn-height-md: 2.75rem; --btn-height-lg: 3.25rem; --btn-padding-x: 1.5rem; --btn-font-size: 0.875rem; /* 卡片 —— 中度软化:阴影加深(透明度 0.06→0.08),新增 y 偏移的 hover 抬升过渡。 让卡片从"靠 1px 硬边分界"变为"靠柔和阴影分层",与增大圆角呼应。 */ --card-padding: 1.5rem; --card-padding-lg: 2.5rem; --card-gap: 1.5rem; --card-border-radius: var(--radius-lg); --card-shadow: 0 1px 2px rgba(10, 14, 20, 0.04), 0 2px 8px rgba(10, 14, 20, 0.08); --card-shadow-hover: 0 4px 12px rgba(10, 14, 20, 0.06), 0 12px 32px rgba(10, 14, 20, 0.12); --card-border: 1px solid var(--color-border-light); --card-transition: transform var(--transition-normal) var(--ease-out), box-shadow var(--transition-normal) var(--ease-out), border-color var(--transition-normal) var(--ease-out); /* 输入框 */ --input-height: 2.75rem; --input-padding-x: 1rem; --input-border-radius: var(--radius-sm); /* Section 间距 —— Mobile First,默认移动端 —— 中度软化:节奏更舒展 */ --section-gap: var(--spacing-4xl); --section-gap-sm: var(--spacing-3xl); --section-padding-y: var(--spacing-4xl); /* === 组件令牌层(Component Tokens)=== */ /* Badge 标签 */ --badge-height-sm: 1.25rem; --badge-height-md: 1.5rem; --badge-padding-x: 0.625rem; --badge-font-size: 0.6875rem; --badge-radius: var(--radius-full); /* Tabs 标签页 */ --tab-height: 2.5rem; --tab-padding-x: 1rem; --tab-font-size: 0.875rem; --tab-indicator-height: 2px; /* Modal / Dialog 弹窗 */ --modal-padding: 2rem; --modal-radius: var(--radius-xl); --modal-max-width-sm: 420px; --modal-max-width-md: 560px; --modal-max-width-lg: 720px; /* Tooltip 提示 */ --tooltip-padding: 0.5rem 0.75rem; --tooltip-radius: var(--radius-sm); --tooltip-font-size: 0.75rem; /* Form 表单 */ --label-font-size: 0.875rem; --label-margin-bottom: 0.5rem; --form-group-gap: 1.25rem; /* Avatar 头像 */ --avatar-size-sm: 2rem; --avatar-size-md: 2.5rem; --avatar-size-lg: 3rem; --avatar-radius: var(--radius-full); /* Table 表格 */ --table-header-bg: var(--color-bg-secondary); --table-header-font-size: 0.75rem; --table-cell-padding-y: 0.75rem; --table-cell-padding-x: 1rem; --table-border-color: var(--color-border-primary); /* Breadcrumb 面包屑 */ --breadcrumb-font-size: 0.875rem; --breadcrumb-separator-margin: 0.5rem; /* Menu / Dropdown 菜单 */ --menu-item-height: 2.5rem; --menu-padding-y: 0.5rem; --menu-min-width: 180px; /* Accordion 手风琴 */ --accordion-item-gap: 0.5rem; --accordion-trigger-height: 3rem; --accordion-trigger-padding-x: 1rem; /* === 12 列网格系统(Grid System)=== */ --grid-columns: 12; --grid-gap-xs: 0.5rem; --grid-gap-sm: 1rem; --grid-gap-md: 1.5rem; --grid-gap-lg: 2rem; --grid-gap-xl: 2.5rem; --grid-gap-2xl: 3rem; } /* === Logo 明暗双版(html[data-theme] 驱动)=== 站点主题由 html[data-theme='dark'] 属性驱动,而非 .dark class, 因此 Tailwind dark: 变体(darkMode:'class')不匹配 —— 用显式属性选择器切换。 - logo.svg(深黑字)用于浅色背景;logo-white.svg(白字)用于深色背景。 两个 都在 DOM 内、按 data-theme 显隐(display:none,不占位), 无 JS 闪烁,未来主题切换器改 data-theme 时自动生效。 SSR 初始 HTML 无 data-theme → 默认显示 light 版,head 内联脚本同步设置 data-theme 后即时切换,不产生重叠。 */ html[data-theme='dark'] .logo-on-light { display: none; } html:not([data-theme='dark']) .logo-on-dark { display: none; } /* === 暗黑模式(html[data-theme='dark'])=== 策略:仅覆盖 CSS 变量,组件无需逐元素反色。 - 文字墨色 --color-ink 反色为浅色(其语义收窄为"文字/描边跟随主题") - 页面底色 --color-bg-* 反色为深色 - 深色区块(--color-dark-* / --color-brand-section / --color-overlay / footer) 使用独立 token,不随反色 —— 由组件显式引用(如 bg-dark-bg) */ html[data-theme='dark'] { /* 墨色反色 → 文字浅色 */ --color-ink: #F8FAFC; --color-ink-light: #E2E8F0; --color-ink-lighter: #CBD5E1; --color-ink-rgb: 248 250 252; /* 页面底色反色 */ --color-bg-primary: #0A0E14; --color-bg-primary-rgb: 10 14 20; --color-bg-secondary: #0F1419; --color-bg-secondary-rgb: 15 20 25; --color-bg-tertiary: #151B23; --color-bg-section: #0F1419; /* 与 :root 的 --color-bg-section-rgb 成对覆写,否则深色下 bg-bg-section/NN 会退回浅色值 */ --color-bg-section-rgb: 15 20 25; --color-bg-hover: #151B23; --color-bg-elevated: #151B23; /* 文字层级反色 */ --color-text-primary: #F8FAFC; --color-text-secondary: #CBD5E1; --color-text-secondary-rgb: 203 213 225; --color-text-tertiary: #94A3B8; --color-text-muted: #94A3B8; --color-text-muted-rgb: 148 163 184; --color-text-subtle: #94A3B8; --color-text-placeholder: #94A3B8; --color-text-hint: #94A3B8; --color-text-inverse: #0A0E14; /* 边框层级反色 */ --color-border-primary: #1E293B; --color-border-primary-rgb: 30 41 59; --color-border-secondary: #334155; --color-border-secondary-rgb: 51 65 85; --color-border-accent: #F8FAFC; --color-border-accent-rgb: 248 250 252; --color-border-light: #1E293B; --color-border-light-rgb: 30 41 59; --color-border-dark: #CBD5E1; --color-border-dark-rgb: 203 213 225; /* 链接反色 */ --color-link: #F8FAFC; --color-link-hover: #E04A68; /* 功能色反色:浅色调背景 → 深色同色调底;文字/图标 → 同色调浅色,于暗底达 AA。 按钮底色(DEFAULT)与边框(border-*)保持品牌饱和色,暗黑底仍可读/可见,故不覆盖。 */ --color-success-bg: #0E2A1A; --color-success-text: #4ADE80; --color-warning-bg: #2A2008; --color-warning-text: #FBBF24; --color-error-bg: #2A1418; --color-error-text: #F87171; --color-info-bg: #0E1A2A; --color-info-text: #60A5FA; /* 品牌色分两条通道,只有「文字」通道翻转: - --color-brand / --color-brand-rgb(bg-brand、border-brand)**刻意不翻**:红底白字实测 5.58:1, 若随主题提亮到 #E04A68 反而掉到 3.75:1。 - --color-brand-ink-rgb(text-brand-ink)→ #F87171,与上方 --color-error-text 同值,不引入新色; 于三种深底 6.99 / 6.69 / 6.26,全达 AA。 - --color-brand-bg 补齐:它与 --color-error-bg 在浅色下同为 #FEF2F4, 此前只翻了 error-bg,导致深色下白字压浅粉底仅 1.04:1(首页「首批客户共创计划」卡)。 */ --color-brand-ink: #F87171; --color-brand-ink-rgb: 248 113 113; --color-brand-ink-hover: #FCA5A5; --color-brand-ink-hover-rgb: 252 165 165; --color-brand-bg: #2A1418; /* 42 20 24 = #2A1418;与上方 --color-brand-bg 同步翻转,否则 bg-brand-bg/NN 在深色下仍是浅粉 */ --color-brand-bg-rgb: 42 20 24; /* hero 徽章文字:accentColor 直用作深底文字不可读(如 #1e3a5f 于 #0B1119 仅 1.65:1), 深色下按 accent 45% + 白 55% 提亮;--badge-accent 未注入时回退到反色墨字。 */ --badge-accent-text: color-mix(in srgb, var(--badge-accent, var(--color-ink)) 45%, white); } /* html/body 背景跟随主题 token(覆盖顶部 !important 硬编码) */ html[data-theme='dark'], html[data-theme='dark'] body { background-color: var(--color-bg-primary) !important; color: var(--color-text-primary) !important; } @layer base { * { @apply antialiased; border-color: var(--color-border-primary); } html { scroll-behavior: smooth; /* 桌面端字号分级(mobile-first 16 → tablet 17 → desktop 18): 桌面端 18px 根字号使所有 rem 单位放大 12.5%,标题与留白更舒展, 与增强的圆角+阴影形成"软化"语言。 权衡:会覆盖用户浏览器字号缩放设置 —— 经 design review 决定保留视觉一致性。 */ font-size: 16px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; overflow-x: hidden; } @media (min-width: 640px) { html { font-size: 17px; } } @media (min-width: 1024px) { html { font-size: 18px; } } body { background-color: var(--color-bg-primary); color: var(--color-text-primary); font-family: var(--font-sans); line-height: var(--line-height-normal); letter-spacing: var(--letter-spacing-normal); position: relative; overflow-x: hidden; width: 100%; transition: background-color var(--transition-normal) var(--ease-out), color var(--transition-normal) var(--ease-out); } body::before { content: ''; position: fixed; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none; z-index: -1; } h1, h2, h3, h4, h5, h6 { font-weight: 700; line-height: var(--line-height-tight); letter-spacing: var(--letter-spacing-tight); color: var(--color-text-primary); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } h1 { font-size: var(--font-size-5xl); letter-spacing: var(--letter-spacing-tighter); font-weight: 800; } h2 { font-size: var(--font-size-4xl); letter-spacing: var(--letter-spacing-tight); font-weight: 700; } h3 { font-size: var(--font-size-2xl); letter-spacing: var(--letter-spacing-tight); font-weight: 700; } h4 { font-size: var(--font-size-xl); letter-spacing: var(--letter-spacing-normal); font-weight: 600; } h5 { font-size: var(--font-size-lg); letter-spacing: var(--letter-spacing-normal); font-weight: 600; } h6 { font-size: var(--font-size-base); letter-spacing: var(--letter-spacing-wide); font-weight: 600; text-transform: uppercase; } p { color: var(--color-text-secondary); line-height: var(--line-height-relaxed); margin-bottom: var(--paragraph-spacing); } p:last-child { margin-bottom: 0; } /* 列表样式优化 */ ul, ol { color: var(--color-text-secondary); line-height: var(--line-height-relaxed); margin-bottom: var(--paragraph-spacing); padding-left: 1.5em; } li { margin-bottom: 0.5em; } li:last-child { margin-bottom: 0; } ul { list-style-type: none; } ul li::before { content: ''; position: absolute; left: 0; top: 0.75em; width: 6px; height: 6px; border-radius: 1px; background: var(--color-brand); transform: rotate(45deg); } ul li { position: relative; padding-left: 0.5em; } /* 引用样式 */ blockquote { border-left: 3px solid var(--color-brand); padding-left: 1.5em; margin: 2em 0; font-size: var(--font-size-lg); color: var(--color-text-primary); font-style: normal; line-height: var(--line-height-relaxed); background: var(--color-bg-secondary); padding: 1.5em 2em; border-radius: 0 var(--radius-md) var(--radius-md) 0; } /* 强调文本 */ strong { font-weight: 600; color: var(--color-text-primary); } /* 代码样式 */ code { font-family: var(--font-mono); font-size: 0.9em; background: var(--color-bg-tertiary); padding: 0.15em 0.4em; border-radius: var(--radius-sm); color: var(--color-brand-ink); } pre { font-family: var(--font-mono); font-size: var(--font-size-sm); line-height: var(--line-height-snug); background: var(--color-dark-bg); color: var(--color-dark-text-primary); padding: 1.5em; border-radius: var(--radius-lg); overflow-x: auto; margin: 2em 0; } pre code { background: transparent; padding: 0; color: inherit; font-size: inherit; } /* 水平分隔线 */ hr { border: none; height: 1px; background: var(--color-border-primary); margin: 3em 0; } /* 数字和符号的字体优化 */ .tabular-nums { font-variant-numeric: tabular-nums; } .oldstyle-nums { font-variant-numeric: oldstyle-nums; } /* 小字说明文字 */ .caption { font-size: var(--font-size-caption); line-height: var(--line-height-caption); color: var(--color-text-muted); letter-spacing: var(--letter-spacing-wide); } /* 眉毛标签(Eyebrow Label) */ .eyebrow { font-size: var(--font-size-xs); font-weight: 600; letter-spacing: var(--letter-spacing-eyebrow); text-transform: uppercase; color: var(--color-brand-ink); } a { color: var(--color-link); text-decoration: none; transition: color var(--transition-fast) var(--ease-out); } a:hover { color: var(--color-link-hover); } a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; border-radius: 4px; } button:focus:not(:focus-visible), a:focus:not(:focus-visible), input:focus:not(:focus-visible), textarea:focus:not(:focus-visible) { outline: none; } button { font-family: inherit; cursor: pointer; } input, textarea { font-family: inherit; outline: none; } input:focus, textarea:focus { outline: none; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } @media (prefers-contrast: more) { :root { --color-text-primary: #000000; --color-text-secondary: #1a1a1a; --color-border-primary: #000000; /* Tailwind border-* 工具类消费 rgb 通道,需同步覆写,否则高对比度模式下边框静默失效 */ --color-border-primary-rgb: 0 0 0; } } .font-brand { font-family: var(--font-brand), "STKaiti", "KaiTi", serif !important; font-weight: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; } ::selection { background-color: var(--color-brand); color: white; } } @layer utilities { .container-x { width: 100%; max-width: var(--container-max); margin-left: auto; margin-right: auto; padding-left: var(--container-padding); padding-right: var(--container-padding); } @media (min-width: 768px) { .container-x { --container-padding: 2.5rem; } } @media (min-width: 1024px) { .container-x { --container-padding: 3rem; } } .section-padding { padding-top: var(--section-padding-y); padding-bottom: var(--section-padding-y); } .text-balance { text-wrap: balance; } .bg-dots { background-image: radial-gradient(circle, var(--color-border-primary) 1px, transparent 1px); background-size: 24px 24px; } /* === Hero 工程网格 + 品牌红光标聚光(L1 静态网格 + L2 聚光)=== L1 工程网格(hero-grid-overlay--light/dark):墨色 hairline 44px 网格 + 径向遮罩聚焦版心,零 JS 自动反色。 L2 聚光层(hero-spot-glow)用 2 个 CSS 变量(--spot-x/--spot-y)跟随光标,无 canvas、无逐帧 JS。 旧点阵类 hero-dot-grid/hero-dot-spot 已被工程网格取代,2026-09-01 清理。 */ :root { --spot-x: 50%; --spot-y: 50%; } /* Hero 科技感工程网格层(浅色/深色 Hero 共用,跟随 HERO_VARIANT 切换) */ .hero-grid-overlay--dark { background-image: linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px); background-size: 44px 44px; -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 35%, transparent 82%); mask-image: radial-gradient(circle at 50% 50%, #000 35%, transparent 82%); } .hero-grid-overlay--light { background-image: linear-gradient(rgba(10, 14, 20, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(10, 14, 20, 0.05) 1px, transparent 1px); background-size: 44px 44px; -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 35%, transparent 82%); mask-image: radial-gradient(circle at 50% 50%, #000 35%, transparent 82%); } /* 品牌红光标聚光(spotlight 变体):跟随 --spot-x/--spot-y,无 canvas、无逐帧 JS */ .hero-spot-glow { background: radial-gradient(440px circle at var(--spot-x) var(--spot-y), rgba(var(--color-brand-rgb), 0.16), transparent 60%); } .bg-grain { position: relative; } .bg-grain::before { content: ''; position: absolute; inset: 0; opacity: 0.04; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E"); background-repeat: repeat; background-size: 128px 128px; pointer-events: none; z-index: 0; } .bg-glow-brand { background: radial-gradient(ellipse at 50% 0%, rgba(var(--color-brand-rgb), 0.08) 0%, transparent 60%); } /* Bain 式干净卡片(替代旧墨韵光晕卡片) */ .bain-card { background: var(--color-bg-primary); border: var(--card-border); border-radius: var(--card-border-radius); box-shadow: var(--card-shadow); transition: transform var(--transition-fast) var(--ease-out), box-shadow var(--transition-fast) var(--ease-out); } .bain-card:hover { transform: translateY(-4px); box-shadow: var(--card-shadow-hover); } /* === Bain 式不对称布局系统 === */ /* 宽窄列:左宽右窄(65/35) */ .asymmetric-wide-narrow { display: grid; grid-template-columns: 1fr; gap: var(--spacing-2xl); } @media (min-width: 1024px) { .asymmetric-wide-narrow { grid-template-columns: 5fr 3fr; gap: var(--spacing-4xl); } } /* 宽窄列:左窄右宽(35/65) */ .asymmetric-narrow-wide { display: grid; grid-template-columns: 1fr; gap: var(--spacing-2xl); } @media (min-width: 1024px) { .asymmetric-narrow-wide { grid-template-columns: 3fr 5fr; gap: var(--spacing-4xl); } } /* 不对称三列:左宽 + 中窄 + 右窄(50/25/25) */ .asymmetric-three { display: grid; grid-template-columns: 1fr; gap: var(--spacing-2xl); } @media (min-width: 1024px) { .asymmetric-three { grid-template-columns: 2fr 1fr 1fr; gap: var(--spacing-3xl); } } /* 大留白区块:用于 Hero 下方过渡 */ .section-breathing { padding-top: var(--spacing-5xl); padding-bottom: var(--spacing-5xl); } @media (min-width: 768px) { .section-breathing { padding-top: var(--spacing-6xl); padding-bottom: var(--spacing-6xl); } } /* 紧致区块:用于数据密集区 */ .section-compact { padding-top: var(--spacing-2xl); padding-bottom: var(--spacing-2xl); } @media (min-width: 768px) { .section-compact { padding-top: var(--spacing-3xl); padding-bottom: var(--spacing-3xl); } } /* 品牌色深色区块(Bain 式 Hero/CTA 深红背景) */ .bg-brand-section { background-color: var(--color-brand-section); color: var(--color-brand-section-text); } .bg-glow-hero { background: radial-gradient(ellipse at 20% 30%, rgba(var(--color-brand-rgb), 0.1) 0%, transparent 50%), radial-gradient(ellipse at 80% 70%, rgba(var(--color-accent-blue-rgb), 0.06) 0%, transparent 50%); } /* 斜切装饰(Accenture 风格) */ .clip-slant-right { clip-path: polygon(0 0, 100% 0, 92% 100%, 0 100%); } .clip-slant-left { clip-path: polygon(8% 0, 100% 0, 100% 100%, 0 100%); } /* 渐变分隔线 */ .divider-gradient { height: 1px; background: linear-gradient(90deg, transparent, var(--color-border-secondary), transparent); } /* L 形角框 */ .corner-frame { position: relative; } .corner-frame::before, .corner-frame::after { content: ''; position: absolute; width: 16px; height: 16px; border-color: var(--color-brand); border-style: solid; transition: all var(--transition-normal) var(--ease-out); } .corner-frame::before { top: 0; left: 0; border-width: 2px 0 0 2px; } .corner-frame::after { bottom: 0; right: 0; border-width: 0 2px 2px 0; } /* 编号样式(超大背景编号) */ .bg-number { font-size: clamp(6rem, 20vw, 16rem); font-weight: 900; line-height: 0.8; color: transparent; -webkit-text-stroke: 1px var(--color-border-primary); user-select: none; pointer-events: none; } /* === 12 列网格系统 === */ .grid-12 { display: grid; grid-template-columns: repeat(12, 1fr); } .grid-gap-xs { gap: var(--grid-gap-xs); } .grid-gap-sm { gap: var(--grid-gap-sm); } .grid-gap-md { gap: var(--grid-gap-md); } .grid-gap-lg { gap: var(--grid-gap-lg); } .grid-gap-xl { gap: var(--grid-gap-xl); } .grid-gap-2xl { gap: var(--grid-gap-2xl); } /* 列跨越(1-12) */ .col-span-1 { grid-column: span 1 / span 1; } .col-span-2 { grid-column: span 2 / span 2; } .col-span-3 { grid-column: span 3 / span 3; } .col-span-4 { grid-column: span 4 / span 4; } .col-span-5 { grid-column: span 5 / span 5; } .col-span-6 { grid-column: span 6 / span 6; } .col-span-7 { grid-column: span 7 / span 7; } .col-span-8 { grid-column: span 8 / span 8; } .col-span-9 { grid-column: span 9 / span 9; } .col-span-10 { grid-column: span 10 / span 10; } .col-span-11 { grid-column: span 11 / span 11; } .col-span-12 { grid-column: span 12 / span 12; } /* 响应式列跨越 */ @media (min-width: 640px) { .sm\:col-span-1 { grid-column: span 1 / span 1; } .sm\:col-span-2 { grid-column: span 2 / span 2; } .sm\:col-span-3 { grid-column: span 3 / span 3; } .sm\:col-span-4 { grid-column: span 4 / span 4; } .sm\:col-span-5 { grid-column: span 5 / span 5; } .sm\:col-span-6 { grid-column: span 6 / span 6; } .sm\:col-span-7 { grid-column: span 7 / span 7; } .sm\:col-span-8 { grid-column: span 8 / span 8; } .sm\:col-span-9 { grid-column: span 9 / span 9; } .sm\:col-span-10 { grid-column: span 10 / span 10; } .sm\:col-span-11 { grid-column: span 11 / span 11; } .sm\:col-span-12 { grid-column: span 12 / span 12; } } @media (min-width: 768px) { .md\:col-span-1 { grid-column: span 1 / span 1; } .md\:col-span-2 { grid-column: span 2 / span 2; } .md\:col-span-3 { grid-column: span 3 / span 3; } .md\:col-span-4 { grid-column: span 4 / span 4; } .md\:col-span-5 { grid-column: span 5 / span 5; } .md\:col-span-6 { grid-column: span 6 / span 6; } .md\:col-span-7 { grid-column: span 7 / span 7; } .md\:col-span-8 { grid-column: span 8 / span 8; } .md\:col-span-9 { grid-column: span 9 / span 9; } .md\:col-span-10 { grid-column: span 10 / span 10; } .md\:col-span-11 { grid-column: span 11 / span 11; } .md\:col-span-12 { grid-column: span 12 / span 12; } } @media (min-width: 1024px) { .lg\:col-span-1 { grid-column: span 1 / span 1; } .lg\:col-span-2 { grid-column: span 2 / span 2; } .lg\:col-span-3 { grid-column: span 3 / span 3; } .lg\:col-span-4 { grid-column: span 4 / span 4; } .lg\:col-span-5 { grid-column: span 5 / span 5; } .lg\:col-span-6 { grid-column: span 6 / span 6; } .lg\:col-span-7 { grid-column: span 7 / span 7; } .lg\:col-span-8 { grid-column: span 8 / span 8; } .lg\:col-span-9 { grid-column: span 9 / span 9; } .lg\:col-span-10 { grid-column: span 10 / span 10; } .lg\:col-span-11 { grid-column: span 11 / span 11; } .lg\:col-span-12 { grid-column: span 12 / span 12; } } /* 网格行跨越 */ .row-span-1 { grid-row: span 1 / span 1; } .row-span-2 { grid-row: span 2 / span 2; } .row-span-3 { grid-row: span 3 / span 3; } } /* ===== 动画关键帧 ===== */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-24px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideInLeft { from { opacity: 0; transform: translateX(-32px); } to { opacity: 1; transform: translateX(0); } } @keyframes slideInRight { from { opacity: 0; transform: translateX(32px); } to { opacity: 1; transform: translateX(0); } } @keyframes scaleIn { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } @keyframes pulse-soft { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } } @keyframes ripple { 0% { transform: scale(0); opacity: 0.5; } 100% { transform: scale(4); opacity: 0; } } @keyframes skeletonPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } } @keyframes growWidth { from { transform: scaleX(0); } to { transform: scaleX(1); } } @keyframes spinSlow { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .animate-fade-in-up { animation: fadeInUp var(--transition-slower) var(--ease-out) forwards; } .animate-fade-in-down { animation: fadeInDown var(--transition-slower) var(--ease-out) forwards; } .animate-fade-in { animation: fadeIn var(--transition-normal) var(--ease-out) forwards; } .animate-slide-in-left { animation: slideInLeft var(--transition-slow) var(--ease-out) forwards; } .animate-slide-in-right { animation: slideInRight var(--transition-slow) var(--ease-out) forwards; } .animate-scale-in { animation: scaleIn var(--transition-normal) var(--ease-out) forwards; } .animate-pulse-soft { animation: pulse-soft 2s ease-in-out infinite; } .animate-float { animation: float 3s ease-in-out infinite; } .animate-ripple { animation: ripple var(--transition-normal) var(--ease-out) forwards; } .animate-grow-width { animation: growWidth var(--transition-slow) var(--ease-out) forwards; transform-origin: left center; } .animate-spin-slow { animation: spinSlow 8s linear infinite; } .skeleton-pulse { animation: skeletonPulse 2s ease-in-out infinite; } .skeleton-shimmer { background: linear-gradient( 90deg, var(--color-bg-tertiary) 25%, var(--color-bg-secondary) 50%, var(--color-bg-tertiary) 75% ); background-size: 200% 100%; animation: shimmer 1.5s ease-in-out infinite; } .animation-delay-100 { animation-delay: 100ms; } .animation-delay-200 { animation-delay: 200ms; } .animation-delay-300 { animation-delay: 300ms; } .animation-delay-400 { animation-delay: 400ms; } .animation-delay-500 { animation-delay: 500ms; } .animation-delay-600 { animation-delay: 600ms; } .animation-delay-700 { animation-delay: 700ms; } .animation-delay-800 { animation-delay: 800ms; } /* ===== 滚动条样式 ===== */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--color-border-secondary); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted); } /* ===== 响应式调整(Mobile First) ===== */ body { padding-bottom: 64px; } p, li, span { overflow-wrap: break-word; word-wrap: break-word; } /* WCAG 2.5.5 (AAA): 44×44px 触控目标仅作用于移动端导航/页眉/页脚交互元素。 原全局选择器会撑大正文行内链接,破坏排版节奏与组件自有的尺寸控制。 */ @media (max-width: 768px) { /* MobileTabBar 是 fixed bottom-0 高度 64px(含 env 安全区),需给页面底部留出等高的避让。 全站单一
(ClientLayout)且