This commit is contained in:
ChuXun
2025-10-19 20:28:31 +08:00
parent c81f8a8b03
commit eaab9a762a
100 changed files with 23416 additions and 0 deletions

340
styles/design-tokens.wxss Normal file
View File

@@ -0,0 +1,340 @@
/**
* ============================================
* 🎨 知芽小筑 - 企业级设计令牌系统
* ============================================
* 参考小红书、Instagram、微信、Twitter
* 版本v3.0.0
* 更新2025-10-14
*/
/* ==================== 🌈 颜色系统 ==================== */
page {
/* ---------- 品牌主色 - 活力渐变系统 ---------- */
--brand-primary: #667EEA;
--brand-secondary: #764BA2;
--brand-accent: #FF6B9D;
/* 主渐变色组 - 用于不同场景 */
--gradient-purple-dream: linear-gradient(135deg, #667EEA 0%, #764BA2 100%);
--gradient-ocean-blue: linear-gradient(135deg, #4FACFE 0%, #00F2FE 100%);
--gradient-fresh-green: linear-gradient(135deg, #43E97B 0%, #38F9D7 100%);
--gradient-sunset-pink: linear-gradient(135deg, #FA709A 0%, #FEE140 100%);
--gradient-midnight-city: linear-gradient(135deg, #30CFD0 0%, #330867 100%);
--gradient-aurora: linear-gradient(135deg, #FA8BFF 0%, #2BD2FF 50%, #2BFF88 100%);
/* 场景专用渐变 */
--gradient-home: linear-gradient(135deg, #667EEA 0%, #764BA2 100%);
--gradient-course: linear-gradient(135deg, #4FACFE 0%, #00F2FE 100%);
--gradient-forum: linear-gradient(135deg, #FA8BFF 0%, #2BD2FF 90%, #2BFF88 100%);
--gradient-tools: linear-gradient(135deg, #FCCF31 0%, #F55555 100%);
--gradient-profile: linear-gradient(135deg, #A8EDEA 0%, #FED6E3 100%);
/* ---------- 语义化颜色 ---------- */
--color-success: #52C41A;
--color-success-light: #95DE64;
--color-success-bg: #F6FFED;
--color-success-border: #B7EB8F;
--color-warning: #FAAD14;
--color-warning-light: #FFC53D;
--color-warning-bg: #FFFBE6;
--color-warning-border: #FFE58F;
--color-error: #FF4D4F;
--color-error-light: #FF7875;
--color-error-bg: #FFF1F0;
--color-error-border: #FFCCC7;
--color-info: #1890FF;
--color-info-light: #69C0FF;
--color-info-bg: #E6F7FF;
--color-info-border: #91D5FF;
/* ---------- 中性色 - 文字系统 ---------- */
--text-primary: #1A1A1A; /* 主要文字 - 标题 */
--text-secondary: #595959; /* 次要文字 - 正文 */
--text-tertiary: #8C8C8C; /* 三级文字 - 辅助信息 */
--text-quaternary: #BFBFBF; /* 四级文字 - 占位符 */
--text-disabled: #D9D9D9; /* 禁用文字 */
--text-inverse: #FFFFFF; /* 反色文字 - 深色背景上 */
--text-link: #4A90E2; /* 链接文字 */
--text-link-hover: #357ABD; /* 链接悬停 */
/* ---------- 背景色系统 ---------- */
--bg-page: #F5F7FA; /* 页面背景 */
--bg-primary: #FFFFFF; /* 主要背景 - 卡片 */
--bg-secondary: #FAFAFA; /* 次要背景 */
--bg-tertiary: #F0F2F5; /* 三级背景 */
--bg-hover: #F5F5F5; /* 悬停背景 */
--bg-active: #E8E8E8; /* 激活背景 */
--bg-disabled: #F5F5F5; /* 禁用背景 */
--bg-mask: rgba(0, 0, 0, 0.6); /* 遮罩层 */
/* ---------- 毛玻璃效果Glassmorphism---------- */
--glass-white: rgba(255, 255, 255, 0.7);
--glass-white-light: rgba(255, 255, 255, 0.5);
--glass-white-strong: rgba(255, 255, 255, 0.9);
--glass-black: rgba(0, 0, 0, 0.5);
--glass-black-light: rgba(0, 0, 0, 0.3);
--glass-border: rgba(255, 255, 255, 0.18);
--glass-shadow: 0 8rpx 32rpx 0 rgba(31, 38, 135, 0.37);
/* ---------- 边框色系统 ---------- */
--border-base: #E5E5E5;
--border-light: #F0F0F0;
--border-lighter: #FAFAFA;
--border-dark: #D9D9D9;
--border-darker: #BFBFBF;
--divider: #F0F0F0;
/* ==================== 📝 字体系统 ==================== */
/* ---------- 字体家族 ---------- */
--font-family-base: -apple-system-font, BlinkMacSystemFont, 'Helvetica Neue',
'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei',
'Segoe UI', Arial, sans-serif;
--font-family-display: 'DIN Alternate Bold', -apple-system-font, 'SF Pro Display',
'Helvetica Neue', sans-serif;
--font-family-mono: 'SF Mono', 'Monaco', 'Consolas', 'Courier New', monospace;
/* ---------- 字号系统14级 ---------- */
--font-size-2xs: 18rpx; /* 极小 - 法律文本 */
--font-size-xs: 22rpx; /* 很小 - 辅助信息 */
--font-size-sm: 26rpx; /* 小 - 次要文本 */
--font-size-base: 30rpx; /* 基础 - 正文 */
--font-size-md: 32rpx; /* 中等 */
--font-size-lg: 36rpx; /* 大 - 小标题 */
--font-size-xl: 40rpx; /* 超大 - 标题 */
--font-size-2xl: 48rpx; /* 2倍大 - 大标题 */
--font-size-3xl: 56rpx; /* 3倍大 - 页面标题 */
--font-size-4xl: 64rpx; /* 4倍大 - 特大标题 */
--font-size-5xl: 72rpx; /* 5倍大 - Hero标题 */
--font-size-6xl: 96rpx; /* 6倍大 - 展示标题 */
--font-size-7xl: 128rpx; /* 7倍大 - 超级展示 */
--font-size-8xl: 160rpx; /* 8倍大 - 巨型标题 */
/* ---------- 字重系统 ---------- */
--font-weight-thin: 100; /* 极细 */
--font-weight-extralight: 200; /* 超细 */
--font-weight-light: 300; /* 细 */
--font-weight-regular: 400; /* 常规 */
--font-weight-medium: 500; /* 中等 */
--font-weight-semibold: 600; /* 半粗 */
--font-weight-bold: 700; /* 粗 */
--font-weight-extrabold: 800; /* 超粗 */
--font-weight-black: 900; /* 最粗 */
/* ---------- 行高系统 ---------- */
--line-height-none: 1;
--line-height-tight: 1.25;
--line-height-snug: 1.375;
--line-height-normal: 1.5;
--line-height-relaxed: 1.625;
--line-height-loose: 2;
/* ---------- 字间距 ---------- */
--letter-spacing-tighter: -0.05em;
--letter-spacing-tight: -0.025em;
--letter-spacing-normal: 0;
--letter-spacing-wide: 0.025em;
--letter-spacing-wider: 0.05em;
--letter-spacing-widest: 0.1em;
/* ==================== 📏 间距系统 ==================== */
/* 基于4rpx的精细间距系统 */
--space-0: 0rpx;
--space-1: 4rpx;
--space-2: 8rpx;
--space-3: 12rpx;
--space-4: 16rpx;
--space-5: 20rpx;
--space-6: 24rpx;
--space-7: 28rpx;
--space-8: 32rpx;
--space-9: 36rpx;
--space-10: 40rpx;
--space-11: 44rpx;
--space-12: 48rpx;
--space-14: 56rpx;
--space-16: 64rpx;
--space-18: 72rpx;
--space-20: 80rpx;
--space-24: 96rpx;
--space-28: 112rpx;
--space-32: 128rpx;
--space-36: 144rpx;
--space-40: 160rpx;
--space-44: 176rpx;
--space-48: 192rpx;
--space-52: 208rpx;
--space-56: 224rpx;
--space-60: 240rpx;
--space-64: 256rpx;
--space-72: 288rpx;
--space-80: 320rpx;
--space-96: 384rpx;
/* ==================== 🔲 圆角系统 ==================== */
--radius-none: 0rpx;
--radius-xs: 4rpx;
--radius-sm: 8rpx;
--radius-base: 12rpx;
--radius-md: 16rpx;
--radius-lg: 20rpx;
--radius-xl: 24rpx;
--radius-2xl: 32rpx;
--radius-3xl: 40rpx;
--radius-4xl: 48rpx;
--radius-full: 9999rpx;
--radius-round: 50%;
/* ==================== 🌑 阴影系统 ==================== */
/* 基础阴影 - 层次感 */
--shadow-none: none;
--shadow-xs: 0 1rpx 2rpx 0 rgba(0, 0, 0, 0.05);
--shadow-sm: 0 2rpx 4rpx 0 rgba(0, 0, 0, 0.06), 0 2rpx 8rpx 0 rgba(0, 0, 0, 0.04);
--shadow-base: 0 4rpx 8rpx 0 rgba(0, 0, 0, 0.08), 0 2rpx 4rpx 0 rgba(0, 0, 0, 0.04);
--shadow-md: 0 8rpx 16rpx 0 rgba(0, 0, 0, 0.1), 0 4rpx 8rpx 0 rgba(0, 0, 0, 0.06);
--shadow-lg: 0 12rpx 24rpx 0 rgba(0, 0, 0, 0.12), 0 8rpx 16rpx 0 rgba(0, 0, 0, 0.08);
--shadow-xl: 0 16rpx 32rpx 0 rgba(0, 0, 0, 0.14), 0 12rpx 24rpx 0 rgba(0, 0, 0, 0.10);
--shadow-2xl: 0 24rpx 48rpx 0 rgba(0, 0, 0, 0.18), 0 16rpx 32rpx 0 rgba(0, 0, 0, 0.12);
--shadow-3xl: 0 32rpx 64rpx 0 rgba(0, 0, 0, 0.20), 0 24rpx 48rpx 0 rgba(0, 0, 0, 0.14);
/* 彩色阴影 - 品牌感 */
--shadow-primary: 0 8rpx 24rpx -4rpx rgba(102, 126, 234, 0.4);
--shadow-secondary: 0 8rpx 24rpx -4rpx rgba(118, 75, 162, 0.4);
--shadow-success: 0 8rpx 24rpx -4rpx rgba(82, 196, 26, 0.4);
--shadow-warning: 0 8rpx 24rpx -4rpx rgba(250, 173, 20, 0.4);
--shadow-error: 0 8rpx 24rpx -4rpx rgba(255, 77, 79, 0.4);
--shadow-info: 0 8rpx 24rpx -4rpx rgba(24, 144, 255, 0.4);
/* 内阴影 */
--shadow-inner: inset 0 2rpx 4rpx 0 rgba(0, 0, 0, 0.06);
/* ==================== ⚡ 动画系统 ==================== */
/* ---------- 持续时间 ---------- */
--duration-fastest: 100ms;
--duration-fast: 150ms;
--duration-normal: 200ms;
--duration-moderate: 300ms;
--duration-slow: 400ms;
--duration-slower: 500ms;
--duration-slowest: 600ms;
/* ---------- 缓动函数 ---------- */
--ease-linear: linear;
--ease-in: cubic-bezier(0.4, 0, 1, 1);
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--ease-sharp: cubic-bezier(0.4, 0, 0.6, 1);
--ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
--ease-elastic: cubic-bezier(0.175, 0.885, 0.32, 1.275);
/* ---------- 组合过渡 ---------- */
--transition-fast: all var(--duration-fast) var(--ease-out);
--transition-base: all var(--duration-normal) var(--ease-in-out);
--transition-slow: all var(--duration-slow) var(--ease-in-out);
/* ==================== 📱 布局系统 ==================== */
/* ---------- 容器宽度 ---------- */
--container-xs: 640rpx;
--container-sm: 750rpx;
--container-md: 960rpx;
--container-lg: 1200rpx;
--container-xl: 1400rpx;
/* ---------- Z-index 层级 ---------- */
--z-index-base: 0;
--z-index-dropdown: 1000;
--z-index-sticky: 1010;
--z-index-fixed: 1020;
--z-index-modal-backdrop: 1030;
--z-index-modal: 1040;
--z-index-popover: 1050;
--z-index-tooltip: 1060;
--z-index-notification: 1070;
/* ---------- 安全区域 ---------- */
--safe-area-inset-top: env(safe-area-inset-top);
--safe-area-inset-right: env(safe-area-inset-right);
--safe-area-inset-bottom: env(safe-area-inset-bottom);
--safe-area-inset-left: env(safe-area-inset-left);
/* ==================== 🎭 特效系统 ==================== */
/* ---------- 模糊效果 ---------- */
--blur-none: 0;
--blur-sm: 8rpx;
--blur-base: 16rpx;
--blur-md: 24rpx;
--blur-lg: 32rpx;
--blur-xl: 40rpx;
--blur-2xl: 80rpx;
--blur-3xl: 160rpx;
/* ---------- 透明度 ---------- */
--opacity-0: 0;
--opacity-5: 0.05;
--opacity-10: 0.1;
--opacity-20: 0.2;
--opacity-25: 0.25;
--opacity-30: 0.3;
--opacity-40: 0.4;
--opacity-50: 0.5;
--opacity-60: 0.6;
--opacity-70: 0.7;
--opacity-75: 0.75;
--opacity-80: 0.8;
--opacity-90: 0.9;
--opacity-95: 0.95;
--opacity-100: 1;
/* ---------- 渐变叠加效果 ---------- */
--overlay-dark: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.6) 100%);
--overlay-light: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.6) 100%);
}
/* ==================== 🌙 深色模式支持 ==================== */
[data-theme="dark"] {
/* 文字颜色反转 */
--text-primary: #FFFFFF;
--text-secondary: #B3B3B3;
--text-tertiary: #808080;
--text-quaternary: #595959;
--text-disabled: #404040;
--text-inverse: #1A1A1A;
/* 背景色反转 */
--bg-page: #0A0A0A;
--bg-primary: #1A1A1A;
--bg-secondary: #262626;
--bg-tertiary: #2F2F2F;
--bg-hover: #333333;
--bg-active: #404040;
--bg-mask: rgba(0, 0, 0, 0.8);
/* 毛玻璃效果 */
--glass-white: rgba(255, 255, 255, 0.1);
--glass-white-light: rgba(255, 255, 255, 0.05);
--glass-black: rgba(0, 0, 0, 0.7);
--glass-border: rgba(255, 255, 255, 0.1);
/* 边框色 */
--border-base: #333333;
--border-light: #262626;
--border-dark: #404040;
--divider: #262626;
/* 阴影调整 */
--shadow-sm: 0 2rpx 8rpx 0 rgba(0, 0, 0, 0.3);
--shadow-base: 0 4rpx 16rpx 0 rgba(0, 0, 0, 0.4);
--shadow-md: 0 8rpx 24rpx 0 rgba(0, 0, 0, 0.5);
--shadow-lg: 0 12rpx 32rpx 0 rgba(0, 0, 0, 0.6);
}

View File

@@ -0,0 +1,765 @@
/**
* ============================================
* ⚡ 企业级动画系统
* ============================================
* 参考iOS、Material Design、Framer Motion
*/
@import './design-tokens.wxss';
/* ==================== 🎭 入场动画 ==================== */
/* 淡入 */
.animate-fade-in {
animation: fade-in var(--duration-moderate) var(--ease-out) forwards;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 从上滑入 */
.animate-slide-in-up {
animation: slide-in-up var(--duration-moderate) var(--ease-out) forwards;
}
@keyframes slide-in-up {
from {
opacity: 0;
transform: translateY(60rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 从下滑入 */
.animate-slide-in-down {
animation: slide-in-down var(--duration-moderate) var(--ease-out) forwards;
}
@keyframes slide-in-down {
from {
opacity: 0;
transform: translateY(-60rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 从左滑入 */
.animate-slide-in-left {
animation: slide-in-left var(--duration-moderate) var(--ease-out) forwards;
}
@keyframes slide-in-left {
from {
opacity: 0;
transform: translateX(-60rpx);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 从右滑入 */
.animate-slide-in-right {
animation: slide-in-right var(--duration-moderate) var(--ease-out) forwards;
}
@keyframes slide-in-right {
from {
opacity: 0;
transform: translateX(60rpx);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 缩放入场 */
.animate-scale-in {
animation: scale-in var(--duration-moderate) var(--ease-out) forwards;
}
@keyframes scale-in {
from {
opacity: 0;
transform: scale(0.85);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* 弹跳入场 */
.animate-bounce-in {
animation: bounce-in var(--duration-slow) var(--ease-bounce) forwards;
}
@keyframes bounce-in {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1.05);
}
70% {
transform: scale(0.95);
}
100% {
transform: scale(1);
}
}
/* 旋转入场 */
.animate-rotate-in {
animation: rotate-in var(--duration-moderate) var(--ease-out) forwards;
}
@keyframes rotate-in {
from {
opacity: 0;
transform: rotate(-180deg) scale(0.5);
}
to {
opacity: 1;
transform: rotate(0) scale(1);
}
}
/* 翻转入场 */
.animate-flip-in {
animation: flip-in var(--duration-slow) var(--ease-out) forwards;
}
@keyframes flip-in {
from {
opacity: 0;
transform: perspective(2000rpx) rotateX(-90deg);
}
to {
opacity: 1;
transform: perspective(2000rpx) rotateX(0);
}
}
/* ==================== 🎯 退场动画 ==================== */
/* 淡出 */
.animate-fade-out {
animation: fade-out var(--duration-moderate) var(--ease-in) forwards;
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
/* 向上滑出 */
.animate-slide-out-up {
animation: slide-out-up var(--duration-moderate) var(--ease-in) forwards;
}
@keyframes slide-out-up {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(-60rpx);
}
}
/* 向下滑出 */
.animate-slide-out-down {
animation: slide-out-down var(--duration-moderate) var(--ease-in) forwards;
}
@keyframes slide-out-down {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(60rpx);
}
}
/* 缩放退出 */
.animate-scale-out {
animation: scale-out var(--duration-moderate) var(--ease-in) forwards;
}
@keyframes scale-out {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.85);
}
}
/* ==================== 💫 循环动画 ==================== */
/* 脉冲 */
.animate-pulse {
animation: pulse 2s var(--ease-in-out) infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
/* 心跳 */
.animate-heartbeat {
animation: heartbeat 1.5s var(--ease-in-out) infinite;
}
@keyframes heartbeat {
0%, 100% {
transform: scale(1);
}
14% {
transform: scale(1.15);
}
28% {
transform: scale(1);
}
42% {
transform: scale(1.15);
}
70% {
transform: scale(1);
}
}
/* 弹跳 */
.animate-bounce {
animation: bounce 1s var(--ease-bounce) infinite;
}
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-20rpx);
}
}
/* 摇晃 */
.animate-shake {
animation: shake 0.5s var(--ease-in-out);
}
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(-10rpx);
}
20%, 40%, 60%, 80% {
transform: translateX(10rpx);
}
}
/* 摆动 */
.animate-swing {
animation: swing 1s var(--ease-in-out);
}
@keyframes swing {
20% {
transform: rotate(15deg);
}
40% {
transform: rotate(-10deg);
}
60% {
transform: rotate(5deg);
}
80% {
transform: rotate(-5deg);
}
100% {
transform: rotate(0deg);
}
}
/* 旋转 */
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* 慢速旋转 */
.animate-spin-slow {
animation: spin 3s linear infinite;
}
/* 反向旋转 */
.animate-spin-reverse {
animation: spin-reverse 1s linear infinite;
}
@keyframes spin-reverse {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
/* 漂浮 */
.animate-float {
animation: float 3s var(--ease-in-out) infinite;
}
@keyframes float {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-20rpx);
}
}
/* 呼吸灯 */
.animate-breathing {
animation: breathing 3s var(--ease-in-out) infinite;
}
@keyframes breathing {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.05);
opacity: 0.8;
}
}
/* 闪烁 */
.animate-blink {
animation: blink 1s steps(2) infinite;
}
@keyframes blink {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
/* ==================== 🌊 高级特效 ==================== */
/* 波纹扩散 */
.animate-ripple {
position: relative;
overflow: hidden;
}
.animate-ripple::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
transform: translate(-50%, -50%);
animation: ripple 0.6s ease-out;
}
@keyframes ripple {
to {
width: 300%;
height: 300%;
opacity: 0;
}
}
/* 渐变动画 */
.animate-gradient {
background-size: 200% 200%;
animation: gradient-shift 3s ease infinite;
}
@keyframes gradient-shift {
0%, 100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}
/* 光晕效果 */
.animate-glow {
animation: glow 2s ease-in-out infinite;
}
@keyframes glow {
0%, 100% {
box-shadow: 0 0 10rpx rgba(102, 126, 234, 0.5);
}
50% {
box-shadow: 0 0 30rpx rgba(102, 126, 234, 0.8);
}
}
/* 彩虹边框 */
.animate-rainbow-border {
position: relative;
border: 3rpx solid transparent;
background-clip: padding-box;
}
.animate-rainbow-border::before {
content: '';
position: absolute;
top: -3rpx;
left: -3rpx;
right: -3rpx;
bottom: -3rpx;
background: linear-gradient(45deg,
#FF6B6B, #FFD93D, #6BCF7F, #4ECDC4, #667EEA, #C77DFF);
background-size: 400% 400%;
border-radius: inherit;
z-index: -1;
animation: rainbow 3s ease infinite;
}
@keyframes rainbow {
0%, 100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
}
/* 打字效果 */
.animate-typing {
overflow: hidden;
border-right: 3rpx solid;
white-space: nowrap;
animation: typing 3.5s steps(40) 1s forwards,
blink-caret 0.75s step-end infinite;
width: 0;
}
@keyframes typing {
to {
width: 100%;
}
}
@keyframes blink-caret {
from, to {
border-color: transparent;
}
50% {
border-color: currentColor;
}
}
/* ==================== 🎨 悬停效果 ==================== */
/* 悬停上浮 */
.hover-lift {
transition: transform var(--duration-fast) var(--ease-out),
box-shadow var(--duration-fast) var(--ease-out);
}
.hover-lift:active {
transform: translateY(-8rpx);
box-shadow: var(--shadow-lg);
}
/* 悬停放大 */
.hover-scale {
transition: transform var(--duration-fast) var(--ease-out);
}
.hover-scale:active {
transform: scale(1.05);
}
/* 悬停缩小 */
.hover-shrink {
transition: transform var(--duration-fast) var(--ease-out);
}
.hover-shrink:active {
transform: scale(0.95);
}
/* 悬停倾斜 */
.hover-tilt {
transition: transform var(--duration-fast) var(--ease-out);
}
.hover-tilt:active {
transform: perspective(1000rpx) rotateX(5deg) rotateY(5deg);
}
/* 悬停发光 */
.hover-glow {
transition: box-shadow var(--duration-fast) var(--ease-out);
}
.hover-glow:active {
box-shadow: 0 0 30rpx rgba(102, 126, 234, 0.6);
}
/* 悬停彩色阴影 */
.hover-shadow-color {
transition: box-shadow var(--duration-fast) var(--ease-out);
}
.hover-shadow-color:active {
box-shadow: 0 10rpx 40rpx rgba(102, 126, 234, 0.4);
}
/* ==================== ⚙️ 延迟类 ==================== */
.delay-0 { animation-delay: 0ms !important; }
.delay-50 { animation-delay: 50ms !important; }
.delay-100 { animation-delay: 100ms !important; }
.delay-150 { animation-delay: 150ms !important; }
.delay-200 { animation-delay: 200ms !important; }
.delay-300 { animation-delay: 300ms !important; }
.delay-400 { animation-delay: 400ms !important; }
.delay-500 { animation-delay: 500ms !important; }
.delay-600 { animation-delay: 600ms !important; }
.delay-700 { animation-delay: 700ms !important; }
.delay-800 { animation-delay: 800ms !important; }
.delay-900 { animation-delay: 900ms !important; }
.delay-1000 { animation-delay: 1000ms !important; }
/* ==================== 🏃 速度类 ==================== */
.duration-fast { animation-duration: var(--duration-fast) !important; }
.duration-normal { animation-duration: var(--duration-normal) !important; }
.duration-moderate { animation-duration: var(--duration-moderate) !important; }
.duration-slow { animation-duration: var(--duration-slow) !important; }
.duration-slower { animation-duration: var(--duration-slower) !important; }
/* ==================== 🔄 列表过渡动画 ==================== */
/* 列表项淡入 - 阶梯延迟 */
.list-item-fade {
animation: fade-in var(--duration-moderate) var(--ease-out) backwards;
}
.list-item-fade:nth-child(1) { animation-delay: 0ms; }
.list-item-fade:nth-child(2) { animation-delay: 50ms; }
.list-item-fade:nth-child(3) { animation-delay: 100ms; }
.list-item-fade:nth-child(4) { animation-delay: 150ms; }
.list-item-fade:nth-child(5) { animation-delay: 200ms; }
.list-item-fade:nth-child(6) { animation-delay: 250ms; }
.list-item-fade:nth-child(7) { animation-delay: 300ms; }
.list-item-fade:nth-child(8) { animation-delay: 350ms; }
.list-item-fade:nth-child(9) { animation-delay: 400ms; }
.list-item-fade:nth-child(10) { animation-delay: 450ms; }
/* 列表项滑入 - 阶梯延迟 */
.list-item-slide {
animation: slide-in-up var(--duration-moderate) var(--ease-out) backwards;
}
.list-item-slide:nth-child(1) { animation-delay: 0ms; }
.list-item-slide:nth-child(2) { animation-delay: 50ms; }
.list-item-slide:nth-child(3) { animation-delay: 100ms; }
.list-item-slide:nth-child(4) { animation-delay: 150ms; }
.list-item-slide:nth-child(5) { animation-delay: 200ms; }
.list-item-slide:nth-child(6) { animation-delay: 250ms; }
.list-item-slide:nth-child(7) { animation-delay: 300ms; }
.list-item-slide:nth-child(8) { animation-delay: 350ms; }
.list-item-slide:nth-child(9) { animation-delay: 400ms; }
.list-item-slide:nth-child(10) { animation-delay: 450ms; }
/* ==================== 📱 页面转场动画 ==================== */
/* 页面淡入 */
.page-enter {
animation: page-fade-in var(--duration-moderate) var(--ease-out);
}
@keyframes page-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 页面从右滑入 */
.page-slide-in {
animation: page-slide-in var(--duration-moderate) var(--ease-out);
}
@keyframes page-slide-in {
from {
opacity: 0;
transform: translateX(100rpx);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 页面缩放进入 */
.page-zoom-in {
animation: page-zoom-in var(--duration-moderate) var(--ease-out);
}
@keyframes page-zoom-in {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* ==================== 🎯 骨架屏动画 ==================== */
.skeleton-shimmer {
background: linear-gradient(
90deg,
rgba(0, 0, 0, 0.06) 25%,
rgba(0, 0, 0, 0.15) 37%,
rgba(0, 0, 0, 0.06) 63%
);
background-size: 400% 100%;
animation: skeleton-loading 1.4s ease infinite;
}
@keyframes skeleton-loading {
0% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}
/* ==================== 🌟 特殊效果 ==================== */
/* 故障效果 */
.glitch {
position: relative;
animation: glitch 2s infinite;
}
@keyframes glitch {
0%, 100% {
transform: translate(0);
}
20% {
transform: translate(-2rpx, 2rpx);
}
40% {
transform: translate(-2rpx, -2rpx);
}
60% {
transform: translate(2rpx, 2rpx);
}
80% {
transform: translate(2rpx, -2rpx);
}
}
/* 霓虹灯效果 */
.neon {
animation: neon 1.5s ease-in-out infinite alternate;
}
@keyframes neon {
from {
text-shadow:
0 0 10rpx #fff,
0 0 20rpx #fff,
0 0 30rpx #fff,
0 0 40rpx #667EEA,
0 0 70rpx #667EEA,
0 0 80rpx #667EEA,
0 0 100rpx #667EEA,
0 0 150rpx #667EEA;
}
to {
text-shadow:
0 0 5rpx #fff,
0 0 10rpx #fff,
0 0 15rpx #fff,
0 0 20rpx #667EEA,
0 0 35rpx #667EEA,
0 0 40rpx #667EEA,
0 0 50rpx #667EEA,
0 0 75rpx #667EEA;
}
}
/* 粒子飘散 */
.particle-float {
animation: particle-float 3s ease-in-out infinite;
}
@keyframes particle-float {
0%, 100% {
transform: translateY(0) translateX(0);
}
33% {
transform: translateY(-20rpx) translateX(10rpx);
}
66% {
transform: translateY(-10rpx) translateX(-10rpx);
}
}

View File

@@ -0,0 +1,755 @@
/**
* ============================================
* 🎨 企业级通用组件样式库
* ============================================
* 参考Ant Design、Material Design、iOS HIG
*/
@import './design-tokens.wxss';
/* ==================== 按钮组件 ==================== */
.btn {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
padding: var(--space-4) var(--space-8);
border-radius: var(--radius-xl);
font-size: var(--font-size-base);
font-weight: var(--font-weight-medium);
line-height: var(--line-height-tight);
transition: var(--transition-base);
border: none;
outline: none;
overflow: hidden;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
.btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
transform: translate(-50%, -50%);
transition: width var(--duration-moderate) var(--ease-out),
height var(--duration-moderate) var(--ease-out);
}
.btn:active::before {
width: 200%;
height: 200%;
}
/* 主要按钮 */
.btn-primary {
background: var(--gradient-purple-dream);
color: var(--text-inverse);
box-shadow: var(--shadow-primary);
}
.btn-primary:active {
transform: translateY(2rpx);
box-shadow: var(--shadow-sm);
}
/* 次要按钮 */
.btn-secondary {
background: var(--bg-secondary);
color: var(--text-primary);
box-shadow: var(--shadow-sm);
}
/* 幽灵按钮 */
.btn-ghost {
background: transparent;
border: 2rpx solid var(--border-base);
color: var(--text-primary);
}
/* 文本按钮 */
.btn-text {
background: transparent;
color: var(--brand-primary);
padding: var(--space-2) var(--space-4);
}
/* 危险按钮 */
.btn-danger {
background: linear-gradient(135deg, #FF6B6B 0%, #FF4757 100%);
color: var(--text-inverse);
box-shadow: var(--shadow-error);
}
/* 按钮尺寸 */
.btn-large {
padding: var(--space-6) var(--space-12);
font-size: var(--font-size-lg);
border-radius: var(--radius-2xl);
}
.btn-small {
padding: var(--space-2) var(--space-6);
font-size: var(--font-size-sm);
border-radius: var(--radius-md);
}
.btn-mini {
padding: var(--space-1) var(--space-4);
font-size: var(--font-size-xs);
border-radius: var(--radius-sm);
}
/* 块级按钮 */
.btn-block {
width: 100%;
}
/* 禁用状态 */
.btn-disabled {
opacity: 0.4;
pointer-events: none;
}
/* 加载状态 */
.btn-loading {
pointer-events: none;
}
.btn-loading::after {
content: '';
display: inline-block;
width: 28rpx;
height: 28rpx;
margin-left: var(--space-2);
border: 3rpx solid currentColor;
border-right-color: transparent;
border-radius: 50%;
animation: btn-spin 0.6s linear infinite;
}
@keyframes btn-spin {
to { transform: rotate(360deg); }
}
/* ==================== 卡片组件 ==================== */
.card {
background: var(--bg-primary);
border-radius: var(--radius-2xl);
box-shadow: var(--shadow-sm);
overflow: hidden;
transition: var(--transition-base);
}
.card-hover {
cursor: pointer;
}
.card-hover:active {
transform: scale(0.98);
box-shadow: var(--shadow-md);
}
/* 卡片头部 */
.card-header {
padding: var(--space-6);
border-bottom: 1rpx solid var(--divider);
}
.card-title {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-semibold);
color: var(--text-primary);
}
.card-subtitle {
margin-top: var(--space-1);
font-size: var(--font-size-sm);
color: var(--text-tertiary);
}
/* 卡片内容 */
.card-body {
padding: var(--space-6);
}
/* 卡片底部 */
.card-footer {
padding: var(--space-6);
border-top: 1rpx solid var(--divider);
background: var(--bg-secondary);
}
/* 渐变卡片 */
.card-gradient {
background: var(--gradient-purple-dream);
color: var(--text-inverse);
box-shadow: var(--shadow-primary);
}
/* 毛玻璃卡片 */
.card-glass {
background: var(--glass-white);
backdrop-filter: blur(var(--blur-lg));
border: 1rpx solid var(--glass-border);
box-shadow: var(--glass-shadow);
}
/* 边框卡片 */
.card-bordered {
border: 1rpx solid var(--border-base);
box-shadow: none;
}
/* 无阴影卡片 */
.card-flat {
box-shadow: none;
}
/* ==================== 头像组件 ==================== */
.avatar {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
overflow: hidden;
background: var(--bg-tertiary);
color: var(--text-tertiary);
font-weight: var(--font-weight-medium);
}
.avatar-sm {
width: 48rpx;
height: 48rpx;
font-size: var(--font-size-xs);
}
.avatar-base {
width: 64rpx;
height: 64rpx;
font-size: var(--font-size-sm);
}
.avatar-lg {
width: 80rpx;
height: 80rpx;
font-size: var(--font-size-base);
}
.avatar-xl {
width: 120rpx;
height: 120rpx;
font-size: var(--font-size-lg);
}
.avatar-2xl {
width: 160rpx;
height: 160rpx;
font-size: var(--font-size-xl);
}
.avatar-img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* 头像组 */
.avatar-group {
display: inline-flex;
align-items: center;
}
.avatar-group .avatar {
margin-left: calc(var(--space-2) * -1);
border: 3rpx solid var(--bg-primary);
}
.avatar-group .avatar:first-child {
margin-left: 0;
}
/* ==================== 徽标组件 ==================== */
.badge {
position: relative;
display: inline-flex;
}
.badge-dot {
position: absolute;
top: 0;
right: 0;
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: var(--color-error);
border: 3rpx solid var(--bg-primary);
}
.badge-count {
position: absolute;
top: -8rpx;
right: -8rpx;
min-width: 32rpx;
height: 32rpx;
padding: 0 8rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
background: var(--color-error);
color: var(--text-inverse);
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
line-height: 1;
white-space: nowrap;
border: 2rpx solid var(--bg-primary);
box-shadow: var(--shadow-sm);
}
/* 标签徽标 */
.tag {
display: inline-flex;
align-items: center;
gap: var(--space-1);
padding: var(--space-1) var(--space-3);
border-radius: var(--radius-base);
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
line-height: var(--line-height-tight);
white-space: nowrap;
}
.tag-primary {
background: rgba(102, 126, 234, 0.1);
color: var(--brand-primary);
}
.tag-success {
background: var(--color-success-bg);
color: var(--color-success);
}
.tag-warning {
background: var(--color-warning-bg);
color: var(--color-warning);
}
.tag-error {
background: var(--color-error-bg);
color: var(--color-error);
}
.tag-info {
background: var(--color-info-bg);
color: var(--color-info);
}
/* ==================== 分割线组件 ==================== */
.divider {
height: 1rpx;
background: var(--divider);
border: none;
margin: var(--space-6) 0;
}
.divider-vertical {
width: 1rpx;
height: auto;
margin: 0 var(--space-4);
display: inline-block;
}
.divider-text {
position: relative;
text-align: center;
margin: var(--space-6) 0;
}
.divider-text::before,
.divider-text::after {
content: '';
position: absolute;
top: 50%;
width: calc(50% - 60rpx);
height: 1rpx;
background: var(--divider);
}
.divider-text::before {
left: 0;
}
.divider-text::after {
right: 0;
}
.divider-text-content {
position: relative;
padding: 0 var(--space-4);
color: var(--text-tertiary);
font-size: var(--font-size-sm);
background: var(--bg-primary);
}
/* ==================== 空状态组件 ==================== */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--space-20) var(--space-6);
text-align: center;
}
.empty-icon {
font-size: 120rpx;
margin-bottom: var(--space-6);
opacity: 0.5;
}
.empty-title {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-medium);
color: var(--text-secondary);
margin-bottom: var(--space-2);
}
.empty-description {
font-size: var(--font-size-sm);
color: var(--text-tertiary);
line-height: var(--line-height-relaxed);
max-width: 400rpx;
}
.empty-action {
margin-top: var(--space-8);
}
/* ==================== 骨架屏组件 ==================== */
.skeleton {
background: linear-gradient(90deg,
var(--bg-tertiary) 25%,
var(--bg-secondary) 50%,
var(--bg-tertiary) 75%
);
background-size: 200% 100%;
animation: skeleton-loading 1.5s ease-in-out infinite;
border-radius: var(--radius-base);
}
@keyframes skeleton-loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
.skeleton-text {
height: 28rpx;
margin-bottom: var(--space-3);
}
.skeleton-title {
height: 40rpx;
width: 60%;
margin-bottom: var(--space-4);
}
.skeleton-avatar {
width: 80rpx;
height: 80rpx;
border-radius: var(--radius-full);
}
.skeleton-image {
width: 100%;
height: 400rpx;
border-radius: var(--radius-xl);
}
.skeleton-button {
height: 72rpx;
width: 160rpx;
border-radius: var(--radius-xl);
}
/* ==================== 加载组件 ==================== */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--space-12);
}
.loading-spinner {
width: 64rpx;
height: 64rpx;
border: 6rpx solid var(--border-light);
border-top-color: var(--brand-primary);
border-radius: 50%;
animation: spinner-rotate 0.8s linear infinite;
}
@keyframes spinner-rotate {
to { transform: rotate(360deg); }
}
.loading-dots {
display: flex;
gap: var(--space-3);
}
.loading-dot {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background: var(--brand-primary);
animation: dot-bounce 1.4s ease-in-out infinite;
}
.loading-dot:nth-child(1) {
animation-delay: -0.32s;
}
.loading-dot:nth-child(2) {
animation-delay: -0.16s;
}
@keyframes dot-bounce {
0%, 80%, 100% {
transform: scale(0);
opacity: 0.5;
}
40% {
transform: scale(1);
opacity: 1;
}
}
.loading-text {
margin-top: var(--space-4);
font-size: var(--font-size-sm);
color: var(--text-tertiary);
}
/* ==================== 遮罩组件 ==================== */
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--bg-mask);
z-index: var(--z-index-modal-backdrop);
animation: overlay-fadein var(--duration-normal) var(--ease-out);
}
@keyframes overlay-fadein {
from { opacity: 0; }
to { opacity: 1; }
}
/* ==================== 模态框组件 ==================== */
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
padding: var(--space-8);
z-index: var(--z-index-modal);
animation: modal-fadein var(--duration-normal) var(--ease-out);
}
@keyframes modal-fadein {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
.modal-content {
width: 100%;
max-width: 600rpx;
background: var(--bg-primary);
border-radius: var(--radius-2xl);
box-shadow: var(--shadow-2xl);
overflow: hidden;
animation: modal-slideup var(--duration-moderate) var(--ease-out);
}
@keyframes modal-slideup {
from {
opacity: 0;
transform: translateY(40rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.modal-header {
position: relative;
padding: var(--space-8);
border-bottom: 1rpx solid var(--divider);
}
.modal-title {
font-size: var(--font-size-xl);
font-weight: var(--font-weight-semibold);
color: var(--text-primary);
text-align: center;
}
.modal-close {
position: absolute;
top: var(--space-6);
right: var(--space-6);
width: 56rpx;
height: 56rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
background: var(--bg-hover);
color: var(--text-tertiary);
font-size: var(--font-size-lg);
transition: var(--transition-fast);
}
.modal-close:active {
background: var(--bg-active);
transform: scale(0.9);
}
.modal-body {
padding: var(--space-8);
max-height: 800rpx;
overflow-y: auto;
}
.modal-footer {
padding: var(--space-6) var(--space-8);
border-top: 1rpx solid var(--divider);
display: flex;
gap: var(--space-4);
}
.modal-footer .btn {
flex: 1;
}
/* ==================== Toast 组件 ==================== */
.toast {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: var(--space-6) var(--space-8);
background: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(var(--blur-md));
color: var(--text-inverse);
border-radius: var(--radius-xl);
font-size: var(--font-size-base);
text-align: center;
z-index: var(--z-index-notification);
animation: toast-show var(--duration-normal) var(--ease-out);
max-width: 500rpx;
box-shadow: var(--shadow-lg);
}
@keyframes toast-show {
from {
opacity: 0;
transform: translate(-50%, -50%) scale(0.8);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}
.toast-icon {
font-size: 64rpx;
margin-bottom: var(--space-3);
}
/* ==================== 输入框组件 ==================== */
.input-group {
margin-bottom: var(--space-6);
}
.input-label {
display: block;
margin-bottom: var(--space-2);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
color: var(--text-secondary);
}
.input-field {
width: 100%;
padding: var(--space-4) var(--space-6);
border: 2rpx solid var(--border-base);
border-radius: var(--radius-xl);
font-size: var(--font-size-base);
color: var(--text-primary);
background: var(--bg-primary);
transition: var(--transition-fast);
}
.input-field:focus {
border-color: var(--brand-primary);
box-shadow: 0 0 0 6rpx rgba(102, 126, 234, 0.1);
}
.input-field::placeholder {
color: var(--text-quaternary);
}
.input-error {
border-color: var(--color-error);
}
.input-error:focus {
box-shadow: 0 0 0 6rpx var(--color-error-bg);
}
.input-helper {
margin-top: var(--space-2);
font-size: var(--font-size-xs);
color: var(--text-tertiary);
}
.input-error-text {
color: var(--color-error);
}