/* ============================================================
   设计系统 —— 深蓝轻奢
   所有组件类名以 ds- 为前缀。新代码必须用设计系统类名，禁止写 inline style。

   本文件负责：设计 token · 基础重置 · 通用组件 · 登录页
   外壳（侧边栏/顶栏/双栏布局/空态）在 shell.css
   加载顺序：design-system.css → shell.css
   ============================================================ */

:root {
  /* ---------- 深蓝家族：侧边栏与品牌 ---------- */
  --ink:       #0E1A2B;
  --ink-2:     #17273D;
  --ink-3:     #0B1524;
  --navy:      #1B2A4A;
  --navy-soft: #24406E;

  /* ---------- 香槟铜：唯一金属强调色 ----------
     深底用 --champagne（对 --ink 约 8:1）
     浅底用 --champagne-ink（对白约 4.7:1，10px 小字也达标）
     ⚠️ 别在白底上用 --champagne 写文字，对比度只有 2.2:1 */
  --champagne:      #C6A472;
  --champagne-ink:  #8A6D3F;
  --champagne-dim:  rgba(198, 164, 114, 0.32);
  --champagne-wash: #F8F1E4;

  /* ---------- 纸面 ---------- */
  --paper:  #F7F8FA;
  --card:   #FFFFFF;
  --line:   #E8EBF0;
  --line-2: #F1F3F7;
  --text:   #16202F;
  --muted:  #7C8798;
  --faint:  #A8B0BD;

  /* ---------- 语义色（沉稳变体，非默认网页色） ----------
     ⚠️ 别改回 #f00 / #ff9800 之类：库存预警和 ACOS 超标在这个系统里
        天天出现，正红显廉价且过度警报，酒红能保住紧迫感又不破坏调性 */
  --success: #1F7A4D;  --success-wash: #EAF3EE;
  --danger:  #B4353A;  --danger-wash:  #FBEEEE;
  --warning: #B8873B;  --warning-wash: #F8F1E4;
  --info:    #2F6E8F;  --info-wash:    #EAF1F5;

  /* ---------- 数据可视化（Chart.js 用，与语义色分开，避免"红=危险"串味） ---------- */
  --viz-1: #1B2A4A;
  --viz-2: #C6A472;
  --viz-3: #2F6E8F;
  --viz-4: #7C8798;
  --viz-5: #6B7F99;

  /* ---------- 几何与层次 ---------- */
  --r-sm: 7px;
  --r:    10px;
  --r-lg: 14px;
  --sidebar-w: 268px;
  --topbar-h:  56px;

  --sh-sm: 0 1px 2px rgba(14, 26, 43, 0.04);
  --sh-md: 0 8px 24px -14px rgba(14, 26, 43, 0.18), 0 1px 2px rgba(14, 26, 43, 0.04);

  /* ---------- 字体 ----------
     个性放在数字与微标签上，不追异质中文显示字体
     （思源宋体全量 10MB 级，且 Google Fonts 在国内不可靠） */
  --sans: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", "SFMono-Regular", Consolas, "Roboto Mono", ui-monospace, Menlo, monospace;

}
/* 2026-07-30：旧 token 别名层（--primary / --bg / --border / --radius / --cyan …）
   已移除。业务 JS 里那 171 处内联样式全部抽成 ds- 类之后，没有代码再引用它们。
   剩下的 33 处内联样式只有 width / min-width —— 表格列宽和输入框宽度是逐处的
   布局参数，不承载视觉设计，留在内联更清楚，也不影响以后换配色。 */

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.6;
  color: var(--text);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

/* 内联 SVG 的全局默认：线性描边、随文字色走。
   漏了这条，没被更具体规则命中的图标会退成黑色实心块。 */
svg {
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ============================================================
   微标签 —— 全站复用的「仪表读数」标签，签名元素之一
   ============================================================ */
.ds-eyebrow {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--champagne-ink);
}
.ds-eyebrow--on-dark { color: var(--champagne); }
.ds-eyebrow--muted { color: var(--faint); }

/* ============================================================
   卡片
   ============================================================ */
.ds-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 20px 22px;
  box-shadow: var(--sh-sm);
  margin-bottom: 16px;
}
.ds-card-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line-2);
}
.ds-card-title {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.012em;
}
/* 次级标题（卡片内的小节，如「近30天趋势」「问题 ASIN」） */
.ds-card-title--sm { font-size: 15px; }

