/* ==================================================================
   售后绩效看板 · 设计系统
   风格：Apple / iOS 语言（大圆角、毛玻璃、克制的留白、系统色）
   ================================================================== */

:root {
  --bg:            #f5f5f7;
  --bg-elev:       #ffffff;
  --bg-sunken:     #ececee;
  --nav-bg:        rgba(255, 255, 255, 0.72);
  --fill:          rgba(120, 120, 128, 0.12);
  --fill-2:        rgba(120, 120, 128, 0.08);
  --fill-strong:   rgba(120, 120, 128, 0.20);

  --text:          #1d1d1f;
  --text-2:        #6e6e73;
  --text-3:        #8e8e93;
  --text-invert:   #ffffff;

  --line:          rgba(60, 60, 67, 0.12);
  --line-2:        rgba(60, 60, 67, 0.07);

  --accent:        #0071e3;
  --accent-hover:  #0077ed;
  --accent-soft:   rgba(0, 113, 227, 0.10);

  --red:           #ff3b30;
  --red-soft:      rgba(255, 59, 48, 0.12);
  --orange:        #ff9500;
  --orange-soft:   rgba(255, 149, 0, 0.14);
  --green:         #34c759;
  --green-soft:    rgba(52, 199, 89, 0.14);
  --purple:        #af52de;
  --purple-soft:   rgba(175, 82, 222, 0.12);
  --teal:          #30b0c7;

  --shadow-xs:  0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-sm:  0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 2px rgba(0, 0, 0, 0.03);
  --shadow-md:  0 4px 14px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.04);
  --shadow-lg:  0 16px 40px rgba(0, 0, 0, 0.10), 0 2px 8px rgba(0, 0, 0, 0.04);

  --r-xs: 8px;
  --r-sm: 12px;
  --r-md: 16px;
  --r-lg: 20px;
  --r-xl: 26px;

  --ease: cubic-bezier(0.25, 0.1, 0.25, 1);
  --maxw: 1200px;
}

/* 深色主题：由 JS 在 <html> 上写入 data-theme，
   默认取系统偏好，用户可手动切换并记忆。
   这样只需维护一份深色变量，不与媒体查询打架。 */
html[data-theme='dark'] {
  --bg:          #000000;
  --bg-elev:     #1c1c1e;
  --bg-sunken:   #0a0a0b;
  --nav-bg:      rgba(28, 28, 30, 0.72);
  --fill:        rgba(120, 120, 128, 0.24);
  --fill-2:      rgba(120, 120, 128, 0.14);
  --fill-strong: rgba(120, 120, 128, 0.36);
  --text:        #f5f5f7;
  --text-2:      #a1a1a6;
  --text-3:      #8e8e93;
  --line:        rgba(255, 255, 255, 0.13);
  --line-2:      rgba(255, 255, 255, 0.07);
  --accent:      #0a84ff;
  --accent-hover:#3d9bff;
  --accent-soft: rgba(10, 132, 255, 0.18);
  --red:         #ff453a;
  --red-soft:    rgba(255, 69, 58, 0.18);
  --orange:      #ff9f0a;
  --orange-soft: rgba(255, 159, 10, 0.18);
  --green:       #30d158;
  --green-soft:  rgba(48, 209, 88, 0.18);
  --purple:      #bf5af2;
  --purple-soft: rgba(191, 90, 242, 0.18);
  --teal:        #40c8e0;
  --shadow-xs:  0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-sm:  0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-md:  0 4px 16px rgba(0, 0, 0, 0.5);
  --shadow-lg:  0 16px 44px rgba(0, 0, 0, 0.6);
}
html { color-scheme: light; }
html[data-theme='dark'] { color-scheme: dark; }

/* ---------- Reset ---------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "tnum" 1;
}
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent); text-decoration: none; }
h1,h2,h3,h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
svg { display: block; }

/* ==================================================================
   顶栏
   ================================================================== */
.nav {
  position: sticky; top: 0; z-index: 60;
  background: var(--nav-bg);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line-2);
}
.nav-inner {
  max-width: var(--maxw); margin: 0 auto;
  height: 52px; padding: 0 22px;
  display: flex; align-items: center; gap: 14px;
}
.brand { display: flex; align-items: center; gap: 9px; flex: 0 0 auto; }
.brand-mark { width: 22px; height: 22px; color: var(--text); }
.brand-name { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; }
.nav-spacer { flex: 1 1 auto; }

.month-picker {
  display: flex; align-items: center; gap: 6px;
  background: var(--fill); border-radius: 10px; padding: 4px 6px;
}
.month-picker button {
  width: 24px; height: 24px; border: 0; border-radius: 7px;
  background: transparent; cursor: pointer; color: var(--text-2);
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s var(--ease);
}
.month-picker button:hover { background: var(--fill-strong); }
.month-picker .m-label {
  font-size: 13.5px; font-weight: 600; font-variant-numeric: tabular-nums;
  min-width: 84px; text-align: center; letter-spacing: -0.01em;
}

.user-chip {
  display: flex; align-items: center; gap: 8px;
  background: var(--fill); border: 0; border-radius: 999px;
  padding: 5px 12px 5px 6px; cursor: pointer;
  transition: background 0.15s var(--ease);
}
.user-chip:hover { background: var(--fill-strong); }
.user-avatar {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--accent); color: #fff;
  font-size: 11.5px; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
}
.user-name { font-size: 13px; font-weight: 500; white-space: nowrap; }

