/* ==========================================================================
   门店销售日报看板 · 全局设计系统
   商务化风格：克制、专业、扁平，无深色模式，无装饰图标
   ========================================================================== */

/* ---------- 1. 设计令牌 ---------- */
:root {
    --brand-500: #2563eb;
    --brand-600: #1d4ed8;
    --accent:    #06b6d4;
    --success:   #059669;
    --warning:   #d97706;
    --danger:    #dc2626;

    --bg-body:     #f5f6fa;
    --bg-surface:  #ffffff;
    --bg-surface-2:#f8fafc;
    --bg-surface-3:#f1f5f9;
    --bg-glass:    rgba(255,255,255,0.92);

    --text-primary:   #0f172a;
    --text-secondary: #475569;
    --text-tertiary:  #94a3b8;

    --border-color: #e2e8f0;
    --border-light: #eef2f7;

    --shadow-sm: 0 1px 3px rgba(15,23,42,0.06), 0 1px 2px rgba(15,23,42,0.04);
    --shadow-md: 0 4px 12px -2px rgba(15,23,42,0.08), 0 2px 6px -2px rgba(15,23,42,0.05);
    --shadow-lg: 0 12px 32px -8px rgba(15,23,42,0.14), 0 4px 12px -4px rgba(15,23,42,0.06);
    --shadow-glow: 0 0 0 4px rgba(37,99,235,0.12);

    --radius-sm:  6px;
    --radius-md:  10px;
    --radius-lg:  14px;
    --radius-full:999px;

    --ease-out:    cubic-bezier(0.22,1,0.36,1);
    --dur-fast:    0.15s;
    --dur-base:    0.25s;
    --dur-slow:    0.45s;

    --topnav-h: 56px;
    --page-max: 1440px;
}

/* ---------- 2. 基础 ---------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC",
        "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", sans-serif;
    font-size: 14px;
    line-height: 1.6;
    background: var(--bg-body);
    color: var(--text-primary);
    -webkit-font-smoothing: antialiased;
}
::selection { background: rgba(37,99,235,0.15); }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(100,116,139,0.35); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(100,116,139,0.55); }
a { color: var(--brand-600); text-decoration: none; }
a:hover { text-decoration: underline; }
h1,h2,h3,h4 { line-height: 1.3; }

/* 页面进场 */
@keyframes pageIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}
.page-enter { animation: pageIn var(--dur-slow) var(--ease-out) both; }
.container { max-width: var(--page-max); margin: 0 auto; padding: 0 24px; }

/* ---------- 3. 顶部导航 ---------- */
.topnav {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: var(--topnav-h);
    padding: 0 24px;
    background: var(--bg-glass);
    border-bottom: 1px solid var(--border-color);
    flex-wrap: wrap;
}
.topnav .brand { display: flex; align-items: center; gap: 10px; margin-right: 18px; text-decoration: none; }
.topnav h1 { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; color: var(--text-primary); white-space: nowrap; }
.topnav .nav-link {
    position: relative;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    padding: 8px 14px;
    border-radius: var(--radius-full);
    transition: color var(--dur-fast), background var(--dur-fast);
}
.topnav .nav-link:hover { color: var(--text-primary); background: var(--bg-surface-3); }
.topnav .nav-link.active { color: var(--brand-600); background: rgba(37,99,235,0.08); font-weight: 600; }
.topnav .spacer { flex: 1; }
.topnav .user-info { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-secondary); white-space: nowrap; }
.topnav .user-info b { color: var(--text-primary); font-weight: 600; }
.topnav .user-info .role-text { color: var(--text-tertiary); }

/* ---------- 4. 按钮 ---------- */
.btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 18px;
    border: none;
    border-radius: var(--radius-sm);
    background: var(--brand-500);
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: all var(--dur-fast) var(--ease-out);
}
.btn:hover { background: var(--brand-600); transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.98); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none !important; }

.btn-secondary {
    background: var(--bg-surface);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
    box-shadow: var(--shadow-sm);
    font-weight: 500;
}
.btn-secondary:hover { background: var(--bg-surface-2); color: var(--text-primary); border-color: var(--brand-500); }

.btn-danger { background: var(--danger); }
.btn-danger:hover { background: #b91c1c; }

.btn-ghost { background: transparent; color: var(--text-secondary); border: none; box-shadow: none; font-weight: 500; }
.btn-ghost:hover { background: var(--bg-surface-3); color: var(--text-primary); }

.btn-sm { padding: 4px 12px; font-size: 12.5px; border-radius: 5px; }

.btn.is-loading { pointer-events: none; opacity: 0.75; }
.btn.is-loading::before {
    content: ""; width: 13px; height: 13px; border: 2px solid currentColor;
    border-top-color: transparent; border-radius: 50%; display: inline-block;
    animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 5. 卡片 / 面板 ---------- */
.panel {
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: 22px 24px;
    box-shadow: var(--shadow-sm);
    margin: 20px 24px;
    transition: box-shadow var(--dur-base) var(--ease-out);
}
.panel:hover { box-shadow: var(--shadow-md); }
.panel h2 { margin: 0 0 4px; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.panel .panel-desc { margin: 0 0 16px; font-size: 13px; color: var(--text-tertiary); }
.panel .panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.panel .panel-head h2 { margin: 0; }

/* KPI 统计卡 */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; padding: 20px 24px 4px; }
.stat-card {
    background: var(--bg-surface);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
    box-shadow: var(--shadow-sm);
    transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
    animation: pageIn var(--dur-slow) var(--ease-out) both;
}
.stat-card:nth-child(2) { animation-delay: 0.05s; }
.stat-card:nth-child(3) { animation-delay: 0.10s; }
.stat-card:nth-child(4) { animation-delay: 0.15s; }
.stat-card:nth-child(5) { animation-delay: 0.20s; }
.stat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.stat-card .stat-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.stat-card .label { font-size: 13px; color: var(--text-secondary); font-weight: 500; }
.stat-card .value { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1.2; }
.stat-card .unit { font-size: 14px; font-weight: 500; color: var(--text-tertiary); margin-left: 2px; }
.stat-card .foot { margin-top: 6px; font-size: 12px; color: var(--text-tertiary); }

/* ---------- 6. 数据表格 ---------- */
.table-wrap { margin: 16px 24px 28px; background: var(--bg-surface); border: 1px solid var(--border-light); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); overflow: hidden; }
.table-wrap .table-scroll { overflow-x: auto; }
table.data-table { width: 100%; border-collapse: collapse; background: transparent; }
table.data-table th, table.data-table td { padding: 11px 16px; border-bottom: 1px solid var(--border-light); font-size: 13px; text-align: left; white-space: nowrap; }
table.data-table th { position: sticky; top: 0; z-index: 2; background: var(--bg-surface-2); color: var(--text-secondary); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
table.data-table tbody tr { transition: background var(--dur-fast); }
table.data-table tbody tr:hover { background: var(--bg-surface-2); }
table.data-table tbody tr:last-child td { border-bottom: none; }
table.data-table td.num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }

/* 进度条 */
.rate-cell { display: flex; align-items: center; gap: 8px; min-width: 120px; }
.rate-bar { flex: 1; height: 6px; border-radius: 3px; background: var(--bg-surface-3); overflow: hidden; }
.rate-bar > i { display: block; height: 100%; border-radius: 3px; background: var(--brand-500); transition: width 0.8s var(--ease-out); }
.rate-bar > i.good { background: var(--success); }
.rate-bar > i.bad  { background: var(--danger); }

/* ---------- 7. 标签 ---------- */
.tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px; border-radius: var(--radius-full); font-size: 12px; font-weight: 600; line-height: 1.6; }
.tag-green { background: rgba(5,150,105,.1); color: var(--success); }
.tag-gray  { background: var(--bg-surface-3); color: var(--text-secondary); }
.tag-blue  { background: rgba(37,99,235,.1); color: var(--brand-600); }
.tag-amber { background: rgba(217,119,6,.1); color: var(--warning); }
.tag-red   { background: rgba(220,38,38,.1); color: var(--danger); }
.review-flag { color: var(--danger); font-weight: 600; }