/* 标题前的香槟短杠 —— 卡片标题的统一起手式 */
.ds-card-title::before {
  content: "";
  flex: none;
  width: 3px;
  height: 14px;
  border-radius: 2px;
  background: var(--champagne);
}
/* 在 ds-card-head 内的标题不重复画短杠（那里由 eyebrow 领衔） */
.ds-card-head .ds-card-title::before { display: none; }

/* ============================================================
   KPI 指标卡 —— 香槟 eyebrow + 大号等宽数字
   ============================================================ */
.ds-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
  gap: 14px;
  margin-bottom: 16px;
}
.ds-stat {
  --stat-accent: var(--navy);   /* 默认色，被 .ds-stat--X 变体覆盖 */
  position: relative;
  padding: 17px 19px 18px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
  transition: border-color 0.2s ease, box-shadow 0.24s ease, transform 0.2s ease;
}
.ds-stat:hover {
  transform: translateY(-2px);
  border-color: var(--champagne-dim);
  box-shadow: var(--sh-md);
}
/* 旧类名：业务 JS 用 .ds-stat-label，与 .ds-eyebrow 同一视觉 */
.ds-stat-label {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--champagne-ink);
}
.ds-stat-value {
  margin-top: 9px;
  font-size: 29px;
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--stat-accent);
}
.ds-stat-value .ds-unit {
  margin-left: 3px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--muted);
}
.ds-stat-sub,
.ds-stat-foot {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}
/* 语义变体：一个 --stat-accent 同时驱动数值颜色和可选的左侧色条，
   卡片本体保持安静。加变体只需加一行，不用再写 .ds-stat--X .ds-stat-value。 */
.ds-stat--primary { --stat-accent: var(--navy); }
.ds-stat--text    { --stat-accent: var(--text); }
.ds-stat--cyan    { --stat-accent: var(--info); }
.ds-stat--success { --stat-accent: var(--success); }
.ds-stat--warning { --stat-accent: var(--warning); }
.ds-stat--danger  { --stat-accent: var(--danger); }
.ds-stat--muted   { --stat-accent: var(--faint); }
/* 需要左侧色条时叠加（广告效率分档那类） */
.ds-stat--bar { border-left: 3px solid var(--stat-accent); }

/* 涨跌 */
.ds-delta { font-weight: 700; font-variant-numeric: tabular-nums; }
.ds-delta-up { color: var(--success); }
.ds-delta-down { color: var(--danger); }

/* ============================================================
   表格
   ============================================================ */
.ds-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--card);
}
.ds-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}
.ds-table th {
  /* top 必须是 0：线上 10 个模块都把表格套在自己的 overflow:auto 容器里
     （invWrap / lstWrap / ordWrap / ppTableWrap …），sticky 相对该容器定位。
     写成 var(--topbar-h) 会把表头在容器内下推 56px，留出一条空隙。 */
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 11px 14px;
  background: #FAFBFC;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
  color: var(--muted);
}
.ds-table td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-2);
  font-size: 13px;
  vertical-align: middle;
}
.ds-table tbody tr { transition: background 0.14s ease; }
.ds-table tbody tr:hover { background: var(--paper); }
.ds-table tbody tr:last-child td { border-bottom: 0; }

.ds-num { text-align: right; font-variant-numeric: tabular-nums; }
.ds-strong { font-weight: 600; }
.ds-sub { font-size: 11.5px; color: var(--muted); }
.ds-truncate {
  display: block;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ds-asin {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--navy);
  text-decoration: none;
  border-bottom: 1px solid var(--champagne-dim);
}
.ds-asin:hover { color: var(--champagne-ink); }
.ds-thumb {
  width: 34px;
  height: 34px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
}

/* ============================================================
   徽章
   ============================================================ */
.ds-badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}
.ds-badge-success { background: var(--success-wash); color: var(--success); }
.ds-badge-danger  { background: var(--danger-wash);  color: var(--danger); }
.ds-badge-warning { background: var(--warning-wash); color: var(--champagne-ink); }
.ds-badge-info    { background: var(--info-wash);    color: var(--info); }
.ds-badge-neutral { background: var(--line-2);       color: var(--muted); }

/* ============================================================
   按钮 —— 主按钮是深蓝，不做金色按钮、不做金色渐变
   这个克制是「轻奢」和「土豪金」的分界线
   ============================================================ */
