Files
shanxia2.0/bx-mobile/src/styles/index.css
T
2026-08-09 19:42:32 +08:00

2187 lines
47 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.
/* ============================================================
BX-Mobile Global Styles — V1 Fresh Mint 清新薄荷
Directly from v1-fresh-mint.html design spec
============================================================ */
/* ----------------------------------------------------------
1. CSS VARIABLES (Design Tokens)
---------------------------------------------------------- */
:root {
--primary: #00c98d;
--primary-dark: #00a874;
--primary-darker: #008f62;
--primary-bg: #eafff6;
--primary-light: #f0fdf9;
--success: #10b981;
--success-bright: #34d399;
--success-bg: #ecfdf5;
--success-border: #a7f3d0;
--warning: #f59e0b;
--warning-bright: #fbbf24;
--warning-bg: #fffbeb;
--warning-border: #fcd34d;
--danger: #ef4444;
--danger-bright: #f87171;
--danger-bg: #fef2f2;
--danger-border: #fecaca;
--info: #3b82f6;
--info-bright: #60a5fa;
--info-bg: #eff6ff;
--info-border: #93c5fd;
--processing: #6366f1;
--processing-bright: #818cf8;
--processing-bg: #eef2ff;
--processing-border: #a5b4fc;
--text: #1a1a2e;
--text-sec: #64748b;
--text-muted: #94a3b8;
--bg: #f8fafc;
--surface: #fff;
--border: #e2e8f0;
--shadow: 0 2px 12px rgba(0, 0, 0, .06);
--shadow-md: 0 4px 16px rgba(0, 0, 0, .08);
--shadow-lg: 0 8px 24px rgba(0, 0, 0, .1);
--r: 12px;
--rs: 8px;
--rl: 16px;
--font: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;
/* Vant 组件默认 --van-primary-color 指向蓝色;对齐薄荷主色,避免 Tab/指示条/开关等发蓝 */
--van-primary-color: var(--primary);
--van-tab-active-text-color: var(--primary);
}
/* ----------------------------------------------------------
2. GLOBAL RESET
---------------------------------------------------------- */
* { box-sizing: border-box; margin: 0; padding: 0 }
body {
font-family: var(--font);
font-size: 14px;
color: var(--text);
background: var(--bg);
line-height: 1.5;
-webkit-tap-highlight-color: transparent;
-webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none }
#app { min-height: 100vh }
/* ----------------------------------------------------------
3. PAGE STRUCTURE
---------------------------------------------------------- */
.page {
max-width: 430px;
margin: 0 auto;
min-height: 100vh;
padding-bottom: 80px;
/* 列表空态占位:顶栏 + Tab 等;长筛选页用 .page--empty-chrome-tall 等覆盖 */
--empty-fill-chrome: 100px;
}
.page.page--empty-chrome-medium {
--empty-fill-chrome: 150px;
}
.page.page--empty-chrome-tall {
--empty-fill-chrome: 230px;
}
.page.page--empty-chrome-wf {
--empty-fill-chrome: 280px;
}
.page-padded {
padding: 0 16px;
}
/* 顶栏(sticky topbar)与紧随的主内容区间距 5px:新建/表单/详情等统一 */
.page > .topbar + .page-padded {
padding-top: 5px;
}
/* 首屏/整页内容区加载:顶栏下方水平垂直居中(详情、工作流配置等复用) */
.page-body-loading {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: calc(100vh - 140px);
min-height: calc(100dvh - 140px);
box-sizing: border-box;
padding: 24px 16px 80px;
}
/* 弹窗、分区列表等内嵌区域加载:固定占位高度内居中 */
.page-body-loading--embed {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
min-height: 200px;
box-sizing: border-box;
padding: 24px 16px;
}
.page-body-loading .van-loading,
.page-body-loading--embed .van-loading {
color: var(--primary);
}
/* 底部弹窗:标题区距弹窗顶 16px,与下方表单卡间距 5px */
.popup-sheet-title-wrap {
padding: 16px 16px 0;
}
.popup-sheet-title-wrap + .form-card {
margin-top: 5px;
}
.popup-sheet-title-wrap + div:not(.form-card) {
margin-top: 5px;
}
/* van-dialog:标题栏与插槽内容区顶部留白 16px */
.dialog-form-body {
padding: 16px 16px 16px;
}
.section-title {
font-size: 13px;
font-weight: 700;
color: var(--text-sec);
letter-spacing: .04em;
padding: 20px 16px 10px;
display: flex;
align-items: center;
gap: 6px;
}
.section-title::before {
content: '';
width: 3px;
height: 14px;
background: var(--primary);
border-radius: 2px;
}
/* 外层已含左右 padding 的弹窗滚动区:区块标题与 KV/附件/流程正文左缘对齐 */
.popup-sheet-body .section-title {
padding-left: 0;
padding-right: 0;
}
/* .popup-sheet-title-wrap 已含左右 padding:标题与下方 form-card(margin 0 16px)左缘对齐 */
.popup-sheet-title-wrap .section-title {
padding-left: 0;
padding-right: 0;
}
/* ----------------------------------------------------------
4. TOPBAR (replaces van-nav-bar)
---------------------------------------------------------- */
.topbar {
position: sticky;
top: 0;
z-index: 50;
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
height: calc(58px + env(safe-area-inset-top));
padding: env(safe-area-inset-top) 12px 0;
background: rgba(255, 255, 255, .84);
backdrop-filter: saturate(180%) blur(14px);
-webkit-backdrop-filter: saturate(180%) blur(14px);
box-shadow: 0 1px 0 rgba(217, 232, 226, .85), 0 8px 20px rgba(15, 23, 42, .06);
}
.topbar::before {
content: '';
position: absolute;
left: 0; right: 0; top: 0;
height: calc(58px + env(safe-area-inset-top));
background: linear-gradient(135deg, rgba(16, 185, 129, .10), rgba(236, 253, 245, .55) 45%, rgba(255, 255, 255, 0) 100%);
pointer-events: none;
}
.topbar > * { position: relative }
.topbar-left {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 8px;
min-width: 0;
}
.topbar-back {
width: 40px; height: 40px;
display: flex; align-items: center; justify-content: center;
border: none;
background: transparent;
color: var(--text);
border-radius: 10px;
cursor: pointer;
transition: .15s;
}
.topbar-back svg { width: 22px; height: 22px; stroke-linecap: round; stroke-linejoin: round }
.topbar-back:active {
transform: scale(.96);
opacity: .75;
}
.topbar-title {
justify-self: center;
text-align: center;
font-size: 17px;
font-weight: 800;
letter-spacing: .01em;
max-width: min(52vw, 220px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.topbar-right {
display: flex;
justify-content: flex-end;
gap: 4px;
min-width: 0;
}
.topbar-btn {
width: 34px; height: 34px;
display: flex; align-items: center; justify-content: center;
border: 1px solid rgba(217, 232, 226, .9);
background: rgba(255, 255, 255, .75);
color: var(--text-sec);
border-radius: 10px;
cursor: pointer;
transition: .15s;
}
.topbar-btn svg { width: 19px; height: 19px; stroke-linecap: round; stroke-linejoin: round }
.topbar-btn:active {
transform: scale(.96);
background: var(--primary-bg);
color: var(--primary-dark);
border-color: rgba(16, 185, 129, .35);
}
/* ----------------------------------------------------------
5. SEARCH BOX (replaces van-search)
---------------------------------------------------------- */
.search-wrap {
padding: 12px 16px;
background: var(--surface);
}
/* 搜索条与白卡片列表之间的留白(与首条卡片间距约 5px) */
.search-wrap + .page-padded {
padding-top: 5px;
}
.search-box {
display: flex;
align-items: center;
gap: 8px;
background: var(--bg);
border: 1.5px solid var(--border);
border-radius: 20px;
padding: 0 14px;
height: 40px;
transition: .2s;
}
.search-box:focus-within {
border-color: var(--primary);
background: #fff;
box-shadow: 0 0 0 3px rgba(0, 201, 141, .12);
}
.search-box svg { width: 18px; height: 18px; color: var(--text-muted); flex-shrink: 0 }
.search-box input {
flex: 1;
border: none;
outline: none;
background: none;
font-size: 14px;
color: var(--text);
font-family: var(--font);
}
.search-box input::placeholder { color: var(--text-muted) }
.search-box__clear {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
margin: 0 -2px 0 0;
padding: 0;
border: none;
background: transparent;
border-radius: 8px;
color: var(--text-muted);
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.search-box__clear:active {
background: var(--primary-bg);
color: var(--text-sec);
}
.search-box__clear svg {
width: 16px;
height: 16px;
}
.search-filter {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 0 0;
}
/* 状态 chip 较多时横向滑动(列表页与「我的申请」共用) */
.search-filter--scroll {
flex-wrap: nowrap;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
padding-bottom: 4px;
}
.search-filter--scroll::-webkit-scrollbar {
display: none;
}
.filter-tag {
padding: 4px 12px;
border-radius: 14px;
font-size: 12px;
font-weight: 500;
border: 1px solid var(--border);
color: var(--text-sec);
background: var(--surface);
cursor: pointer;
transition: .15s;
white-space: nowrap;
}
.filter-tag.active {
background: var(--primary-bg);
border-color: var(--primary);
color: var(--primary-dark);
}
.filter-tag:active { transform: scale(.95) }
/* ----------------------------------------------------------
6. STAT CARDS (horizontal scroll)
---------------------------------------------------------- */
.stat-scroll {
display: flex;
gap: 10px;
padding: 0 16px 4px;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
.stat-scroll::-webkit-scrollbar { display: none }
.stat-card {
flex-shrink: 0;
width: 100px;
padding: 14px 12px;
border-radius: var(--r);
background: var(--surface);
border: 1px solid var(--border);
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
box-shadow: var(--shadow);
cursor: pointer;
transition: .2s;
}
.stat-card:active { transform: scale(.96) }
.stat-card.active {
background: var(--primary-bg);
border-color: var(--primary);
}
.stat-card .num {
font-size: 22px;
font-weight: 800;
color: var(--primary);
font-variant-numeric: tabular-nums;
}
.stat-card .label {
font-size: 11px;
color: var(--text-sec);
font-weight: 500;
}
.stat-card.warn .num { color: var(--danger) }
.stat-card.warn.active {
background: #fef2f2;
border-color: var(--danger);
}
/* ----------------------------------------------------------
7. EXPENSE LIST CARD
---------------------------------------------------------- */
.expense-card {
background: var(--surface);
border-radius: var(--r);
padding: 16px;
margin-bottom: 10px;
border: 1px solid var(--border);
box-shadow: var(--shadow);
cursor: pointer;
transition: .15s;
}
.expense-card:active {
transform: scale(.985);
box-shadow: 0 1px 6px rgba(0, 0, 0, .04);
}
.ec-top {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
margin-bottom: 8px;
}
.ec-type {
display: inline-flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
min-width: 0;
font-size: 15px;
font-weight: 600;
line-height: 1.3;
}
.ec-top .status-tag {
flex-shrink: 0;
}
/* 列表/详情状态徽标(与 StatusTag 组件统一为 tag pill) */
.status-tag {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 2px 10px;
border-radius: 10px;
font-size: 11px;
font-weight: 600;
border: 1px solid var(--border);
white-space: nowrap;
line-height: 1.25;
background: var(--bg);
color: var(--text-sec);
}
.status-tag.success {
background: var(--success-bg);
color: var(--success);
border-color: var(--success-border);
}
.status-tag.danger {
background: var(--danger-bg);
color: var(--danger);
border-color: var(--danger-border);
}
.status-tag.warning {
background: var(--warning-bg);
color: var(--warning);
border-color: var(--warning-border);
}
.status-tag.info {
background: var(--info-bg);
color: var(--info);
border-color: var(--info-border);
}
.status-tag.muted {
background: #f1f5f9;
color: #64748b;
border-color: rgba(100, 116, 139, .15);
}
.status-tag.processing {
background: var(--processing-bg);
color: var(--processing);
border-color: var(--processing-border);
}
.status-tag.s-draft { background: #f1f5f9; color: #64748b; border-color: rgba(100, 116, 139, .15) }
.status-tag.s-pending {
background: var(--warning-bg);
color: var(--warning);
border-color: var(--warning-border);
}
.status-tag.s-approved { background: var(--primary-bg); color: var(--primary-dark); border-color: rgba(0, 201, 141, .2) }
.status-tag.s-rejected { background: #fef2f2; color: #ef4444; border-color: rgba(239, 68, 68, .2) }
.status-tag.s-withdrawn { background: #fffbeb; color: #d97706; border-color: rgba(245, 158, 11, .25) }
.status-tag.s-issued { background: #eef2ff; color: #6366f1; border-color: rgba(99, 102, 241, .25) }
.status-tag.s-paid { background: var(--primary-bg); color: var(--primary-dark); border-color: rgba(0, 201, 141, .2) }
.status-tag.s-processed { background: var(--primary-bg); color: var(--primary-dark); border-color: rgba(0, 201, 141, .2) }
.status-tag.s-offset { background: #fffbeb; color: #d97706; border-color: rgba(245, 158, 11, .25) }
.ec-amount {
font-size: 24px;
font-weight: 800;
color: var(--primary-dark);
margin-bottom: 6px;
font-variant-numeric: tabular-nums;
}
.ec-amount::before {
content: '¥';
font-size: 14px;
margin-right: 2px;
}
.ec-meta {
display: flex;
gap: 12px;
font-size: 12px;
color: var(--text-muted);
}
.ec-bottom {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed var(--border);
}
.ec-desc {
font-size: 13px;
color: var(--text-sec);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ec-arrow { color: var(--text-muted); flex-shrink: 0 }
/* ----------------------------------------------------------
8. BUTTONS (replaces van-button in custom layouts)
---------------------------------------------------------- */
/*
* 语义归类(全项目统一,全部为实心,无描边型主按钮):
* - btn-primary 薄荷绿实心:保存、提交、通过、登录、发放、查看、编辑、去处理、
* + 新增明细行、新增子项/子菜单 等(同语义跨页必须同类名)
* - btn-secondary 取消、上移/下移、分配用户/分配菜单(中性灰实心)
* - btn-danger 删除、驳回、退出登录(红实心)
* - btn-warning 冲抵、禁用(橙实心)
* 尺寸:默认 40px 高;列表/卡片内配合 .btn-sm(与 .op-actions 内 32px 对齐)
*/
.btn-row {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
height: 40px;
padding: 0 20px;
border-radius: var(--rs);
font-size: 14px;
font-weight: 600;
font-family: var(--font);
cursor: pointer;
border: 1px solid transparent;
transition: .15s;
-webkit-user-select: none;
}
.btn:disabled {
opacity: 0.55;
cursor: not-allowed;
}
.btn:disabled:active {
transform: none;
}
.btn:active:not(:disabled) { transform: scale(.96) }
/* 全局按钮:实心填充 */
.btn-primary {
background: var(--primary);
color: #fff;
border-color: var(--primary);
}
.btn-primary:active:not(:disabled) {
background: var(--primary-dark);
border-color: var(--primary-dark);
}
.btn-secondary {
background: var(--text-sec);
color: #fff;
border-color: var(--text-sec);
}
.btn-secondary:active:not(:disabled) {
background: #475569;
border-color: #475569;
}
.btn-danger {
background: var(--danger);
color: #fff;
border-color: var(--danger);
}
.btn-danger:active:not(:disabled) {
background: #dc2626;
border-color: #dc2626;
}
.btn-warning,
.btn-warning-outline {
background: var(--warning);
color: #fff;
border-color: var(--warning);
}
.btn-warning:active:not(:disabled),
.btn-warning-outline:active:not(:disabled) {
background: #d97706;
border-color: #d97706;
}
.btn-disabled {
background: #e2e8f0;
color: #94a3b8;
cursor: not-allowed;
border-color: #e2e8f0;
}
.btn-disabled:active { transform: none }
.btn-loading {
position: relative;
color: transparent !important;
}
.btn-loading::after {
content: '';
position: absolute;
width: 18px; height: 18px;
border: 2px solid rgba(255, 255, 255, .35);
border-top-color: #fff;
border-radius: 50%;
animation: spin .6s linear infinite;
}
.btn-danger.btn-loading::after {
border-color: rgba(255, 255, 255, .35);
border-top-color: #fff;
}
.btn-secondary.btn-loading::after {
border-color: rgba(255, 255, 255, .35);
border-top-color: #fff;
}
.btn-warning.btn-loading::after,
.btn-warning-outline.btn-loading::after {
border-color: rgba(255, 255, 255, .35);
border-top-color: #fff;
}
.btn-block { width: 100% }
.btn-sm {
height: 32px;
padding: 0 12px;
font-size: 12px;
border-radius: 8px;
}
.btn-link {
background: transparent;
border-color: transparent;
color: var(--primary-dark);
padding: 0 6px;
}
.btn-link:active:not(:disabled) {
background: var(--primary-bg);
border-color: rgba(16, 185, 129, .25);
}
@keyframes spin { to { transform: rotate(360deg) } }
/* ----------------------------------------------------------
9. FORM SYSTEM (replaces van-field)
---------------------------------------------------------- */
.form-card {
background: var(--surface);
border-radius: var(--r);
padding: 16px;
border: 1px solid var(--border);
}
.form-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}
.form-header h3 {
font-size: 16px;
font-weight: 700;
}
.form-badge {
font-size: 11px;
font-weight: 600;
padding: 2px 8px;
border-radius: 4px;
background: var(--primary-bg);
color: var(--primary-dark);
}
.field { margin-bottom: 14px }
.field-label {
display: block;
font-size: 13px;
font-weight: 600;
color: var(--text);
margin-bottom: 6px;
}
.field-label .req { color: var(--danger); margin-left: 2px }
.form-input {
width: 100%;
height: 42px;
padding: 0 12px;
border: 1.5px solid var(--border);
border-radius: var(--rs);
font-size: 14px;
font-family: var(--font);
color: var(--text);
background: var(--surface);
transition: .2s;
outline: none;
}
.form-input:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(0, 201, 141, .1);
}
.form-input:disabled {
background: var(--bg);
color: var(--text-muted);
}
.form-input.error {
border-color: var(--danger);
box-shadow: 0 0 0 3px rgba(239, 68, 68, .1);
}
.form-input-icon { position: relative }
.form-input-icon .form-input { padding-right: 36px }
.form-input-icon svg {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
width: 18px;
height: 18px;
color: var(--text-muted);
}
.form-input-icon .form-input-pwd-toggle {
position: absolute;
right: 4px;
top: 50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
margin: 0;
padding: 0;
border: none;
background: transparent;
color: var(--text-muted);
cursor: pointer;
border-radius: 8px;
-webkit-tap-highlight-color: transparent;
}
.form-input-icon .form-input-pwd-toggle:active {
background: rgba(15, 23, 42, 0.06);
}
.form-input-icon .form-input-pwd-toggle svg {
position: static;
transform: none;
right: auto;
top: auto;
width: 16px;
height: 16px;
flex-shrink: 0;
}
.form-textarea {
width: 100%;
min-height: 80px;
padding: 10px 12px;
border: 1.5px solid var(--border);
border-radius: var(--rs);
font-size: 14px;
font-family: var(--font);
color: var(--text);
resize: vertical;
outline: none;
transition: .2s;
}
.form-textarea:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(0, 201, 141, .1);
}
.form-textarea.error {
border-color: var(--danger);
box-shadow: 0 0 0 3px rgba(239, 68, 68, .1);
}
.form-textarea-counter {
text-align: right;
font-size: 11px;
color: var(--text-muted);
margin-top: 4px;
}
.field-error {
font-size: 12px;
color: var(--danger);
margin-top: 4px;
}
.form-input-prefix { position: relative }
.form-input-prefix .form-input { padding-left: 28px }
.form-input-prefix::before {
content: '¥';
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
font-size: 14px;
font-weight: 700;
color: var(--primary);
}
.edit-highlight .form-input {
background: var(--primary-light);
}
/* ----------------------------------------------------------
10. DETAIL PAGE
---------------------------------------------------------- */
.detail-hero {
background: linear-gradient(135deg, var(--primary-bg), var(--primary-light));
border-radius: var(--r);
padding: 20px;
text-align: center;
margin-bottom: 12px;
}
.detail-amount {
font-size: 32px;
font-weight: 800;
color: var(--primary-dark);
font-variant-numeric: tabular-nums;
}
.detail-amount::before {
content: '¥';
font-size: 16px;
margin-right: 4px;
}
.detail-status {
display: inline-block;
margin-top: 8px;
font-size: 12px;
font-weight: 600;
padding: 3px 12px;
border-radius: 10px;
background: var(--primary);
color: #fff;
}
.detail-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 12px;
}
.detail-item {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--rs);
padding: 10px 12px;
}
.detail-item .di-label {
font-size: 11px;
color: var(--text-muted);
margin-bottom: 2px;
}
.detail-item .di-value {
font-size: 14px;
font-weight: 500;
color: var(--text);
word-break: break-all;
}
.detail-item.full { grid-column: 1 / -1 }
/* ----------------------------------------------------------
11. TIMELINE (approval flow)
---------------------------------------------------------- */
.timeline {
padding-left: 20px;
border-left: 2px solid var(--border);
margin: 12px 0;
}
.tl-step {
position: relative;
padding: 0 0 20px 16px;
}
.tl-step:last-child { padding-bottom: 0 }
.tl-step::before {
content: '';
position: absolute;
left: -25px;
top: 4px;
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--border);
border: 2px solid var(--surface);
}
.tl-step.done::before {
background: var(--primary);
box-shadow: 0 0 0 2px var(--primary-bg);
}
.tl-step.current::before {
background: var(--info);
box-shadow: 0 0 0 3px rgba(59, 130, 246, .2);
animation: pulse-dot 1.5s infinite;
}
.tl-step.rejected::before {
background: var(--danger);
box-shadow: 0 0 0 2px rgba(239, 68, 68, .15);
}
@keyframes pulse-dot {
0%, 100% { box-shadow: 0 0 0 3px rgba(59, 130, 246, .2) }
50% { box-shadow: 0 0 0 6px rgba(59, 130, 246, .08) }
}
.tl-title { font-size: 13px; font-weight: 600 }
.tl-meta { font-size: 12px; color: var(--text-muted); margin-top: 2px }
/* ----------------------------------------------------------
12. UPLOAD ZONE
---------------------------------------------------------- */
.upload-zone {
border: 2px dashed var(--border);
border-radius: var(--r);
padding: 24px;
text-align: center;
background: var(--bg);
cursor: pointer;
transition: .2s;
}
.upload-zone:active {
border-color: var(--primary);
background: var(--primary-bg);
}
.upload-zone svg { width: 36px; height: 36px; color: var(--text-muted); margin-bottom: 6px }
.upload-zone p { font-size: 13px; color: var(--text-sec) }
.upload-zone .hint { font-size: 11px; color: var(--text-muted); margin-top: 4px }
/* van-uploader 插槽:仅「上传附件」实心按钮,不占大块区域 */
.uploader-slot-btn .van-uploader {
display: inline-block;
}
.uploader-slot-btn .van-uploader__wrapper {
display: inline-flex;
}
/* ----------------------------------------------------------
13. ATTACHMENT GRID
---------------------------------------------------------- */
.att-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
}
.att-img {
position: relative;
aspect-ratio: 1;
border-radius: var(--rs);
overflow: hidden;
border: 1px solid var(--border);
background: var(--bg);
}
.att-img img { width: 100%; height: 100%; object-fit: cover }
/* 附件上传中:本地缩略图 + 半透明遮罩,避免「选完突然出现」 */
.att-img.is-uploading {
pointer-events: none;
}
.att-upload-mask {
position: absolute;
inset: 0;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
background: rgba(15, 23, 42, 0.48);
color: #fff;
}
.att-upload-mask__text {
font-size: 11px;
font-weight: 600;
letter-spacing: 0.02em;
line-height: 1;
}
.att-img .del {
position: absolute;
top: 4px;
right: 4px;
width: 20px;
height: 20px;
border-radius: 50%;
background: rgba(0, 0, 0, .5);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
border: none;
cursor: pointer;
line-height: 1;
}
.att-file {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--rs);
}
.att-file-icon {
width: 36px;
height: 36px;
border-radius: 6px;
background: var(--primary-bg);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.att-file-icon svg { width: 20px; height: 20px; color: var(--primary-dark) }
.att-file-info { flex: 1; min-width: 0 }
.att-file-name {
font-size: 13px;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.att-file-size { font-size: 11px; color: var(--text-muted) }
/* ----------------------------------------------------------
14. FORM CONTROLS
---------------------------------------------------------- */
.ctrl-group { margin-bottom: 16px }
.ctrl-label { font-size: 13px; font-weight: 600; margin-bottom: 8px }
.radio-group, .check-group {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.radio-item, .check-item {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
cursor: pointer;
padding: 6px 12px;
border: 1px solid var(--border);
border-radius: var(--rs);
transition: .15s;
}
.radio-item:active, .check-item:active { background: var(--primary-bg) }
.radio-item.selected, .check-item.selected {
border-color: var(--primary);
background: var(--primary-bg);
color: var(--primary-dark);
font-weight: 600;
}
/* ----------------------------------------------------------
15. EMPTY STATE
---------------------------------------------------------- */
.empty-state {
text-align: center;
padding: 40px 20px;
}
.empty-state svg {
width: 80px;
height: 80px;
color: var(--text-muted);
margin-bottom: 12px;
opacity: .5;
}
.empty-state p {
font-size: 15px;
color: var(--text-muted);
margin-bottom: 16px;
}
/* 列表无数据:视口剩余区域水平垂直居中(--empty-fill-chrome 由 .page 修饰符控制) */
.empty-state.empty-state--fill {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
min-height: calc(100dvh - var(--empty-fill-chrome, 100px) - env(safe-area-inset-top) - env(safe-area-inset-bottom));
min-height: calc(100vh - var(--empty-fill-chrome, 100px) - env(safe-area-inset-top) - env(safe-area-inset-bottom));
padding: 24px 20px 80px;
margin: 0 auto;
max-width: 100%;
}
/* 弹窗/卡片分区内的无数据 */
.empty-state.empty-state--embed {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
min-height: 160px;
padding: 24px 16px;
margin: 0 auto;
}
.empty-state.empty-state--fill > .van-icon:first-child,
.empty-state.empty-state--embed > .van-icon:first-child {
opacity: 0.55;
margin-bottom: 14px;
}
.empty-state.empty-state--fill p:last-child,
.empty-state.empty-state--embed p:last-child {
margin-bottom: 0;
line-height: 1.5;
}
/* ----------------------------------------------------------
16. TAGS & BADGES
---------------------------------------------------------- */
.tag {
display: inline-flex;
align-items: center;
padding: 2px 10px;
border-radius: 10px;
font-size: 11px;
font-weight: 600;
border: 1px solid transparent;
}
.tag-green { background: var(--primary-bg); color: var(--primary-dark); border-color: rgba(0, 201, 141, .2) }
.tag-blue { background: #eff6ff; color: #3b82f6; border-color: rgba(59, 130, 246, .2) }
/** 报销等业务类型徽标(非状态):避免与「审批中」等蓝色混淆 */
.tag-amber { background: var(--warning-bg); color: var(--warning); border-color: var(--warning-border) }
.tag-neutral { background: #f1f5f9; color: #64748b; border-color: rgba(100, 116, 139, .15) }
.tag-red { background: #fef2f2; color: #ef4444; border-color: rgba(239, 68, 68, .2) }
.tag-orange { background: #fffbeb; color: #d97706; border-color: rgba(245, 158, 11, .2) }
.tag-gray { background: #f1f5f9; color: #64748b; border-color: rgba(100, 116, 139, .15) }
/* detail / approve 等区域可与 .tag 混用;列表优先 .status-tag */
.badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 18px;
height: 18px;
padding: 0 5px;
border-radius: 9px;
background: var(--danger);
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 1;
}
.badge-dot {
width: 8px;
height: 8px;
padding: 0;
min-width: 8px;
border-radius: 50%;
}
/* ----------------------------------------------------------
17. FLOW CARD (approval)
---------------------------------------------------------- */
.flow-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--r);
padding: 16px;
}
.flow-step {
display: flex;
align-items: flex-start;
gap: 12px;
padding-bottom: 16px;
position: relative;
}
.flow-step:last-child { padding-bottom: 0 }
.flow-step:not(:last-child)::after {
content: '';
position: absolute;
left: 15px;
top: 32px;
bottom: 0;
width: 2px;
background: var(--border);
}
.flow-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 700;
color: #fff;
flex-shrink: 0;
}
.flow-avatar.av-done { background: var(--primary) }
.flow-avatar.av-current { background: var(--warning); animation: pulse-dot 1.5s infinite }
.flow-avatar.av-reject { background: var(--danger) }
.flow-avatar.av-pending { background: var(--border); color: var(--text-muted) }
.flow-info { flex: 1 }
.flow-name { font-size: 13px; font-weight: 600 }
.flow-role { font-size: 11px; color: var(--text-muted) }
.flow-time { font-size: 11px; color: var(--text-muted); margin-top: 2px }
.flow-status { font-size: 11px; font-weight: 600; margin-left: auto; flex-shrink: 0 }
/* ----------------------------------------------------------
18. OP-CARD (card with action buttons)
---------------------------------------------------------- */
.card-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.op-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--r);
box-shadow: var(--shadow);
padding: 14px;
cursor: pointer;
transition: .15s;
}
.op-card:active {
transform: scale(.988);
box-shadow: 0 1px 8px rgba(0, 0, 0, .04);
}
.op-card-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
}
.op-card-title {
font-size: 15px;
font-weight: 900;
line-height: 1.2;
}
.op-card-sub {
margin-top: 4px;
font-size: 12px;
color: var(--text-muted);
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.op-card-amount {
font-size: 20px;
font-weight: 900;
color: var(--primary-dark);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.op-card-amount::before {
content: '¥';
font-size: 12px;
margin-right: 2px;
}
.op-card-body {
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed var(--border);
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
}
.op-card-body > .op-actions:only-child {
margin-left: auto;
}
.op-card-desc {
font-size: 13px;
color: var(--text-sec);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.op-card-desc--wrap {
white-space: normal;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
word-break: break-word;
}
/* 列表卡片内多字段对照(op-card / expense-card 通用) */
.list-card-kv {
margin-top: 10px;
padding: 10px 12px;
border-radius: var(--rs);
background: var(--bg);
border: 1px solid var(--border);
display: flex;
flex-direction: column;
gap: 6px;
font-size: 12px;
}
.list-card-kv__row {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 10px;
line-height: 1.45;
}
.list-card-kv__k {
flex-shrink: 0;
color: var(--text-muted);
font-size: 11px;
max-width: 42%;
}
.list-card-kv__v {
flex: 1;
min-width: 0;
text-align: right;
color: var(--text);
font-weight: 500;
word-break: break-word;
}
/* 详情/弹窗内无数据提示 */
.detail-section-empty {
margin: 0;
padding: 12px;
font-size: 13px;
color: var(--text-muted);
text-align: center;
background: var(--bg);
border-radius: var(--rs);
border: 1px dashed var(--border);
}
.op-card-amount-label {
margin-top: 8px;
font-size: 11px;
color: var(--text-muted);
font-weight: 600;
}
.op-card-reason {
margin-top: 8px;
font-size: 13px;
color: var(--text-sec);
line-height: 1.45;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
word-break: break-word;
}
.op-actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
justify-content: flex-end;
}
.op-actions .btn {
height: 32px;
padding: 0 12px;
font-size: 12px;
border-radius: 8px;
}
.op-actions .btn svg { width: 14px; height: 14px }
/* ----------------------------------------------------------
19. HOME HERO (首页顶部)
---------------------------------------------------------- */
.home-hero {
background: linear-gradient(135deg, #10b981 0%, #34d399 55%, #6ee7b7 100%);
color: #fff;
border-radius: 14px;
padding: 16px;
box-shadow: 0 10px 24px rgba(16, 185, 129, .25);
}
.home-hero-main { min-width: 0 }
.home-hero .hello { font-size: 12px; opacity: .9 }
.home-hero .name { font-size: 20px; font-weight: 900; margin-top: 4px }
.home-hero-stats-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin-top: 10px;
}
.home-hero-stats-row .meta {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
flex: 1;
min-width: 0;
}
.home-hero .chip {
font-size: 11px;
font-weight: 700;
padding: 4px 10px;
border-radius: 999px;
background: rgba(255, 255, 255, .2);
border: 1px solid rgba(255, 255, 255, .35);
}
.home-hero-logout {
flex-shrink: 0;
align-self: center;
margin: 0;
padding: 0;
border: none;
background: transparent;
font: inherit;
font-size: 11px;
font-weight: 700;
color: inherit;
opacity: .9;
cursor: pointer;
line-height: 1.2;
white-space: nowrap;
}
.home-hero-logout:active {
opacity: .75;
}
/* 首页:分组标题与菜单卡片文案使用主色文字(深色),与正文一致 */
.home-page .section-title {
color: var(--text);
}
/* ----------------------------------------------------------
20. MENU GRID
---------------------------------------------------------- */
.menu-grid {
margin-top: 12px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.menu-item {
position: relative;
border: none;
background: var(--surface);
border-radius: var(--r);
padding: 10px 8px 9px;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
cursor: pointer;
box-shadow: var(--shadow);
transition: background .15s, box-shadow .15s, transform .15s;
}
.menu-item:active {
transform: scale(.96);
background: var(--primary-light);
box-shadow: 0 1px 6px rgba(0, 0, 0, .05);
}
.menu-item .icon {
width: 40px;
height: 40px;
border-radius: 11px;
display: flex;
align-items: center;
justify-content: center;
background: var(--primary-bg);
color: var(--primary-dark);
border: none;
}
.menu-item .txt {
font-size: 13px;
font-weight: 700;
color: var(--text);
align-self: stretch;
text-align: center;
line-height: 1.35;
white-space: pre-line;
}
.menu-item.hot .icon {
background: #eff6ff;
color: var(--info);
}
.menu-item.warn .icon {
background: #fffbeb;
color: #d97706;
}
.menu-item .msg-dot {
position: absolute;
top: 8px;
right: 10px;
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--danger);
box-shadow: 0 0 0 2px var(--surface);
}
.menu-item .msg-badge {
position: absolute;
top: 4px;
right: 4px;
z-index: 1;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 16px;
height: 16px;
padding: 0 4px;
font-size: 10px;
font-weight: 700;
font-variant-numeric: tabular-nums;
line-height: 1;
color: #fff;
pointer-events: none;
background: #dc2626;
border-radius: 8px;
box-shadow: 0 0 0 2px var(--surface);
}
/* ----------------------------------------------------------
21. TODO CARD
---------------------------------------------------------- */
.todo-card {
background: transparent;
border: none;
border-radius: 12px;
padding: 12px 0;
box-shadow: none;
}
.todo-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.todo-head--badge-only {
justify-content: flex-end;
}
.todo-head .title {
font-size: 11px;
font-weight: 800;
color: var(--text);
}
.todo-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 9px 0;
border-top: 1px dashed rgba(226, 232, 240, .9);
}
.todo-item:first-of-type { border-top: none; padding-top: 0 }
.todo-item .left { min-width: 0 }
.todo-item .name {
font-size: 11px;
font-weight: 700;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.todo-item .meta { font-size: 11px; color: var(--text-muted); margin-top: 2px }
/* 待办「去处理」与列表卡片内按钮同高同圆角 */
.todo-item .btn.btn-sm {
height: 32px;
border-radius: 8px;
}
/* ----------------------------------------------------------
22. LOGIN PAGE
---------------------------------------------------------- */
.login-page {
min-height: 100vh;
min-height: 100dvh;
background: linear-gradient(180deg, #ecfdf5 0%, #f8fafc 42%, #f8fafc 100%);
padding: calc(16px + env(safe-area-inset-top, 0px)) 16px calc(16px + env(safe-area-inset-bottom, 0px));
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
}
.login-page-inner {
width: 100%;
max-width: 400px;
display: flex;
flex-direction: column;
align-items: stretch;
}
.login-brand-block {
text-align: center;
margin-bottom: 22px;
}
.brand-logo-img {
display: block;
width: 100%;
max-width: min(180px, 48vw);
height: auto;
margin: 0 auto 12px;
object-fit: contain;
}
.login-brand-block .brand-sub {
font-size: 22px;
font-weight: 700;
letter-spacing: 0.02em;
color: var(--text);
margin-top: 2px;
}
.login-card {
margin: 0;
width: 100%;
box-sizing: border-box;
background: transparent;
border: none;
border-radius: 12px;
padding: 14px;
box-shadow: none;
}
.login-title { font-size: 16px; font-weight: 900; margin-bottom: 12px }
.login-input {
display: flex;
align-items: center;
gap: 8px;
height: 42px;
padding: 0 12px;
border: 1.5px solid var(--border);
border-radius: 10px;
background: var(--surface);
margin-bottom: 10px;
}
.login-input:focus-within {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(16, 185, 129, .12);
}
.login-input.error {
border-color: var(--danger);
box-shadow: 0 0 0 3px rgba(239, 68, 68, .12);
}
.login-input svg { width: 17px; height: 17px; color: var(--text-muted); flex-shrink: 0 }
.login-input input {
border: none;
outline: none;
background: none;
flex: 1;
font-size: 14px;
color: var(--text);
min-width: 0;
}
/* 密码行:右侧眼睛图标叠在输入区内,避免单独一列的割裂感 */
.login-input--password {
position: relative;
}
.login-input--password input {
padding-right: 38px;
}
.login-eye {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
width: 32px;
height: 32px;
margin: 0;
padding: 0;
border: none;
background: transparent;
border-radius: 6px;
color: var(--text-muted);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.login-eye svg { width: 16px; height: 16px }
.login-eye:active {
color: var(--primary-dark);
}
.login-card .btn-primary.btn-block {
margin-top: 12px;
}
.login-error-msg {
margin-top: -4px;
margin-bottom: 8px;
font-size: 12px;
color: var(--danger);
display: none;
}
.login-error-msg.show { display: block }
/* ----------------------------------------------------------
23. BOTTOM ACTION BAR
---------------------------------------------------------- */
.bottom-action-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 12px 16px;
padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
background: var(--surface);
box-shadow: 0 -2px 12px rgba(0, 0, 0, .06);
z-index: 100;
display: flex;
gap: 10px;
}
/* 列表/管理页:右下角新增(圆形主色 + 白加号) */
.fab-add {
position: fixed;
right: 16px;
bottom: calc(20px + env(safe-area-inset-bottom, 0px));
z-index: 120;
width: 48px;
height: 48px;
padding: 0;
border: none;
border-radius: 50%;
background: var(--primary);
color: #fff;
box-shadow: 0 3px 12px rgba(0, 201, 141, .38);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
transition: transform .15s, opacity .15s;
}
.fab-add svg {
width: 22px;
height: 22px;
stroke: currentColor;
stroke-width: 2.25;
flex-shrink: 0;
}
.fab-add:active {
transform: scale(.94);
opacity: .92;
}
/* ----------------------------------------------------------
24. PICKER TRIGGER (expense item)
---------------------------------------------------------- */
.picker-trigger {
display: flex;
align-items: center;
gap: 10px;
padding: 12px;
border: 1.5px solid var(--border);
border-radius: var(--r);
background: var(--surface);
box-shadow: 0 1px 3px rgba(0, 0, 0, .04);
cursor: pointer;
}
.picker-trigger:active {
background: var(--primary-bg);
border-color: rgba(16, 185, 129, .35);
}
.picker-trigger .left { flex: 1; min-width: 0 }
.picker-trigger .label { font-size: 11px; color: var(--text-muted); margin-bottom: 2px }
.picker-trigger .value {
font-size: 14px;
font-weight: 700;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.picker-trigger .ph { color: var(--text-muted); font-weight: 600 }
.picker-trigger .arrow { color: var(--text-muted); flex-shrink: 0 }
/* ----------------------------------------------------------
25. TREE (menu/expense item tree)
---------------------------------------------------------- */
.tree-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--r);
box-shadow: var(--shadow);
overflow: hidden;
}
.tree-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
background: linear-gradient(135deg, var(--primary-bg), #fff);
}
.tree-head .title { font-size: 14px; font-weight: 800; color: var(--text) }
.tree-head .meta { font-size: 12px; color: var(--text-sec) }
.tree { padding: 6px 0 }
.tree-node {
position: relative;
display: flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
cursor: pointer;
-webkit-user-select: none;
}
.tree-node:active { background: var(--primary-bg) }
.tree-node + .tree-node { border-top: 1px solid rgba(226, 232, 240, .7) }
.tree-node .twisty {
width: 22px; height: 22px; border-radius: 7px;
display: flex; align-items: center; justify-content: center;
background: rgba(16, 185, 129, .10);
color: var(--primary-dark);
flex-shrink: 0;
transition: .15s;
}
.tree-node.leaf .twisty { opacity: .35; background: transparent }
.tree-node .twisty svg { width: 14px; height: 14px; transition: .15s }
.tree-node.expanded > .twisty svg { transform: rotate(90deg) }
.tree-node .icon {
width: 30px; height: 30px; border-radius: 10px;
display: flex; align-items: center; justify-content: center;
background: var(--bg);
border: 1px solid rgba(226, 232, 240, .9);
color: var(--text-sec);
flex-shrink: 0;
}
.tree-node .main { flex: 1; min-width: 0 }
.tree-node .name {
font-size: 14px;
font-weight: 700;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tree-node .sub {
margin-top: 2px;
font-size: 11px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tree-node .right { display: flex; align-items: center; gap: 8px; flex-shrink: 0 }
.tree-count {
font-size: 11px;
font-weight: 800;
color: var(--primary-dark);
background: var(--primary-bg);
border: 1px solid rgba(16, 185, 129, .22);
padding: 2px 8px;
border-radius: 999px;
}
.tree-selected {
outline: 2px solid rgba(16, 185, 129, .22);
outline-offset: -2px;
background: rgba(236, 253, 245, .55);
}
/* ----------------------------------------------------------
26. VANT MINIMAL OVERRIDES (functional only)
---------------------------------------------------------- */
/* Vant Toast 的根节点同时是 .van-popup + .van-toast;vant 中 .van-popup 白底若后加载/同特异度会盖住 toast 深色底 → 白底白字。
* 全项目凡 showToast / showSuccessToast 等均走此组件;用 !important + 字面 fallback 保证任意页面可读。
* (依赖 main.ts 中在 vant.css 之后引入本文件。) */
.van-popup.van-toast {
background: var(--van-toast-background, rgba(0, 0, 0, 0.78)) !important;
color: var(--van-toast-text-color, #fff) !important;
}
.van-popup.van-toast .van-toast__text {
color: inherit !important;
}
.van-popup.van-toast .van-toast__icon,
.van-popup.van-toast .van-icon {
color: inherit !important;
}
.van-popup.van-toast .van-toast__loading {
color: var(--van-toast-loading-icon-color, #fff) !important;
}
.van-popup.van-toast .van-loading__spinner .van-loading__dot {
background: currentColor !important;
}
.van-popup--bottom {
border-radius: 14px 14px 0 0 !important;
}
.van-overlay {
background: rgba(0, 0, 0, .42) !important;
}
.van-tabs__line {
background: var(--primary) !important;
background-color: var(--primary) !important;
border-radius: 2px !important;
height: 3px !important;
}
.van-tab--active {
color: var(--primary) !important;
font-weight: 600 !important;
}
/* 与变量链一致,防止个别主题下 Tab 文字仍回落到蓝 */
.van-tabs__nav .van-tab--active {
color: var(--primary) !important;
}
.van-loading__spinner .van-loading__dot {
background: var(--primary) !important;
}
.van-pull-refresh__head {
color: var(--primary) !important;
}
.van-switch--on {
background: var(--primary) !important;
}
.van-dialog {
border-radius: 14px !important;
overflow: hidden;
}
/* 勿对 .van-dialog__confirm 使用 color !important,否则会盖住 Vant 的 confirmButtonColor(删除确认需红色) */
.van-dialog__confirm {
font-weight: 600;
}
.van-notice-bar {
background: var(--primary-bg) !important;
color: var(--primary-dark) !important;
}