Files
yuyueguahao/admin/styles.css
T
2026-07-05 14:43:34 +08:00

617 lines
18 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.
/*
* styles.css
* 苏州肛泰中医院 · 运营管理后台视觉系统
* 设计原则:医疗专业感 · 克制留白 · 蓝绿主色 · 8pt 间距
*/
:root {
--color-primary: #1f7ae0;
--color-primary-light: #4f9bff;
--color-primary-dark: #0d5fc4;
--color-primary-50: #eaf3ff;
--color-accent: #15b9a3;
--color-accent-50: #e6faf7;
--color-success: #15b9a3;
--color-success-bg: #e6faf7;
--color-warning: #ff8a00;
--color-warning-bg: #fff3e0;
--color-error: #e5454b;
--color-error-bg: #fdecec;
--color-info-bg: #eaf3ff;
--color-bg-page: #f4f6fa;
--color-bg-card: #ffffff;
--color-bg-hover: #f0f3f8;
--color-bg-elevated: #ffffff;
--color-text-primary: #0f172a;
--color-text-secondary: #475569;
--color-text-tertiary: #94a3b8;
--color-text-disabled: #cbd5e1;
--color-text-white: #ffffff;
--color-border: #e2e8f0;
--color-border-light: #eef1f6;
--color-divider: #eef1f6;
--shadow-xs: 0 1px 2px rgba(15, 23, 42, .04);
--shadow-sm: 0 2px 8px rgba(15, 23, 42, .06);
--shadow-md: 0 4px 16px rgba(15, 23, 42, .08);
--shadow-lg: 0 8px 28px rgba(15, 23, 42, .10);
--shadow-xl: 0 16px 48px rgba(15, 23, 42, .14);
--radius-xs: 4px;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 20px;
--radius-2xl: 24px;
--radius-pill: 999px;
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-3: 12px;
--spacing-4: 16px;
--spacing-5: 20px;
--spacing-6: 24px;
--spacing-7: 32px;
--spacing-8: 40px;
--spacing-9: 48px;
--transition-fast: 0.15s cubic-bezier(.4,0,.2,1);
--transition-base: 0.25s cubic-bezier(.4,0,.2,1);
--gradient-primary: linear-gradient(135deg, #1f7ae0 0%, #15b9a3 100%);
--gradient-hero: linear-gradient(160deg, #1f7ae0 0%, #2b80f5 45%, #15b9a3 100%);
--gradient-card: linear-gradient(180deg, #ffffff 0%, #fafbfd 100%);
--font-display: 'Plus Jakarta Sans', 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-body: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
font-family: var(--font-body);
font-size: 14px;
line-height: 1.5;
color: var(--color-text-primary);
background: var(--color-bg-page);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
button { font-family: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
code { font-family: 'SF Mono', Menlo, Consolas, monospace; font-size: 12px; background: var(--color-bg-hover); padding: 1px 6px; border-radius: 4px; color: var(--color-primary); }
.hidden { display: none !important; }
/* ============== 登录页 ============== */
.login-page {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: var(--gradient-hero);
position: relative;
overflow: hidden;
}
.login-bg-decor { position: absolute; inset: 0; pointer-events: none; }
.orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
opacity: .55;
animation: float 16s ease-in-out infinite;
}
.orb-1 { width: 360px; height: 360px; background: #4f9bff; top: -120px; left: -80px; }
.orb-2 { width: 280px; height: 280px; background: #15b9a3; bottom: -100px; right: -60px; animation-delay: -4s; }
.orb-3 { width: 200px; height: 200px; background: #7ad6ff; top: 40%; right: 20%; animation-delay: -8s; opacity: .35; }
@keyframes float {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(30px, -20px) scale(1.05); }
66% { transform: translate(-20px, 30px) scale(.95); }
}
.login-card {
position: relative;
width: 100%;
max-width: 420px;
margin: 24px;
background: rgba(255, 255, 255, .96);
backdrop-filter: blur(20px);
border-radius: var(--radius-2xl);
padding: 40px 36px;
box-shadow: 0 30px 60px rgba(13, 95, 196, .25);
animation: fadeInUp .5s var(--transition-base) both;
}
@keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.login-brand { text-align: center; margin-bottom: 28px; }
.login-logo {
width: 64px; height: 64px;
display: inline-flex;
align-items: center;
justify-content: center;
background: var(--gradient-primary);
color: #fff;
font-size: 32px;
border-radius: 18px;
box-shadow: 0 8px 24px rgba(31, 122, 224, .35);
margin-bottom: 12px;
}
.login-title { font-size: 22px; font-weight: 700; margin: 0 0 4px; color: var(--color-text-primary); }
.login-subtitle { font-size: 13px; color: var(--color-text-tertiary); margin: 0; }
.login-form { display: flex; flex-direction: column; gap: 18px; }
.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field label { font-size: 13px; color: var(--color-text-secondary); font-weight: 500; }
.form-field input, .form-field select, .form-field textarea {
width: 100%;
padding: 12px 14px;
border: 1.5px solid var(--color-border);
border-radius: var(--radius-md);
background: #fff;
font-size: 14px;
font-family: inherit;
color: var(--color-text-primary);
transition: all var(--transition-fast);
outline: none;
}
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(31, 122, 224, .15);
}
.form-field textarea { min-height: 80px; resize: vertical; }
.login-hint { text-align: center; font-size: 12px; color: var(--color-text-tertiary); margin: 0; }
/* ============== 按钮 ============== */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 10px 18px;
border: none;
border-radius: var(--radius-md);
font-size: 14px;
font-weight: 500;
background: var(--color-bg-hover);
color: var(--color-text-primary);
transition: all var(--transition-fast);
white-space: nowrap;
}
.btn:hover { background: var(--color-border-light); }
.btn:active { transform: scale(.97); }
.btn-primary {
background: var(--gradient-primary);
color: #fff;
box-shadow: 0 4px 12px rgba(31, 122, 224, .25);
}
.btn-primary:hover { box-shadow: 0 6px 18px rgba(31, 122, 224, .35); }
.btn-ghost { background: transparent; color: var(--color-text-secondary); }
.btn-ghost:hover { background: var(--color-bg-hover); }
.btn-danger { background: var(--color-error-bg); color: var(--color-error); }
.btn-danger:hover { background: #f9d4d5; }
.btn-success { background: var(--color-success-bg); color: var(--color-success); }
.btn-warning { background: var(--color-warning-bg); color: var(--color-warning); }
.btn-sm { padding: 6px 12px; font-size: 12px; }
.btn-block { width: 100%; }
.btn-icon { padding: 6px 8px; background: transparent; color: var(--color-text-tertiary); }
.btn-icon:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
/* ============== 主控制台 ============== */
.app-page {
min-height: 100vh;
display: flex;
flex-direction: column;
background: var(--color-bg-page);
}
.app-header {
height: 64px;
background: #fff;
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
position: sticky;
top: 0;
z-index: 50;
box-shadow: var(--shadow-xs);
}
.app-header-left { display: flex; align-items: center; gap: 12px; }
.app-logo {
width: 40px; height: 40px;
background: var(--gradient-primary);
color: #fff;
display: flex; align-items: center; justify-content: center;
font-size: 22px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(31, 122, 224, .25);
}
.app-title { font-size: 15px; font-weight: 700; color: var(--color-text-primary); }
.app-subtitle { font-size: 11px; color: var(--color-text-tertiary); margin-top: 2px; }
.app-header-right { display: flex; align-items: center; gap: 16px; }
.header-link { font-size: 13px; color: var(--color-text-secondary); }
.header-link:hover { color: var(--color-primary); }
.user-chip { display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; background: var(--color-bg-hover); border-radius: 999px; }
.user-avatar {
width: 28px; height: 28px;
background: var(--gradient-primary);
color: #fff;
display: flex; align-items: center; justify-content: center;
border-radius: 999px;
font-size: 13px;
font-weight: 600;
}
.user-name { font-size: 13px; font-weight: 500; }
.app-body { display: flex; flex: 1; min-height: 0; }
.app-side {
width: 220px;
background: #fff;
border-right: 1px solid var(--color-border);
display: flex;
flex-direction: column;
flex-shrink: 0;
}
.side-nav { padding: 16px 12px; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.side-link {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-radius: var(--radius-md);
font-size: 14px;
color: var(--color-text-secondary);
cursor: pointer;
transition: all var(--transition-fast);
user-select: none;
}
.side-link:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
.side-link.active {
background: var(--color-primary-50);
color: var(--color-primary);
font-weight: 600;
}
.side-icon { font-size: 16px; width: 20px; text-align: center; }
.side-foot { padding: 16px 20px; border-top: 1px solid var(--color-border-light); }
.side-foot-line { font-size: 11px; color: var(--color-text-tertiary); }
.side-foot-line.muted { color: var(--color-text-disabled); margin-top: 2px; }
.app-main {
flex: 1;
padding: 24px 32px;
overflow-y: auto;
min-width: 0;
}
.page-loading { text-align: center; color: var(--color-text-tertiary); padding: 60px 0; font-size: 14px; }
/* ============== 页面通用 ============== */
.page { animation: fadeIn .35s var(--transition-base) both; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.subtab-bar {
display: flex;
flex-direction: row;
gap: 8px;
margin-bottom: 20px;
background: #f1f5f9;
padding: 4px;
border-radius: 10px;
width: fit-content;
}
.subtab-bar .subtab {
padding: 8px 18px;
font-size: 14px;
color: var(--color-text-secondary);
border-radius: 8px;
cursor: pointer;
user-select: none;
transition: all .2s;
border: none;
background: transparent;
}
.subtab-bar .subtab.active {
background: #fff;
color: var(--color-primary);
font-weight: 600;
box-shadow: var(--shadow-sm);
}
.subtab-bar .subtab:hover:not(.active) { color: var(--color-text-primary); }
.page-head {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-bottom: 20px;
flex-wrap: wrap;
gap: 12px;
}
.page-title { font-size: 22px; font-weight: 700; margin: 0 0 4px; }
.page-desc { font-size: 13px; color: var(--color-text-tertiary); margin: 0; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* ============== 卡片 ============== */
.card {
background: #fff;
border-radius: var(--radius-lg);
padding: 20px 24px;
box-shadow: var(--shadow-sm);
border: 1px solid var(--color-border-light);
}
.card + .card { margin-top: 16px; }
.card-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
}
.card-title { font-size: 16px; font-weight: 600; margin: 0; }
.card-subtitle { font-size: 12px; color: var(--color-text-tertiary); margin: 2px 0 0; }
/* ============== 统计卡 ============== */
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
margin-bottom: 20px;
}
.stat-card {
background: #fff;
border-radius: var(--radius-lg);
padding: 20px;
box-shadow: var(--shadow-sm);
border: 1px solid var(--color-border-light);
position: relative;
overflow: hidden;
}
.stat-card::after {
content: '';
position: absolute;
top: 0; right: 0;
width: 80px; height: 80px;
background: var(--color-primary-50);
border-radius: 50%;
transform: translate(30px, -30px);
opacity: .5;
}
.stat-label { font-size: 13px; color: var(--color-text-tertiary); margin-bottom: 6px; }
.stat-value { font-size: 28px; font-weight: 700; color: var(--color-text-primary); font-family: var(--font-display); }
.stat-foot { font-size: 12px; color: var(--color-text-tertiary); margin-top: 6px; }
/* ============== 工具栏 ============== */
.toolbar {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
flex-wrap: wrap;
}
.toolbar .form-field { flex-direction: row; align-items: center; gap: 8px; }
.toolbar input, .toolbar select {
padding: 8px 12px;
border: 1.5px solid var(--color-border);
border-radius: var(--radius-md);
font-size: 13px;
outline: none;
transition: all var(--transition-fast);
background: #fff;
}
.toolbar input:focus, .toolbar select:focus { border-color: var(--color-primary); }
.toolbar input { min-width: 220px; }
/* ============== 表格 ============== */
.table-wrap {
background: #fff;
border-radius: var(--radius-lg);
border: 1px solid var(--color-border-light);
overflow: hidden;
box-shadow: var(--shadow-sm);
}
table.data-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.data-table thead th {
text-align: left;
padding: 12px 16px;
background: var(--color-bg-page);
color: var(--color-text-secondary);
font-weight: 600;
font-size: 12px;
border-bottom: 1px solid var(--color-border);
white-space: nowrap;
}
.data-table tbody td {
padding: 14px 16px;
border-bottom: 1px solid var(--color-border-light);
vertical-align: middle;
color: var(--color-text-primary);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--color-bg-page); }
.data-table .avatar-cell { display: flex; align-items: center; gap: 10px; }
.data-table .avatar {
width: 40px; height: 40px;
border-radius: 50%;
background: var(--color-bg-hover);
object-fit: cover;
flex-shrink: 0;
}
.data-table .name-cell { font-weight: 600; }
.data-table .sub { font-size: 12px; color: var(--color-text-tertiary); margin-top: 2px; }
.data-table .actions { display: flex; gap: 6px; justify-content: flex-end; }
.empty-state { text-align: center; padding: 60px 20px; color: var(--color-text-tertiary); }
/* ============== 状态标签 ============== */
.tag {
display: inline-flex;
align-items: center;
padding: 2px 10px;
font-size: 12px;
font-weight: 500;
border-radius: 999px;
background: var(--color-bg-hover);
color: var(--color-text-secondary);
}
.tag-primary { background: var(--color-primary-50); color: var(--color-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); }
/* ============== Toast ============== */
.toast {
position: fixed;
top: 24px;
left: 50%;
transform: translateX(-50%) translateY(-100%);
background: var(--color-text-primary);
color: #fff;
padding: 10px 18px;
border-radius: var(--radius-md);
font-size: 13px;
z-index: 9999;
transition: transform var(--transition-base), opacity var(--transition-base);
opacity: 0;
box-shadow: var(--shadow-lg);
max-width: 80vw;
}
.toast.show { transform: translateX(-50%) translateY(0); opacity: 1; }
.toast.success { background: var(--color-success); }
.toast.error { background: var(--color-error); }
/* ============== Modal ============== */
.modal {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.modal-mask {
position: absolute;
inset: 0;
background: rgba(15, 23, 42, .55);
backdrop-filter: blur(4px);
animation: fadeIn .2s both;
}
.modal-card {
position: relative;
background: #fff;
border-radius: var(--radius-xl);
width: 90%;
max-width: 560px;
max-height: 90vh;
display: flex;
flex-direction: column;
box-shadow: var(--shadow-xl);
animation: modalIn .3s var(--transition-base) both;
}
@keyframes modalIn { from { opacity: 0; transform: scale(.92) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }
.modal-card.modal-lg { max-width: 760px; }
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 24px;
border-bottom: 1px solid var(--color-border-light);
}
.modal-header h3 { font-size: 16px; font-weight: 600; margin: 0; }
.modal-close {
background: transparent;
border: none;
font-size: 24px;
line-height: 1;
color: var(--color-text-tertiary);
cursor: pointer;
padding: 0;
width: 28px; height: 28px;
border-radius: var(--radius-sm);
transition: all var(--transition-fast);
}
.modal-close:hover { background: var(--color-bg-hover); color: var(--color-text-primary); }
.modal-body { padding: 20px 24px; overflow-y: auto; flex: 1; }
.modal-body .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.modal-body .form-grid .full { grid-column: 1 / -1; }
.modal-footer {
padding: 16px 24px;
border-top: 1px solid var(--color-border-light);
display: flex;
justify-content: flex-end;
gap: 8px;
}
/* ============== 开关 ============== */
.switch {
position: relative;
display: inline-block;
width: 36px; height: 20px;
flex-shrink: 0;
}
.switch input { display: none; }
.switch .slider {
position: absolute;
inset: 0;
background: var(--color-border);
border-radius: 999px;
transition: background var(--transition-fast);
cursor: pointer;
}
.switch .slider::before {
content: '';
position: absolute;
top: 2px; left: 2px;
width: 16px; height: 16px;
background: #fff;
border-radius: 50%;
transition: transform var(--transition-fast);
box-shadow: 0 1px 3px rgba(0,0,0,.2);
}
.switch input:checked + .slider { background: var(--color-primary); }
.switch input:checked + .slider::before { transform: translateX(16px); }
/* ============== 响应式 ============== */
@media (max-width: 900px) {
.app-side { width: 64px; }
.side-link span:not(.side-icon) { display: none; }
.side-link { justify-content: center; padding: 12px; }
.side-foot { display: none; }
.app-main { padding: 16px; }
.modal-body .form-grid { grid-template-columns: 1fr; }
}
/* ============== Leads 问卷答案(Phase 3 ============== */
.lead-q {
display: flex;
flex-direction: column;
gap: 2px;
padding: 8px 0;
border-bottom: 1px dashed var(--color-border-light);
font-size: 13px;
}
.lead-q:last-child { border-bottom: none; }
.lead-qi {
flex-shrink: 0;
color: var(--color-text-tertiary);
font-weight: 600;
font-size: 12px;
}
.lead-qtext {
color: var(--color-text-secondary);
font-size: 13px;
}
.lead-qv {
color: var(--color-primary);
font-weight: 500;
}
.text-ellipsis-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
word-break: break-all;
}