.ds-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 15px;
  border: 1px solid transparent;
  border-radius: 9px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  /* 无修饰类时的默认样态（业务 JS 有 class="ds-btn" 单用的写法） */
  background: var(--navy);
  color: #fff;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease, box-shadow 0.2s ease;
}
.ds-btn:focus-visible { outline: 2px solid var(--champagne-ink); outline-offset: 2px; }
.ds-btn[disabled] { opacity: 0.45; cursor: default; box-shadow: none; }
.ds-btn svg { width: 15px; height: 15px; stroke-width: 1.7; }

.ds-btn-primary {
  background: var(--navy);
  color: #fff;
  box-shadow: 0 6px 16px -10px rgba(27, 42, 74, 0.7);
}
.ds-btn-primary:hover:not([disabled]) { background: var(--navy-soft); }

.ds-btn-outline {
  background: #fff;
  border-color: var(--line);
  color: var(--text);
}
.ds-btn-outline:hover:not([disabled]) { border-color: var(--champagne-dim); color: var(--champagne-ink); }

.ds-btn-danger { background: var(--danger); color: #fff; }
.ds-btn-danger:hover:not([disabled]) { background: #9c2b30; }

.ds-btn-ghost { background: none; color: var(--muted); }
.ds-btn-ghost:hover:not([disabled]) { background: var(--paper); color: var(--text); }

/* 筛选胶囊 */
.ds-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.ds-chip {
  height: 30px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--muted);
  cursor: pointer;
  transition: border-color 0.18s ease, color 0.18s ease, background 0.18s ease;
}
.ds-chip:hover { border-color: var(--champagne-dim); color: var(--text); }
.ds-chip:focus-visible { outline: 2px solid var(--champagne-ink); outline-offset: 2px; }
.ds-chip.is-on { background: var(--navy); border-color: var(--navy); color: #fff; }

/* ============================================================
   表单控件 —— 业务 JS 里大量裸 input / select，统一兜底
   ============================================================ */
/* ⚠️ 必须排除 .ds-login-input：属性选择器 input[type="text"] 的优先级(0,1,1)
   高于类选择器 .ds-login-input(0,1,0)，不排除会把登录页的深色玻璃输入框压平。 */
input[type="text"]:not(.ds-login-input), input[type="number"], input[type="date"],
input[type="password"]:not(.ds-login-input), input:not([type]), select, textarea {
  height: 34px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: #fff;
  font-family: inherit;
  font-size: 13.5px;
  color: var(--text);
  transition: border-color 0.16s ease, box-shadow 0.2s ease;
}
textarea { height: auto; padding: 9px 11px; line-height: 1.7; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--champagne-dim);
  box-shadow: 0 0 0 3px rgba(198, 164, 114, 0.14);
}
input::placeholder, textarea::placeholder { color: var(--faint); }
label { font-size: 13px; color: var(--muted); }

/* 输入框清空按钮（项目规范：文本框右侧必须有灰色 × 清空按钮） */
.inp-clear-wrap { position: relative; display: inline-flex; align-items: center; }
.inp-clear-btn {
  position: absolute;
  right: 8px;
  background: none;
  border: none;
  color: var(--faint);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  display: none;
}
.inp-clear-btn:hover { color: var(--muted); }
.inp-clear-wrap input:not(:placeholder-shown) + .inp-clear-btn { display: block; }

/* 列宽拖拽把手 */
.col-resize-handle {
  position: absolute;
  right: 0;
  top: 0;
  width: 4px;
  height: 100%;
  cursor: col-resize;
  background: rgba(22, 32, 47, 0.06);
}
.col-resize-handle:hover { background: var(--champagne-dim); }

/* ============================================================
   Toast 提示
   ============================================================ */
.ds-toast {
  position: fixed;
  top: calc(var(--topbar-h) + 16px);
  right: 24px;
  z-index: 9999;
  padding: 11px 18px;
  border-radius: var(--r);
  border: 1px solid var(--champagne-dim);
  background: var(--ink);
  color: #fff;
  font-size: 13.5px;
  box-shadow: 0 16px 40px -18px rgba(11, 21, 36, 0.6);
  animation: ds-toast-in 0.28s ease;
}
@keyframes ds-toast-in { from { transform: translateX(14px); opacity: 0; } }

/* ============================================================
   模态层
   ============================================================ */
.ds-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(11, 21, 36, 0.5);
}
.ds-modal-panel {
  width: min(900px, 94vw);
  max-height: 88vh;
  overflow: auto;
  background: var(--card);
}

