/* ==========================================================================
   达播工作台 — components.css
   按钮 / 输入 / 徽章 / 卡片
   ========================================================================== */

/* ---- 按钮 ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 36px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  white-space: nowrap;
  transition: background-color var(--motion-fast) var(--motion-ease-standard),
    color var(--motion-fast) var(--motion-ease-standard),
    border-color var(--motion-fast) var(--motion-ease-standard),
    transform var(--motion-fast) var(--motion-ease-standard),
    box-shadow var(--motion-fast) var(--motion-ease-standard);
}

.btn:hover:not(:disabled) {
  background: var(--color-surface-2);
}

.btn:active:not(:disabled) {
  /* ⚠️ 原来这里是 `background: var(--color-surface-2)` —— **与 .btn:hover 完全相同**，
     等于按下没有任何视觉变化（hover/pressed 不可区分，违反 ui-ux-pro-max
     「state-clarity：hover/pressed/disabled 三态必须可区分」+「press-feedback」）。
     改为深一档（gray-100）+ 极轻缩放：缩放用 transform，不触发重排（transform-performance）。 */
  background: var(--color-gray-100);
  transform: scale(0.985);
}

.btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn--lg {
  height: 44px;
  padding: 0 var(--space-5);
}

.btn--sm {
  height: 30px;
  padding: 0 var(--space-3);
  font-size: var(--font-size-sm);
}

.btn--primary {
  background: var(--button-primary-bg);
  color: var(--button-primary-fg);
}

.btn--primary:hover:not(:disabled) {
  background: var(--button-primary-hover);
}

.btn--primary:active:not(:disabled) {
  background: var(--button-primary-active);
}

.btn--secondary {
  background: var(--button-secondary-bg);
  color: var(--button-secondary-fg);
  border-color: var(--button-secondary-border);
}

.btn--secondary:hover:not(:disabled) {
  border-color: var(--color-accent-text);
  background: var(--color-primary-50);
}

.btn--ghost {
  background: var(--button-ghost-bg);
  color: var(--button-ghost-fg);
  border-color: var(--color-border);
}

.btn--ghost:hover:not(:disabled) {
  background: var(--color-surface-2);
  border-color: var(--color-gray-400);
}

/* ==========================================================================
   费用大类的语义色按钮（2026-09-18 乐哥拍板）
   --------------------------------------------------------------------------
   用途：批量操作栏的三个归属按钮（达人溯源直播 / 商务BD / 其他费用），
   让「按钮颜色」与「列表标签颜色」是同一套 —— 用户在勾选维护时，
   看到的色相与他在列表里认出的大类一致，不需要重新学一套。

   ⚠️ 色值不在 CSS 里写死，由 JS 通过 --scope-fg / --scope-bg 注入，
      来源唯一（dict.js 的 Dict.expenseScopeStyle）——
      色义规则写在那边，这里只负责"怎么用"。
      两处各写一份色值就会出现"按钮是绿、标签是蓝"的静默不一致。
   ⚠️ 底色用浅底（--scope-bg）：整排彩色按钮若用实心色会过分抢眼，
      抢掉真正该被注意的金额与异常状态；实心色只留给"选中态"（见 .seg__btn--scope）。
   ========================================================================== */
.btn--scope {
  color: var(--scope-fg, var(--color-fg-2));
  background: var(--scope-bg, transparent);
  border-color: var(--scope-bg, var(--color-border));
}

.btn--scope:hover:not(:disabled) {
  background: var(--scope-bg, var(--color-surface-2));
  border-color: var(--scope-fg, var(--color-gray-400));
}

/* 分段选项的语义色选中态：选中的那一项用**它自己的归属色**做实心底 + 白字。
   用途：行内「费用归属」弹窗的选项（达人溯源直播/商务BD/其他费用…）——
   用户点开一条记录时，一眼看出"当前这笔算什么"。 */
.seg__btn--scope.is-active {
  background: var(--scope-fg, var(--color-accent));
  color: #FFFFFF;
}

.btn--danger {
  background: var(--button-danger-bg);
  color: var(--button-danger-fg);
}

.btn--danger:hover:not(:disabled) {
  /* 必须显式保持红色背景：否则会被 .btn:hover 的 background:surface-2 覆盖，白字在浅灰底上看不清 */
  background: var(--button-danger-bg);
  filter: brightness(0.9);
}

.btn--icon {
  width: 36px;
  padding: 0;
}

/* ---- 输入 / 选择 ---- */
.input,
.select,
.textarea {
  height: 44px;
  padding: 0 var(--space-3);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-md);
  background: var(--input-bg);
  color: var(--color-fg);
  font-size: var(--font-size-base);
  transition: border-color var(--motion-fast) var(--motion-ease-standard),
    box-shadow var(--motion-fast) var(--motion-ease-standard);
}

.textarea {
  height: auto;
  padding: var(--space-2) var(--space-3);
  resize: vertical;
  min-height: 96px;
}

/* 下拉选择框：去掉默认箭头，用自定义向下箭头，离右边框留白避免贴边 */
.select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%238595A4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 12px;
  padding-right: 32px;
}

/* 带下拉提示的输入框（datalist）：去掉浏览器原生黑色箭头，用自定义向下箭头 */
.input[list] {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%238595A4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 12px;
  padding-right: 32px;
}
/* 移除 WebKit 对 datalist 输入框的原生下拉指示器（黑色实心箭头，hover/focus 时出现；必须 !important 覆盖浏览器内置样式） */
.input[list]::-webkit-calendar-picker-indicator {
  display: none !important;
  opacity: 0 !important;
}

/* 数字输入框：去掉上下增减箭头（spinner） */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

.input::placeholder,
.textarea::placeholder {
  color: var(--color-placeholder);   /* #B9C1CC，设计稿占位符色 */
}

.input:focus,
.select:focus,
.textarea:focus {
  outline: none;
  border-color: var(--input-focus-border);
  box-shadow: var(--focus-ring);
}

.input:disabled,
.select:disabled {
  background: var(--input-disabled-bg);
  color: var(--input-disabled-text);
  cursor: not-allowed;
}

