修复 A:header logo 深色模式字被吞 - logo.svg 右侧公司名(睿新致遠 + NOVALON)硬编码 fill='#0A0E14', 深色背景下 background 同色不可见,红色印章下书法字与英文全部被吞。 - 复用既有 logo-white.svg(白字 + 红印章)作为深色版, header 渲染双 <Image>,按 html[data-theme] CSS 显隐。 - 双 Image 不占位(display:none),零 JS 闪烁,未来主题切换器自动生效。 修复 B:font-calligraphy 工具类不生成 - tailwind.config.js 的 fontFamily 此前未声明 calligraphy key, 导致 font-calligraphy utility 永不生成,4 处装饰书法字 (BrandStamp「值得信赖」/ ChallengeSection「使命」/ WhyUsSection「睿」「我们」) 静默回退 sans。 - fontFamily 加 calligraphy: ['var(--font-calligraphy-system)']。 审计脚本: - logo-compare*.mjs:生产 vs 本地 logo 对比定位 - logo-dark-verify.mjs:明暗双版渲染验证 - font-calligraphy-verify.mjs:合成探针验证 utility 生效 验证: - type-check 0 error · lint 0 error(127 warnings 既有项与本次无关) - 深浅色 header 截图:明暗版正确切换,书法字 + NOVALON 清晰可见 - font-calligraphy 合成探针 computed fontFamily = STKaiti, KaiTi, 楷体, SimKai, serif ✓
278 lines
11 KiB
JavaScript
278 lines
11 KiB
JavaScript
/** @type {import('tailwindcss').Config} */
|
||
module.exports = {
|
||
content: [
|
||
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
||
],
|
||
darkMode: 'class',
|
||
theme: {
|
||
extend: {
|
||
colors: {
|
||
/* 重要:Tailwind v3 无法对纯 hex 的 CSS 变量套用 /50 这类透明度修饰符,
|
||
会生成无效 CSS 并静默失效(样式不报错,但效果不出现)。
|
||
故常用色改用 rgb(通道 / <alpha-value>) 形式 —— 无修饰符时 alpha 默认 1,
|
||
视觉结果与原来一致,同时 bg-brand/10、border-ink/30 等能正确编译。 */
|
||
ink: {
|
||
DEFAULT: 'rgb(var(--color-ink-rgb) / <alpha-value>)',
|
||
light: 'var(--color-ink-light)',
|
||
lighter: 'var(--color-ink-lighter)',
|
||
rgb: 'var(--color-ink-rgb)',
|
||
},
|
||
brand: {
|
||
DEFAULT: 'rgb(var(--color-brand-rgb) / <alpha-value>)',
|
||
hover: 'var(--color-brand-hover)',
|
||
light: 'var(--color-brand-light)',
|
||
soft: 'rgb(var(--color-brand-rgb) / calc(0.12 * <alpha-value>))',
|
||
bg: 'var(--color-brand-bg)',
|
||
rgb: 'var(--color-brand-rgb)',
|
||
section: 'var(--color-brand-section)',
|
||
'section-text': 'var(--color-brand-section-text)',
|
||
'section-muted': 'var(--color-brand-section-muted)',
|
||
},
|
||
accent: {
|
||
blue: 'rgb(var(--color-accent-blue-rgb) / <alpha-value>)',
|
||
'blue-soft': 'var(--color-accent-blue-soft)',
|
||
teal: 'rgb(var(--color-accent-teal-rgb) / <alpha-value>)',
|
||
'teal-soft': 'var(--color-accent-teal-soft)',
|
||
amber: 'rgb(var(--color-accent-amber-rgb) / <alpha-value>)',
|
||
'amber-soft': 'var(--color-accent-amber-soft)',
|
||
purple: 'rgb(var(--color-accent-purple-rgb) / <alpha-value>)',
|
||
'purple-soft': 'var(--color-accent-purple-soft)',
|
||
cyan: 'rgb(var(--color-accent-cyan-rgb) / <alpha-value>)',
|
||
'cyan-soft': 'var(--color-accent-cyan-soft)',
|
||
rose: 'rgb(var(--color-accent-rose-rgb) / <alpha-value>)',
|
||
'rose-soft': 'var(--color-accent-rose-soft)',
|
||
indigo: 'rgb(var(--color-accent-indigo-rgb) / <alpha-value>)',
|
||
'indigo-soft': 'var(--color-accent-indigo-soft)',
|
||
},
|
||
bg: {
|
||
primary: 'rgb(var(--color-bg-primary-rgb) / <alpha-value>)',
|
||
secondary: 'rgb(var(--color-bg-secondary-rgb) / <alpha-value>)',
|
||
tertiary: 'var(--color-bg-tertiary)',
|
||
section: 'var(--color-bg-section)',
|
||
hover: 'var(--color-bg-hover)',
|
||
elevated: 'var(--color-bg-elevated)',
|
||
},
|
||
text: {
|
||
primary: 'var(--color-text-primary)',
|
||
secondary: 'rgb(var(--color-text-secondary-rgb) / <alpha-value>)',
|
||
tertiary: 'var(--color-text-tertiary)',
|
||
muted: 'rgb(var(--color-text-muted-rgb) / <alpha-value>)',
|
||
subtle: 'var(--color-text-subtle)',
|
||
placeholder: 'var(--color-text-placeholder)',
|
||
hint: 'var(--color-text-hint)',
|
||
inverse: 'var(--color-text-inverse)',
|
||
},
|
||
border: {
|
||
primary: 'rgb(var(--color-border-primary-rgb) / <alpha-value>)',
|
||
secondary: 'rgb(var(--color-border-secondary-rgb) / <alpha-value>)',
|
||
accent: 'rgb(var(--color-border-accent-rgb) / <alpha-value>)',
|
||
light: 'rgb(var(--color-border-light-rgb) / <alpha-value>)',
|
||
dark: 'rgb(var(--color-border-dark-rgb) / <alpha-value>)',
|
||
brand: 'rgb(var(--color-border-brand-rgb) / <alpha-value>)',
|
||
},
|
||
link: {
|
||
DEFAULT: 'var(--color-link)',
|
||
hover: 'var(--color-link-hover)',
|
||
},
|
||
success: {
|
||
DEFAULT: 'rgb(var(--color-success-rgb) / <alpha-value>)',
|
||
hover: 'var(--color-success-hover)',
|
||
bg: 'var(--color-success-bg)',
|
||
rgb: 'var(--color-success-rgb)',
|
||
/** 文字请用此变体:DEFAULT 仅 3.30:1,不达 AA */
|
||
text: 'var(--color-success-text)',
|
||
},
|
||
warning: {
|
||
DEFAULT: 'rgb(var(--color-warning-rgb) / <alpha-value>)',
|
||
hover: 'var(--color-warning-hover)',
|
||
bg: 'var(--color-warning-bg)',
|
||
rgb: 'var(--color-warning-rgb)',
|
||
/** 文字请用此变体:DEFAULT 仅 3.19:1,不达 AA */
|
||
text: 'var(--color-warning-text)',
|
||
},
|
||
error: {
|
||
DEFAULT: 'rgb(var(--color-error-rgb) / <alpha-value>)',
|
||
hover: 'var(--color-error-hover)',
|
||
bg: 'var(--color-error-bg)',
|
||
rgb: 'var(--color-error-rgb)',
|
||
/** 文字请用此变体:DEFAULT(品牌红 #C41E3A)在暗黑底仅 3.3:1,不达 AA;
|
||
* 本值浅红,暗黑模式经 html[data-theme='dark'] 覆盖后达 AA。 */
|
||
text: 'var(--color-error-text)',
|
||
},
|
||
info: {
|
||
DEFAULT: 'rgb(var(--color-info-rgb) / <alpha-value>)',
|
||
bg: 'var(--color-info-bg)',
|
||
/** 文字请用此变体:DEFAULT 仅 3.68:1,不达 AA */
|
||
text: 'var(--color-info-text)',
|
||
},
|
||
dark: {
|
||
bg: 'var(--color-dark-bg)',
|
||
'bg-secondary': 'var(--color-dark-bg-secondary)',
|
||
'bg-tertiary': 'var(--color-dark-bg-tertiary)',
|
||
'text-primary': 'var(--color-dark-text-primary)',
|
||
'text-secondary': 'var(--color-dark-text-secondary)',
|
||
'text-muted': 'var(--color-dark-text-muted)',
|
||
border: 'var(--color-dark-border)',
|
||
},
|
||
overlay: 'rgb(var(--color-overlay-rgb) / <alpha-value>)',
|
||
},
|
||
fontFamily: {
|
||
sans: ['var(--font-sans)'],
|
||
display: ['var(--font-display)'],
|
||
mono: ['var(--font-mono)'],
|
||
brand: ['var(--font-brand)'],
|
||
serif: ['var(--font-serif)'],
|
||
// 书法体:globals.css 的 --font-calligraphy-system(STKaiti / KaiTi 系统字栈)
|
||
// 此前 fontFamily 未声明该 key,导致 font-calligraphy utility 不生成,
|
||
// 4 处装饰书法字(why-us / challenge / brand-visuals)静默回退 sans。
|
||
calligraphy: ['var(--font-calligraphy-system)'],
|
||
},
|
||
fontSize: {
|
||
caption: 'var(--font-size-caption)',
|
||
xs: 'var(--font-size-xs)',
|
||
sm: 'var(--font-size-sm)',
|
||
base: 'var(--font-size-base)',
|
||
lg: 'var(--font-size-lg)',
|
||
xl: 'var(--font-size-xl)',
|
||
'2xl': 'var(--font-size-2xl)',
|
||
'3xl': 'var(--font-size-3xl)',
|
||
'4xl': 'var(--font-size-4xl)',
|
||
'5xl': 'var(--font-size-5xl)',
|
||
'6xl': 'var(--font-size-6xl)',
|
||
'7xl': 'var(--font-size-7xl)',
|
||
display: 'var(--font-size-display)',
|
||
},
|
||
lineHeight: {
|
||
caption: 'var(--line-height-caption)',
|
||
tight: 'var(--line-height-tight)',
|
||
snug: 'var(--line-height-snug)',
|
||
normal: 'var(--line-height-normal)',
|
||
relaxed: 'var(--line-height-relaxed)',
|
||
},
|
||
letterSpacing: {
|
||
tighter: 'var(--letter-spacing-tighter)',
|
||
tight: 'var(--letter-spacing-tight)',
|
||
normal: 'var(--letter-spacing-normal)',
|
||
wide: 'var(--letter-spacing-wide)',
|
||
wider: 'var(--letter-spacing-wider)',
|
||
widest: 'var(--letter-spacing-widest)',
|
||
eyebrow: 'var(--letter-spacing-eyebrow)',
|
||
},
|
||
spacing: {
|
||
xs: 'var(--spacing-xs)',
|
||
sm: 'var(--spacing-sm)',
|
||
md: 'var(--spacing-md)',
|
||
lg: 'var(--spacing-lg)',
|
||
xl: 'var(--spacing-xl)',
|
||
'2xl': 'var(--spacing-2xl)',
|
||
'3xl': 'var(--spacing-3xl)',
|
||
'4xl': 'var(--spacing-4xl)',
|
||
'5xl': 'var(--spacing-5xl)',
|
||
'6xl': 'var(--spacing-6xl)',
|
||
},
|
||
borderRadius: {
|
||
xs: 'var(--radius-xs)',
|
||
sm: 'var(--radius-sm)',
|
||
md: 'var(--radius-md)',
|
||
lg: 'var(--radius-lg)',
|
||
xl: 'var(--radius-xl)',
|
||
'2xl': 'var(--radius-2xl)',
|
||
'3xl': 'var(--radius-3xl)',
|
||
full: 'var(--radius-full)',
|
||
},
|
||
boxShadow: {
|
||
xs: 'var(--shadow-xs)',
|
||
sm: 'var(--shadow-sm)',
|
||
md: 'var(--shadow-md)',
|
||
lg: 'var(--shadow-lg)',
|
||
xl: 'var(--shadow-xl)',
|
||
brand: 'var(--shadow-brand)',
|
||
'brand-hover': 'var(--shadow-brand-hover)',
|
||
inset: 'var(--shadow-inset)',
|
||
glow: 'var(--shadow-glow)',
|
||
},
|
||
transitionDuration: {
|
||
instant: 'var(--transition-instant)',
|
||
fast: 'var(--transition-fast)',
|
||
normal: 'var(--transition-normal)',
|
||
slow: 'var(--transition-slow)',
|
||
slower: 'var(--transition-slower)',
|
||
gentle: 'var(--transition-gentle)',
|
||
},
|
||
transitionTimingFunction: {
|
||
standard: 'var(--ease-standard)',
|
||
decelerate: 'var(--ease-decelerate)',
|
||
accelerate: 'var(--ease-accelerate)',
|
||
'ease-out': 'var(--ease-ink)',
|
||
'ease-in-out': 'var(--ease-sharp)',
|
||
'ease-spring': 'var(--ease-spring)',
|
||
'ease-spring-soft': 'var(--ease-spring-soft)',
|
||
sharp: 'var(--ease-sharp)',
|
||
ink: 'var(--ease-ink)',
|
||
},
|
||
maxWidth: {
|
||
container: 'var(--container-max)',
|
||
},
|
||
animation: {
|
||
'fade-in-up': 'fadeInUp 0.7s var(--ease-out) forwards',
|
||
'fade-in': 'fadeIn 0.5s var(--ease-out) forwards',
|
||
'scale-in': 'scaleIn 0.5s var(--ease-out) forwards',
|
||
'slide-in-left': 'slideInLeft 0.6s var(--ease-out) forwards',
|
||
'slide-in-right': 'slideInRight 0.6s var(--ease-out) forwards',
|
||
'pulse-soft': 'pulse-soft 2s ease-in-out infinite',
|
||
'ripple': 'ripple 0.6s ease-out forwards',
|
||
'skeleton-pulse': 'skeletonPulse 2s ease-in-out infinite',
|
||
'accordion-down': 'accordionDown 0.2s ease-out forwards',
|
||
'accordion-up': 'accordionUp 0.2s ease-out forwards',
|
||
},
|
||
keyframes: {
|
||
fadeInUp: {
|
||
from: { opacity: '0', transform: 'translateY(24px)' },
|
||
to: { opacity: '1', transform: 'translateY(0)' },
|
||
},
|
||
fadeIn: {
|
||
from: { opacity: '0' },
|
||
to: { opacity: '1' },
|
||
},
|
||
slideInLeft: {
|
||
from: { opacity: '0', transform: 'translateX(-32px)' },
|
||
to: { opacity: '1', transform: 'translateX(0)' },
|
||
},
|
||
slideInRight: {
|
||
from: { opacity: '0', transform: 'translateX(32px)' },
|
||
to: { opacity: '1', transform: 'translateX(0)' },
|
||
},
|
||
scaleIn: {
|
||
from: { opacity: '0', transform: 'scale(0.95)' },
|
||
to: { opacity: '1', transform: 'scale(1)' },
|
||
},
|
||
'pulse-soft': {
|
||
'0%, 100%': { opacity: '1' },
|
||
'50%': { opacity: '0.6' },
|
||
},
|
||
ripple: {
|
||
'0%': { transform: 'scale(0)', opacity: '0.5' },
|
||
'100%': { transform: 'scale(4)', opacity: '0' },
|
||
},
|
||
skeletonPulse: {
|
||
'0%, 100%': { backgroundColor: 'var(--color-bg-tertiary)', opacity: '1' },
|
||
'50%': { backgroundColor: 'color-mix(in srgb, var(--color-brand) 8%, var(--color-bg-tertiary))', opacity: '0.8' },
|
||
},
|
||
accordionDown: {
|
||
from: { height: '0', opacity: '0' },
|
||
to: { height: 'var(--radix-accordion-content-height)', opacity: '1' },
|
||
},
|
||
accordionUp: {
|
||
from: { height: 'var(--radix-accordion-content-height)', opacity: '1' },
|
||
to: { height: '0', opacity: '0' },
|
||
},
|
||
},
|
||
},
|
||
},
|
||
plugins: [
|
||
require('tailwindcss-animate'),
|
||
],
|
||
};
|