/* ============================================================
   上传拖放区（识别图片模块）
   ============================================================ */
.ds-dropzone {
  padding: 2em;
  border: 1.5px dashed var(--line);
  border-radius: var(--r);
  text-align: center;
  cursor: pointer;
  transition: border-color 0.16s ease, background 0.16s ease;
}
.ds-dropzone:hover { border-color: var(--champagne-dim); background: var(--paper); }
/* 拖拽悬停态：用 class 切换，不在 JS 里直接写 style.borderColor */
.ds-dropzone.is-over { border-color: var(--champagne); background: var(--champagne-wash); }
.ds-dropzone-icon { font-size: 34px; line-height: 1; }
.ds-preview-img {
  max-width: 220px;
  max-height: 180px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.ds-textarea-lg {
  width: 100%;
  min-height: 280px;
  margin-top: 12px;
  line-height: 1.7;
  resize: vertical;
}

/* ============================================================
   文本与状态（替代业务 JS 里散落的内联 color / font-size）
   ============================================================ */
/* 小字说明 */
.ds-note    { font-size: 12px; color: var(--muted); }
.ds-note-sm { font-size: 11px; color: var(--muted); }
.ds-note-md { font-size: 13px; color: var(--muted); }
.ds-note-ink { color: var(--text); }
/* 只染色不改字号，继承父级字号 */
.ds-note-inherit { color: var(--muted); }

/* 小节标题 */
.ds-section { margin: 14px 0 6px; font-size: 13px; font-weight: 600; }

/* 区块内的状态占位（加载中 / 空 / 出错），区别于整页的 .ds-empty */
.ds-state       { padding: 2em; text-align: center; color: var(--muted); }
.ds-state-sm    { padding: 1em; text-align: center; color: var(--muted); }
.ds-state-lg    { padding: 3em; text-align: center; color: var(--muted); }
.ds-state-error { padding: 2em; text-align: center; color: var(--danger); }

/* 表格里按值染色的数字（ACOS 超标、毛利为负…）
   配套：各模块的 _*_acosColor() 返回的是这些类名，不再返回颜色字符串 */
.ds-val { font-weight: 600; font-variant-numeric: tabular-nums; }
.ds-val--plain   { color: var(--text); }
.ds-val--success { color: var(--success); }
.ds-val--danger  { color: var(--danger); }
.ds-val--warning { color: var(--warning); }
.ds-val--muted   { color: var(--muted); }

/* 左侧色条标记（异常/机会清单用） */
.ds-flag-success { border-left: 3px solid var(--success); }
.ds-flag-danger  { border-left: 3px solid var(--danger); }

/* 链接 */
.ds-link {
  color: var(--navy);
  text-decoration: none;
  border-bottom: 1px solid var(--champagne-dim);
}
.ds-link:hover { color: var(--champagne-ink); }

/* 截断宽度变体（.ds-truncate 默认 240px） */
.ds-truncate-sm { max-width: 180px; }
.ds-truncate-lg { max-width: 260px; }

/* 表格滚动容器 */
.ds-scroll    { overflow: auto; }
.ds-scroll-58 { max-height: 58vh; overflow: auto; }
.ds-scroll-60 { max-height: 60vh; overflow: auto; }
.ds-scroll-64 { max-height: 64vh; overflow: auto; }

/* 筛选/操作工具条 */
.ds-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 12px 0 4px;
}

/* ============================================================
   布局工具类（业务 JS 在用，勿删）
   ============================================================ */
.ds-center { text-align: center; }
.ds-nowrap { white-space: nowrap; }
.ds-clickable { cursor: pointer; }
.ds-hidden { display: none; }
.ds-mono { font-family: var(--mono); }
.ds-mt { margin-top: 12px; }
.ds-mt-lg { margin-top: 18px; }
.ds-mb { margin-bottom: 12px; }
.ds-grow { flex: 1; }

.flex { display: flex; }
.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-sm { gap: 8px; }
.gap-md { gap: 16px; }
.gap-lg { gap: 24px; }
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
.grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.grid-4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); gap: 14px; }