.icon-btn {
  width: 32px; height: 32px; border: 0; border-radius: 9px;
  background: transparent; color: var(--text-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.icon-btn:hover { background: var(--fill); color: var(--text); }

/* ==================================================================
   分段控件（Apple Segmented Control）
   ================================================================== */
.seg-wrap {
  position: sticky; top: 52px; z-index: 55;
  background: var(--nav-bg);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line-2);
}
.seg-scroll { max-width: var(--maxw); margin: 0 auto; padding: 9px 22px; overflow-x: auto; }
.seg {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--fill); border-radius: 11px;
}
.seg button {
  border: 0; background: transparent; cursor: pointer;
  padding: 6px 16px; border-radius: 8px;
  font-size: 13.5px; font-weight: 500; color: var(--text-2);
  white-space: nowrap; transition: all 0.18s var(--ease);
}
.seg button:hover { color: var(--text); }
.seg button.on {
  background: var(--bg-elev); color: var(--text); font-weight: 600;
  box-shadow: var(--shadow-xs);
}

/* 卡片里的分段控件（例如推送页的文案预览切换器）按钮可能很多，
   而 .seg 是 inline-flex + 按钮 nowrap —— 人数一多会直接把卡片撑破，
   手机上表现为整页横向滚动。这里让它在自身宽度内**换行**。
   早先是让它横向滚动，但滚动条在触屏上不可见，最后那个按钮被裁掉半个，
   看着像渲染坏了；而这一排恰恰是「有哪些文案可看」的全部选项，
   藏起来等于让人以为只有前几个。
   顶栏那一个由 .seg-scroll 负责滚动，不受影响。 */
.card .seg {
  display: flex;
  flex-wrap: wrap;
  width: fit-content;
  max-width: 100%;
}
.card .seg > button { flex: 0 0 auto; }

/* ==================================================================
   布局
   ================================================================== */
.main { max-width: var(--maxw); margin: 0 auto; padding: 22px 22px 64px; }
/* 数据录入 / 目标配置这类宽表页面放开宽度，避免横向滚动；
   顶栏与标签栏同步放宽，保持视觉对齐 */
body.wide .main,
body.wide .nav-inner,
body.wide .seg-scroll { max-width: 1560px; }
.page-head { margin-bottom: 18px; }
.page-title { font-size: 26px; font-weight: 700; letter-spacing: -0.025em; }
.page-sub { font-size: 13.5px; color: var(--text-2); margin-top: 4px; }

.grid { display: grid; gap: 14px; }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.g-hero { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }

.card {
  background: var(--bg-elev); border-radius: var(--r-lg);
  padding: 18px 20px; box-shadow: var(--shadow-sm);
  border: 1px solid var(--line-2);
}
.card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px;
}
.card-title { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.card-note { font-size: 12px; color: var(--text-3); }

/* ---------- 指标卡 ---------- */
.kpi { display: flex; flex-direction: column; gap: 4px; }
.kpi-label { font-size: 12.5px; color: var(--text-2); font-weight: 500; }
.kpi-value {
  font-size: 27px; font-weight: 700; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.kpi-value .unit { font-size: 13px; font-weight: 500; color: var(--text-3); margin-left: 3px; letter-spacing: 0; }
.kpi-foot { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.kpi-value.c-red { color: var(--red); }
.kpi-value.c-orange { color: var(--orange); }
.kpi-value.c-green { color: var(--green); }
.kpi-value.c-accent { color: var(--accent); }

/* ---------- 进度条 ---------- */
.bar { height: 7px; border-radius: 999px; background: var(--fill); overflow: hidden; }
.bar > i {
  display: block; height: 100%; border-radius: 999px;
  background: var(--accent); transition: width 0.6s var(--ease);
}
.bar.thin { height: 5px; }
/* 等级类名与后端保持一致（red / amber / green），amber 映射到橙色 */
.bar.red > i { background: var(--red); }
.bar.amber > i,
.bar.orange > i { background: var(--orange); }
.bar.green > i { background: var(--green); }
.bar-row { display: flex; align-items: center; gap: 10px; }
.bar-row .bar { flex: 1 1 auto; }
.bar-row .pct {
  flex: 0 0 auto; font-size: 12.5px; font-weight: 600;
  font-variant-numeric: tabular-nums; min-width: 46px; text-align: right;
}

/* ---------- 徽标 ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; font-weight: 600; line-height: 1.6;
  padding: 1px 8px; border-radius: 999px; white-space: nowrap;
}
.badge.red { background: var(--red-soft); color: var(--red); }
.badge.orange { background: var(--orange-soft); color: var(--orange); }
.badge.green { background: var(--green-soft); color: var(--green); }
.badge.gray { background: var(--fill); color: var(--text-2); }
.badge.blue { background: var(--accent-soft); color: var(--accent); }

/* ---------- 行列表 ---------- */
.list { display: flex; flex-direction: column; }
.row-item {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 0; border-bottom: 1px solid var(--line-2);
}
.row-item:last-child { border-bottom: 0; }
.row-item .grow { flex: 1 1 auto; min-width: 0; }
.row-item .name { font-size: 14px; font-weight: 500; }
.row-item .sub { font-size: 12px; color: var(--text-3); margin-top: 1px; }
.row-item .num {
  font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums;
  text-align: right;
}
.rank-dot {
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--fill); color: var(--text-2);
}
.rank-dot.top1 { background: #d4af37; color: #fff; }
.rank-dot.top2 { background: #a8a8ad; color: #fff; }
.rank-dot.top3 { background: #c08457; color: #fff; }

/* ==================================================================
   表格 / 录入矩阵
   ================================================================== */
.matrix-wrap {
  overflow: auto; border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--bg-elev); box-shadow: var(--shadow-sm);
  -webkit-overflow-scrolling: touch;
}
table.matrix { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13px; }
table.matrix th, table.matrix td {
  padding: 8px 8px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--line-2); border-right: 1px solid var(--line-2);
  font-variant-numeric: tabular-nums;
}
table.matrix thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--bg-elev); font-weight: 600; color: var(--text-2);
  font-size: 12px; letter-spacing: 0.01em;
}
table.matrix thead tr.grp th {
  background: var(--fill-2); color: var(--text-3);
  font-size: 11.5px; font-weight: 600; text-align: center; letter-spacing: 0.06em;
}
table.matrix tbody th.sticky, table.matrix thead th.sticky {
  position: sticky; left: 0; z-index: 4; text-align: left;
  background: var(--bg-elev); border-right: 1px solid var(--line);
}
table.matrix thead tr.grp th.sticky { z-index: 6; background: var(--bg-sunken); }
table.matrix thead tr.col th.sticky { z-index: 6; }
table.matrix tbody tr:hover td { background: var(--fill-2); }
table.matrix tbody tr:hover th.sticky { background: var(--bg-sunken); }
table.matrix td.total, table.matrix th.total { background: var(--fill-2); font-weight: 600; }
table.matrix tr.sum-row td, table.matrix tr.sum-row th {
  background: var(--bg-sunken); font-weight: 700; border-top: 1px solid var(--line);
}
table.matrix tr.sum-row th.sticky { background: var(--bg-sunken); }
table.matrix .cell-name { font-weight: 500; color: var(--text); }
table.matrix .cell-sub { font-size: 11px; color: var(--text-3); }
.neg-col { color: var(--red); }
.pre-col { color: var(--purple); }

/* 表格内输入框 */
input.cell {
  width: 100%; min-width: 52px; text-align: right;
  border: 1px solid transparent; background: var(--fill-2);
  border-radius: var(--r-xs); padding: 5px 7px;
  font-size: 13px; font-variant-numeric: tabular-nums;
  transition: all 0.15s var(--ease);
}
input.cell:hover { background: var(--fill); }
input.cell:focus {
  outline: none; background: var(--bg-elev);
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
input.cell.filled { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
input.cell::-webkit-outer-spin-button,
input.cell::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input.cell[type="number"] { -moz-appearance: textfield; }

/* ==================================================================
   表单控件
   ================================================================== */
.toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.toolbar .spacer { flex: 1 1 auto; }

.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 12.5px; color: var(--text-2); font-weight: 500; }
.input, select.input {
  background: var(--bg-elev); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 9px 12px; font-size: 14px;
  transition: all 0.15s var(--ease); width: 100%;
}
.input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
select.input { cursor: pointer; appearance: none; padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238e8e93' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center;
}
input[type="date"].input, input[type="month"].input { min-height: 39px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 0; border-radius: var(--r-sm); padding: 9px 17px;
  font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: all 0.16s var(--ease); white-space: nowrap;
  background: var(--fill); color: var(--text);
}
.btn:hover { background: var(--fill-strong); }
.btn:active { transform: scale(0.975); }
.btn.primary { background: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--accent-hover); }
.btn.danger { background: var(--red-soft); color: var(--red); }
.btn.danger:hover { background: rgba(255, 59, 48, 0.2); }
.btn.ghost { background: transparent; color: var(--accent); }
.btn.ghost:hover { background: var(--accent-soft); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.sm { padding: 6px 12px; font-size: 12.5px; border-radius: 9px; }
.btn.block { width: 100%; }

/* ==================================================================
   环形进度
   ================================================================== */
.ring-wrap { display: flex; align-items: center; gap: 22px; }
.ring { position: relative; flex: 0 0 auto; }
.ring svg { transform: rotate(-90deg); }
.ring .track { stroke: var(--fill); }
.ring .prog { transition: stroke-dashoffset 0.9s var(--ease); stroke-linecap: round; }
.ring-center {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
}
.ring-num {
  font-size: 30px; font-weight: 700; letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums; line-height: 1;
}
.ring-num .pct-sign { font-size: 16px; font-weight: 600; margin-left: 1px; }
.ring-cap { font-size: 11.5px; color: var(--text-3); }

/* ==================================================================
   图例 / 小徽记
   ================================================================== */
.legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: 12px; color: var(--text-2); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 9px; height: 9px; border-radius: 3px; display: block; }

.stat-line {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 7px 0; border-bottom: 1px solid var(--line-2); font-size: 13px;
}
.stat-line:last-child { border-bottom: 0; }
.stat-line .k { color: var(--text-2); }
.stat-line .v { font-weight: 600; font-variant-numeric: tabular-nums; }

/* ==================================================================
   遮罩 / 弹窗 / 提示
   ================================================================== */
.overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0, 0, 0, 0.4);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  animation: fade 0.2s var(--ease);
}
.sheet {
  background: var(--bg-elev); border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg); width: 100%; max-width: 460px;
  padding: 24px; animation: pop 0.24s var(--ease);
  max-height: 88vh; overflow: auto;
}
.sheet h3 { font-size: 18px; margin-bottom: 4px; letter-spacing: -0.02em; }
.sheet .sheet-sub { font-size: 13px; color: var(--text-2); margin-bottom: 18px; }
.sheet-actions { display: flex; gap: 10px; margin-top: 22px; }
.sheet-actions .btn { flex: 1 1 0; }

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop {
  from { opacity: 0; transform: scale(0.94) translateY(8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

#toast-host {
  position: fixed; left: 50%; bottom: 34px; transform: translateX(-50%);
  z-index: 300; display: flex; flex-direction: column; gap: 8px;
  align-items: center; pointer-events: none;
}
.toast {
  background: rgba(28, 28, 30, 0.94); color: #fff;
  border-radius: 999px; padding: 9px 20px; font-size: 13.5px; font-weight: 500;
  box-shadow: var(--shadow-md); animation: pop 0.22s var(--ease);
  display: flex; align-items: center; gap: 8px;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.toast.err { background: rgba(200, 38, 30, 0.95); }
.toast.ok  { background: rgba(28, 28, 30, 0.94); }

.empty {
  text-align: center; padding: 44px 20px; color: var(--text-3); font-size: 13.5px;
}
.empty svg { margin: 0 auto 12px; color: var(--fill-strong); }

.skeleton {
  background: linear-gradient(90deg, var(--fill-2) 25%, var(--fill) 37%, var(--fill-2) 63%);
  background-size: 400% 100%; animation: sk 1.4s ease infinite;
  border-radius: var(--r-xs); color: transparent;
}
@keyframes sk { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ==================================================================
   登录页
   ================================================================== */
.login-page {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 24px; background: var(--bg);
}
.login-card {
  width: 100%; max-width: 380px;
  background: var(--bg-elev); border-radius: var(--r-xl);
  padding: 38px 32px 30px; box-shadow: var(--shadow-lg);
  border: 1px solid var(--line-2);
}
.login-mark { width: 46px; height: 46px; color: var(--accent); margin: 0 auto 18px; }
.login-title { font-size: 22px; font-weight: 700; text-align: center; letter-spacing: -0.03em; }
.login-sub {
  font-size: 13px; color: var(--text-2); text-align: center;
  margin: 6px 0 26px; line-height: 1.6;
}
.login-form { display: flex; flex-direction: column; gap: 12px; }
.login-foot {
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line-2);
  font-size: 12px; color: var(--text-3); line-height: 1.9; text-align: center;
}

/* ==================================================================
   账号设置
   ================================================================== */
.strength { display: flex; gap: 5px; margin-top: 9px; }
.strength i {
  flex: 1 1 0; height: 5px; border-radius: 999px;
  background: var(--fill); transition: background 0.22s var(--ease);
}
.strength.lv1 i:nth-child(-n+1) { background: var(--red); }
.strength.lv2 i:nth-child(-n+2) { background: var(--orange); }
.strength.lv3 i:nth-child(-n+3) { background: var(--green); }
.strength.lv4 i { background: var(--green); }

.req-list { display: flex; flex-direction: column; gap: 6px; margin-top: 13px; }
.req {
  display: flex; align-items: center; gap: 7px;
  font-size: 12.5px; color: var(--text-3); transition: color 0.18s var(--ease);
}
.req svg { flex: 0 0 auto; }
.req.ok { color: var(--green); }

.pwd-err {
  margin-top: 13px; font-size: 12.5px; color: var(--red);
  line-height: 1.6; display: flex; gap: 7px; align-items: flex-start;
}
.pwd-err svg { flex: 0 0 auto; margin-top: 1px; }

/* 首次登录强制改密的提示条 */
.notice {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--accent-soft); border: 1px solid var(--accent);
  border-radius: var(--r-lg); padding: 15px 18px; margin-bottom: 14px;
}
.notice .notice-icon { flex: 0 0 auto; color: var(--accent); }
.notice .notice-title { font-size: 14px; font-weight: 600; margin-bottom: 3px; }
.notice .notice-text { font-size: 12.5px; color: var(--text-2); line-height: 1.65; }

.user-chip.static { cursor: default; }
.user-chip.static:hover { background: var(--fill); }

/* ==================================================================
   账号管理 / 权限分配
   ================================================================== */
.sheet-wide { max-width: 560px; }

/* 勾选行：原生 checkbox 藏起来，用自绘方框，保持苹果风格的一致性 */
.switch-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 11px; border-radius: var(--r-sm);
  background: var(--fill-2); cursor: pointer;
  transition: background 0.16s var(--ease);
}
.switch-row:hover { background: var(--fill); }
.switch-row input {
  position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0;
}
.switch-box {
  flex: 0 0 auto; width: 19px; height: 19px; margin-top: 1px;
  border-radius: 6px; border: 1.6px solid var(--line-2);
  background: var(--bg-elev); position: relative;
  transition: background 0.16s var(--ease), border-color 0.16s var(--ease);
}
.switch-box::after {
  content: ''; position: absolute; left: 6px; top: 2px;
  width: 5px; height: 10px; border: solid #fff;
  border-width: 0 2px 2px 0; transform: rotate(45deg) scale(0.4);
  opacity: 0; transition: opacity 0.16s var(--ease), transform 0.16s var(--ease);
}
.switch-row input:checked ~ .switch-box { background: var(--accent); border-color: var(--accent); }
.switch-row input:checked ~ .switch-box::after { opacity: 1; transform: rotate(45deg) scale(1); }
.switch-row input:focus-visible ~ .switch-box { box-shadow: 0 0 0 3px var(--accent-soft); }
.switch-row input:checked ~ .switch-text b { color: var(--accent); }
.switch-text { min-width: 0; }
.switch-text b { display: block; font-size: 13.5px; font-weight: 550; }
.switch-text i {
  display: block; font-style: normal; font-size: 11.5px;
  color: var(--text-3); line-height: 1.55; margin-top: 2px;
}

.perm-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin: 20px 0 10px; padding-top: 16px; border-top: 1px solid var(--line-2);
  font-size: 13px; font-weight: 600;
}
.perm-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.perm-presets .btn.sm { padding: 4px 9px; font-size: 12px; }
.perm-grid { display: flex; flex-direction: column; gap: 14px; }
.perm-group-title {
  font-size: 11.5px; color: var(--text-3); margin-bottom: 7px;
  letter-spacing: 0.04em;
}
.perm-group .switch-row + .switch-row { margin-top: 6px; }