/* 可清空下拉（sel-clear）：包一层 wrapper，右侧 ✕ 位于箭头左侧 */
.sel-clear-wrap {
  position: relative;
  display: inline-block;
  width: 100%;
}
.sel-clear-wrap select.sel-clear {
  width: 100%;
  padding-right: 52px; /* 给右侧 ✕ + 原生箭头让位 */
}
.sel-clear-x {
  position: absolute;
  right: 30px; /* 原生箭头在 right 12px 处，✕ 放它左侧 */
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--color-fg-2);
  border-radius: 50%;
  line-height: 1;
}
.sel-clear-x:hover {
  color: var(--color-fg);
  background: var(--color-surface-2);
}

/* 字段级错误态：红边框 + 就近提示 */
.input.is-error,
.select.is-error,
.textarea.is-error {
  border-color: var(--color-danger);
}
.input.is-error:focus,
.select.is-error:focus,
.textarea.is-error:focus {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px var(--color-danger-bg);
}
.field-error {
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-danger);
}
/* 飞书选人组件等复合控件的错误态 */
.is-error .fp__box {
  border-color: var(--color-danger);
}

.input--search {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* 放大镜图标：绝对定位到输入框内部左侧（页面里图标是裸 svg 或 .search-icon 包裹，两种都兼容） */
.input--search .search-icon,
.input--search > svg {
  position: absolute;
  left: var(--space-3);
  z-index: 1;
  color: var(--color-meta);
  pointer-events: none;
  display: inline-flex;
}

.input--search .input,
.input--search .select {
  padding-left: var(--space-8);
}

/* 日期范围筛选：日历图标 + 两个日期选择器 + 「至」分隔，与输入框同高同风格 */
.range-filter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-meta);
}
.range-filter > svg {
  flex-shrink: 0;
  color: var(--color-meta);
}
.range-filter__sep {
  color: var(--color-meta);
  font-size: var(--font-size-sm);
  flex-shrink: 0;
}

/* 密码框：右侧眼睛切换显示/隐藏 */
.input--password {
  position: relative;
  display: flex;
  align-items: center;
}
.input--password .input {
  width: 100%;
  padding-right: var(--space-10);
}
.pwd-toggle {
  position: absolute;
  right: var(--space-1);
  border: none;
  background: none;
  cursor: pointer;
  color: var(--color-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  transition: color var(--motion-fast) var(--motion-ease-standard),
    background-color var(--motion-fast) var(--motion-ease-standard);
}
.pwd-toggle:hover {
  color: var(--color-fg);
  background: var(--color-surface-2);
}
.pwd-toggle:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.field-label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-fg-2);
}

.field-hint {
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}

.field-hint.is-error {
  color: var(--color-danger);
}

/* 字段宽度工具类（按业务语义，替代内联 grid 列比例）：数字窄 / 日期金额中 / 下拉宽 */
.f-w-xs { width: 96px; }
.f-w-sm { width: 140px; }
.f-w-md { width: 220px; }

/* ---- 徽章（深字 + 浅底成对） ---- */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  height: 24px;
  /* 中文字面在行盒内偏上：顶部留 1px、底部 0，视觉上居中 */
  padding: 1px var(--space-2) 0;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  white-space: nowrap;
}

.badge--success { color: var(--badge-success-fg); background: var(--badge-success-bg); }
.badge--warning { color: var(--badge-warning-fg); background: var(--badge-warning-bg); }
.badge--danger  { color: var(--badge-danger-fg);  background: var(--badge-danger-bg); }
.badge--info    { color: var(--badge-info-fg);    background: var(--badge-info-bg); }
.badge--neutral { color: var(--color-fg-2);       background: var(--color-surface-2); }

.badge--outline {
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-fg-2);
}

/* ---- 彩色标签（达人类型 / 平台等，颜色由 JS 通过 --tag-fg/bg 内联注入，无边框对齐 badge 风格） ---- */
.tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 22px;
  /* 同 .badge：顶部留白补偿中文字面偏上，视觉居中 */
  padding: 2px 8px 0;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  line-height: 1;
  white-space: nowrap;
  color: var(--tag-fg, var(--color-fg-2));
  background: var(--tag-bg, var(--color-surface-2));
}
.tag--sm {
  height: 18px;
  padding: 1px 6px 0;
  font-size: var(--font-size-xs);
}

/* ---- 卡片（白底 + 1px 浅描边，无阴影，对齐 Meta 设计语言） ---- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: none;
}

/* ============================================================
   模块卡（全站通用）—— 信息模块的统一容器
   用法：
     <div class="module-card">
       <div class="module-card__head">…</div>                          有状态开关 → 标题栏状态底色
       <div class="module-card__head module-card__head--plain">…</div>  无开关   → 默认色 + 分隔线
       <div class="module-card__title">模块名</div>
     </div>
   规律（重要）：标题栏**有底色就不加线，没底色才用线补分界**；
   状态色只出现在标题栏与状态开关上，不外溢到卡片边框（禁止彩色描边 / 彩色外发光）。
   **间距标准：相邻模块卡之间固定 24px（由卡片自身用 + 选择器保证，不依赖外层容器配置）**。
   ============================================================ */
.module-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card-float);
  padding: var(--space-4);
}
/* 模块间距（标准）：相邻模块卡之间 24px。
   放在卡片自身而不是容器 gap 上 —— 任何容器里都自动生效，不会因为"忘了给容器配 gap"而贴在一起 */
.module-card + .module-card {
  margin-top: var(--space-6);
}
/* 表格类模块卡（通栏变体）：卡内是「工具栏 + 表格」，两者**自带内边距**，
   所以卡片自身不留内边距 —— 观感与全站表格页一致，也**不挤压表格的可用宽度**
   （订单明细/商品汇总这类表的列宽是按容器宽度抠过的，多 32px 内缩就会让长商品名折行）。
   用法：<div class="module-card module-card--flush">…</div> 后直接放 .table-toolbar / .table-wrap。
   注意：卡内**不要**再用 .card（那会套两层白底）。 */