/* ---------- 8. 表单控件 ---------- */
.form-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.form-row label { font-size: 13.5px; color: var(--text-secondary); font-weight: 500; }
.field { margin-bottom: 16px; }
.field > label { display: block; font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-bottom: 7px; }
input[type=text], input[type=password], input[type=date], input[type=number],
input[type=search], select, textarea {
    padding: 9px 13px; border: 1px solid var(--border-color); border-radius: var(--radius-sm);
    font-size: 14px; font-family: inherit; background: var(--bg-surface); color: var(--text-primary);
    transition: border-color var(--dur-fast), box-shadow var(--dur-fast), background var(--dur-fast);
}
input:hover, select:hover, textarea:hover { border-color: var(--brand-500); }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--brand-500); box-shadow: var(--shadow-glow); }
input::placeholder { color: var(--text-tertiary); }

/* 验证 */
input.is-invalid, select.is-invalid { border-color: var(--danger) !important; box-shadow: 0 0 0 4px rgba(220,38,38,.12) !important; animation: shake 0.4s var(--ease-out); }
.field-error { margin-top: 5px; font-size: 12px; color: var(--danger); animation: pageIn 0.2s var(--ease-out); }
@keyframes shake {
    0%,100% { transform: translateX(0); }
    20% { transform: translateX(-6px); }
    40% { transform: translateX(6px); }
    60% { transform: translateX(-4px); }
    80% { transform: translateX(4px); }
}

/* 开关 */
.switch { position: relative; display: inline-block; width: 40px; height: 22px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .slider { position: absolute; inset: 0; background: var(--bg-surface-3); border: 1px solid var(--border-color); border-radius: var(--radius-full); cursor: pointer; transition: all var(--dur-base) var(--ease-out); }
.switch .slider::before { content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm); transition: transform var(--dur-base) var(--ease-out); }
.switch input:checked + .slider { background: var(--brand-500); border-color: transparent; }
.switch input:checked + .slider::before { transform: translateX(18px); }

/* ---------- 9. 提示 / 通知 ---------- */
.notice { display: flex; align-items: flex-start; gap: 8px; padding: 11px 15px; border-radius: var(--radius-md); font-size: 13.5px; font-weight: 500; margin-bottom: 12px; border: 1px solid transparent; animation: pageIn var(--dur-base) var(--ease-out); }
.notice-error { background: rgba(220,38,38,.05); color: var(--danger); border-color: rgba(220,38,38,.15); }
.notice-ok    { background: rgba(5,150,105,.05); color: var(--success); border-color: rgba(5,150,105,.15); }
.notice-warn  { background: rgba(217,119,6,.05); color: var(--warning); border-color: rgba(217,119,6,.15); }

/* Toast */
.toast-container { position: fixed; top: calc(var(--topnav-h) + 12px); right: 20px; z-index: 300; display: flex; flex-direction: column; gap: 10px; pointer-events: none; }
.toast { display: flex; align-items: center; gap: 10px; min-width: 240px; max-width: 360px; padding: 12px 16px; border-radius: var(--radius-md); background: var(--bg-glass); border: 1px solid var(--border-color); box-shadow: var(--shadow-lg); font-size: 13.5px; font-weight: 500; pointer-events: auto; animation: toastIn 0.35s var(--ease-out); }
.toast.hide { animation: toastOut 0.3s var(--ease-out) forwards; }
.toast .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.toast.ok    .dot { background: var(--success); }
.toast.error .dot { background: var(--danger); }
.toast.warn  .dot { background: var(--warning); }
@keyframes toastIn { from { opacity: 0; transform: translateX(40px) scale(0.95); } to { opacity: 1; transform: translateX(0) scale(1); } }
@keyframes toastOut { to { opacity: 0; transform: translateX(40px) scale(0.95); } }

/* ---------- 10. 弹窗 ---------- */
/* 遮罩必须独立覆盖页面，隐藏时不拦截点击；显示时锁定背景滚动并建立清晰层级 */
.modal-mask {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 20px;
    background: rgba(15, 23, 42, 0.58);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-out), visibility var(--dur-base);
}
.modal-mask.show {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
body:has(.modal-mask.show) { overflow: hidden; }
.modal {
    background: var(--bg-surface);
    border: 1px solid rgba(148, 163, 184, 0.34);
    border-radius: var(--radius-lg);
    padding: 26px 28px;
    width: 440px;
    max-width: 100%;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    box-shadow: 0 24px 72px rgba(15, 23, 42, 0.28), 0 8px 24px rgba(15, 23, 42, 0.14);
    transform: translateY(12px) scale(0.97);
    transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.modal-mask.show .modal {
    transform: translateY(0) scale(1);
    box-shadow: 0 28px 88px rgba(15, 23, 42, 0.32), 0 10px 28px rgba(15, 23, 42, 0.16);
}
.modal h3 { margin: 0 0 6px; font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.modal .modal-sub { margin: 0 0 18px; font-size: 13px; color: var(--text-tertiary); }
.modal .form-row { align-items: center; }
.modal .form-row > label { width: 84px; flex-shrink: 0; }
.modal .form-row > input, .modal .form-row > select { flex: 1; min-width: 0; }
.modal .actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border-light); }

/* 宽弹窗（用户详情） */
.modal-wide { width: 720px; max-width: 92vw; }
.modal-wide .detail-section { margin-bottom: 24px; }
.modal-wide .detail-section h4 { margin: 0 0 10px; font-size: 15px; font-weight: 650; color: var(--text-primary); }
.modal-wide .detail-section .hint { margin: 0 0 10px; font-size: 13px; color: var(--text-tertiary); }

/* ---------- 11. 骨架屏 ---------- */
.skeleton { position: relative; overflow: hidden; background: var(--bg-surface-3); border-radius: 6px; min-height: 1em; }
.skeleton::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent); animation: shimmer 1.4s infinite; }
@keyframes shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.skel-card { height: 96px; border-radius: var(--radius-lg); }
.skel-chart { height: 320px; border-radius: var(--radius-lg); }
.skel-row { height: 20px; margin: 12px 16px; }

