1
This commit is contained in:
340
styles/design-tokens.wxss
Normal file
340
styles/design-tokens.wxss
Normal 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);
|
||||
}
|
||||
765
styles/premium-animations.wxss
Normal file
765
styles/premium-animations.wxss
Normal 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);
|
||||
}
|
||||
}
|
||||
755
styles/premium-components.wxss
Normal file
755
styles/premium-components.wxss
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user