.module-card--flush {
  padding: 0;
  overflow: hidden; /* 让内部表格/工具栏跟随卡片圆角裁切 */
}
/* flush 卡没有内边距 → 标题栏不需要负 margin 抵消；顶部圆角回到卡片圆角本身 */
.module-card--flush > .module-card__head {
  margin: 0;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
/* 无内容体变体：卡内只有标题栏、没有正文（如排期页「大概排期」开关关闭时）。
   必须**同时**清掉标题栏的 margin-bottom 与卡片 padding-bottom —— 两者相加是 28px 空隙，
   留着的后果是卡片下沿多出一块空白、与下方内容视觉粘连（2026-09-15 乐哥反馈「排期展示有问题」）。
   顺带去掉标题栏的下分隔线：没有内容就没有分界的必要，留着会紧贴卡片底边像多画了一条线。 */
.module-card--bodyless {
  padding-bottom: 0;
}
.module-card--bodyless > .module-card__head {
  margin-bottom: 0;
  border-bottom: none;
}
/* 去卡片化变体（2026-09-15）：用于「一行分组标题 + 一行内容」这类**轻量区块**。
   乐哥原话：「大概排期就不要那个底了，直接和下面的板块一根线隔开就行，然后上下间距大点」。
   改前：整块是浮影卡片（白底 + 阴影 + 圆角 + 16px 内边距），与下方板块是「两个盒子」的关系；
   改后：去掉底（背景 / 阴影 / 圆角 / 内边距），退化为「标题行 + 内容」，
   用**一条分隔线**与下方断开 —— 与详情页 `.detail-block` 的视觉语言一致。
   做成通用变体而不是就地 hack：这类"轻量分组"在表单页会反复出现。

   ⚠️ 分隔线放在**整块的下沿**（border-bottom），**不是**标题行下面：
      语义是"这一组到此结束"；放标题下方会被读成"标题栏的装饰线"，与分组无关。 */
.module-card--bare {
  background: none;
  box-shadow: none;
  border-radius: 0;
  padding: 0 0 var(--space-6); /* 分隔线**上方**的留白（下方的留白由后继元素自己的 margin-top 给） */
  border-bottom: 1px solid var(--color-border);
}
/* 内边距归零后，标题栏不需要负 margin 抵消；底色与它自带的分隔线也一并去掉（线已挪到整块下沿）。
   ⚠️ 但**上内边距要保留** `--space-3`（2026-09-15 收尾实测发现）：
      普通卡的标题靠 `.module-card__head` 自身的 `padding-top: --space-3` 把文字压到
      「卡片顶 + 12px」；`--plain` 版的原实现把 padding 一并清零 →
      同一页里两个 tab 的标题文字顶差 3px、区块起点差 8px，切 tab 时标题会"跳"。
      去卡片化要去的是**底**（背景/阴影/圆角）和**线的位置**，不是标题行的呼吸。
      左右仍为 0：bare 块没有底色盒，标题与它自己的内容必须共享同一条左基线。 */
.module-card--bare > .module-card__head {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) 0 0;
  background: none;
  border-radius: 0;
  border-bottom: 0;
  min-height: 0;
}
/* 无内容体（开关关闭）时高度只剩标题行 —— 底部留白要收窄，否则线上方吊着一段空白。
   与 --bodyless 同一个诉求（"没有内容就别留内容的位置"），故两条变体合并处理。
   ⚠️ 必须用**双类**选择器：单类 `.module-card--bare` 与 `.module-card--bodyless` 特异性相同(0,1,0)，
      谁写在后面谁赢 —— 靠源码顺序"碰巧生效"是最脆的那种写法，显式提高特异性才稳。 */
.module-card--bodyless.module-card--bare {
  padding-bottom: var(--space-4);
}
.module-card--bodyless.module-card--bare > .module-card__head {
  margin-bottom: 0;
}
/* 模块卡内的二级区块（同一趴里的子分组，如佣金配置卡内的「排期单独维护」）：
   与上方内容用一条浅分隔线断开，标题用 .detail-section__title */
.module-card__sub {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border-soft);
}
/* 标题栏：通栏（负 margin 抵消卡片内边距，四角跟随卡片圆角） */
.module-card__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin: calc(var(--space-4) * -1) calc(var(--space-4) * -1) var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-head-off-bg);
  border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0;
}
/* 开启态：标题栏底色/字色切到"黄"。
   两种写法都要认 —— 有的页面把 is-on 加在标题栏自身（schedule-form.js），
   有的加在外层卡片上（influencer-detail.js / schedule-detail.js）。
   只认前者的话，后两处的"单独维护"会落到默认的关闭态绿底，语义正好相反（2026-09-10 排查发现）。 */
.module-card__head.is-on,
.module-card.is-on > .module-card__head {
  background: var(--color-head-on-bg);
}
/* 标题行内的开关：靠右，并清掉开关自带的上下外边距 */
.module-card__head .switch {
  margin-left: auto;
  margin-top: 0;
  margin-bottom: 0;
}
.module-card__title {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-head-off-fg);
}
.module-card__head.is-on .module-card__title,
.module-card.is-on > .module-card__head .module-card__title {
  color: var(--color-head-on-fg);
}
/* 无开关 / 无状态的模块：标题栏默认色（不着色），用一条分隔线与内容区分 */
.module-card__head--plain {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}
.module-card__head--plain .module-card__title {
  color: var(--color-fg);
}

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border-soft);
}

.card__title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
}

.card__body {
  padding: var(--space-5);
}

/* 卡片内嵌的一级 tab / 工具栏 / KPI（整页内容包一个白卡片时，各区左右留白对齐） */
.card > .tabs {
  padding: 0 var(--space-5);
  border-bottom: 1px solid var(--color-border-soft);
}
.card > .toolbar {
  padding: var(--space-4) var(--space-5) var(--space-3);
  margin: 0;
}
.card > .kpi-row {
  padding: var(--space-3) var(--space-5);
  margin-bottom: 0;
}

/* ---- 开关 switch ---- */
.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex-direction: row-reverse; /* 文字在左，开关轨道在右 */
  cursor: pointer;
  user-select: none;
}
.switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  margin: 0;
}
.switch__track {
  position: relative;
  width: 40px;
  height: 22px;
  background: var(--color-border);
  border-radius: var(--radius-pill);
  flex-shrink: 0;
  transition: background-color var(--motion-fast) var(--motion-ease-standard);
}
.switch__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
  transition: transform var(--motion-fast) var(--motion-ease-standard);
}
.switch input:checked + .switch__track {
  background: var(--switch-active-bg);
}
.switch input:checked + .switch__track .switch__thumb {
  transform: translateX(18px);
}
.switch input:focus-visible + .switch__track {
  box-shadow: var(--focus-ring);
}
.switch input:disabled + .switch__track {
  opacity: 0.5;
  cursor: not-allowed;
}
.switch__label {
  margin-right: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-fg);
}
.switch--sm .switch__track {
  width: 34px;
  height: 19px;
}
.switch--sm .switch__thumb {
  width: 15px;
  height: 15px;
  top: 2px;
  left: 2px;
}
.switch--sm input:checked + .switch__track .switch__thumb {
  transform: translateX(15px);
}

