Files
claude-relay-service/web/apiStats/style.css
2025-07-27 18:42:07 +08:00

870 lines
20 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 🎨 用户统计页面自定义样式 - 与管理页面保持一致 */
/* CSS 变量 - 与管理页面保持一致 */
:root {
--primary-color: #667eea;
--secondary-color: #764ba2;
--accent-color: #f093fb;
--success-color: #10b981;
--warning-color: #f59e0b;
--error-color: #ef4444;
--surface-color: rgba(255, 255, 255, 0.95);
--glass-color: rgba(255, 255, 255, 0.1);
--text-primary: #1f2937;
--text-secondary: #6b7280;
--border-color: rgba(255, 255, 255, 0.2);
}
/* 📱 响应式布局优化 */
@media (max-width: 768px) {
.container {
padding-left: 1rem;
padding-right: 1rem;
}
.card {
margin-bottom: 1rem;
}
.grid {
grid-template-columns: 1fr;
gap: 1rem;
}
.stat-card {
padding: 0.75rem;
}
.stat-card .text-2xl {
font-size: 1.5rem;
}
.model-usage-item .grid {
grid-template-columns: 1fr 1fr;
gap: 0.5rem;
}
.text-4xl {
font-size: 2rem;
}
.input-field, .btn-primary {
padding: 0.75rem 1rem;
}
}
@media (max-width: 480px) {
.container {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.text-4xl {
font-size: 1.75rem;
}
.text-lg {
font-size: 1rem;
}
.card {
padding: 1rem;
}
.stat-card {
padding: 0.5rem;
}
.stat-card .text-2xl {
font-size: 1.25rem;
}
.stat-card .text-sm {
font-size: 0.75rem;
}
.model-usage-item .grid {
grid-template-columns: 1fr;
}
.flex.gap-3 {
flex-direction: column;
gap: 0.75rem;
}
.btn-primary {
width: 100%;
justify-content: center;
}
}
/* 🌈 渐变背景 - 与管理页面一致 */
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 50%, var(--accent-color) 100%);
background-attachment: fixed;
min-height: 100vh;
margin: 0;
overflow-x: hidden;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
radial-gradient(circle at 20% 80%, rgba(240, 147, 251, 0.2) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(102, 126, 234, 0.2) 0%, transparent 50%),
radial-gradient(circle at 40% 40%, rgba(118, 75, 162, 0.1) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
}
.gradient-bg {
/* 移除原有的渐变使用body的背景 */
}
/* ✨ 卡片样式 - 与管理页面一致 */
.glass {
background: var(--glass-color);
backdrop-filter: blur(20px);
border: 1px solid var(--border-color);
box-shadow:
0 20px 25px -5px rgba(0, 0, 0, 0.1),
0 10px 10px -5px rgba(0, 0, 0, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.glass-strong {
background: var(--surface-color);
backdrop-filter: blur(25px);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow:
0 25px 50px -12px rgba(0, 0, 0, 0.25),
0 0 0 1px rgba(255, 255, 255, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.card {
background: var(--surface-color);
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow:
0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
overflow: hidden;
position: relative;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
}
.card:hover {
transform: translateY(-2px);
box-shadow:
0 20px 25px -5px rgba(0, 0, 0, 0.15),
0 10px 10px -5px rgba(0, 0, 0, 0.08);
}
/* 🎯 统计卡片样式 - 与管理页面一致 */
.stat-card {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.8) 100%);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 24px;
position: relative;
overflow: hidden;
transition: all 0.3s ease;
}
.stat-card::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
opacity: 0;
transition: opacity 0.3s ease;
}
.stat-card:hover {
transform: translateY(-4px);
box-shadow:
0 20px 25px -5px rgba(0, 0, 0, 0.1),
0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.stat-card:hover::before {
opacity: 1;
}
/* 🔍 输入框样式 - 与管理页面一致 */
.form-input {
background: rgba(255, 255, 255, 0.9);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
padding: 16px;
font-size: 16px;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
color: var(--text-primary);
}
.form-input::placeholder {
color: var(--text-secondary);
}
.form-input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow:
0 0 0 3px rgba(102, 126, 234, 0.1),
0 10px 15px -3px rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.95);
}
/* 兼容旧的 input-field 类名 */
.input-field {
background: rgba(255, 255, 255, 0.9);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
padding: 16px;
font-size: 16px;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
color: var(--text-primary);
}
.input-field::placeholder {
color: var(--text-secondary);
}
.input-field:focus {
outline: none;
border-color: var(--primary-color);
box-shadow:
0 0 0 3px rgba(102, 126, 234, 0.1),
0 10px 15px -3px rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.95);
}
/* ====== 系统标题样式 ====== */
.header-title {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 700;
letter-spacing: -0.025em;
}
/* ====== 玻璃按钮样式 ====== */
.glass-button {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%) !important;
border: 1px solid rgba(255, 255, 255, 0.2) !important;
backdrop-filter: blur(10px) !important;
-webkit-backdrop-filter: blur(10px) !important;
border-radius: 12px !important;
transition: all 0.3s ease !important;
color: white !important;
text-decoration: none !important;
box-shadow:
0 10px 15px -3px rgba(102, 126, 234, 0.3),
0 4px 6px -2px rgba(102, 126, 234, 0.05) !important;
position: relative;
overflow: hidden;
}
.glass-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s;
}
.glass-button:hover::before {
left: 100%;
}
.glass-button:hover {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%) !important;
border-color: rgba(255, 255, 255, 0.3) !important;
transform: translateY(-1px) !important;
box-shadow:
0 20px 25px -5px rgba(102, 126, 234, 0.3),
0 10px 10px -5px rgba(102, 126, 234, 0.1) !important;
color: white !important;
text-decoration: none !important;
}
/* 🎨 按钮样式 - 与管理页面一致 */
.btn {
font-weight: 500;
border-radius: 12px;
border: none;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
letter-spacing: 0.025em;
}
.btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
transform: translate(-50%, -50%);
transition: width 0.3s ease, height 0.3s ease;
}
.btn:active::before {
width: 300px;
height: 300px;
}
.btn-primary {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
color: white;
box-shadow:
0 10px 15px -3px rgba(102, 126, 234, 0.3),
0 4px 6px -2px rgba(102, 126, 234, 0.05);
}
.btn-primary:hover {
transform: translateY(-1px);
box-shadow:
0 20px 25px -5px rgba(102, 126, 234, 0.3),
0 10px 10px -5px rgba(102, 126, 234, 0.1);
}
.btn-primary:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
/* 🎯 修复时间范围按钮样式 */
.btn-primary {
border-radius: 12px !important;
}
.btn {
border-radius: 12px !important;
}
/* 🎯 时间范围按钮 - 与管理页面 tab-btn 样式一致 */
.period-btn {
position: relative;
overflow: hidden;
border-radius: 12px;
font-weight: 500;
letter-spacing: 0.025em;
transition: all 0.3s ease;
border: none;
cursor: pointer;
}
.period-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s;
}
.period-btn:hover::before {
left: 100%;
}
.period-btn.active {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
color: white;
box-shadow:
0 10px 15px -3px rgba(102, 126, 234, 0.3),
0 4px 6px -2px rgba(102, 126, 234, 0.05);
transform: translateY(-1px);
}
.period-btn:not(.active) {
color: #374151;
background: transparent;
}
.period-btn:not(.active):hover {
background: rgba(255, 255, 255, 0.1);
color: #1f2937;
}
/* 📊 模型使用项样式 - 与管理页面保持一致 */
.model-usage-item {
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 16px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.model-usage-item::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
}
.model-usage-item:hover {
transform: translateY(-2px);
box-shadow:
0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
border-color: rgba(255, 255, 255, 0.3);
}
/* 🔄 加载动画增强 */
.loading-spinner {
animation: spin 1s linear infinite;
filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.5));
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 🌟 动画效果 */
.fade-in {
animation: fadeIn 0.6s ease-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.slide-in {
animation: slideIn 0.4s ease-out;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 🎯 焦点样式增强 */
.input-field:focus-visible,
.btn-primary:focus-visible {
outline: 2px solid rgba(255, 255, 255, 0.5);
outline-offset: 2px;
}
/* 📱 滚动条样式 */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.3);
border-radius: 4px;
transition: background 0.3s ease;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.5);
}
/* 🚨 错误状态样式 */
.error-border {
border-color: #ef4444 !important;
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
}
/* 🎉 成功状态样式 */
.success-border {
border-color: #10b981 !important;
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}
/* 🌙 深色模式适配 */
@media (prefers-color-scheme: dark) {
.card {
background: rgba(0, 0, 0, 0.2);
border-color: rgba(255, 255, 255, 0.15);
}
.stat-card {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
}
.input-field {
background: rgba(0, 0, 0, 0.3);
border-color: rgba(255, 255, 255, 0.3);
}
}
/* 🔍 高对比度模式支持 */
@media (prefers-contrast: high) {
.card {
border-width: 2px;
border-color: rgba(255, 255, 255, 0.5);
}
.input-field {
border-width: 2px;
border-color: rgba(255, 255, 255, 0.6);
}
.btn-primary {
border: 2px solid rgba(255, 255, 255, 0.5);
}
}
/* 📊 数据可视化增强 */
.chart-container {
position: relative;
background: rgba(255, 255, 255, 0.05);
border-radius: 12px;
padding: 20px;
border: 1px solid rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
}
/* 🎨 图标动画 */
.fas {
transition: transform 0.3s ease;
}
.card:hover .fas {
transform: scale(1.1);
}
/* 💫 悬浮效果 */
.hover-lift {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.hover-lift:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
}
/* 🎯 选中状态 */
.selected {
background: rgba(255, 255, 255, 0.2) !important;
border-color: rgba(255, 255, 255, 0.4) !important;
transform: scale(1.02);
}
/* 🌈 彩虹边框效果 */
.rainbow-border {
position: relative;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4, #feca57);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
padding: 2px;
border-radius: 12px;
}
.rainbow-border > * {
background: rgba(0, 0, 0, 0.8);
border-radius: 10px;
}
@keyframes gradientBG {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* 🎯 单层宽卡片样式优化 */
.api-input-wide-card {
background: var(--surface-color);
backdrop-filter: blur(25px);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow:
0 25px 50px -12px rgba(0, 0, 0, 0.25),
0 0 0 1px rgba(255, 255, 255, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.api-input-wide-card:hover {
box-shadow:
0 32px 64px -12px rgba(0, 0, 0, 0.35),
0 0 0 1px rgba(255, 255, 255, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.15);
transform: translateY(-1px);
}
/* 🎯 宽卡片内标题样式 */
.wide-card-title h2 {
color: #1f2937 !important;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
font-weight: 700;
}
.wide-card-title p {
color: #4b5563 !important;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
}
.wide-card-title .fas.fa-chart-line {
color: #3b82f6 !important;
text-shadow: 0 1px 2px rgba(59, 130, 246, 0.2);
}
/* 🎯 网格布局优化 */
.api-input-grid {
align-items: end;
gap: 1rem;
}
@media (min-width: 1024px) {
.api-input-grid {
grid-template-columns: 3fr 1fr;
gap: 1.5rem;
}
}
/* 🎯 输入框在宽卡片中的样式调整 */
.wide-card-input {
background: rgba(255, 255, 255, 0.95);
border: 2px solid rgba(255, 255, 255, 0.4);
border-radius: 12px;
padding: 14px 16px;
font-size: 16px;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
color: var(--text-primary);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.wide-card-input::placeholder {
color: #9ca3af;
}
.wide-card-input:focus {
outline: none;
border-color: #60a5fa;
box-shadow:
0 0 0 3px rgba(96, 165, 250, 0.2),
0 10px 15px -3px rgba(0, 0, 0, 0.1);
background: white;
}
/* 🎯 安全提示样式优化 */
.security-notice {
background: rgba(255, 255, 255, 0.15);
border: 1px solid rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
border-radius: 8px;
padding: 12px 16px;
color: #374151;
font-size: 0.875rem;
transition: all 0.3s ease;
}
.security-notice:hover {
background: rgba(255, 255, 255, 0.2);
border-color: rgba(255, 255, 255, 0.35);
}
.security-notice .fas.fa-shield-alt {
color: #10b981 !important;
text-shadow: 0 1px 2px rgba(16, 185, 129, 0.2);
}
/* 🎯 时间范围选择器在卡片内的样式优化 */
.time-range-section {
background: rgba(255, 255, 255, 0.05);
border-radius: 12px;
padding: 16px;
margin-bottom: 24px;
border: 1px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
}
.time-range-section:hover {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.15);
}
/* 📱 响应式优化 - 宽卡片布局 */
@media (max-width: 768px) {
.api-input-wide-card {
padding: 1.25rem !important;
margin-left: 1rem;
margin-right: 1rem;
}
.wide-card-title {
margin-bottom: 1.25rem !important;
}
.wide-card-title h2 {
font-size: 1.5rem !important;
}
.wide-card-title p {
font-size: 0.875rem !important;
}
.api-input-grid {
grid-template-columns: 1fr !important;
gap: 1rem !important;
}
.wide-card-input {
padding: 12px 14px !important;
font-size: 16px !important;
}
.security-notice {
padding: 10px 14px !important;
font-size: 0.8rem !important;
}
}
@media (max-width: 480px) {
.api-input-wide-card {
padding: 1rem !important;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.wide-card-title h2 {
font-size: 1.25rem !important;
}
.wide-card-title p {
font-size: 0.8rem !important;
}
}
/* 📱 响应式优化 - 时间范围选择器 */
@media (max-width: 768px) {
.time-range-section .flex {
flex-direction: column;
align-items: flex-start !important;
gap: 1rem;
}
.time-range-section .flex .flex {
width: 100%;
justify-content: center;
}
.period-btn {
flex: 1;
justify-content: center;
}
}
/* 📱 触摸设备优化 */
@media (hover: none) and (pointer: coarse) {
.card:hover {
transform: none;
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
}
.btn-primary:hover {
transform: none;
background-position: 0% 0;
}
.model-usage-item:hover {
transform: none;
background: rgba(255, 255, 255, 0.05);
}
.time-range-section:hover {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.1);
}
.query-title-section:hover {
background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(99, 102, 241, 0.05) 100%);
border-color: rgba(59, 130, 246, 0.1);
}
.api-input-wide-card:hover {
transform: none;
box-shadow:
0 25px 50px -12px rgba(0, 0, 0, 0.25),
0 0 0 1px rgba(255, 255, 255, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.security-notice:hover {
background: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.25);
}
}
/* 🎯 打印样式 */
@media print {
.gradient-bg {
background: white !important;
color: black !important;
}
.card {
border: 1px solid #ccc !important;
background: white !important;
box-shadow: none !important;
}
.btn-primary {
display: none !important;
}
.input-field {
border: 1px solid #ccc !important;
background: white !important;
}
}