.field-hint { font-size: 11.5px; color: var(--text-3); margin-top: 6px; line-height: 1.55; }

/* 接收消息（回调）设置：步骤写成有序列表 —— 这里顺序不能错，
   配错一步只会在企业微信那边得到一句「验证失败」，排查成本很高。
   地址与「复制」按钮同一行，输入框可伸缩、按钮不换行。 */
.cb-steps { margin: 4px 0 0; padding-left: 20px; }
.cb-steps li { font-size: 12.5px; color: var(--text-2); line-height: 1.75; }
.cb-steps li b { color: var(--text); font-weight: 500; }
.cb-copy { display: flex; align-items: center; gap: 8px; }
.cb-copy .input {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
}
.cb-copy .btn { flex: 0 0 auto; }

@media (max-width: 560px) {
  .cb-copy { flex-wrap: wrap; }
  .cb-copy .input { flex: 1 1 100%; }
}

/* ---------- 推送页的两列布局 ----------
   这一页原来七张卡片一路竖着排下来，滚三四屏才到底。改成两列之后：
   左边是「要填的」（配置、文案预览），右边是「要看的、要点一下的」（接收消息、发送记录）。
   配置那张卡很高，右边两张矮卡叠在一列正好把高度补齐。
   窄屏（≤1080px）自动退回单列，手机上仍是原来从上到下的顺序。 */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 14px; align-items: start; margin-top: 14px;
}
.split > .col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.split .card { margin-top: 0; }
@media (max-width: 1080px) {
  .split { grid-template-columns: 1fr; }
}