/* ---- 分段控件 / 筛选条（白容器 + 选中项内缩蓝色圆角块，对齐乐哥截图：T+35口径 样式）---- */
.seg {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);                    /* 选项间 4px 间隙（不紧贴） */
  padding: 4px;                            /* 容器内边距 → 选中块内缩 */
  background: var(--color-surface);        /* 白色容器 */
  border: 1px solid var(--color-border);   /* #E5E8EC */
  border-radius: var(--radius-md);          /* 8px 圆角矩形 */
}
.seg__btn {
  padding: 6px 16px;
  border: none;
  border-radius: var(--radius-seg);         /* 6px：选中块自身圆角 */
  background: transparent;
  color: var(--color-fg-2);                 /* 未选中深字 #3F4753 */
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--motion-fast) var(--motion-ease-standard),
    background var(--motion-fast) var(--motion-ease-standard);
}
.seg__btn:hover {
  color: var(--color-accent-text);
}
.seg__btn.is-active {
  background: var(--color-accent);     /* 选中主色实底 #0064E0（内缩圆角块） */
  color: var(--color-accent-on);       /* 白字 */
}

/* 分段控件内的分组标签 + 下拉 + 分隔线 */
.seg__label {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2) 0 var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-muted);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
}
.seg__divider {
  width: 1px;
  align-self: stretch;
  margin: 4px var(--space-1);
  background: var(--color-border);
}
.seg-select {
  padding: 6px 16px;
  border: none;
  border-radius: var(--radius-seg);
  background: transparent;
  color: var(--color-fg-2);
  font-size: var(--font-size-sm);
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  outline: none;
  transition: color var(--motion-fast) var(--motion-ease-standard),
    background var(--motion-fast) var(--motion-ease-standard);
}
.seg-select:hover {
  color: var(--color-accent-text);
}
.seg-select.is-active {
  background: var(--color-accent);
  color: var(--color-accent-on);
}

/* ---- 筛选条别名（.pill-filter，与 .seg 同规格：白容器 + 选中项内缩蓝色圆角块）---- */
.pill-filter {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.pill-filter__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 原 6px 16px：改上 6.5 下 5.5，配合 flex 居中补偿中文字面偏上 */
  padding: 6.8px 16px 5.2px;
  border: none;
  border-radius: var(--radius-seg);
  background: transparent;
  color: var(--color-fg-2);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--motion-fast) var(--motion-ease-standard),
    background var(--motion-fast) var(--motion-ease-standard);
}

.pill-filter__item:hover {
  color: var(--color-accent-text);
}

.pill-filter__item.is-active {
  background: var(--color-accent);
  color: var(--color-accent-on);
}

/* 胶囊上的人数角标（2026-09-15，提成总览「类目」筛选用）——
   让「点助播能筛出几个人」在点之前就知道。
   ⚠️ 用 <em> 而不是 <span>：<em> 语义上是"强调"，这里恰好是"次要补充信息"，
      用 span 也行但项目里 <em> 已被用于这类数字角标（与 .co-role-n 呼应）。
   ⚠️ 继承当前文字色阶（未选中=次要色、选中=白字），不要写死颜色，
      否则选中态（蓝底）上会出现灰字看不清。 */
.pill-filter__item .co-role-n {
  margin-left: 5px;
  font-size: var(--font-size-xs);
  font-style: normal;
  opacity: .78;
}

/* 0 人的类目：置灰但**不禁用**（禁用会让"这个类目不存在"和"今天没数据"看起来一样） */
.pill-filter__item.is-empty {
  opacity: .45;
}
.pill-filter__item.is-empty.is-active {
  opacity: 1;   /* 已选中的不置灰：用户明确选了它，得看清楚自己选了什么 */
}

/* ---- 货品缩略图 ---- */
.product-thumb {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  border: 1px solid var(--color-border-soft);
}
.product-thumb--empty {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface-2);
  color: var(--color-muted);
}

/* ---- 图片上传控件 ---- */
.img-upload {
  position: relative;
  width: 160px;
  height: 160px;
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--motion-fast) var(--motion-ease-standard);
}
.img-upload:hover {
  border-color: var(--color-accent-text);
}
.img-upload__empty {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  color: var(--color-muted);
  font-size: var(--font-size-sm);
}
.img-upload__preview {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.img-upload__remove {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--radius-sm);
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  cursor: pointer;
}
.img-upload__remove:hover {
  background: rgba(0, 0, 0, 0.7);
}

