Files
AIPlaylet/web/src/assets/styles/main.css
2026-01-16 17:30:40 +08:00

1136 lines
24 KiB
CSS

@tailwind base;
@tailwind components;
@tailwind utilities;
/* ========================================
CSS Variables for Theme / 主题 CSS 变量
Modern minimalist design system
======================================== */
:root {
/* Background colors / 背景色 */
--bg-primary: #f8fafc;
--bg-secondary: #ffffff;
--bg-card: #ffffff;
--bg-card-hover: #f1f5f9;
--bg-elevated: #ffffff;
--bg-overlay: rgba(15, 23, 42, 0.5);
/* Text colors / 文字色 */
--text-primary: #0f172a;
--text-secondary: #475569;
--text-muted: #94a3b8;
--text-inverse: #ffffff;
/* Border colors / 边框色 */
--border-primary: #e2e8f0;
--border-secondary: #cbd5e1;
--border-focus: #0ea5e9;
/* Primary accent / 主强调色 */
--accent: #0ea5e9;
--accent-hover: #0284c7;
--accent-light: #e0f2fe;
--accent-dark: #0369a1;
/* Status colors / 状态色 */
--success: #10b981;
--success-light: #d1fae5;
--warning: #f59e0b;
--warning-light: #fef3c7;
--error: #ef4444;
--error-light: #fee2e2;
--info: #3b82f6;
--info-light: #dbeafe;
/* Shadows / 阴影 - refined for depth */
--shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.03);
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.05), 0 1px 2px -1px rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.07), 0 2px 4px -2px rgb(0 0 0 / 0.05);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.08), 0 4px 6px -4px rgb(0 0 0 / 0.05);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.05);
--shadow-glow: 0 0 20px rgba(14, 165, 233, 0.15);
--shadow-card: 0 1px 3px 0 rgb(0 0 0 / 0.04), 0 1px 2px -1px rgb(0 0 0 / 0.04);
--shadow-card-hover: 0 8px 16px -4px rgb(0 0 0 / 0.1), 0 4px 6px -2px rgb(0 0 0 / 0.05);
/* Transition / 过渡 */
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-normal: 200ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-bounce: 500ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
/* Border radius / 圆角 */
--radius-xs: 0.25rem;
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--radius-xl: 1rem;
--radius-2xl: 1.25rem;
--radius-full: 9999px;
/* Spacing scale / 间距比例 */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-5: 1.25rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-10: 2.5rem;
--space-12: 3rem;
}
/* Dark mode theme / 深色模式主题 - 参考深色UI设计 */
.dark {
/* Background - 深邃的蓝黑色调 */
--bg-primary: #0c1015;
--bg-secondary: #12181f;
--bg-card: #181f28;
--bg-card-hover: #1e2730;
--bg-elevated: #1a2129;
--bg-overlay: rgba(0, 0, 0, 0.8);
/* Text - 清晰的层次对比 */
--text-primary: #e8edf3;
--text-secondary: #8b9bb0;
--text-muted: #5a6a7e;
--text-inverse: #0c1015;
/* Border - 微妙的边框 */
--border-primary: #252d38;
--border-secondary: #323d4d;
--border-focus: #22d3ee;
/* Accent - 青色强调色 */
--accent: #22d3ee;
--accent-hover: #06b6d4;
--accent-light: rgba(34, 211, 238, 0.12);
--accent-dark: #67e8f9;
/* Status colors / 状态色 */
--success: #34d399;
--success-light: rgba(52, 211, 153, 0.12);
--warning: #fbbf24;
--warning-light: rgba(251, 191, 36, 0.12);
--error: #f87171;
--error-light: rgba(248, 113, 113, 0.12);
--info: #60a5fa;
--info-light: rgba(96, 165, 250, 0.12);
/* Shadows - 更深的阴影 */
--shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.4);
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.5), 0 1px 2px -1px rgb(0 0 0 / 0.5);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.6), 0 2px 4px -2px rgb(0 0 0 / 0.5);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.7), 0 4px 6px -4px rgb(0 0 0 / 0.6);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.8), 0 8px 10px -6px rgb(0 0 0 / 0.7);
--shadow-glow: 0 0 20px rgba(34, 211, 238, 0.25);
--shadow-card: 0 2px 4px 0 rgb(0 0 0 / 0.3);
--shadow-card-hover: 0 8px 20px -4px rgb(0 0 0 / 0.5), 0 0 0 1px rgba(34, 211, 238, 0.15);
--el-fill-color-blank: #181F28;
--el-border-color: #4d4d4d;
--el-border-color-light: #2a333d;
--el-fill-color-light: #2a333d;
--el-bg-color-overlay: #181F28;
--el-text-color-regular: #e8edf3;
--el-descriptions-table-border: #4d4d4d;
--el-border-color-lighter: #4d4d4d;
--el-text-color-primary: #e8edf3;
}
/* ========================================
Base Styles / 基础样式
======================================== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
transition: background-color var(--transition-normal), color var(--transition-normal);
}
#app {
width: 100%;
height: 100%;
}
/* ========================================
Element Plus Overrides / Element Plus 样式覆盖
Modern minimalist design overrides
======================================== */
/* 单行打点 */
.overflow-tooltip {
display: inline-block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
}
.el-select-dropdown__item {
line-height: unset;
}
/* Button overrides / 按钮样式覆盖 */
.el-button {
--el-button-border-radius: var(--radius-lg);
font-weight: 500;
transition: all var(--transition-fast);
border: none;
letter-spacing: -0.01em;
}
.el-button--default {
background: var(--bg-card);
border: 1px solid var(--border-primary);
color: var(--text-primary);
}
.el-button--default:hover {
background: var(--bg-card-hover);
border-color: var(--border-secondary);
color: var(--text-primary);
}
.el-button--primary {
--el-button-bg-color: var(--accent);
--el-button-border-color: var(--accent);
--el-button-hover-bg-color: var(--accent-hover);
--el-button-hover-border-color: var(--accent-hover);
background: linear-gradient(135deg, var(--accent) 0%, #0284c7 100%);
box-shadow: 0 2px 8px rgba(14, 165, 233, 0.25);
}
.el-button--primary:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(14, 165, 233, 0.35);
}
.el-button--primary:active {
transform: translateY(0);
}
.el-button--danger {
background: linear-gradient(135deg, var(--error) 0%, #dc2626 100%);
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.25);
}
.el-button--danger:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.35);
}
.el-button--success {
background: linear-gradient(135deg, var(--success) 0%, #059669 100%);
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.25);
}
.el-button.is-text {
color: var(--text-secondary);
}
.el-button.is-text:hover {
color: var(--accent);
background: var(--accent-light);
}
.el-button.is-circle {
background: var(--bg-card);
border: 1px solid var(--border-primary);
color: var(--text-secondary);
}
.el-button.is-circle:hover {
background: var(--bg-card-hover);
border-color: var(--border-secondary);
color: var(--text-primary);
}
/* Back button / 返回按钮 */
.back-btn {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.5rem 0.875rem;
background: var(--bg-card);
border: 1px solid var(--border-primary);
border-radius: var(--radius-lg);
color: var(--text-secondary);
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: all var(--transition-fast);
white-space: nowrap;
}
.back-btn:hover {
background: var(--bg-card-hover);
color: var(--text-primary);
border-color: var(--border-secondary);
}
.back-btn:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* Card overrides / 卡片样式覆盖 */
.el-card {
--el-card-bg-color: var(--bg-card);
--el-card-border-color: var(--border-primary);
--el-card-border-radius: var(--radius-xl);
border: 1px solid var(--border-primary);
box-shadow: var(--shadow-card);
transition: all var(--transition-normal);
}
.el-card:hover {
box-shadow: var(--shadow-card-hover);
}
.el-card__header {
border-bottom: 1px solid var(--border-primary);
padding: var(--space-4) var(--space-5);
}
.el-card__body {
padding: var(--space-5);
}
.dark .el-card {
--el-card-bg-color: var(--bg-card);
--el-card-border-color: var(--border-primary);
}
/* Dialog overrides / 对话框样式覆盖 */
.el-dialog {
--el-dialog-bg-color: var(--bg-card);
--el-dialog-border-radius: var(--radius-2xl);
box-shadow: var(--shadow-xl);
border: 1px solid var(--border-primary);
}
.el-dialog__header {
padding: var(--space-5) var(--space-6);
border-bottom: 1px solid var(--border-primary);
margin-right: 0;
}
.el-dialog__title {
font-size: 1.125rem;
font-weight: 600;
color: var(--text-primary);
letter-spacing: -0.02em;
}
.el-dialog__body {
padding: var(--space-6);
}
.el-dialog__footer {
padding: var(--space-4) var(--space-6);
border-top: 1px solid var(--border-primary);
}
.dark .el-dialog {
--el-dialog-bg-color: var(--bg-card);
}
.dark .el-dialog__title {
color: var(--text-primary);
}
/* Input overrides / 输入框样式覆盖 */
.el-input__wrapper {
--el-input-bg-color: var(--bg-secondary);
--el-input-border-color: var(--border-primary);
border-radius: var(--radius-lg) !important;
box-shadow: 0 0 0 1px var(--border-primary) inset !important;
transition: all var(--transition-fast);
padding: 0 var(--space-3);
}
.el-input__wrapper:hover {
box-shadow: 0 0 0 1px var(--border-secondary) inset !important;
}
.el-input__wrapper.is-focus {
box-shadow: 0 0 0 2px var(--accent) inset !important;
}
.el-input__inner {
color: var(--text-primary);
font-size: 0.875rem;
}
.el-input__inner::placeholder {
color: var(--text-muted);
}
.el-textarea__inner {
--el-input-bg-color: var(--bg-secondary);
border-radius: var(--radius-lg) !important;
box-shadow: 0 0 0 1px var(--border-primary) inset;
transition: all var(--transition-fast);
padding: var(--space-3);
color: var(--text-primary);
font-size: 0.875rem;
}
.el-textarea__inner:hover {
box-shadow: 0 0 0 1px var(--border-secondary) inset;
}
.el-textarea__inner:focus {
box-shadow: 0 0 0 2px var(--accent) inset;
}
.el-textarea__inner::placeholder {
color: var(--text-muted);
}
.dark .el-input__wrapper {
background-color: var(--bg-secondary);
}
.dark .el-input__inner {
color: var(--text-primary);
}
.dark .el-textarea__inner {
background-color: var(--bg-secondary);
color: var(--text-primary);
}
/* Select overrides / 选择器样式覆盖 */
.el-select .el-input__wrapper {
background: var(--bg-secondary);
}
.el-select-dropdown {
border-radius: var(--radius-lg);
border: 1px solid var(--border-primary);
box-shadow: var(--shadow-lg);
}
.el-select-dropdown__item {
font-size: 0.875rem;
padding: var(--space-2) var(--space-3);
border-radius: var(--radius-sm);
margin: 2px var(--space-1);
}
.el-select-dropdown__item.is-selected {
background: var(--accent-light);
color: var(--accent);
font-weight: 500;
}
.el-select-dropdown__item:hover {
background: var(--bg-card-hover);
}
.dark .el-select-dropdown {
background: var(--bg-elevated);
border-color: var(--border-primary);
}
.dark .el-select-dropdown__item:hover {
background: var(--bg-card-hover);
}
/* Tag overrides / 标签样式覆盖 */
.el-tag {
--el-tag-border-radius: var(--radius-md);
font-weight: 500;
font-size: 0.75rem;
padding: 0 var(--space-2);
height: 1.5rem;
line-height: 1.5rem;
border: none;
}
.el-tag--info {
background: var(--bg-card-hover);
color: var(--text-secondary);
}
.el-tag--primary {
background: var(--accent-light);
color: var(--accent);
}
.el-tag--success {
background: var(--success-light);
color: var(--success);
}
.el-tag--warning {
background: var(--warning-light);
color: var(--warning);
}
.el-tag--danger {
background: var(--error-light);
color: var(--error);
}
/* Tabs overrides / 标签页样式覆盖 */
.el-tabs__header {
margin-bottom: var(--space-6);
}
.el-tabs__nav-wrap::after {
display: none;
}
.el-tabs__item {
font-weight: 500;
font-size: 0.875rem;
color: var(--text-secondary);
padding: 0 var(--space-5);
height: 2.5rem;
line-height: 2.5rem;
transition: color var(--transition-fast);
}
.el-tabs__item:hover {
color: var(--text-primary);
}
.el-tabs__item.is-active {
color: var(--accent);
font-weight: 600;
}
.el-tabs__active-bar {
background: var(--accent);
height: 2px;
border-radius: var(--radius-full);
}
.dark .el-tabs__item {
color: var(--text-secondary);
}
.dark .el-tabs__item.is-active {
color: var(--accent);
}
/* Table overrides / 表格样式覆盖 */
.el-table {
--el-table-bg-color: var(--bg-card);
--el-table-header-bg-color: var(--bg-secondary);
--el-table-tr-bg-color: var(--bg-card);
--el-table-row-hover-bg-color: var(--bg-card-hover);
--el-table-border-color: var(--border-primary);
border-radius: var(--radius-lg);
overflow: hidden;
}
.el-table th.el-table__cell {
font-weight: 600;
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
}
.el-table td.el-table__cell {
font-size: 0.875rem;
color: var(--text-primary);
}
.dark .el-table {
--el-table-bg-color: var(--bg-card);
--el-table-header-bg-color: var(--bg-secondary);
--el-table-tr-bg-color: var(--bg-card);
--el-table-row-hover-bg-color: var(--bg-card-hover);
}
.dark .el-table th.el-table__cell,
.dark .el-table td.el-table__cell {
border-color: var(--border-primary);
}
/* Pagination overrides / 分页样式覆盖 */
.el-pagination {
--el-pagination-bg-color: transparent;
--el-pagination-button-bg-color: var(--bg-card);
gap: var(--space-1);
}
.el-pager li {
min-width: 2rem;
height: 2rem;
line-height: 2rem;
font-weight: 500;
font-size: 0.8125rem;
border-radius: var(--radius-md);
background: transparent;
color: var(--text-secondary);
transition: all var(--transition-fast);
}
.el-pager li:hover {
color: var(--accent);
background: var(--accent-light);
}
.el-pager li.is-active {
background: var(--accent);
color: white;
font-weight: 600;
}
.el-pagination button {
min-width: 2rem;
height: 2rem;
border-radius: var(--radius-md);
background: transparent;
color: var(--text-secondary);
transition: all var(--transition-fast);
}
.el-pagination button:hover:not(:disabled) {
color: var(--accent);
background: var(--accent-light);
}
.el-pagination button:disabled {
opacity: 0.4;
}
.dark .el-pagination {
--el-pagination-text-color: var(--text-secondary);
--el-pagination-button-color: var(--text-primary);
}
.dark .el-pagination button,
.dark .el-pager li {
background-color: transparent;
color: var(--text-secondary);
}
.dark .el-pager li:hover {
background: var(--accent-light);
}
.dark .el-pager li.is-active {
background: var(--accent);
color: var(--text-inverse);
}
/* Empty state overrides / 空状态样式覆盖 */
.el-empty {
padding: var(--space-12) var(--space-6);
}
.el-empty__description p {
color: var(--text-muted);
font-size: 0.875rem;
}
.dark .el-empty__description p {
color: var(--text-muted);
}
/* Alert overrides / 提示框样式覆盖 */
.el-alert {
border-radius: var(--radius-lg);
border: none;
padding: var(--space-4);
}
.el-alert--info {
background: var(--info-light);
}
.el-alert--success {
background: var(--success-light);
}
.el-alert--warning {
background: var(--warning-light);
}
.el-alert--error {
background: var(--error-light);
}
.dark .el-alert--info {
--el-alert-bg-color: var(--info-light);
}
/* Form overrides / 表单样式覆盖 */
.el-form-item__label {
font-weight: 500;
font-size: 0.875rem;
color: var(--text-primary);
margin-bottom: var(--space-2);
}
.dark .el-form-item__label {
color: var(--text-primary);
}
/* Descriptions overrides / 描述列表样式覆盖 */
.el-descriptions {
--el-descriptions-item-bordered-label-background: var(--bg-secondary);
}
.el-descriptions__label {
font-weight: 500;
color: var(--text-secondary);
}
.el-descriptions__content {
color: var(--text-primary);
}
.dark .el-descriptions__label,
.dark .el-descriptions__content {
background: var(--bg-secondary);
}
/* Message Box overrides / 消息框样式覆盖 */
.el-message-box {
border-radius: var(--radius-xl);
border: 1px solid var(--border-primary);
box-shadow: var(--shadow-xl);
}
.dark .el-message-box {
background: var(--bg-card);
}
/* Popconfirm overrides / 确认弹窗样式覆盖 */
.el-popconfirm {
border-radius: var(--radius-lg);
}
.dark .el-popconfirm {
--el-popconfirm-bg-color: var(--bg-card);
}
/* Loading overrides / 加载样式覆盖 */
.el-loading-mask {
background: var(--bg-overlay);
backdrop-filter: blur(4px);
}
.el-loading-spinner .circular {
width: 32px;
height: 32px;
}
.el-loading-spinner .path {
stroke: var(--accent);
}
/* Switch overrides / 开关样式覆盖 */
.el-switch {
--el-switch-on-color: var(--accent);
}
.dark .el-switch__core {
background: var(--bg-secondary);
border-color: var(--border-primary);
}
/* Tooltip overrides / 提示框样式覆盖 */
.el-tooltip__trigger {
outline: none;
}
/* Avatar overrides / 头像样式覆盖 */
.el-avatar {
--el-avatar-bg-color: var(--accent);
}
/* Scrollbar overrides / 滚动条样式覆盖 */
.el-scrollbar__thumb {
background: var(--border-secondary);
border-radius: var(--radius-full);
}
.el-scrollbar__thumb:hover {
background: var(--text-muted);
}
/* ========================================
Utility Classes / 工具类
======================================== */
.page-container {
min-height: 100vh;
background-color: var(--bg-primary);
padding: var(--space-2) var(--space-3);
transition: background-color var(--transition-normal);
}
@media (min-width: 768px) {
.page-container {
padding: var(--space-3) var(--space-4);
}
}
@media (min-width: 1024px) {
.page-container {
padding: var(--space-4) var(--space-5);
}
}
.content-wrapper {
margin: 0 auto;
width: 100%;
}
/* ========================================
Layout Components / 布局组件
======================================== */
/* Glass morphism card / 玻璃态卡片 */
.glass-card {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(12px);
border: 1px solid var(--border-primary);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-card);
transition: all var(--transition-normal);
}
.dark .glass-card {
background: rgba(26, 35, 50, 0.8);
}
.glass-card:hover {
box-shadow: var(--shadow-card-hover);
}
/* Gradient backgrounds / 渐变背景 */
.gradient-primary {
background: linear-gradient(135deg, var(--accent) 0%, #0284c7 100%);
}
.gradient-success {
background: linear-gradient(135deg, var(--success) 0%, #059669 100%);
}
.gradient-warning {
background: linear-gradient(135deg, var(--warning) 0%, #d97706 100%);
}
.gradient-error {
background: linear-gradient(135deg, var(--error) 0%, #dc2626 100%);
}
/* Animated gradient / 动画渐变 */
.gradient-animated {
background: linear-gradient(-45deg, #0ea5e9, #06b6d4, #8b5cf6, #ec4899);
background-size: 400% 400%;
animation: gradient-shift 15s ease infinite;
}
@keyframes gradient-shift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* Glow effect / 发光效果 */
.glow-primary {
box-shadow: 0 0 20px rgba(14, 165, 233, 0.3);
}
.glow-success {
box-shadow: 0 0 20px rgba(16, 185, 129, 0.3);
}
/* Skeleton loading / 骨架屏加载 */
.skeleton {
background: linear-gradient(90deg, var(--bg-card-hover) 25%, var(--bg-secondary) 50%, var(--bg-card-hover) 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
border-radius: var(--radius-md);
}
@keyframes skeleton-loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
/* Hover lift effect / 悬停提升效果 */
.hover-lift {
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.hover-lift:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
/* Interactive scale / 交互缩放 */
.interactive-scale {
transition: transform var(--transition-fast);
}
.interactive-scale:hover {
transform: scale(1.02);
}
.interactive-scale:active {
transform: scale(0.98);
}
/* Focus ring / 焦点环 */
.focus-ring:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* Text truncation / 文本截断 */
.truncate-1 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.truncate-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.truncate-3 {
display: -webkit-box;
-webkit-line-clamp: 3;
line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Scrollbar styling / 滚动条样式 */
.custom-scrollbar::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: var(--border-secondary);
border-radius: var(--radius-full);
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: var(--text-muted);
}
/* Hide scrollbar / 隐藏滚动条 */
.hide-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
/* ========================================
Animation Utilities / 动画工具
======================================== */
/* Fade in / 淡入 */
.animate-fade-in {
animation: fade-in 0.3s ease-out;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* Slide up / 向上滑入 */
.animate-slide-up {
animation: slide-up 0.3s ease-out;
}
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Scale in / 缩放进入 */
.animate-scale-in {
animation: scale-in 0.2s ease-out;
}
@keyframes scale-in {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* Pulse / 脉冲 */
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
/* Spin / 旋转 */
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Bounce / 弹跳 */
.animate-bounce {
animation: bounce 1s infinite;
}
@keyframes bounce {
0%,
100% {
transform: translateY(-5%);
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
}
50% {
transform: translateY(0);
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
}
/* ========================================
Status Indicators / 状态指示器
======================================== */
.status-dot {
width: 8px;
height: 8px;
border-radius: var(--radius-full);
flex-shrink: 0;
}
.status-dot.success {
background: var(--success);
}
.status-dot.warning {
background: var(--warning);
}
.status-dot.error {
background: var(--error);
}
.status-dot.info {
background: var(--info);
}
.status-dot.muted {
background: var(--text-muted);
}
.status-dot.pulse {
animation: status-pulse 2s infinite;
}
@keyframes status-pulse {
0%,
100% {
box-shadow: 0 0 0 0 currentColor;
opacity: 1;
}
50% {
box-shadow: 0 0 0 4px currentColor;
opacity: 0.5;
}
}
/* ========================================
Typography Utilities / 排版工具
======================================== */
.text-gradient {
background: linear-gradient(135deg, var(--accent) 0%, #06b6d4 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.font-display {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-weight: 700;
letter-spacing: -0.02em;
}
.font-mono {
font-family: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
}