/* ---------- 12. 看板专用 ---------- */
/* 顶部工具行（导出 Excel / 刷新）——**刻意不吸顶**：
   原来写的是 position: sticky + top: var(--topnav-h)，于是往下滚动时它一直挂在
   页眉下面（页眉 + 工具行两条固定带）。用户要求"下拉后应该看不到"，改成随页面滚走。 */
.toolbar { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; padding: 14px 24px; background: var(--bg-glass); border-bottom: 1px solid var(--border-color); }
.toolbar .filter-group { display: flex; align-items: center; gap: 8px; }
.toolbar .filter-group > label { font-size: 13px; color: var(--text-secondary); font-weight: 500; white-space: nowrap; }

.quick-ranges { display: inline-flex; background: var(--bg-surface-3); border-radius: var(--radius-full); padding: 3px; gap: 2px; }
.quick-ranges button { border: none; background: transparent; color: var(--text-secondary); font-size: 12.5px; font-weight: 500; font-family: inherit; padding: 5px 13px; border-radius: var(--radius-full); cursor: pointer; transition: all var(--dur-fast); white-space: nowrap; }
.quick-ranges button:hover { color: var(--text-primary); }
.quick-ranges button.active { background: var(--bg-surface); color: var(--brand-600); font-weight: 600; box-shadow: var(--shadow-sm); }

.charts { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px; padding: 16px 24px 0; }
.chart-box { position: relative; background: var(--bg-surface); border: 1px solid var(--border-light); border-radius: var(--radius-lg); padding: 18px 20px; box-shadow: var(--shadow-sm); grid-column: span 6; min-width: 0; transition: box-shadow var(--dur-base) var(--ease-out); }
.chart-box:hover { box-shadow: var(--shadow-md); }
.chart-box.span-4 { grid-column: span 4; }
.chart-box.span-5 { grid-column: span 5; }
.chart-box.span-7 { grid-column: span 7; }
.chart-box.span-8 { grid-column: span 8; }
.chart-box.span-12 { grid-column: span 12; }
.chart-box .chart-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; flex-wrap: wrap; row-gap: 6px; }
.chart-box .chart-title h3 { margin: 0; font-size: 14.5px; font-weight: 650; }
.chart-box .chart-title .hint { font-size: 12px; color: var(--text-tertiary); }
.chart-box .chart-canvas { width: 100%; height: 300px; }

.live-dot { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--success); font-weight: 600; }
.live-dot::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--success); animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(5,150,105,.5); } 50% { box-shadow: 0 0 0 6px rgba(5,150,105,0); } }

.empty-state { margin: 48px 24px; background: var(--bg-surface); border: 1px dashed var(--border-color); border-radius: var(--radius-xl); padding: 72px 24px; text-align: center; color: var(--text-secondary); }
.empty-state .title { font-size: 16px; font-weight: 650; margin-bottom: 6px; }
.empty-state .desc { font-size: 13.5px; color: var(--text-tertiary); }

.table-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 16px 20px; border-bottom: 1px solid var(--border-light); }
.table-head h3 { margin: 0; font-size: 14.5px; font-weight: 650; }
.table-head .tools { display: flex; gap: 10px; align-items: center; }

/* ---------- 日报明细：右上角筛选（门店 / 时间范围，取代原来的搜索框） ---------- */
.filter-inline {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12.5px; color: var(--text-secondary); white-space: nowrap;
}
.filter-inline select,
.filter-inline input[type=date] {
    height: 30px; padding: 0 8px;
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
    background: var(--bg-surface); color: var(--text-primary);
    font-size: 12.5px; font-family: inherit;
}
.filter-inline select { max-width: 190px; }
.filter-inline select:focus, .filter-inline input[type=date]:focus {
    outline: none; border-color: var(--brand-500);
}

/* 明细里数字列的表头也要右对齐 —— 数字是右对齐的，
   表头原来沿用全局的 text-align: left，两边参差不齐。 */
table.data-table th.num { text-align: right; }

/* ---------- 日报明细：默认收起 + 底部分页（10 / 50 / 全部） ---------- */
.detail-scope { margin-left: 6px; font-size: 12px; font-weight: 400; color: var(--text-tertiary); }
.table-head .tools-sep { width: 1px; height: 18px; background: var(--border-color); }

/* 收起状态：只留标题栏那一行（展开按钮永远看得见） */
.table-wrap.is-collapsed .table-scroll,
.table-wrap.is-collapsed .detail-pager { display: none; }