/* 同一张卡里分两段（手动操作 / 推送记录）时的细分割线 */
.card-split { height: 1px; background: var(--line-2); margin: 16px 0; }

/* ---------- 折叠与「加载更多」 ----------
   日志类列表不再一次全铺在页面上：默认只露前几条，其余折起来。
   折的是 display，不是数据 —— 展开是纯前端的事，不再打一次接口。 */
.list .fold-hidden { display: none; }
.list.expanded .fold-hidden { display: flex; }
.more-row { display: flex; justify-content: center; margin-top: 12px; }

/* 推送文案预览 / 推送记录详情：按原文展示。
   用等宽字体是有意的 —— 这里要让人看清 markdown 标记和换行位置，
   而不是假装它已经是渲染后的样子。 */
.msg-preview {
  background: var(--bg-sunken);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 14px 16px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text);
  max-height: 420px;
  overflow: auto;
}
/* 弹层里的预览在下拉时容易顶到底部按钮，收紧一点 */
.sheet .msg-preview { max-height: 46vh; margin-bottom: 4px; }

/* ==================================================================
   表格导入（录入页 ← 门店汇总表）
   ================================================================== */

/* 默认弹窗宽 460px，11 个指标列根本摆不下，这里单独放宽 */
.sheet.imp-sheet { max-width: 1100px; }

.imp-pick { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.imp-pick .btn { flex: 0 0 auto; cursor: pointer; }
.imp-fname {
  font-size: 12.5px; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.imp-hint { padding: 16px 2px; font-size: 13px; color: var(--text-2); }
.imp-hint.err { display: flex; gap: 8px; align-items: flex-start; color: var(--red); }

/* 提示不是装饰：导入最怕的是「数字悄悄少了一块」，
   所以有话要说的时候就得显眼，不能做成一行灰字让人划过去 */
.imp-warn {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 11px 13px; margin-bottom: 12px;
  border: 1px solid var(--orange); border-radius: var(--r-sm);
  background: var(--orange-soft); color: var(--text);
  font-size: 12.5px; line-height: 1.7;
}
.imp-warn > svg { flex: 0 0 auto; margin-top: 2px; }

.imp-stat { font-size: 12.5px; color: var(--text-2); margin-bottom: 10px; line-height: 1.7; }

/* 对账条：明细现算 vs 表内自带的分类合计页。
   这不是装饰 —— 它是对「我算得对不对」唯一的外部证据，所以要一眼看得见。 */
.imp-recon {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-bottom: 12px; font-size: 12px; color: var(--text-2);
}
.imp-recon .rc {
  padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--green); color: var(--text-2);
}
.imp-recon .rc-bad {
  border-color: var(--orange); color: var(--text);
  background: var(--orange-soft); font-weight: 600;
}
.imp-bad { color: var(--orange); font-weight: 600; }

/* 这份表的来源：导出时间 + 表内日期。
   「手上这份是不是旧文件」不该靠人记 —— 门店 DMS 每个页签的第 2 行就写着导出时间。 */
.imp-src {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 9px 12px; margin-bottom: 10px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg-sunken);
  font-size: 12.5px; color: var(--text-2); line-height: 1.7;
}
.imp-src > svg { flex: 0 0 auto; margin-top: 2px; color: var(--text-3); }
.imp-src-tip { color: var(--text-3); }

/* 与库里已存同一天数据的差异。
   保存是覆盖式的，旧值会被默默换掉 —— 不把两边摆出来，就没人知道数变过。 */
.imp-diff {
  margin-bottom: 10px;
  border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden;
}
.imp-diff-h {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 9px 12px; background: var(--orange-soft);
  font-size: 12.5px; color: var(--text-2); line-height: 1.7;
}
.imp-diff-h > svg { flex: 0 0 auto; margin-top: 2px; color: var(--orange); }
.imp-diff-list { max-height: 208px; overflow: auto; }
.imp-diff-row {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr) auto 14px auto;
  gap: 10px; align-items: baseline;
  padding: 6px 12px; border-top: 1px solid var(--line-2);
  font-size: 12.5px; font-variant-numeric: tabular-nums;
}
.imp-diff-who { font-weight: 600; color: var(--text); }
.imp-diff-m { color: var(--text-2); }
.imp-diff-was { color: var(--text-3); text-align: right; }
.imp-diff-arrow { color: var(--text-3); text-align: center; }
.imp-diff-now { font-weight: 600; text-align: right; color: var(--text); }
.imp-diff-more {
  padding: 6px 12px; border-top: 1px solid var(--line-2);
  font-size: 12px; color: var(--text-3);
}
.imp-diff-ok {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 9px 12px; margin-bottom: 10px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: 12.5px; color: var(--text-2); line-height: 1.7;
}
.imp-diff-ok > svg { flex: 0 0 auto; margin-top: 2px; color: var(--green); }
@media (max-width: 640px) {
  .imp-diff-row { grid-template-columns: minmax(0, 1fr) auto 12px auto; }
  .imp-diff-m { display: none; }
}