/* ---- 飞书通讯录选人组件 ---- */
.fp {
  position: relative;
}
.fp__box {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  min-height: 40px;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-md);
  background: var(--input-bg);
  cursor: text;
}
.fp__box:focus-within {
  border-color: var(--input-focus-border);
  box-shadow: var(--focus-ring);
}
.fp__field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  min-width: 120px;
}
.fp__value {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-base);
}
.fp__placeholder {
  color: var(--color-muted);
}
.fp__search {
  flex: 1;
  min-width: 80px;
  border: none;
  outline: none;
  font-size: var(--font-size-base);
  background: transparent;
}
.fp__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.fp-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px 2px 2px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-2);
  font-size: var(--font-size-sm);
}
.fp-chip__x {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--color-muted);
  display: inline-flex;
  padding: 0;
}
.fp-chip__x:hover {
  color: var(--color-danger);
}
.fp-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.fp-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.fp-avatar--empty {
  background: var(--color-primary-100);
  color: var(--color-accent-text);
  font-size: var(--font-size-xs);
}
.fp__dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  width: 100%; /* 显式约束，不让内容撑大溢出到旁边列 */
  max-height: 240px;
  overflow-y: auto;
  overflow-x: hidden; /* 裁剪水平溢出，防止 fp-item 长名字撑开 */
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-raised);
  z-index: var(--z-dropdown, 1000);
}
.fp-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  font-size: var(--font-size-sm);
}
/* 下拉项圆角：首项顶部、末项底部跟随弹窗圆角，避免直角突兀 */
.fp__dropdown .fp-item:first-child,
.fp__dropdown .fp-empty:first-child {
  border-top-left-radius: calc(var(--radius-md) - 1px);
  border-top-right-radius: calc(var(--radius-md) - 1px);
}
.fp__dropdown .fp-item:last-child,
.fp__dropdown .fp-empty:last-child {
  border-bottom-left-radius: calc(var(--radius-md) - 1px);
  border-bottom-right-radius: calc(var(--radius-md) - 1px);
}
.fp-item:hover {
  background: var(--color-surface-2);
}
.fp-item__name {
  color: var(--color-fg);
}
.fp-empty {
  padding: var(--space-4);
  text-align: center;
  color: var(--color-muted);
  font-size: var(--font-size-sm);
}
/* 选人组件修复：输入框占满剩余空间，点击任意位置可聚焦 */
.fp__box .fp__value {
  flex-shrink: 0;
  max-width: 100%;
}
.fp__search {
  flex: 1;
  min-width: 80px;
  cursor: text;
}
/* 历史「常用」标签 */
.fp-item__tag {
  margin-left: auto;
  padding: 0 6px;
  font-size: var(--font-size-xs);
  line-height: 16px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-2);
  color: var(--color-muted);
}
/* 下拉可滚动（移动端顺滑） */
.fp__dropdown {
  -webkit-overflow-scrolling: touch;
}
/* 外部人员（不在飞书通讯录，如兼职商务） */
.fp-item--external {
  border-top: 1px dashed var(--color-border-soft);
  margin-top: 4px;
  padding-top: 8px;
}
.fp-item__tag--ext {
  background: var(--color-warning-bg, #fff7e6);
  color: var(--color-warning, #d48806);
}

/* ---- 列表操作列按钮：一行展示 + 配色 ---- */
.table .toolbar {
  flex-wrap: nowrap;
}
/* 图标按钮配色：查看灰 / 编辑蓝 / 删除红 */
.icon-btn[data-view] { color: var(--color-muted); }
.icon-btn[data-view]:hover { color: var(--color-fg); background: var(--color-surface-2); }
.icon-btn[data-edit] { color: var(--color-accent-text); }
.icon-btn[data-edit]:hover { color: var(--color-accent-hover); background: var(--color-primary-100); }
.icon-btn[data-del] { color: var(--color-danger); }
.icon-btn[data-del]:hover { color: var(--color-danger); background: var(--color-danger-bg); }
/* 表单页小删除按钮（trash 图标）统一红色 */
.icon-btn.n-del,
.icon-btn.sess-del,
.icon-btn.acc-del,
.icon-btn.bf-del,
.icon-btn.pid-del,
.icon-btn.rule-del,
.icon-btn.sk-del,
.icon-btn.item-del,
.icon-btn.pf-prod-del {
  color: var(--color-danger);
}
.icon-btn.n-del:hover,
.icon-btn.sess-del:hover,
.icon-btn.acc-del:hover,
.icon-btn.bf-del:hover,
.icon-btn.pid-del:hover,
.icon-btn.rule-del:hover,
.icon-btn.sk-del:hover,
.icon-btn.item-del:hover,
.icon-btn.pf-prod-del:hover {
  color: var(--color-danger);
  background: var(--color-danger-bg);
}
/* 文字按钮配色（用户管理等）：改角色/重置密码蓝 / 停用启用灰 / 删除红 */
.btn--ghost[data-role], .btn--ghost[data-pwd] { color: var(--color-accent-text); }
.btn--ghost[data-role]:hover, .btn--ghost[data-pwd]:hover { color: var(--color-accent-hover); background: var(--color-primary-100); }
.btn--ghost[data-status] { color: var(--color-muted); }
.btn--ghost[data-status]:hover { color: var(--color-fg); background: var(--color-surface-2); }
.btn--ghost[data-del] { color: var(--color-danger); }
.btn--ghost[data-del]:hover { color: var(--color-danger); background: var(--color-danger-bg); }

/* ---- 必填项星号 ---- */
.field-label .req { color: var(--color-danger); }

/* ---- 移动端：搜索框占满、控件触控目标 ≥40px、表格紧凑 ---- */
@media (max-width: 768px) {
  .input--search {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
  }
  .input--search .input {
    width: auto !important;
    flex: 1 1 auto;
    min-width: 0;
  }
  /* 触控目标（Apple HIG ≥44px 可点区域）：输入/选择/日期触发 44，按钮/分段 40 */
  .input,
  .select {
    min-height: 44px;
  }
  .dtp-trigger,
  .fp__box {
    min-height: 44px;
  }
  .seg {
    min-height: 40px;
  }
  .btn {
    min-height: 40px;
  }
  .btn--lg {
    min-height: 44px;
  }
  /* 表格更紧凑 */
  .table tbody td {
    padding: 8px 12px;
  }
}

/* ===== 数据导入页 ===== */
.upload-drop {
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
  text-align: center;
  cursor: pointer;
  color: var(--color-muted);
  transition: border-color .15s, background .15s;
  margin-top: var(--space-2);
}
.upload-drop:hover { border-color: var(--color-accent); background: var(--color-surface-2); }
.upload-drop.is-dragover { border-color: var(--color-accent); background: var(--color-accent-bg, #eef3ff); }
.upload-drop svg { color: var(--color-muted); }

.sheet-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-2);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.sheet-option:hover { border-color: var(--color-accent); }
.sheet-option.is-active { border-color: var(--color-accent); background: var(--color-accent-bg); }

/* 导入预览：原始数据可编辑单元格 */
.pv-cell { cursor: text; }
.pv-cell.is-edited { background: var(--color-warning-bg); }

/* 导入预览·「导入后效果」视图（落地结果，只读） */
.ld-ok { color: var(--color-success-text); font-size: var(--font-size-sm); line-height: 1.4; }
.ld-bad { color: var(--color-danger); font-size: var(--font-size-sm); line-height: 1.4; }
.ld-ok + .ld-ok, .ld-bad + .ld-ok, .ld-ok + .ld-bad, .ld-bad + .ld-bad { margin-top: 2px; }
/* 行内 SVG 图标与文字基线对齐（2026-09-14 新增）
   起因：`.ld-ok/.ld-bad` 的状态标记、排期表「其他佣金备注」标记原先用 ✓/✗/✱ **文字符号**当图标，
        违反 P0 规则（禁止用文字符号/emoji 代替图标），已改用 icons.js 的 SVG。
        SVG 默认按基线对齐会略微偏上，故统一下移一点，视觉上与文字居中。 */
.ld-ok > svg, .ld-bad > svg, .icon-inline > svg { vertical-align: -0.15em; }

/* 一级 Tab 卡（跨页共用）：业绩总表 ↔ 订单明细 顶部是同一组 tab，切页后 tab 仍在，不会「困在」某一页 */
.tabs-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5) 0;
  margin-bottom: var(--space-4);
}
.tabs-card > .tabs { margin-bottom: 0; }

/* ============ 月份选择组件 UI.MonthPicker ============ */
.mp { position: relative; display: inline-block; }
.mp__trigger {
  height: 44px;   /* 与同排的 .input / .select 齐平（它们也是 44px） */
  padding: 0 32px 0 var(--space-3);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-md);
  background: var(--input-bg);
  color: var(--color-fg);
  font-size: var(--font-size-base);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .15s;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%238595A4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 12px;
}
.mp__trigger:hover { border-color: var(--input-focus-border); }

