/** @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: ['variant', '[data-theme="dark"] &'], theme: { extend: { colors: { /* 重要:Tailwind v3 无法对纯 hex 的 CSS 变量套用 /50 这类透明度修饰符, 会生成无效 CSS 并静默失效(样式不报错,但效果不出现)。 故常用色改用 rgb(通道 / ) 形式 —— 无修饰符时 alpha 默认 1, 视觉结果与原来一致,同时 bg-brand/10、border-ink/30 等能正确编译。 */ ink: { DEFAULT: 'rgb(var(--color-ink-rgb) / )', light: 'var(--color-ink-light)', lighter: 'var(--color-ink-lighter)', rgb: 'var(--color-ink-rgb)', }, brand: { DEFAULT: 'rgb(var(--color-brand-rgb) / )', // 文字专用通道:深色下 --color-brand-ink-rgb 翻转为 #F87171(AA 达标)。 // 不要拿 DEFAULT 当文字色用 —— 它同时是 bg-brand/border-brand 的取值,深色下不翻。 ink: 'rgb(var(--color-brand-ink-rgb) / )', hover: 'var(--color-brand-hover)', light: 'var(--color-brand-light)', soft: 'rgb(var(--color-brand-rgb) / calc(0.12 * ))', 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) / )', 'blue-soft': 'var(--color-accent-blue-soft)', teal: 'rgb(var(--color-accent-teal-rgb) / )', 'teal-soft': 'var(--color-accent-teal-soft)', amber: 'rgb(var(--color-accent-amber-rgb) / )', 'amber-soft': 'var(--color-accent-amber-soft)', purple: 'rgb(var(--color-accent-purple-rgb) / )', 'purple-soft': 'var(--color-accent-purple-soft)', cyan: 'rgb(var(--color-accent-cyan-rgb) / )', 'cyan-soft': 'var(--color-accent-cyan-soft)', rose: 'rgb(var(--color-accent-rose-rgb) / )', 'rose-soft': 'var(--color-accent-rose-soft)', indigo: 'rgb(var(--color-accent-indigo-rgb) / )', 'indigo-soft': 'var(--color-accent-indigo-soft)', }, bg: { primary: 'rgb(var(--color-bg-primary-rgb) / )', secondary: 'rgb(var(--color-bg-secondary-rgb) / )', 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) / )', tertiary: 'var(--color-text-tertiary)', muted: 'rgb(var(--color-text-muted-rgb) / )', 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) / )', secondary: 'rgb(var(--color-border-secondary-rgb) / )', accent: 'rgb(var(--color-border-accent-rgb) / )', light: 'rgb(var(--color-border-light-rgb) / )', dark: 'rgb(var(--color-border-dark-rgb) / )', brand: 'rgb(var(--color-border-brand-rgb) / )', }, link: { DEFAULT: 'var(--color-link)', hover: 'var(--color-link-hover)', }, success: { DEFAULT: 'rgb(var(--color-success-rgb) / )', 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) / )', 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) / )', 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) / )', 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) / )', }, 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)', 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'), ], };