.imp-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-sm); }
.imp-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.imp-table th, .imp-table td { padding: 7px 10px; white-space: nowrap; }
.imp-table thead th {
  background: var(--bg-sunken); border-bottom: 1px solid var(--line);
  font-weight: 600; color: var(--text-2); text-align: right;
}
.imp-table thead th.imp-from { text-align: left; }
.imp-table tbody tr { border-bottom: 1px solid var(--line-2); }
.imp-table tbody tr:last-child { border-bottom: 0; }
.imp-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.imp-from { color: var(--text-2); }
.imp-zero { color: var(--text-3); }

/* 对不上系统顾问的那几行要一眼看见 —— 它们默认不会被导入 */
.imp-table tr.imp-unmatched { background: var(--orange-soft); }
.imp-table tr.imp-unmatched .imp-from { color: var(--text); font-weight: 600; }

.imp-sel { min-width: 118px; font-size: 12.5px; padding: 4px 6px; }

.imp-rules { margin-top: 12px; font-size: 12.5px; color: var(--text-2); }
.imp-rules > summary { cursor: pointer; user-select: none; }
.imp-rule {
  margin-top: 7px; padding: 2px 0 2px 12px;
  border-left: 2px solid var(--line); line-height: 1.7;
}
.imp-rule > b { color: var(--text); font-weight: 600; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; background: var(--fill); padding: 1px 5px; border-radius: 5px;
}

/* 数据录入：已保存且无修改权限的行，锁住并压暗，避免误以为能改 */
.matrix tr.locked { background: var(--fill-2); }
.matrix tr.locked input.cell {
  color: var(--text-3); opacity: 0.75; cursor: not-allowed;
}
.matrix tr.locked input.cell.filled { background: var(--fill-2); }

/* ---------- 列分组着色 ----------
   四类指标各给一种颜色，录入时不用反复数格子确认自己填的是哪一栏。
   data-g 的取值与后端 src/metrics.js 的 group 字段一致（count/output/negative/prepaid）。
   色相只用四支：蓝=台次、绿=产值、红=负产值、紫=增值预收；
   「合计」列保持中性灰，避免和原始指标抢注意力。 */
table.matrix thead tr.grp th[data-g="count"]    { background: var(--accent-soft); color: var(--accent); }
table.matrix thead tr.grp th[data-g="output"]   { background: var(--green-soft);  color: var(--green); }
table.matrix thead tr.grp th[data-g="negative"] { background: var(--red-soft);    color: var(--red); }
table.matrix thead tr.grp th[data-g="prepaid"]  { background: var(--purple-soft); color: var(--purple); }
table.matrix thead tr.grp th[data-g="total"]    { background: var(--fill); color: var(--text-2); }

/* 列标题下沿再用同色画一条细线，把色带从分组标题延续到具体指标名上 */
table.matrix thead tr.col th[data-g="count"]    { border-bottom: 2px solid var(--accent); }
table.matrix thead tr.col th[data-g="output"]   { border-bottom: 2px solid var(--green); }
table.matrix thead tr.col th[data-g="negative"] { border-bottom: 2px solid var(--red); }
table.matrix thead tr.col th[data-g="prepaid"]  { border-bottom: 2px solid var(--purple); }

/* ---------- 录入交叉高亮 ----------
   光标落进某个格子时，整行与整列一起提亮，形成十字定位。
   宽表录入最容易出的错就是「看着这一行、填到了上一行」，
   十字定位能把这个错扼杀掉。类由 JS 挂载（见 app.js 的 bindCrosshair），
   不用 :has()，避免依赖较新的浏览器。 */
table.matrix tbody tr.hl-row > td,
table.matrix tbody tr.hl-row > th.sticky { background: var(--accent-soft); }
table.matrix tbody td.hl-col,
table.matrix tfoot td.hl-col,
table.matrix thead tr.col th.hl-col { background: var(--accent-soft); color: var(--accent); }
/* 表头分组条上再压一道该组颜色的下划线，指明「这一列属于哪一组」 */
table.matrix thead tr.grp th.hl-grp { box-shadow: inset 0 -2px 0 currentColor; }
/* 当前格子自己保持白底 + 蓝色描边，是十字的中心 */
table.matrix tbody tr.hl-row > td.hl-focus { background: transparent; }

/* ==================================================================
   数据查询（录入页 → 区间汇总）
   ================================================================== */

/* 11 个指标 + 4 个合计列，默认 460px 的弹窗根本摆不下，和导入弹层一样放宽 */
.sheet.q-sheet { max-width: 1120px; }

.q-range { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 16px; }
.q-quick { display: flex; flex-wrap: wrap; gap: 6px; }
.q-dates { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.q-dates .input { width: auto; }
.q-tilde { font-size: 12.5px; color: var(--text-3); }

/* 一句一行。「有几天没数据」「合计不含谁」这类话必须看得见 ——
   区间的数看着永远很正常，少录几天不会有任何报错。 */
.q-stat { display: flex; flex-direction: column; gap: 3px; margin-bottom: 12px; }
.q-stat > span::before { content: '·'; color: var(--text-3); margin-right: 6px; }

/* 五张卡一行。窄屏由响应式那节的 .g4 规则降到两列 */
.q-kpis { grid-template-columns: repeat(5, minmax(0, 1fr)); margin-bottom: 14px; }
.q-kpis .kpi-value { font-size: 21px; }

.q-scroll { overflow: auto; max-height: 52vh; border: 1px solid var(--line); border-radius: var(--r-sm); }
/* 表头/合计行要 sticky，而 sticky 与 border-collapse: collapse 不共存，
   所以这里用 separate + 零间距 */
.q-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; }
.q-table th, .q-table td { padding: 7px 10px; white-space: nowrap; }
.q-table thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--bg-sunken); border-bottom: 1px solid var(--line);
  font-weight: 600; color: var(--text-2); text-align: right;
}
.q-table thead th .q-u { color: var(--text-3); font-weight: 400; }