/* 筛选生效中（已选中具体某月）：与「未筛选」的素色态明显区分 —— 主色描边 + 前置筛选图标 + 可点的 ✕。
   设计意图：月份触发器与它旁边那些「全部平台 / 全部状态」下拉长得一样时，用户看不出自己正被月份筛着，
   会误以为看到的是全量数据（搜不到别的月份 → 当成 bug）。所以「正在筛」这件事必须在视觉上说出来。 */
.mp__trigger.is-on {
  border-color: var(--color-accent);
  color: var(--color-accent);
  font-weight: var(--font-weight-semibold);
  background-image: none;              /* 去掉下拉箭头：改由前置筛选图标表达「这是筛选条件」 */
  padding-right: var(--space-3);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.mp__trigger.is-on:hover { border-color: var(--color-accent); }
.mp__trigger .mp__label { white-space: nowrap; }
.mp__trigger.is-on > svg { flex-shrink: 0; }
.mp__clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 1px;
  opacity: .5;
  transition: opacity .15s;
}
.mp__trigger.is-on:hover .mp__clear { opacity: 1; }

.mp__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: var(--z-dropdown);
  min-width: 232px;
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft, var(--input-border));
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-raised);
}
.mp__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-2);
}
.mp__nav {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--input-border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-fg-2);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
}
.mp__nav:hover:not(:disabled) { border-color: var(--color-accent); color: var(--color-accent-text); }
.mp__nav:disabled { opacity: .35; cursor: not-allowed; }
.mp__year { font-size: var(--font-size-base); font-weight: 600; color: var(--color-fg); }

.mp__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.mp__month {
  padding: 7px 0;
  border: 1px solid var(--input-border);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-fg);
  font-size: var(--font-size-sm);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.mp__month:hover:not(:disabled) { border-color: var(--color-accent); }
.mp__month.is-active {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-accent-on);
  font-weight: 600;
}
.mp__month.is-disabled,
.mp__month:disabled {
  border-color: var(--input-border);
  background: transparent;
  color: var(--input-disabled-text);
  opacity: .5;
  cursor: not-allowed;
}
/* 当月（今天所在的月）：主色描边 + 主色字。
   要点：必须跟「已选中」区分开 —— 已选中是主色实心，当月是空心描边，两者同月出现时以实心为准。
   当月若没有数据（禁用灰格）也保留描边，让人知道"这是当前月，只是还没数据"。 */
.mp__month.is-current:not(.is-active) {
  border-color: var(--color-accent);
  color: var(--color-accent);
  font-weight: var(--font-weight-semibold);
}
.mp__month.is-current:not(.is-active):disabled {
  color: var(--input-disabled-text);
  opacity: .55;
}

.mp__foot {
  display: flex;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border-soft, var(--input-border));
}
/* 底部两个快捷按钮：给底色提亮，并分出主次 ——
   「全部月份」是"清除月份筛选"的出口（主），给主色淡底；「回到当月」是快捷键（次），给中性淡底。 */
.mp__today,
.mp__all {
  flex: 1;
  padding: 8px 0;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}
.mp__today {
  background: var(--color-surface-2);
  border-color: var(--color-border);
  color: var(--color-fg);
}
.mp__today:hover:not(:disabled) { border-color: var(--color-accent); color: var(--color-accent-text); }
.mp__today:disabled { color: var(--input-disabled-text); opacity: .5; cursor: not-allowed; }
.mp__all {
  background: var(--color-accent-bg);
  color: var(--color-accent);
  font-weight: var(--font-weight-semibold);
}
.mp__all:hover { border-color: var(--color-accent); }

/* 筛选栏「重置」按钮：高度必须对齐同一行里的输入框 / 下拉 / 月份选择器（都是 44px）。
   用小号按钮（30px）会比邻居矮一截、看着又小又弱 —— 2026-09-10 乐哥反馈"太小了、看不清"。 */
.filter-reset {
  height: 44px;
  padding: 0 var(--space-4);
}

/* 兼职助播结算：费用块（开关 + 标题 + 字段） */
.pta-fee {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
}
.pta-fee__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.pta-fee__title {
  font-weight: var(--font-weight-semibold);
  color: var(--color-fg);
}
.pta-fee__body {
  margin-top: var(--space-3);
}

/* 列表多选批量操作栏 */
.batch-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-2);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-3);
}
.batch-bar__count {
  font-size: var(--font-size-sm);
  color: var(--color-fg);
  font-weight: var(--font-weight-medium);
}

/* 提成「人为校准」标记 */
.calib-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-warning);
  background: var(--color-warning-bg);
  border-radius: var(--radius-pill);
  vertical-align: middle;
}

