Task #16 残留陷阱治理(保留待用、不动代码): scope: src/lib/constants/design-system.ts(零生产消费者的死代码) action: 仅加注释,不改令牌值、不动 design-system.test.ts、零行为变化 - 文件头警示块:声明本文件为合规陷阱、令牌与 CONTEXT.md 冲突、 test 用 // @ts-nocheck 断言错误值、勿在新代码 import - 7 处冲突令牌行内 ⚠️ 注释: normal 0.4s 超目标 / slow 0.6s P1 / slower 0.8s P0 硬上限 / smooth 非 ease-ink / bounce 弹性缓动 / stagger 0.08 P2 / scroll 0.6s P1 verified: - eslint design-system.ts: 0 errors (ESLINT_EXIT=0) - jest design-system.test.ts: 20/20 passed (JEST_EXIT=0) - 纯注释改动,tsc 无语法变化(已隔离单文件 diff) note: 此前决策「保留待用、不动代码」——本提交仅显性化陷阱, 未来修正须同步改测试,否则必挂(P1 阶段已实践过该回退)。
149 lines
6.1 KiB
TypeScript
149 lines
6.1 KiB
TypeScript
// Design System Constants — L3 Detail Pages
|
||
// Color tokens reference global CSS variables for dark-mode support.
|
||
// Layout / spacing / animation / easing remain as JS constants.
|
||
//
|
||
// ⚠️ COMPLIANCE TRAP(Task #16 残留,刻意保留待用):
|
||
// 本文件动画令牌与 CONTEXT.md 动效约束冲突(见下方各 ⚠️ 行),且
|
||
// design-system.test.ts 用 `// @ts-nocheck` 断言了这些「错误值」。
|
||
// 它是零生产消费者的死代码,仅作历史参考。请勿照抄带 ⚠️ 的令牌;
|
||
// 新代码请直接用 ScrollReveal 默认(duration 0.3 / stagger 0.05 /
|
||
// easing ease-ink [0.22, 1, 0.36, 1])。要修正须同步改测试,否则必挂。
|
||
|
||
export const DESIGN_SYSTEM = Object.freeze({
|
||
animation: {
|
||
duration: {
|
||
fast: '0.2s',
|
||
normal: '0.4s', // ⚠️ 超目标:CONTEXT.md 入场目标 200-300ms,0.4s=400ms 超时
|
||
slow: '0.6s', // ⚠️ P1:>300ms 目标(仍 ≤700ms 硬上限)
|
||
slower: '0.8s', // ⚠️ P0:>700ms 硬上限违规(最严重)
|
||
countUp: '2s',
|
||
},
|
||
easing: {
|
||
smooth: 'cubic-bezier(0.4, 0, 0.2, 1)', // ⚠️ 非 ease-ink [0.22,1,0.36,1]
|
||
bounce: 'cubic-bezier(0.34, 1.56, 0.64, 1)', // ⚠️ 弹性缓动,违反「禁 spring 内容入场」
|
||
easeOut: 'cubic-bezier(0, 0, 0.2, 1)',
|
||
easeInOut: 'cubic-bezier(0.4, 0, 0.6, 1)',
|
||
},
|
||
delay: {
|
||
stagger: 0.08, // ⚠️ P2:>60ms(应为 ≤0.06,对齐 ScrollReveal 0.05)
|
||
section: 0.15,
|
||
},
|
||
},
|
||
|
||
spacing: {
|
||
section: {
|
||
py: 'py-20 lg:py-28',
|
||
pyCompact: 'py-16 lg:py-20',
|
||
},
|
||
container: {
|
||
default: 'max-w-7xl mx-auto px-4 sm:px-6 lg:px-8',
|
||
narrow: 'max-w-5xl mx-auto px-4 sm:px-6 lg:px-8',
|
||
wide: 'max-w-[1400px] mx-auto px-4 sm:px-6 lg:px-8',
|
||
},
|
||
grid: {
|
||
gap: 'gap-6 lg:gap-8',
|
||
gapSmall: 'gap-4 lg:gap-6',
|
||
},
|
||
},
|
||
|
||
// Typography classes reference CSS variables for theme-aware sizing
|
||
typography: {
|
||
hero: {
|
||
title: 'text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight text-[var(--color-text-primary)]',
|
||
subtitle: 'text-lg md:text-xl leading-relaxed text-[var(--color-text-secondary)]',
|
||
description: 'text-base mt-4 max-w-2xl text-[var(--color-text-muted)]',
|
||
},
|
||
section: {
|
||
title: 'text-3xl md:text-4xl font-bold tracking-tight text-[var(--color-text-primary)]',
|
||
subtitle: 'text-lg mt-2 text-[var(--color-text-secondary)]',
|
||
body: 'text-base leading-relaxed text-[var(--color-text-secondary)]',
|
||
},
|
||
card: {
|
||
title: 'text-lg font-semibold text-[var(--color-text-primary)]',
|
||
description: 'text-sm leading-relaxed text-[var(--color-text-muted)]',
|
||
},
|
||
},
|
||
|
||
effects: {
|
||
inkGlow: {
|
||
border: 'conic-gradient(from var(--angle), transparent 0%, var(--color-brand) 10%, transparent 20%)',
|
||
glow: 'radial-gradient(circle at var(--mouse-x) var(--mouse-y), rgba(var(--color-brand-rgb), 0.15) 0%, transparent 50%)',
|
||
speed: '3s',
|
||
},
|
||
hover: {
|
||
translateY: '-4px',
|
||
shadow: 'shadow-xl',
|
||
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
|
||
},
|
||
scroll: {
|
||
fadeInUp: {
|
||
initial: { opacity: 0, y: 24 },
|
||
animate: { opacity: 1, y: 0 },
|
||
viewport: { once: true, margin: '-80px' },
|
||
transition: { duration: 0.6, ease: [0.16, 1, 0.3, 1] as const }, // ⚠️ P1:0.6s 超 300ms 目标
|
||
},
|
||
staggerChildren: {
|
||
delay: 0.08,
|
||
},
|
||
},
|
||
},
|
||
|
||
// Color references map to CSS custom properties defined in globals.css
|
||
// These are used for inline styles where Tailwind classes aren't feasible
|
||
colors: {
|
||
brand: {
|
||
primary: 'var(--color-brand)',
|
||
light: 'var(--color-brand-bg)',
|
||
lighter: 'rgba(var(--color-brand-rgb), 0.04)',
|
||
gradient: 'linear-gradient(135deg, var(--color-brand) 0%, #99182d 100%)',
|
||
},
|
||
neutral: {
|
||
50: 'var(--color-bg-primary)',
|
||
100: 'var(--color-bg-section)',
|
||
200: 'var(--color-border-primary)',
|
||
300: 'var(--color-text-hint)',
|
||
400: 'var(--color-text-subtle)',
|
||
500: 'var(--color-text-muted)',
|
||
600: 'var(--color-text-secondary)',
|
||
700: 'var(--color-text-primary)',
|
||
800: 'var(--color-text-primary)',
|
||
900: 'var(--color-text-primary)',
|
||
},
|
||
ink: {
|
||
light: 'rgba(0, 0, 0, 0.03)',
|
||
medium: 'rgba(0, 0, 0, 0.06)',
|
||
texture: 'repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(0,0,0,.02) 10px, rgba(0,0,0,.02) 11px)',
|
||
},
|
||
},
|
||
|
||
components: {
|
||
card: {
|
||
base: 'rounded-2xl border border-[var(--color-border-primary)] overflow-hidden transition-all duration-300 bg-[var(--color-bg-primary)]',
|
||
hover: 'hover:border-[rgba(var(--color-brand-rgb),0.2)] hover:shadow-lg hover:-translate-y-1',
|
||
padding: 'p-6 lg:p-8',
|
||
},
|
||
badge: {
|
||
base: 'inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium',
|
||
variants: {
|
||
primary: 'bg-[var(--color-brand-bg)] text-[var(--color-brand)]',
|
||
secondary: 'bg-[var(--color-bg-tertiary)] text-[var(--color-text-secondary)]',
|
||
success: 'bg-green-50 text-green-700',
|
||
warning: 'bg-yellow-50 text-yellow-700',
|
||
},
|
||
},
|
||
button: {
|
||
primary: 'inline-flex items-center gap-2 px-6 py-3 text-white font-semibold rounded-lg shadow-md transition-all duration-200 bg-[var(--color-brand)] hover:brightness-110 hover:shadow-lg',
|
||
secondary: 'inline-flex items-center gap-2 px-6 py-3 font-semibold rounded-lg border transition-all duration-200 bg-[var(--color-bg-primary)] text-[var(--color-text-secondary)] border-[var(--color-border-primary)] hover:border-[var(--color-text-hint)] hover:shadow-sm',
|
||
ghost: 'inline-flex items-center gap-2 px-4 py-2 font-medium rounded-lg transition-colors duration-200 text-[var(--color-brand)] hover:bg-[var(--color-brand-bg)]',
|
||
},
|
||
metric: {
|
||
container: 'text-center p-6 rounded-xl border bg-[var(--color-bg-section)] border-[var(--color-border-primary)]',
|
||
value: 'text-3xl md:text-4xl font-bold mb-1 text-[var(--color-text-primary)]',
|
||
label: 'text-sm text-[var(--color-text-subtle)]',
|
||
description: 'text-xs mt-1 text-[var(--color-text-hint)]',
|
||
},
|
||
},
|
||
});
|
||
|
||
export type DesignSystem = typeof DESIGN_SYSTEM;
|