/* ============================================================
   补货建议（采购中心）—— 左列表 + 右计算器双栏
   只有这个模块用，前缀 ds-rp-。业务逻辑全在后端，这里只负责承载。
   ⚠️ 风险色是业务语义：待确认(gray) 绝不能用 success 绿，
      它表示「数据不完整、建议量被强制归零」，不是「不需补货」。
   ============================================================ */
.ds-rp-split {
  display: grid;
  grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
@media (max-width: 1180px) { .ds-rp-split { grid-template-columns: 1fr; } }

/* ---------- 左：风险 SKU 列表 ---------- */
.ds-rp-list { max-height: 68vh; overflow: auto; margin: 0 -22px -20px; }
.ds-rp-row {
  display: block;
  width: 100%;
  padding: 11px 22px 11px 19px;
  border: 0;
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--line-2);
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease;
}
.ds-rp-row:hover { background: var(--paper); }
.ds-rp-row.is-active { background: var(--champagne-wash); border-left-color: var(--champagne); }
.ds-rp-row-top { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.ds-rp-row-sku { font-size: 13px; font-weight: 700; letter-spacing: -0.01em; }
.ds-rp-row-meta { display: flex; justify-content: space-between; gap: 10px; font-size: 11.5px; color: var(--muted); }

/* ---------- 右：结论横幅 ---------- */
.ds-rp-banner {
  --rp-accent: var(--muted);
  padding: 14px 18px;
  margin-bottom: 16px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--rp-accent);
  border-radius: var(--r);
  background: var(--paper);
}
.ds-rp-banner-title { font-size: 15px; font-weight: 700; color: var(--rp-accent); }
.ds-rp-banner-text { margin-top: 5px; font-size: 12.5px; line-height: 1.65; color: var(--muted); }
.ds-rp-red    { --rp-accent: var(--danger); }
.ds-rp-yellow { --rp-accent: var(--warning); }
.ds-rp-blue   { --rp-accent: var(--info); }
.ds-rp-green  { --rp-accent: var(--success); }
.ds-rp-gray   { --rp-accent: var(--muted); }

/* ---------- 参数与数据行 ---------- */
.ds-rp-section { margin-top: 18px; }
.ds-rp-section > h3 {
  margin-bottom: 6px;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--champagne-ink);
}
.ds-rp-datarow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 34px;
  padding: 4px 0;
  border-bottom: 1px dashed var(--line-2);
  font-size: 13px;
}
.ds-rp-datarow > strong { font-variant-numeric: tabular-nums; }
.ds-rp-datarow input[type="number"] { width: 108px; text-align: right; }
.ds-rp-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 0 26px; }

/* 运营向 tooltip —— 这些原文编码了业务知识（如「美森」是特定船司），不可改写 */
.ds-rp-tip { position: relative; cursor: help; }
.ds-rp-tip-mark {
  display: inline-block;
  width: 13px;
  height: 13px;
  margin-left: 5px;
  border-radius: 999px;
  background: var(--line);
  font-size: 9.5px;
  font-weight: 700;
  line-height: 13px;
  text-align: center;
  color: var(--muted);
}
.ds-rp-tip-bubble {
  position: absolute;
  left: 0;
  bottom: calc(100% + 7px);
  z-index: 20;
  display: none;
  width: 268px;
  padding: 9px 11px;
  border-radius: var(--r-sm);
  background: var(--ink);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.6;
  color: #EAF1F8;
  box-shadow: var(--sh-md);
}
.ds-rp-tip:hover .ds-rp-tip-bubble,
.ds-rp-tip:focus .ds-rp-tip-bubble,
.ds-rp-tip:focus-within .ds-rp-tip-bubble { display: block; }

/* ---------- 提示框：需要注意 / 旧数据只读 ---------- */
.ds-rp-issues {
  padding: 11px 14px;
  margin: 14px 0;
  border: 1px solid var(--warning);
  border-radius: var(--r-sm);
  background: var(--warning-wash);
  font-size: 12.5px;
  line-height: 1.7;
}
.ds-rp-issues > strong { display: block; margin-bottom: 3px; color: var(--champagne-ink); }
.ds-rp-issues span { display: block; color: var(--text); }
.ds-rp-lock {
  padding: 11px 14px;
  margin-bottom: 14px;
  border: 1px solid var(--danger);
  border-radius: var(--r-sm);
  background: var(--danger-wash);
  font-size: 12.5px;
  line-height: 1.7;
}
.ds-rp-lock > strong { display: block; color: var(--danger); }