/* 场次提成：展开子行（与主表同列结构，一行一个直播场次 / 支援人力明细） */
.table tr.row-sub > td {
  background: var(--color-surface-2);
  padding-top: var(--space-2);
  padding-bottom: var(--space-2);
}
.table tbody tr.row-sub:hover > td {
  background: var(--table-row-hover);
}
/* 场次提成：岗位分组分隔线（商务 | 助播 | 商务助理 | 支援人力成本） */
.table th.group-sep,
.table td.group-sep {
  border-left: 1px solid var(--color-border);
  padding-left: var(--space-4);
}
/* 人员维度：展开明细里的内嵌子表 */
.table td .table--sub {
  margin: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.table--sub th,
.table--sub td {
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-xs);
}
.link-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: none;
  background: none;
  color: var(--color-accent-text);
  cursor: pointer;
  font-weight: var(--font-weight-medium);
}
.link-btn:hover {
  color: var(--color-primary-500);
  text-decoration: underline;
}
/* 支援人力「不计成本」：整行淡化 */
.table tr.is-excluded td {
  opacity: 0.55;
}

/* ==========================================================================
   口径提示气泡（tooltip）—— 2026-09-12 新增（配 UI.tip / UI.bindTips）
   · 单例元素挂 body，**position:fixed** —— 必须 fixed：
     表格外层 .table-wrap{overflow-x:auto} 会裁掉 absolute 定位的气泡
   · 默认在触发器上方居中，上方空间不足时由 JS 翻到下方
   ========================================================================== */
.ui-tip {
  position: fixed;
  z-index: var(--z-toast);
  max-width: 320px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-fg);
  color: var(--color-surface);
  box-shadow: var(--shadow-md);
  font-size: var(--font-size-sm);
  line-height: 1.5;
  word-break: break-word;
  pointer-events: none;      /* 气泡本身不拦鼠标：移开就消失，不闪烁 */
}

/* ==========================================================================
   备注文本展示（乐哥 2026-09-13）
   「所有涉及备注的地方，文字表达、排版都优化下，一句话一行会好点，
     展示实在不行就用弹窗。然后展示重点文字得标出来的。」
   --------------------------------------------------------------------------
   为什么要做成组件：改动前全站 7 处备注列是同一个复制粘贴写法
     （`ellipsis + max-width:96px` + `title` 悬停），另有约 10 处裸输出。
   而真实数据（店铺订单备注 550 条）：中位 12 字、最长 98 字、8% 超 40 字，
   55% 用空格 / 42% 用冒号 / 24% 用逗号把好几件事挤在一行 —— 挤成一行等于看不见。
   配合 js/remark.js：拆句（一句一行）+ 重点高亮 + 超长折叠 / 弹窗。
   -------------------------------------------------------------------------- */

/* ---- 文本块 ---- */
.rmk { line-height: 1.6; }
.rmk-line { display: block; }
/* 多句之间给一点行距，读起来像清单而不是一段话 */
.rmk--block > .rmk-line + .rmk-line { margin-top: 6px; }
.rmk--block { font-size: var(--font-size-sm); color: var(--color-fg); }

/* 表格单元格里的备注：小一号、次要色（是辅助信息，不抢主字段的注意力） */
.rmk--cell { font-size: var(--font-size-xs); color: var(--color-fg-2); }
.rmk--cell > .rmk-line + .rmk-line { margin-top: 2px; }
/* ⚠️ 表格里的每句**必须严格占 1 行**（乐哥 2026-09-13 排查「明显高行」时发现的组件缺陷）：
   JS 的 `maxChars` 是**按字符数**限长的，但中文在窄列里会自动折行 ——
   实测：达人列表备注列 100px，一行只放得下 ~7 个中文字，而 maxChars 设的是 36
   → 一句被折成 5 行，"maxLines:2" 实际渲染出 10 行，行高从 67px 涨到 125px
     （全站 3 张表的"明显高行"都是这一个原因：达人列表 / 成本·滴滴 / 成本·报销）。
   这里用 nowrap 把「1 个 .rmk-line == 1 行」这个前提固定下来；
   放不下的部分由 `text-overflow: ellipsis` 收尾，完整内容仍可 hover（title）或点「还有 N 条」看弹窗。
   ⚠️ 只作用于 `.rmk--cell`：弹窗里的 `.rmk--block` **要保持可折行**（那里空间大，应显示完整句子）。 */
.rmk--cell > .rmk-line {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rmk-empty, .rmk--empty { color: var(--color-muted); }

/* 「还有 N 条 / 展开全文」：视觉上是个轻量文字按钮，不占地方但点得到 */
.rmk-more {
  margin-top: 3px; padding: 0;
  border: 0; background: none; cursor: pointer;
  font-size: var(--font-size-xs); font-family: inherit;
  color: var(--color-accent-text); text-decoration: none;
}
.rmk-more:hover { text-decoration: underline; }
.rmk-more:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; border-radius: 2px; }
.rmk-more-dot { color: var(--color-accent-text); }

/* ---- 重点高亮 ----
   ⚠️ `<mark>` 浏览器默认是「黄底黑字」，必须显式覆盖，否则与莫代尔色系冲突。
   只标三类「能拿去做事的」信息（详见 js/remark.js 的注释）：
     id    单号 → 要拿去查单，等宽 + 浅底 + 描边（像一枚可复制的标签）
     money 金额 → 要对账，沿用项目「价格=红」的既有语义（.price 同色）
     act   动作 → 退货/补发/拒绝这类结论词，警示色加粗，一眼看到"这单要不要处理"
   ---- */
.rmk-hl {
  background: none; color: inherit;      /* 先抹掉 <mark> 的默认黄底 */
  padding: 0 2px; border-radius: var(--radius-sm);
  font-weight: var(--font-weight-medium);
}
/* 单号：等宽字体，方便与订单号逐位核对 */
.rmk-hl--id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.94em;                    /* 等宽字略宽，缩一点保持整行长度 */
  background: var(--color-surface-2);
  border: 1px solid var(--color-border-soft);
  color: var(--color-fg);
  letter-spacing: -0.01em;
}
/* 金额：与项目「价格红」一致 */
.rmk-hl--money { color: var(--color-price); font-weight: var(--font-weight-semibold); }
/* 动作词：警示色（不是错误，是"需要留意"） */
.rmk-hl--act { color: var(--color-warning-text); font-weight: var(--font-weight-semibold); }