.detail-pager {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding: 12px 20px; border-top: 1px solid var(--border-light);
    font-size: 12.5px;
}
.pager-nav { display: inline-flex; align-items: center; gap: 8px; }
.pager-nav.is-disabled { opacity: .45; }
.pager-pos { font-variant-numeric: tabular-nums; color: var(--text-tertiary); }
.pager-size { display: inline-flex; align-items: center; gap: 6px; }
.pager-label { color: var(--text-tertiary); }
.pager-btn {
    height: 26px; padding: 0 10px;
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
    background: var(--bg-surface); color: var(--text-secondary);
    font-size: 12px; font-family: inherit; line-height: 1; white-space: nowrap; cursor: pointer;
    transition: border-color var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out),
                background var(--dur-fast) var(--ease-out);
}
.pager-btn:hover:not(:disabled) { border-color: var(--brand-500); color: var(--brand-600); }
.pager-btn:disabled { opacity: .4; cursor: not-allowed; }
.pager-btn.is-active { border-color: var(--brand-500); background: var(--brand-500); color: #fff; }

/* ---------- 13. 登录页 ---------- */
.login-body { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; position: relative; overflow: hidden; background: var(--bg-body); }

.login-bg { position: fixed; inset: 0; overflow: hidden; z-index: 0; }
.login-bg .blob { position: absolute; border-radius: 50%; filter: blur(90px); opacity: 0.4; animation: blobFloat 18s ease-in-out infinite; }
.login-bg .blob-1 { width: 480px; height: 480px; background: #94a3b8; top: -120px; left: -100px; }
.login-bg .blob-2 { width: 420px; height: 420px; background: #cbd5e1; bottom: -140px; right: -80px; animation-delay: -6s; }
.login-bg .blob-3 { width: 360px; height: 360px; background: #e2e8f0; top: 40%; left: 55%; animation-delay: -12s; opacity: .3; }
@keyframes blobFloat { 0%,100% { transform: translate(0,0) scale(1); } 33% { transform: translate(40px,-50px) scale(1.08); } 66% { transform: translate(-30px,30px) scale(0.94); } }

.login-bg::after {
    content: ""; position: absolute; inset: 0;
    background-image: linear-gradient(rgba(148,163,184,.04) 1px, transparent 1px), linear-gradient(90deg, rgba(148,163,184,.04) 1px, transparent 1px);
    background-size: 44px 44px;
    -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 40%, #000 30%, transparent 75%);
    mask-image: radial-gradient(ellipse 80% 70% at 50% 40%, #000 30%, transparent 75%);
}

.login-box { position: relative; z-index: 1; width: 400px; max-width: 100%; padding: 40px 40px 36px; border-radius: var(--radius-lg); background: var(--bg-glass); border: 1px solid rgba(255,255,255,.5); box-shadow: var(--shadow-lg); animation: loginIn 0.7s var(--ease-out) both; }
@keyframes loginIn { from { opacity: 0; transform: translateY(24px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } }

.login-head { margin-bottom: 26px; }
.login-head h1 { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.login-head .sub { color: var(--text-tertiary); font-size: 13px; margin-top: 2px; }

.login-box .field { animation: pageIn 0.5s var(--ease-out) both; }
.login-box .field:nth-of-type(1) { animation-delay: 0.15s; }
.login-box .field:nth-of-type(2) { animation-delay: 0.22s; }
.login-box .field:nth-of-type(3) { animation-delay: 0.29s; }
.login-box .field input { width: 100%; padding: 11px 14px; }

.captcha-row { display: flex; gap: 10px; align-items: center; }
.captcha-row input { flex: 1; min-width: 0; letter-spacing: 0.3em; font-weight: 600; }
.captcha-row img { height: 44px; border-radius: var(--radius-sm); border: 1px solid var(--border-color); cursor: pointer; transition: transform var(--dur-fast), box-shadow var(--dur-fast); }
.captcha-row img:hover { transform: scale(1.04); box-shadow: var(--shadow-md); }

.login-box .btn { width: 100%; padding: 12px; font-size: 15px; margin-top: 8px; border-radius: 10px; animation: pageIn 0.5s var(--ease-out) 0.36s both; }
.login-box .foot-note { margin-top: 20px; text-align: center; font-size: 12px; color: var(--text-tertiary); animation: pageIn 0.5s var(--ease-out) 0.42s both; }

/* ---------- 14. 管理页 ---------- */
.page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 26px 24px 4px; }
.page-header .title h2 { margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -0.02em; }
.page-header .title p { margin: 4px 0 0; font-size: 13px; color: var(--text-tertiary); }

.check-list { max-height: 420px; overflow-y: auto; border: 1px solid var(--border-light); border-radius: var(--radius-md); }
.check-list label { display: flex; align-items: center; gap: 10px; padding: 10px 14px; font-size: 14px; cursor: pointer; border-bottom: 1px solid var(--border-light); transition: background var(--dur-fast); }
.check-list label:last-child { border-bottom: none; }
.check-list label:hover { background: var(--bg-surface-2); }
.check-list .real-name { color: var(--text-tertiary); font-size: 12px; }

/* 可点击用户名链接 */
.user-link { color: var(--brand-600); font-weight: 600; text-decoration: none; cursor: pointer; transition: color var(--dur-fast); }
.user-link:hover { color: var(--brand-500); text-decoration: underline; }

/* 当前用户入口 */
.user-name-link { color: var(--text-primary); font-weight: 600; text-decoration: none; cursor: pointer; }
.user-name-link:hover { color: var(--brand-600); text-decoration: underline; }

/* 密码弹窗 */
.password-modal { width: 460px; }
.password-modal .field-error { margin-bottom: 10px; }
.password-modal .actions { align-items: center; }

/* ---------- 「待人工确认 · 问题原因」弹窗 ---------- */
.review-modal { width: 100%; max-width: 520px; }
.review-notes {
    margin: 0; max-height: 46vh; overflow: auto;
    padding: 12px 14px; border-radius: 8px;
    background: #f8fafc; border: 1px solid var(--border-light);
    font-family: inherit; font-size: 13px; line-height: 1.75; color: var(--text-primary);
    white-space: pre-wrap; word-break: break-word;   /* 原文的换行要保留，长串也要能断 */
}
.review-hint { margin: 10px 0 0; font-size: 12px; color: var(--text-tertiary); }
/* 明细状态列里可点击的「待确认」标签 */
.tag-review { cursor: pointer; }
.tag-review:hover { filter: brightness(.94); }
.tag-review:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }

/* ---------- 15. 时间线（用户行为日志） ---------- */
.timeline { max-height: 320px; overflow-y: auto; padding-right: 8px; }
.timeline-empty { text-align: center; padding: 24px; color: var(--text-tertiary); font-size: 13px; }
.timeline-item { position: relative; display: flex; gap: 12px; padding: 12px 0 12px 20px; border-left: 2px solid var(--border-color); }
.timeline-item:last-child { padding-bottom: 0; }
.timeline-dot { position: absolute; left: -6px; top: 15px; width: 10px; height: 10px; border-radius: 50%; background: var(--brand-500); border: 2px solid var(--bg-surface); }
.timeline-dot.login    { background: var(--success); }
.timeline-dot.logout   { background: var(--text-tertiary); }
.timeline-dot.page_view{ background: var(--brand-500); }
.timeline-dot.export   { background: var(--warning); }
.timeline-dot.button_click { background: var(--accent); }
.timeline-body { flex: 1; }
.timeline-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.timeline-time { font-size: 12px; color: var(--text-tertiary); font-weight: 500; }
.timeline-detail { font-size: 13px; color: var(--text-secondary); margin-top: 2px; line-height: 1.5; }
.timeline-ip { font-size: 11px; color: var(--text-tertiary); margin-top: 2px; }

/* ---------- 16. 复选框 ---------- */
input[type=checkbox] {
    appearance: none; -webkit-appearance: none; width: 17px; height: 17px;
    border: 1.5px solid var(--border-color); border-radius: 5px; background: var(--bg-surface);
    cursor: pointer; position: relative; transition: all var(--dur-fast); flex-shrink: 0; margin: 0;
}
input[type=checkbox]:hover { border-color: var(--brand-500); }
input[type=checkbox]:checked { background: var(--brand-500); border-color: transparent; }
input[type=checkbox]:checked::after { content: ""; position: absolute; left: 4.5px; top: 1.5px; width: 5px; height: 9px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(42deg); }

/* ---------- 17. 响应式 ---------- */
@media (max-width: 1024px) {
    .chart-box, .chart-box.span-4, .chart-box.span-5, .chart-box.span-7, .chart-box.span-8 { grid-column: span 12; }
    .modal-wide { width: 92vw; padding: 22px 20px; }
}
@media (max-width: 768px) {
    .topnav { padding: 8px 12px; gap: 3px; min-height: 52px; }
    .topnav .brand { width: 100%; margin: 0 0 4px; }
    .topnav h1 { font-size: 15px; }
    .topnav .nav-link { padding: 6px 9px; font-size: 13px; }
    .topnav .spacer { display: none; }
    .topnav .user-info { margin-left: auto; }
    .topnav .user-info .role-text { display: none; }
    .topnav > .btn { padding: 5px 9px; }

    .toolbar { position: static; padding: 12px; gap: 8px; }
    .toolbar .filter-group { width: 100%; }
    .toolbar .filter-group select, .toolbar .filter-group input { flex: 1; min-width: 0; }
    .toolbar .quick-ranges { width: 100%; display: grid; grid-template-columns: repeat(4, 1fr); }
    .toolbar .quick-ranges button { padding: 6px 4px; font-size: 12px; }
    .toolbar > .btn { flex: 1; min-width: 0; padding-left: 10px; padding-right: 10px; }
    .toolbar > .spacer { display: none; }
    .toolbar > label:last-child { width: auto; margin-left: auto; }

    .stat-grid { padding: 12px 12px 0; grid-template-columns: repeat(2, 1fr); gap: 8px; }
    .stat-card { padding: 13px 14px; border-radius: 10px; }
    .stat-card .value { font-size: 20px; }
    .stat-card .label { font-size: 12px; }

    .charts { padding: 10px 12px 0; gap: 10px; }
    .chart-box { padding: 14px 12px; border-radius: 10px; }
    .chart-box .chart-title { align-items: flex-start; gap: 6px; flex-direction: column; }
    .chart-box .chart-title h3 { font-size: 14px; }
    .chart-box .chart-title .hint { font-size: 11px; }
    .chart-box .chart-canvas { height: 220px; }

    .panel { margin: 12px; padding: 16px 13px; }
    .table-wrap { margin: 10px 12px 18px; border-radius: 10px; }
    .table-head { padding: 13px 14px; }
    .table-head .tools { width: 100%; }
    /* 明细筛选在手机上占满整行、可换行 */
    .table-head .tools { flex-wrap: wrap; row-gap: 8px; }
    .filter-inline select, .filter-inline input[type=date] { flex: 1; min-width: 0; }
    /* 时间增减按钮与明细分页在窄屏上收紧 */
    .zoom-btn { height: 24px; padding: 0 7px; font-size: 11.5px; }
    .chart-foot { text-align: left; }
    .detail-pager { padding: 10px 14px; }
    .data-table th, .data-table td { padding: 10px 12px; }
    .page-header { padding: 18px 12px 2px; }
    .page-header .title h2 { font-size: 19px; }
    .page-header .title p { font-size: 12px; }

    .modal-mask { align-items: flex-start; padding: 12px; overflow-y: auto; }
    .modal { width: 100%; max-height: calc(100vh - 24px); padding: 20px 16px; border-radius: 10px; }
    .modal-wide { width: 100%; max-width: none; }
    .modal .form-row { align-items: flex-start; }
    .modal .form-row > label { width: 70px; padding-top: 8px; }
    .login-box { padding: 32px 24px 28px; }
    .toast-container { left: 12px; right: 12px; top: auto; bottom: 12px; }
    .toast { max-width: none; min-width: 0; }
}
@media (max-width: 480px) {
    .stat-grid { grid-template-columns: repeat(2, 1fr); }
    .stat-card .value { font-size: 18px; }
    .stat-card .unit { font-size: 12px; }
    .login-box { padding-left: 18px; padding-right: 18px; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}

/* ==========================================================================
   18. 2026-09-14 新增：四行看板结构相关组件
   ========================================================================== */

/* ---------- 查看员视角提示条 ---------- */
.view-banner {
    margin: 0 24px;
    padding: 10px 16px;
    background: rgba(217,119,6,.09);
    border: 1px solid rgba(217,119,6,.28);
    border-radius: var(--radius-md);
    color: #854d0e;
    font-size: 13px;
}
.view-banner strong { font-weight: 700; }

/* ---------- 新增栅格跨度 ---------- */
/* ⚠️ span-5 / span-7 的基础定义必须写在上面第 12 节（与 span-4/8 放一起），
   否则写在这里会排在响应式媒体查询之后，同优先级下把「窄屏铺满一行」的规则覆盖掉，
   导致手机上第二行仍是左右两列、日历被挤到屏幕外。 */

/* 带 dataZoom 滑块的折线图需要更高的画布 */
.chart-box .chart-canvas-tall { height: 340px; }

/* ---------- 刷新按钮 ---------- */
.refresh-icon { display: inline-block; font-size: 13px; line-height: 1; }
#refreshBtn.is-loading .refresh-icon { animation: refreshSpin 0.9s linear infinite; }
@keyframes refreshSpin { to { transform: rotate(360deg); } }

/* ---------- 顶部细工具栏（筛选控件已按需求移除） ---------- */
.toolbar-slim { gap: 10px; }
/* 门店 / 日期控件保留在 DOM 里供内部查询与导出复用，但不显示 */
.hidden-filters { display: none; }
.toolbar-range { font-size: 12.5px; color: var(--text-tertiary); white-space: nowrap; }

/* ---------- 分区标题（分隔"新结构"与"原有模块"） ---------- */
.section-divider {
    display: flex; align-items: center; gap: 12px;
    margin: 30px 24px 2px;
    color: var(--text-tertiary); font-size: 12.5px; font-weight: 500;
}
.section-divider::before,
.section-divider::after { content: ''; flex: 1; height: 1px; background: var(--border-color); }

/* ---------- 门店详情标题栏 ---------- */
.detail-head {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    margin: 26px 24px 0;
}
.detail-head h3 { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }

/* ---------- 第三行：可点击的门店行 ---------- */
.store-row { cursor: pointer; transition: background var(--dur-fast) var(--ease-out); }
.store-row:hover { background: rgba(37,99,235,.05); }
.store-row.is-selected { background: rgba(37,99,235,.09); box-shadow: inset 3px 0 0 var(--brand-500); }

/* 日期状态：已更新当日 = 绿，未更新 = 红 */
.tag.date-ok   { background: rgba(5,150,105,.1);  color: var(--success); }
.tag.date-miss { background: rgba(220,38,38,.1);  color: var(--danger); }

/* ---------- 营业额日历（多个月份纵向堆叠、可滚动、按周吸附） ---------- */
.calendar-wrap {
    position: relative;            /* 复合模式下的锁定遮罩以此为定位基准 */
    padding: 2px 0; user-select: none;
    /* 滚动容器的设计高度（JS 会按「整周」折算成实际高度并写成 inline max-height） */
    --cal-h: 340px;
}

/* 固定高度的滚动容器：上下滑动即可连续查看跨月的日期
   （例如「8 月最后一周 + 9 月前三周」）。
   滚动结束后必须落在整行上，不能卡在半中间 ——
   因为「当前完整可见的那几行」就是右边折线图的时间轴。
   ⚠️ 吸附**只由 JS 负责**（snapCalendarScroll）：早先同时开了 CSS
   scroll-snap-type: y mandatory，两套机制各算各的吸附点、互相打架，
   实际表现就是「经常卡在某一行的中间」。要动这里先读 snapCalendarScroll。 */
.cal-scroll {
    position: relative;
    max-height: var(--cal-h);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* 吸附点要落在吸顶的月份标题下面，由 JS 按实测高度写入 scroll-padding-top */
    /* 左右留出内边距：只要有一边是 auto，浏览器就会把 overflow-x 也当成 auto，
       高亮格子放大后会超出最左/最右列的轨道而被裁掉，用这个内边距给它们让位 */
    padding: 0 10px;
}
.cal-scroll::-webkit-scrollbar { width: 6px; }
.cal-scroll::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 3px; }

.cal-block { margin-bottom: 16px; }
.cal-block:last-child { margin-bottom: 4px; }
.cal-block-head {
    position: sticky; top: 0; z-index: 1;
    padding: 3px 0 7px; margin-bottom: 6px;
    background: var(--bg-surface);
    font-size: 13.5px; font-weight: 650; color: var(--text-primary);
}

.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }

/* 星期表头（日一二三四五六）：**固定在日历最上方，不随日期滚动**（参考 Apple 日历）。
   水平内边距要和 .cal-scroll 的一致，否则列跟下面的日期格对不齐。 */
.cal-fixed-week {
    display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px;
    padding: 0 10px 7px;
    border-bottom: 1px solid var(--border-light);
    margin-bottom: 7px;
    background: var(--bg-surface);
}
.cal-fixed-week span { text-align: center; font-size: 12px; color: var(--text-tertiary); }
/* 周日 / 周六 稍微区分一下，便于看"星期几" */
.cal-fixed-week span:first-child,
.cal-fixed-week span:last-child { color: var(--text-secondary); font-weight: 600; }

/* 日期区按行排：整行是 JS 吸附的最小单位，纵向滚动后不会停在半行上 */
.cal-days { display: flex; flex-direction: column; gap: 5px; }
.cal-row { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }

/* 格子加高、字体加大；内容整体下移，给右上角的天气图标留空间 */
.cal-cell {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    min-height: 64px; padding-top: 12px;
    border-radius: 8px;
    font-size: 12px; line-height: 1.35;
    overflow: hidden;
}
.cal-blank { background: transparent; }
.cal-empty { background: var(--bg-surface-3); color: var(--text-tertiary); }
.cal-has { cursor: pointer; transition: transform var(--dur-fast) var(--ease-out); }
.cal-has:hover { transform: scale(1.06); }
.cal-day { font-weight: 700; font-size: 13.5px; }
/* 金额统一以元显示，位数较多，稍作压缩避免溢出 */
.cal-amt { font-size: 11.5px; opacity: .95; white-space: nowrap; letter-spacing: -0.02em; margin-top: 1px; }
/* 格子金额位数多时（如 1,234,567）收紧字号，避免撑破格子 */
.cal-amt.is-long { font-size: 10px; letter-spacing: -0.05em; }

/* 当前业务日：蓝色实线描边；今天：青色内描边 */
.cal-biz   { outline: 2px solid var(--brand-600); outline-offset: -2px; }
.cal-today { box-shadow: inset 0 0 0 1.5px var(--accent); }

.cal-legend { display: flex; align-items: center; gap: 6px; margin-top: 10px; font-size: 11px; color: var(--text-tertiary); }
.cal-legend-bar { width: 64px; height: 8px; border-radius: var(--radius-full);
    background: linear-gradient(90deg, rgba(37,99,235,.08), rgba(37,99,235,.8)); }
.cal-legend-note { margin-left: auto; }

/* ---------- 营业额日历右边的维度下拉框（按日 / 周 / 月 / 年） ---------- */
.cal-unit {
    height: 28px; padding: 0 6px; flex: none;
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
    background: var(--bg-surface); color: var(--text-secondary);
    font-size: 12px; font-family: inherit; cursor: pointer;
    transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.cal-unit:hover { border-color: var(--brand-500); color: var(--brand-600); }
.cal-unit:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 1px; }

/* ---------- 第三行「各门店当日营业情况」：全字段居中、列距均匀 ---------- */
/* ⚠️ 必须写成 table.data-table.today-table 才能盖过上面第 200 行的
   `table.data-table th, table.data-table td { text-align: left }` ——
   那一条的选择器权重（1 类 2 元素）比 `.today-table td`（1 类 1 元素）高，
   早先用单类名写的「居中」其实一直没生效过。 */
table.data-table.today-table { min-width: 860px; }
table.data-table.today-table th,
table.data-table.today-table td {
    text-align: center;
    vertical-align: middle;
    padding: 18px 20px;
}
/* 连数字列也居中；等宽数字让同一列上下对齐，扫读更整齐 */
table.data-table.today-table td.num {
    text-align: center;
    font-variant-numeric: tabular-nums;
}
table.data-table.today-table th {
    font-size: 12px; line-height: 1.5; letter-spacing: .05em;
    color: var(--text-secondary);
}
table.data-table.today-table td { font-size: 13.5px; line-height: 1.6; }
/* 店铺名是行标识，字号放大一档，与数值列拉开层次 */
table.data-table.today-table td.store-cell { font-weight: 650; font-size: 14px; }
/* 标签（日期 / 序时达成）在格子里垂直居中，避免与数字基线错位 */
table.data-table.today-table td .tag { vertical-align: middle; }
/* 行高统一，横向扫读时列与列更容易对上眼睛 */
table.data-table.today-table tbody tr { height: 58px; }

/* ---------- 第三行：拖动门店行排序 ---------- */
.today-table tbody tr.store-row { cursor: grab; }
.today-table .drag-grip {
    margin-right: 6px; color: var(--text-tertiary);
    font-size: 13px; letter-spacing: -1.5px; user-select: none;
}
.today-table tbody tr.store-row:hover .drag-grip { color: var(--text-secondary); }
/* 拖动中：整行半透明 + 左侧色条，并禁止选中文字、鼠标指针变"抓着" */
.today-table tbody tr.is-dragging {
    opacity: .55;
    background: var(--bg-surface-3) !important;
    box-shadow: inset 3px 0 0 var(--brand-500);
}
body.is-row-dragging, body.is-row-dragging * { cursor: grabbing !important; }
body.is-row-dragging { user-select: none; -webkit-user-select: none; }

/* ---------- 门店详情标题栏：标题 + 门店下拉框 ---------- */
.detail-head .detail-title { display: flex; align-items: center; gap: 8px; }
.detail-head .detail-title select { min-width: 180px; }
.detail-head .hint { font-size: 12px; color: var(--text-tertiary); }

/* ---------- 折线图标题右侧：当前时间范围 + 「本月」恢复按钮 ---------- */
.chart-range { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; row-gap: 4px; }
.chart-range .hint { font-size: 12px; color: var(--text-tertiary); white-space: nowrap; }

/* ---------- 折线图的时间增减按钮（拓宽 / 缩短范围，连点变化更快） ---------- */
.zoom-group { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; row-gap: 4px; }
.zoom-btn {
    height: 26px; padding: 0 9px;
    border: 1px solid var(--border-color); border-radius: var(--radius-sm);
    background: var(--bg-surface); color: var(--text-secondary);
    font-size: 12px; font-family: inherit; line-height: 1; white-space: nowrap;
    cursor: pointer;
    transition: border-color var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out),
                background var(--dur-fast) var(--ease-out);
}
.zoom-btn:hover { border-color: var(--brand-500); color: var(--brand-600); background: var(--brand-50, #eff6ff); }
.zoom-btn:active { transform: translateY(1px); }
/* 点亮态（周末 / 法定节假日 / 全生命周期），颜色与图上的标记带呼应 */
.zoom-btn.is-on { border-color: var(--brand-500); background: var(--brand-500); color: #fff; }
.zoom-btn.is-on:hover { background: var(--brand-600); color: #fff; }
.zoom-btn[data-act="weekend"].is-on { border-color: #4f46e5; background: #4f46e5; }
.zoom-btn[data-act="holiday"].is-on { border-color: #dc2626; background: #dc2626; }
.zoom-btn[data-act="vacation"].is-on { border-color: #d97706; background: #d97706; }
/* 当前维度下不起作用（周末/节假日只在「按日」有意义） */
.zoom-btn.is-dim { opacity: .45; }
.zoom-btn.is-dim.is-on { opacity: .7; }

/* 图表底部的一行小字提示 */
.chart-foot { margin-top: 6px; text-align: right; }
.chart-foot .hint { font-size: 11.5px; color: var(--text-tertiary); }

/* 折线图已不可左右拖动（v3.13 起时间范围只由按钮决定），不要给抓手光标 */
/* 折线图上双击 = 让左边日历跳到那一天。touch-action: manipulation 禁掉「双击缩放」，
   否则手机上双击会被浏览器当成缩放吃掉，事件根本到不了页面。
   ⚠️ 只禁双击缩放，双指捏合缩放与页面滚动都保留。 */
#chartRevenueLine, #chartStoreLine { touch-action: manipulation; }

/* ---------- 营业额日历：格子右上角的天气图标（加大） ---------- */
.wx-icon {
    position: absolute; top: 2px; right: 3px;
    display: inline-flex; align-items: center; gap: 2px;
    padding: 1px 2px; border-radius: 5px;
    background: rgba(255, 255, 255, .82);
    line-height: 0;
}
.wx-icon svg { width: 18px; height: 18px; }
/* 「晴转雨」这类双图标各缩小一点，避免挤到一起 */
.wx-icon.wx-trans svg { width: 15px; height: 15px; }

/* tooltip 里内联使用：不绝对定位、无白底、跟随文字基线 */
.wx-icon.wx-inline {
    position: static; display: inline-flex; padding: 0; background: none;
    vertical-align: -3px; margin-left: 3px;
}
.wx-icon.wx-inline svg { width: 15px; height: 15px; }
.wx-icon.wx-inline.wx-trans svg { width: 13px; height: 13px; }

/* 第三行「天气」列：图标 + 原文居中并排 */
.today-table .today-wx { white-space: nowrap; }
.wx-cell { display: inline-flex; align-items: center; gap: 4px; }
.wx-cell .wx-icon.wx-inline { margin-left: 0; vertical-align: middle; }
.wx-cell .wx-icon.wx-inline svg { width: 17px; height: 17px; }
.wx-cell .wx-icon.wx-inline.wx-trans svg { width: 15px; height: 15px; }
.wx-cell-txt { font-size: 12.5px; color: var(--text-secondary); }

/* ---------- 日历：拖动选中的日期区间（决定折线图时间轴） ---------- */
/* 注意放在 .cal-hover 之前：两者同优先级时后写的生效，hover 要能盖过选区 */
.cal-cell.cal-sel {
    outline: 2px dashed var(--brand-500);
    outline-offset: -2px;
    background-image: linear-gradient(rgba(37,99,235,.16), rgba(37,99,235,.16));
}

/* ---------- 折线图 ↔ 日历 联动高亮（爱马仕橙 #f37021） ---------- */
/* 放大倍数与外发光都刻意收小：它们会超出格子轨道，
   最左/最右列容易被滚动容器裁掉（靠 .cal-scroll 的水平内边距兜住）。 */
.cal-cell.cal-hover {
    outline: 3px solid #f37021;
    outline-offset: -1px;
    transform: scale(1.07);
    z-index: 3;
    box-shadow: 0 0 0 3px rgba(243, 112, 33, .25);
    /* 叠一层橙色底，蓝底格子也能一眼看出被选中 */
    background-image: linear-gradient(rgba(243, 112, 33, .18), rgba(243, 112, 33, .18));
}

@media (max-width: 768px) {
    .view-banner { margin: 0 12px; font-size: 12px; }
    .chart-box .chart-canvas-tall { height: 240px; }

    /* 详情标题栏竖排，下拉框占满整行，方便手指点选 */
    .section-divider, .detail-head { margin-left: 12px; margin-right: 12px; }
    .detail-head { flex-direction: column; align-items: stretch; gap: 6px; }
    .detail-head .detail-title { width: 100%; }
    .detail-head .detail-title select { flex: 1; min-width: 0; }

    /* 第三行表格列多，改为横向滑动查看 */
    .today-table { min-width: 720px; }
    /* 权重要与基础规则一致，否则盖不住（基础规则是 table.data-table.today-table） */
    table.data-table.today-table th,
    table.data-table.today-table td { padding: 12px 10px; }
    .table-wrap .table-scroll { -webkit-overflow-scrolling: touch; }

    /* 日历：滚动区矮一些，格子与图标按比例缩小（仍保持大字号可读）。
       高度由 JS 按「整周」折算后写成 inline max-height，这里只改设计高度基线。 */
    .calendar-wrap { --cal-h: 300px; }
    .cal-cell { min-height: 54px; padding-top: 10px; border-radius: 6px; }
    .cal-day { font-size: 12.5px; }
    .cal-amt { font-size: 10px; }
    .wx-icon svg { width: 15px; height: 15px; }
    .wx-icon.wx-trans svg { width: 12px; height: 12px; }
    .cal-legend-note { display: none; }

    /* 顶部按钮文字较长，允许换行 */
    .topnav { row-gap: 6px; }
}

/* 更窄的手机：日历再紧凑一档（金额保留，只缩小字号） */
@media (max-width: 480px) {
    .calendar-wrap { --cal-h: 260px; }
    .cal-cell { min-height: 46px; padding-top: 9px; }
    .cal-day { font-size: 11.5px; }
    .cal-amt { font-size: 9px; letter-spacing: -0.03em; }
    .wx-icon svg { width: 13px; height: 13px; }
    .wx-icon.wx-trans svg { width: 11px; height: 11px; }
    .detail-head .detail-title h3 { font-size: 14px; }
}


/* ================= 复合折线图（门店详情「每日营业额」标题右侧） =================
   多选门店 → 各自的营业额折线叠在同一张图上；此时左边日历锁定。 */
.cmp-wrap { position: relative; display: inline-flex; align-items: center; gap: 4px; }

/* 下拉面板锚到卡片右边（.chart-box 已 position:relative），
   不跟随按钮位置跑 —— 按钮在窄屏会换行到别处。 */
.cmp-pop {
    display: none;
    position: absolute; top: 46px; right: 20px; z-index: 40;
    width: 258px; max-width: calc(100vw - 32px);
    padding: 10px 10px 8px;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .14);
    text-align: left;
}
.cmp-pop.is-open { display: block; }
.cmp-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.cmp-title { font-size: 12px; font-weight: 650; color: var(--text-primary); }
.cmp-ops { display: inline-flex; gap: 10px; }
.cmp-link {
    border: 0; background: none; padding: 0; cursor: pointer;
    font: inherit; font-size: 12px; color: var(--brand-600);
}
.cmp-link:hover { text-decoration: underline; }
.cmp-list { max-height: 216px; overflow-y: auto; margin: 0 -2px; }
.cmp-item {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px; border-radius: 6px; cursor: pointer;
    font-size: 13px; color: var(--text-secondary);
}
.cmp-item:hover { background: var(--bg-surface-3); }
.cmp-item input { margin: 0; flex: none; accent-color: var(--brand-500); }
.cmp-dot { width: 9px; height: 9px; border-radius: 3px; background: var(--border-color); flex: none; }
.cmp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-empty { margin: 6px; font-size: 12px; color: var(--text-tertiary); }
.cmp-tip { margin: 6px 2px 0; font-size: 11.5px; line-height: 1.5; color: var(--text-tertiary); }

/* 复合模式：左边营业额日历锁定。多店叠加后「某一天」不再对应单独一条线，
   日历的联动高亮只会误导，所以整块盖住并说明怎么解锁。 */
.calendar-wrap.is-locked .cal-scroll { pointer-events: none; }
.cal-lock-mask {
    position: absolute; inset: 0; z-index: 6;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255, 255, 255, .78);
    -webkit-backdrop-filter: blur(1.5px); backdrop-filter: blur(1.5px);
    border-radius: 10px;
}
.cal-lock-box {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 16px; border-radius: 999px;
    background: var(--bg-surface); border: 1px solid var(--border-color);
    box-shadow: var(--shadow-sm);
    font-size: 13px; font-weight: 600; color: var(--text-secondary);
}
.cal-lock-icon { font-size: 14px; line-height: 1; }

/* 汇总日历：当天各门店还没全部上报 → 不显示金额，改写「统计中」。
   要与 .cal-empty（真的没有数据）区分开：这里多一圈描边、文字更"在途"。 */
.cal-cell.cal-pending {
    background: var(--bg-surface-3);
    color: var(--text-secondary);
    box-shadow: inset 0 0 0 1px var(--border-color);
}
.cal-cell.cal-pending .cal-amt { font-size: 11px; letter-spacing: 0; opacity: .9; }

@media (max-width: 768px) {
    .cmp-pop { top: 42px; right: 12px; width: 242px; }
}


/* ================= 门店销售占比：累计时间轴（v3.25） =================
   横跨所有门店的数据周期；拖动它 = 选择累计截止周期，扇区随之变化。 */
.chart-box .chart-canvas-donut { height: 300px; }
.tl { margin-top: 2px; }
.tl-head { min-height: 18px; }
.tl-label { font-size: 12px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.tl-ticks {
    display: flex; justify-content: space-between; gap: 6px;
    margin-top: 1px; font-size: 11px; color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
}
.tl-ticks span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 自绘时间轴：轨道 + 已选填充 + 圆钮。
   ⚠️ 不用原生 <input type="range">：它的滑块拖起来发木、跨浏览器样式也难做，
      而且没法做「已选段渐变」。这里用 Pointer Events，鼠标/触屏一套代码。 */
.tl-track {
    position: relative; height: 20px; margin: 4px 8px 0;
    cursor: pointer; touch-action: none; outline: none;   /* touch-action 必须 none，否则触屏拖动会滚页面 */
}
.tl-track::before {                       /* 底轨 */
    content: ''; position: absolute; left: 0; right: 0; top: 50%;
    height: 6px; transform: translateY(-50%);
    background: var(--bg-surface-3); border: 1px solid var(--border-color);
    border-radius: 999px;
}
.tl-fill {                                /* 已选段：到圆钮为止 */
    position: absolute; left: 0; top: 50%; width: 0; height: 6px;
    transform: translateY(-50%);
    background: linear-gradient(90deg, var(--brand-500), #60a5fa);
    border-radius: 999px; pointer-events: none;
}
.tl-knob {
    position: absolute; top: 50%; left: 0; width: 15px; height: 15px;
    transform: translate(-50%, -50%);
    border-radius: 50%; background: #fff; border: 3px solid var(--brand-500);
    box-shadow: 0 1px 4px rgba(15, 23, 42, .28);
    pointer-events: none;
    transition: box-shadow var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.tl-track:hover .tl-knob { box-shadow: 0 0 0 6px rgba(37, 99, 235, .12), 0 1px 4px rgba(15, 23, 42, .28); }
.tl-track:focus-visible .tl-knob { box-shadow: 0 0 0 5px rgba(37, 99, 235, .28); }
.tl-track.is-drag { cursor: grabbing; }
.tl-track.is-drag .tl-knob {
    transform: translate(-50%, -50%) scale(1.15);
    box-shadow: 0 0 0 8px rgba(37, 99, 235, .16), 0 1px 5px rgba(15, 23, 42, .32);
}
.tl-track.is-off { opacity: .45; cursor: default; }
@media (max-width: 768px) {
    .chart-box .chart-canvas-donut { height: 260px; }
    .tl-ticks { font-size: 10.5px; }
    .tl-track { height: 24px; }            /* 触屏把可点区做大一点 */
}