/* 顾问列左右都钉住：横滚到第 12 列时，还得知道这一行是谁 */
.q-table .q-name {
  position: sticky; left: 0; z-index: 3;
  background: var(--bg-elev); text-align: left; font-weight: 600;
}
.q-table thead .q-name { z-index: 4; background: var(--bg-sunken); }
.q-table tbody th, .q-table tbody td { border-bottom: 1px solid var(--line-2); }
.q-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.q-table tbody tr:hover th, .q-table tbody tr:hover td { background: var(--fill-2); }
/* 区间内一条都没录的顾问：整行压暗，免得和「真的录了 0」混在一起 */
.q-table tr.q-empty th, .q-table tr.q-empty td { color: var(--text-3); }

.q-sep { border-left: 1px solid var(--line); }
.q-negcol { background: var(--fill-2); }
.q-neg { color: var(--red); }

/* 「实收产值」是这一页真正要看的那个数，钉在表格右侧 ——
   11 个原始指标横着放不下，不钉住的话它永远在滚动视野之外。
   sticky 列的底色必须不透明，否则会透出下面滚过去的内容（hover 时也一样）；
   左侧一道阴影是必需的：没有它，被它盖住半截的那一列看着像渲染坏了。 */
.q-table .q-net {
  position: sticky; right: 0; z-index: 3;
  background: var(--bg-elev); font-weight: 600;
  border-left: 1px solid var(--line);
  box-shadow: -7px 0 9px -7px rgba(0, 0, 0, 0.22);
}
.q-table thead .q-net { z-index: 4; background: var(--bg-sunken); }
.q-table tbody tr:hover .q-net { background: var(--bg-elev); }
.q-table tfoot .q-sum .q-net { z-index: 4; background: var(--bg-sunken); }

.q-table tfoot .q-sum th, .q-table tfoot .q-sum td {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--bg-sunken); border-top: 1px solid var(--line); font-weight: 700;
}
.q-table tfoot .q-sum .q-name { background: var(--bg-sunken); z-index: 3; }

@media (max-width: 820px) {
  /* 手机上日期选择器自己占一行，不再往右推 */
  .q-dates { margin-left: 0; width: 100%; }
}

/* ==================================================================
   数据查询页：分项排名
   ==================================================================
   排名比的是**目标完成率**（实际完成 ÷ 本人月度目标），不是绝对数 ——
   各人目标不一样，比绝对数等于比谁的盘子大。条形就画完成率本身，
   铺满即达标（100%），所以「谁做得好」不用看数字也能一眼扫出来。 */
.q-bar { padding: 13px 16px; }
.q-bar .q-range { margin-bottom: 0; }
.q-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }

.rank { margin-top: 14px; }
.rank-head { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.rank-title { display: flex; align-items: center; gap: 7px; font-size: 15px; font-weight: 650; }
.rank-title svg { color: var(--accent); flex: 0 0 auto; }
.rank-dim {
  font-size: 12px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); padding: 2px 9px; border-radius: 999px;
}
.rank-sub { font-size: 12.5px; color: var(--text-2); line-height: 1.6; }