/* ---- 备注弹窗：每句一行、行距舒展 ---- */
.rmk-modal__meta {
  margin-bottom: var(--space-3); padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border-soft);
  font-size: var(--font-size-xs); color: var(--color-meta);
}
.rmk-modal .rmk--block { font-size: var(--font-size-base); }
.rmk-modal .rmk--block > .rmk-line + .rmk-line { margin-top: var(--space-3); }

/* ==========================================================================
   长文本单行省略（乐哥 2026-09-13「统一收敛行内省略号写法」）
   --------------------------------------------------------------------------
   背景：全站 15 处把 `overflow:hidden;text-overflow:ellipsis;white-space:nowrap`
   写成**行内 style**（商品名 / SKU / 订单号 / 地址 / 用户名），散落 8 个文件、重复 15 遍。
   目标统一成一处定义，行为不变（仍单行省略 + title 悬停看全）。

   ⚠️ 为什么**没有**套用 `.rmk`（备注组件）—— 这是本条的判断点：
     这 15 处全是**长文本字段**（单个长字符串），**没有一处是备注**（多句自然语言）。
     `.rmk` 会做「重点高亮」（单号/金额/动作词），套到商品名上会把
     「益畅(30袋)*3」「YY010107-000002」这类**规格数字误标成金额/单号** —— 反而更乱。
     所以这里抽的是「单行省略」工具类，与 `.rmk`（拆句+高亮）职责不同、各用其所。

   `.ell` 同时给 `min-width:0`：flex 子项若不设它，内容会把父级撑宽、ellipsis 不生效
   （项目里 5 处 flex 场景原本靠外层 `min-width:0;flex:1` 凑合，现在内层自己带上更稳）。
   ========================================================================== */
.ell {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* 直接省略一个 span/div 时它需要是块级才吃得住宽度 */
span.ell, div.ell { display: block; }
/* `td.ell`：在单元格上直接省略（不套内层 div 的场景）——限制在自身宽度内，不撑破表格 */
td.ell { max-width: 100%; }


/* ==========================================================================
   交互反馈补齐（按下 / 键盘可达）—— 2026-09-13，依据 ui-ux-pro-max 规范
   ---------------------------------------------------------------------------
   审计实测发现的缺口（全站范围，非个例）：
     ① `.icon-btn` **完全没有 :active 规则**（全站 83 个图标按钮）
        → 按下零反馈：点完不知道有没有生效，在表格里连点容易误操作。
     ② `.btn:hover` 与 `.btn:active` 背景同色（已在上方修掉）。
     ③ **15 处可点击表格行**只有 cursor:pointer，没有任何按下反馈。
   规范依据：
     · 优先级 2「Touch & Interaction」— press-feedback / state-clarity
     · 优先级 7「Animation」— 只用 transform/opacity（不动 width/height 以免重排）、
       时长落在 150–300ms（沿用项目 --motion-fast=150ms）、缩放幅度取细微的 0.94–1.05
   ⚠️ 按下底色用 `--color-gray-100`（#EEEEEE）——比 hover 的 surface-2(#FAFBFC) 深一档，
      莫代尔色系里没有 surface-3，直接用中性色阶，不新造 token。
   ⚠️ 行按下态必须落在 `td` 上：`tr` 的背景会被 `td` 覆盖，只写 tr 看不到效果。
   ========================================================================== */
.icon-btn:active:not(:disabled) {
  background: var(--color-gray-100);
  transform: scale(0.94);
}

/* 可点击行的按下反馈。
   ⚠️ 按下色必须**与 hover 同色系加深**：行 hover 是 `--color-primary-50`(#EDF4FE)，
      按下用 `--color-primary-100`(#DBE8FE)。**不能**用灰色 —— 悬停是淡蓝、按下变灰
      会产生色相跳变，看着像"状态丢了"（违反 state-clarity 的同色系递进原则）。
      这是本次实现时自己先写错、复核 token 后修正的一处。
   选择器同时列「已知 class」+「行内 cursor:pointer」兜底 ——
   后者是因为本项目 15 处可点击行**统一用行内 style 标记可点**（已核实），
   用属性兜底可覆盖未来新增的同惯例行；已知 class 列出便于 grep 定位。 */
.table tbody tr.c-row:active,
.table tbody tr.hs-row:active,
.table tbody tr.ip-row:active,
.table tbody tr.s-row:active,
.table tbody tr.so-row:active,
.table tbody tr.person-row:active,
.table tbody tr.group-row:active,
.table tbody tr.fe-group:active,
.table tbody tr[data-row]:active,
.table tbody tr[data-key]:active,
.table tbody tr[data-pkey]:active,
.table tbody tr[data-inf]:active,
.table tbody tr[data-id]:active,
.table tbody tr[data-day]:active,
.table tbody tr[style*="cursor:pointer"]:active {
  background: var(--color-primary-100);
}

/* 减弱动效：按下态的缩放属于"动效"，偏好减少动效时去掉（保留底色变化作反馈）。
   全局那段把 transition-duration 归零只能让过渡"瞬间完成"，**不会**取消 transform 本身，
   故这里显式重置。 */
@media (prefers-reduced-motion: reduce) {
  .btn:active:not(:disabled),
  .icon-btn:active:not(:disabled) {
    transform: none;
  }
}

/* ---- 占位隐藏（2026-09-18，乐哥「切 tab 工具组会跳」）----
   与 `display:none` 的区别：**保留布局空间**。
   工具组/页头按钮都是右对齐的，用 display:none 隐藏其中一项会让其余控件补位、
   整组横向跳动（实测 订单明细 105px）。visibility:hidden 位置一个像素不动，
   且天然不可点击/不可聚焦。用法：ui.js 的 UI.setKeepSpace(el, visible)。 */
.keep-space-hidden {
  visibility: hidden;
}

/* ---- 「新增」按钮定宽（2026-09-18，乐哥「切 tab 页头按钮会跳」）----
   兼职助播页两个 tab 下这个按钮的文案不同：
     「助播人员名单」tab → 新增兼职助播（实测宽 150px）
     「兼职主播直播场次」tab → 新增结算（实测宽 122px）
   页头按钮组是**右对齐**的 → 按钮变宽会把左边缘向左推 28px（实测）。
   直接给它最小宽度 = 较宽的那个，两种状态下宽度完全一致，位置一动不动。 */
#pta-add {
  min-width: 150px;
  justify-content: center;
}