/* ---------- 货件卡片 ---------- */
.ds-rp-ships { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 12px; }
.ds-rp-ship {
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: var(--r);
  background: var(--card);
}
.ds-rp-ship.is-counted  { border-left-color: var(--success); }
.ds-rp-ship.is-excluded { border-left-color: var(--faint); background: var(--paper); }
.ds-rp-ship-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.ds-rp-ship-id { font-family: var(--mono); font-size: 12px; font-weight: 600; }
.ds-rp-ship-qty { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12px; }
.ds-rp-ship-qty span { color: var(--muted); }
.ds-rp-ship-qty strong { display: block; font-size: 14px; font-variant-numeric: tabular-nums; color: var(--text); }
.ds-rp-ship-meta { margin-top: 8px; font-size: 11.5px; line-height: 1.7; color: var(--muted); }
.ds-rp-ship-note { margin-top: 7px; font-size: 11.5px; }
.ds-rp-ship-note.is-counted  { color: var(--success); }
.ds-rp-ship-note.is-excluded { color: var(--danger); }

/* 原因码：解释「为什么待确认」，只读展示，不是可点筛选，故不用 .ds-chip */
.ds-rp-codes { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.ds-rp-code {
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  font-size: 11.5px;
  color: var(--muted);
}
.ds-rp-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line-2);
}
.ds-rp-dot { display: inline-block; width: 8px; height: 8px; border-radius: 999px; background: var(--faint); }
.ds-rp-dot.is-ok    { background: var(--success); }
.ds-rp-dot.is-error { background: var(--danger); }

/* ============================================================
   登录 · 运营指挥台入口（全屏 dark console）
   这套调性是内页深蓝轻奢的源头，保持原样不动
   ============================================================ */
:root {
  --login-ink:    #0b1526;
  --login-ink-2:  #12213c;
  --login-line:   rgba(150,180,220,0.09);
  --login-cyan:   #4ecdd4;
  --login-lime:   #c3d640;
  --login-fg:     #eaf1f8;
  --login-muted:  #8497b3;
  --login-mono:   "SFMono-Regular", "Roboto Mono", ui-monospace, Menlo, monospace;
}

.ds-login {
  position: fixed;
  inset: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  padding: clamp(1.5rem, 6vw, 7rem);
  overflow: hidden;
  color: var(--login-fg);
  background:
    radial-gradient(120% 80% at 12% -10%, rgba(78,205,212,0.10), transparent 55%),
    radial-gradient(90% 90% at 108% 120%, rgba(27,42,74,0.85), transparent 60%),
    linear-gradient(158deg, var(--login-ink-2), var(--login-ink));
}
/* 细网格 data-field，向左上聚焦淡出 */
.ds-login::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--login-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--login-line) 1px, transparent 1px);
  background-size: 46px 46px;
  -webkit-mask-image: radial-gradient(125% 95% at 18% 28%, #000 38%, transparent 86%);
          mask-image: radial-gradient(125% 95% at 18% 28%, #000 38%, transparent 86%);
  pointer-events: none;
}
/* 缓慢漂移的青色极光 */
.ds-login::after {
  content: "";
  position: absolute;
  inset: -25%;
  background: radial-gradient(38% 38% at 32% 42%, rgba(78,205,212,0.13), transparent 70%);
  pointer-events: none;
}

/* 背景幽灵字：产品自己的模块名作为纹理 */
.ds-login-ghost {
  position: absolute;
  right: clamp(-1rem, 1vw, 2rem);
  bottom: 8vh;
  text-align: right;
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.02em;
  font-size: clamp(3rem, 10vw, 8.5rem);
  color: rgba(255,255,255,0.028);
  white-space: nowrap;
  user-select: none;
  pointer-events: none;
}

.ds-login-panel {
  position: relative;
  z-index: 1;
  max-width: 31rem;
}

.ds-login-status {
  display: inline-flex;
  align-items: center;
  gap: .6em;
  margin-bottom: 2.4rem;
  font-family: var(--login-mono);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--login-muted);
}
.ds-login-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--login-lime);
  box-shadow: 0 0 0 0 rgba(195,214,64,0.5);
}