.rank-dims { display: flex; flex-direction: column; gap: 7px; margin-bottom: 12px; }
.rk-group { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rk-gname { flex: 0 0 auto; width: 32px; font-size: 11.5px; color: var(--text-3); }
.rk-btn {
  font: inherit; font-size: 12.5px; padding: 4px 12px; cursor: pointer;
  border-radius: 999px; border: 1px solid var(--line);
  background: var(--bg-elev); color: var(--text-2);
  transition: background .15s, color .15s, border-color .15s;
}
.rk-btn:hover { border-color: var(--accent); color: var(--text); }
.rk-btn.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

.rank-kpi {
  display: flex; flex-wrap: wrap; gap: 5px 18px; margin-bottom: 12px;
  font-size: 12.5px; color: var(--text-3);
}
.rank-kpi b { color: var(--text); font-variant-numeric: tabular-nums; }

.rank-list { display: flex; flex-direction: column; gap: 3px; }
.rk-row {
  display: grid; align-items: center; gap: 10px;
  /* 名次｜顾问｜条｜实际｜目标｜完成率 —— 六列。
     条形是可伸缩的那一列，三列数字给固定宽度：位数一变整列就在抖，
     扫读一排完成率的时候特别累。 */
  grid-template-columns: 26px minmax(56px, 96px) minmax(0, 1fr) 104px 104px 74px;
  padding: 5px 8px; border-radius: var(--r-sm);
}
.rk-row:hover { background: var(--fill-2); }
/* 列表的表头：六个列里哪个是实际、哪个是目标，没有这一行只能靠猜。
   padding 收窄、去掉 hover 底色，免得看着像一条数据。 */
.rk-hd {
  font-size: 11.5px; color: var(--text-3); padding: 0 8px 3px;
  border-bottom: 1px solid var(--line-2); margin-bottom: 2px;
}
.rk-hd:hover { background: none; }
.rk-no {
  font-size: 11.5px; font-weight: 700; color: var(--text-3);
  text-align: center; font-variant-numeric: tabular-nums;
}
.rk-no.top { color: var(--accent); }
.rk-name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rk-bar { display: block; height: 14px; border-radius: 4px; background: var(--fill-2); overflow: hidden; }
.rk-bar > i { display: block; height: 100%; border-radius: 4px; background: var(--green); }
.rk-val { font-size: 13px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.rk-tgt { font-size: 12.5px; text-align: right; color: var(--text-3); font-variant-numeric: tabular-nums; }
.rk-rate { font-size: 13px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }

/* 完成率高于全店完成率 = 做得好（绿）；低于 = 可以再加把劲（橙）。
   用橙而不是红：低于全店不是错误，红是留给「负产值」「配置坏了」那类事的。 */
.rk-row.up .rk-bar > i { background: var(--green); }
.rk-row.up .rk-rate { color: var(--green); }
.rk-row.down .rk-bar > i { background: var(--orange); }
.rk-row.down .rk-rate { color: var(--orange); }
.rk-row.zero { opacity: .55; }
.rk-row.zero .rk-bar > i { background: var(--line); }
/* 「这几个人这一项没设目标」的分隔说明：不解释一句，
   他们就会看着像被人为压到榜底 */
.rk-sep {
  font-size: 11.5px; color: var(--text-3); line-height: 1.6;
  padding: 9px 8px 3px; margin-top: 6px; border-top: 1px dashed var(--line);
}
.rk-sep b { color: var(--text-2); }

@media (max-width: 820px) {
  /* 窄屏收掉「目标」列：留着它完成率就会被挤到换行。
     实际数与完成率留着 —— 那两个是这一屏真正要看的东西。 */
  .rk-row { grid-template-columns: 22px minmax(48px, 74px) minmax(0, 1fr) 88px 68px; gap: 8px; }
  .rk-tgt { display: none; }
  .rk-gname { width: 100%; }
}

/* ==================================================================
   响应式
   ================================================================== */
@media (max-width: 1080px) {
  .g-hero { grid-template-columns: 1fr; }
  .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .main { padding: 16px 14px 56px; }
  .nav-inner { padding: 0 14px; gap: 10px; }
  .seg-scroll { padding: 8px 14px; }
  .page-title { font-size: 22px; }
  .g3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .brand-name { display: none; }
  .user-name { display: none; }
  .user-chip { padding: 5px 6px; }
  .card { padding: 15px 16px; border-radius: var(--r-md); }
  .ring-wrap { gap: 16px; }
  .ring-num { font-size: 25px; }
  .kpi-value { font-size: 23px; }
}
@media (max-width: 560px) {
  .g2, .g3 { grid-template-columns: 1fr; }
  /* KPI 卡较紧凑，手机上保留两列，避免页面被拉得过长 */
  .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .g4 .kpi-value { font-size: 19px; }
  .month-picker .m-label { min-width: 74px; font-size: 12.5px; }
  .toolbar > .field { flex: 1 1 100%; }
  .toolbar .btn { flex: 1 1 auto; }
  .ring-wrap { flex-direction: column; align-items: flex-start; }
}

/* ---------- TMCI 同期台次进度 ---------- */
/* 条形右端 = 100% = 追平去年同月整月；通栏竖线 = 时间进度。
   判定沿用看板那一套（达成率 − 时间进度），颜色与别处一致，
   不另立一套「同比红绿」。 */
.tmci .tm-row {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) 54px 68px 58px 70px;
  gap: 10px;
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid var(--line-2);
  font-size: 12.5px;
}
.tmci .tm-hd {
  font-size: 11.5px;
  color: var(--text-3);
  padding-bottom: 7px;
  border-bottom: 1px solid var(--line-2);
}
.tmci .tm-hd span { text-align: right; }
.tmci .tm-hd span:first-child,
.tmci .tm-hd span:nth-child(2) { text-align: left; }
.tmci .tm-name { color: var(--text); }
.tmci .tm-num { text-align: right; font-variant-numeric: tabular-nums; }
.tmci .tm-base { color: var(--text-2); }
.tmci .tm-bar {
  position: relative;
  display: block;
  height: 16px;
  border-radius: 5px;
  background: var(--fill);
}
.tmci .tm-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  display: block;
  border-radius: 5px;
}
.tmci .tm-mark {
  position: absolute;
  top: -3px; bottom: -3px;
  width: 2px;
  display: block;
  border-radius: 1px;
  background: var(--text);
  opacity: .8;
}
.tmci .tm-fill.green { background: var(--green); }
.tmci .tm-fill.amber { background: var(--orange); }
.tmci .tm-fill.red { background: var(--red); }
.tmci .tm-fill.none { background: var(--fill-strong); }
.tmci .tm-rate.green, .tmci .tm-diff.green { color: var(--green); }
.tmci .tm-rate.amber, .tmci .tm-diff.amber { color: var(--orange); }
.tmci .tm-rate.red, .tmci .tm-diff.red { color: var(--red); }
.tmci .tm-rate.none, .tmci .tm-diff.none { color: var(--text-3); }
.tmci .tm-sum { border-top: 1px solid var(--line); border-bottom: 0; padding-top: 11px; }
.tmci .tm-sum .tm-name, .tmci .tm-sum .tm-num { font-weight: 600; }
.tmci .tm-foot {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line-2);
  font-size: 12px;
  color: var(--text-2);
  line-height: 1.65;
}

@media (max-width: 900px) {
  /* 窄屏六列放不下：把「差额」收掉（达成率与时间线已经能看出跟没跟上），其余保留 */
  .tmci .tm-row { grid-template-columns: 64px minmax(0, 1fr) 48px 58px 52px; gap: 8px; }
  .tmci .tm-row > :nth-child(6) { display: none; }
}

/* 同期基期表：当前查看月份对应那一行（去年同月）高亮，
   否则对着 12 行不知道该关心哪一个 */
#base-table tr.cur > th,
#base-table tr.cur > td { background: var(--accent-soft); }

@media print {
  .nav, .seg-wrap, .toolbar, .btn { display: none !important; }
  body { background: #fff; }
  .card { box-shadow: none; border: 1px solid #ddd; }
}