.ds-login-eyebrow {
  font-family: var(--login-mono);
  font-size: 12px;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--login-cyan);
  margin-bottom: 1rem;
}
.ds-login-title {
  font-size: clamp(2.3rem, 5.4vw, 3.9rem);
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.03;
  margin-bottom: 1.1rem;
}
.ds-login-rule {
  width: 46px;
  height: 2px;
  border-radius: 2px;
  background: var(--login-cyan);
  margin-bottom: 1.2rem;
}
.ds-login-sub {
  max-width: 25rem;
  font-size: 15px;
  line-height: 1.75;
  color: var(--login-muted);
  margin-bottom: 2.6rem;
}

.ds-login-cta {
  display: inline-flex;
  align-items: center;
  gap: .65em;
  padding: .95em 1.5em;
  border: 0;
  border-radius: 12px;
  background: linear-gradient(180deg, #ffffff, #e9f0f5);
  color: #0d1b30;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 12px 30px -12px rgba(78,205,212,0.55), inset 0 1px 0 rgba(255,255,255,0.6);
  transition: transform .18s ease, box-shadow .25s ease;
}
.ds-login-cta:hover { transform: translateY(-2px); box-shadow: 0 18px 42px -14px rgba(78,205,212,0.8); }
.ds-login-cta:active { transform: translateY(0); }
.ds-login-cta:focus-visible { outline: 2px solid var(--login-cyan); outline-offset: 3px; }
.ds-login-cta[disabled] { opacity: .55; cursor: default; transform: none; box-shadow: none; }
.ds-login-cta svg { width: 18px; height: 18px; }

/* 账号密码登录表单：与 .ds-login-cta 同一视觉语言，深色玻璃输入框 + 亮色主按钮 */
.ds-login-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .7em;
}
.ds-login-input {
  flex: 1 1 10rem;
  min-width: 0;
  height: auto;
  padding: .95em 1.1em;
  border: 1px solid rgba(150,180,220,0.22);
  border-radius: 12px;
  background: rgba(255,255,255,0.05);
  color: var(--login-fg);
  font-family: var(--login-mono);
  font-size: 15px;
  letter-spacing: .08em;
  transition: border-color .18s ease, background .18s ease, box-shadow .25s ease;
}
.ds-login-input::placeholder {
  color: var(--login-muted);
  letter-spacing: normal;
  font-family: inherit;
}
.ds-login-input:focus {
  outline: none;
  border-color: var(--login-cyan);
  background: rgba(255,255,255,0.08);
  box-shadow: 0 0 0 3px rgba(78,205,212,0.16);
}
.ds-login-input[disabled] { opacity: .55; }

.ds-login-foot {
  position: absolute;
  left: clamp(1.5rem, 6vw, 7rem);
  bottom: 2.2rem;
  z-index: 1;
  font-family: var(--login-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.26);
}

/* 动效：仅在用户未要求减弱动画时启用 */
@media (prefers-reduced-motion: no-preference) {
  .ds-login::after { animation: ds-login-drift 20s ease-in-out infinite alternate; }
  .ds-login-dot   { animation: ds-login-pulse 2.4s ease-out infinite; }
  .ds-login-panel > * { animation: ds-login-rise .7s cubic-bezier(.2,.7,.2,1) backwards; }
  .ds-login-panel > *:nth-child(1) { animation-delay: .04s; }
  .ds-login-panel > *:nth-child(2) { animation-delay: .10s; }
  .ds-login-panel > *:nth-child(3) { animation-delay: .16s; }
  .ds-login-panel > *:nth-child(4) { animation-delay: .22s; }
  .ds-login-panel > *:nth-child(5) { animation-delay: .28s; }
  .ds-login-panel > *:nth-child(6) { animation-delay: .34s; }
  /* 第 7 个是加了 logo 底片之后多出来的一格，漏了它会没延迟直接冒出来 */
  .ds-login-panel > *:nth-child(7) { animation-delay: .40s; }
}
@keyframes ds-login-drift { from { transform: translate(-4%, -2%); } to { transform: translate(6%, 4%); } }
@keyframes ds-login-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(195,214,64,0.5); }
  70%  { box-shadow: 0 0 0 9px rgba(195,214,64,0); }
  100% { box-shadow: 0 0 0 0 rgba(195,214,64,0); }
}
@keyframes ds-login-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

@media (max-width: 720px) {
  .ds-login { align-items: flex-start; padding-top: 13vh; }
  .ds-login-ghost { display: none; }
}
