/* ============================================================================
   设计系统 V3 · 第 2 / 3 批
   组件交互 + 页面切换过渡 + 导航指示条 + 内容入场
   ----------------------------------------------------------------------------
   放在 design-tokens-v3-blue.css 之后引入。
   本文件只做「叠加覆盖」，不修改 index.html 内联样式的任何一行，
   因此整体删除本文件 + 移除 <link> 即可完全回退。
   ============================================================================ */

/* ==========================================================================
   0. 基础层
   --------------------------------------------------------------------------
   这部分原先是写在 token 文件里的，后来挪过来：token 文件带规则会以
   「全局覆盖」的方式影响它本不该碰的东西（曾导致移动端字体栈被换掉、
   nowrap 行挤出 90px 横向滚动）。规则归本文件，变量归 token 文件。
   ========================================================================== */

/* 数字与金额：一律等宽并启用 tabular-nums，保证表格数字列纵向对齐 */
.num,.tbl .num,td.num,th.num,[data-num],.mini td,.mini th{
  font-family:var(--mono,var(--font-mono));
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1
}

/* 键盘焦点必须可见。输入类控件已有自己的聚焦环（边框加 box-shadow），
   这里不再叠加 outline，避免出现双重边框。 */
:focus-visible{
  outline:2px solid var(--p-500);
  outline-offset:2px;
  border-radius:var(--r-sm)
}
input:focus-visible,
select:focus-visible,
textarea:focus-visible{outline:none}

/* ==========================================================================
   1. 按钮：悬停提亮 / 按下 / 松手回弹 / 键盘聚焦
   --------------------------------------------------------------------------
   悬停提亮改用 ::before 叠加层动 opacity，不用 filter:brightness ——
   后者会让按钮脱离合成层单独重绘，大面积按钮密集的页面上差距明显。
   ========================================================================== */
.btn{
  position:relative;
  isolation:isolate;
  overflow:hidden;
  transform:translateY(0) scale(1);
  transition:transform var(--d-1) var(--ease-out),
             box-shadow var(--d-1) var(--ease-out)
}
.btn::before{
  content:'';position:absolute;inset:0;z-index:-1;opacity:0;
  background:linear-gradient(140deg,var(--p-300),var(--p-500));
  transition:opacity var(--d-1) var(--ease-out);
  pointer-events:none
}
.btn:hover::before{opacity:1}
.btn:hover{transform:translateY(-1px);
  box-shadow:var(--sh-brand-hover),var(--hi-inset)}
.btn:active{
  transform:translateY(0) scale(.975);
  box-shadow:var(--sh-brand),var(--hi-inset);
  transition:transform var(--d-0) var(--ease-out),
             box-shadow var(--d-0) var(--ease-out)
}

/* 幽灵 / 静默 / 危险按钮的叠加层各自换色，避免统一变亮蓝 */
.btn.ghost::before{background:var(--p-50)}
.btn.ghost{box-shadow:none}
.btn.ghost:hover{box-shadow:var(--sh-2)}
.btn.danger::before{background:linear-gradient(140deg,#e07068,var(--danger))}
.btn.danger:hover{box-shadow:0 7px 20px rgba(199,54,43,.36)}

/* 禁用：关闭全部动效。禁用态不动比动更清楚 */
.btn:disabled,
.btn[disabled]{
  transform:none;
  box-shadow:none
}
.btn:disabled::before,
.btn[disabled]::before{display:none}
.btn:disabled:hover,
.btn[disabled]:hover{transform:none;box-shadow:none}

/* 键盘聚焦：只对 Tab 触发，鼠标点击不出现 */
.btn:focus-visible{
  outline:2px solid var(--p-500);
  outline-offset:2px
}

/* 键盘按下的触感与鼠标一致 */
.btn:focus-visible:active{transform:translateY(0) scale(.975)}

/* ==========================================================================
   2. 表格行：行高亮必须跟手，用最短的一档
   ========================================================================== */
.tbl tbody tr td{
  transition:background var(--d-0) var(--ease-out)
}
.tbl tbody tr:hover td{background:rgba(46,111,232,.055)}
.tbl tr.rx-pending:hover td{background:rgba(199,54,43,.14)}

/* 汇总行与数字列：保证纵向对齐 */
.tbl .num,.tbl td.num,.tbl th.num,.mini td,.mini th{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1
}

/* ==========================================================================
   3. 页面切换：标题进入 + 内容进入
   --------------------------------------------------------------------------
   注意：这里只做「进入」，不做「旧页退出」。
   两阶段的旧页退出需要等 100ms 才换内容，会平白给数据加载加上 100ms 延迟，
   违反「绝不为了播放动画而延迟渲染」这条规矩。进入动画本身已经足以让
   切换被感知到，且不引入任何额外延迟。
   ========================================================================== */
@keyframes v3TitleIn{
  from{opacity:0;transform:translateY(5px)}
  to{opacity:1;transform:translateY(0)}
}
.title-in{animation:v3TitleIn calc(180ms * var(--spd)) var(--ease-out) both}

@keyframes v3PageIn{
  from{opacity:0;transform:translateY(6px)}
  to{opacity:1;transform:translateY(0)}
}
.page-entering{animation:v3PageIn calc(220ms * var(--spd)) var(--ease-snap) both}

/* 顶栏副标题（页面副标题）跟着一起淡入，但比主标题慢一点，形成层次 */
.title-in small{animation:v3TitleIn calc(240ms * var(--spd)) var(--ease-out) both}

/* ==========================================================================
   4. 内容入场：前 8 项交错，步长 32ms
   --------------------------------------------------------------------------
   只对 #content 的直接子区块交错（筛选条、KPI 行、表格、面板），
   不对表格行交错 —— 100 行逐行入场会拉到 3 秒以上，且整表像波浪一样抖。
   JS 在入场结束后会把 entry-on / entry-in 两个类都摘掉，
   否则残留的 transition-delay 会拖住后续的卡片悬停反馈。
   ========================================================================== */
#content.entry-on > *{
  opacity:0;
  transform:translateY(6px);
  transition:opacity calc(240ms * var(--spd)) var(--ease-out),
             transform calc(240ms * var(--spd)) var(--ease-out)
}
#content.entry-on > *:nth-child(1){transition-delay:calc(0ms * var(--spd))}
#content.entry-on > *:nth-child(2){transition-delay:calc(32ms * var(--spd))}
#content.entry-on > *:nth-child(3){transition-delay:calc(64ms * var(--spd))}
#content.entry-on > *:nth-child(4){transition-delay:calc(96ms * var(--spd))}
#content.entry-on > *:nth-child(5){transition-delay:calc(128ms * var(--spd))}
#content.entry-on > *:nth-child(6){transition-delay:calc(160ms * var(--spd))}
#content.entry-on > *:nth-child(7){transition-delay:calc(192ms * var(--spd))}
#content.entry-on > *:nth-child(n+8){transition-delay:calc(224ms * var(--spd))}
#content.entry-on.entry-in > *{opacity:1;transform:translateY(0)}

/* 卡片网格内的 SKU 卡同样做交错（一屏只有 6 到 12 张，适合交错） */
.card-grid.entry-on > *,
.sku-grid.entry-on > *{
  opacity:0;transform:translateY(6px);
  transition:opacity calc(240ms * var(--spd)) var(--ease-out),
             transform calc(240ms * var(--spd)) var(--ease-out)
}
.card-grid.entry-on.entry-in > *,
.sku-grid.entry-on.entry-in > *{opacity:1;transform:translateY(0)}

/* ==========================================================================
   5. 侧栏导航：指示条滑动 + 选中项底色
   --------------------------------------------------------------------------
   指示条是导航容器里的「单个」绝对定位元素，切换时改它的 translateY。
   不是给每个导航项画左边框 —— 那样无法产生位移，只会闪现。
   ========================================================================== */
#nav{position:relative}
.nav-ind{
  position:absolute;left:0;top:0;width:3px;height:16px;
  border-radius:0 3px 3px 0;
  background:linear-gradient(180deg,var(--p-400),var(--p-600));
  opacity:0;
  pointer-events:none;
  transition:transform calc(200ms * var(--spd)) var(--ease-out),
             opacity calc(140ms * var(--spd)) var(--ease-out);
  will-change:transform
}
.nav-ind.on{opacity:1}
/* 指示条取代了每个项自带的 ::before 竖条，避免两者叠加出现双竖条 */
.nav-item.on::before{display:none}
.nav-item.on{
  box-shadow:inset 0 0 0 1px rgba(46,111,232,.22)
}
.nav-item{
  transition:background var(--d-1) var(--ease-out),
             color var(--d-1) var(--ease-out),
             transform var(--d-0) var(--ease-out)
}
.nav-item:active{transform:scale(.985)}
/* 同步区分组用石青而非竞争蓝 */
.nav-group.sync-group{
  color:var(--cy-700);
  background:linear-gradient(90deg,rgba(11,125,150,.10),transparent)
}
.nav-item.sync-item.on{
  background:linear-gradient(135deg,rgba(11,125,150,.14),rgba(9,101,121,.06));
  color:var(--cy-700);
  box-shadow:inset 0 0 0 1px rgba(11,125,150,.24)
}

/* ==========================================================================
   6. 骨架屏（供后续接入；现在无调用也不产生任何影响）
   ========================================================================== */
.sk{
  background:linear-gradient(90deg,var(--n-100) 25%,#fff 50%,var(--n-100) 75%);
  background-size:200% 100%;
  animation:v3Shim calc(1.4s * var(--spd)) linear infinite;
  border-radius:var(--r-xs)
}
@keyframes v3Shim{
  from{background-position:200% 0}
  to{background-position:-200% 0}
}

/* ==========================================================================
   7. 动效降级
   ========================================================================== */
/* 用户系统层面要求减少动效 */
@media (prefers-reduced-motion: reduce){
  .btn,
  .btn::before,
  .nav-ind,
  .nav-item,
  .tbl tbody tr td,
  #content.entry-on > *{
    transition-duration:.001ms !important;
    transition-delay:0ms !important
  }
  .title-in,.page-entering,.sk,
  .title-in small{
    animation:none !important
  }
  .title-in,.page-entering{opacity:1 !important;transform:none !important}
  .sk{background:var(--n-100)}
}

/* 精简模式 / 手动关：html[data-motion="off"]
   由 ymMotion(0) 写入。远程桌面与低配机建议开启。 */
html[data-motion="off"] .btn,
html[data-motion="off"] .btn::before,
html[data-motion="off"] .nav-ind,
html[data-motion="off"] .nav-item,
html[data-motion="off"] .tbl tbody tr td,
html[data-motion="off"] #content.entry-on > *{
  transition:none !important
}
html[data-motion="off"] .title-in,
html[data-motion="off"] .page-entering,
html[data-motion="off"] .sk,
html[data-motion="off"] .title-in small{
  animation:none !important
}
html[data-motion="off"] .sk{background:var(--n-100)}
html[data-motion="off"] #content.entry-on > *{opacity:1 !important;transform:none !important}

/* 精简模式：远程桌面 / 低配机，在 <html> 上加 class="lite"
   关掉玻璃模糊、噪点与光晕 —— 远程桌面下 backdrop-filter 的开销极高。 */
html.lite{--spd:0}
html.lite .grain{display:none}
html.lite .app::before,
html.lite .app::after{display:none}
html.lite .kpi,
html.lite .card,
html.lite .modal,
html.lite .nav,
html.lite .topbar,
html.lite .gsearch{
  backdrop-filter:none !important;
  -webkit-backdrop-filter:none !important;
  background:rgba(255,255,255,.97) !important
}
html.lite *{animation:none !important;transition:none !important}

/* 用户系统层面要求降低透明度：玻璃回退为实底 */
@media (prefers-reduced-transparency: reduce){
  .kpi,.card,.modal,.nav,.topbar,.tbl-wrap,.gsearch{
    background:var(--glass-2) !important;
    backdrop-filter:none !important;
    -webkit-backdrop-filter:none !important
  }
}

/* ==========================================================================
   8. 图表通用基元 chart kit（2026-09-14 立）
   --------------------------------------------------------------------------
   数据总览（桌面 index.html 与移动端 mobile.html）共用这一套。
   之所以放共享层而不是各写一份：改一处就能两端同时生效，
   这正是「持续一致性」的实现方式。

   ★ 为什么必须用类名而不是 attribute
   SVG 的 presentation attribute（fill="var(--x)"）在 Chrome 不解析 var()，
   会静默回退成黑色。所以图形元素一律给类名，颜色由本段提供。

   颜色来源统一为 design-tokens-v3-blue.css 的 --chart-* 组。
   ========================================================================== */
.ck-grid{stroke:var(--chart-grid);stroke-width:1}
.ck-base{stroke:var(--chart-base);stroke-width:1}
.ck-axis{fill:var(--chart-axis);font-size:10.5px;font-family:var(--font-mono,ui-monospace,monospace)}
.ck-axis-r{fill:var(--p-600);font-size:10.5px;font-family:var(--font-mono,ui-monospace,monospace)}
.ck-line-1{fill:none;stroke:var(--chart-c1);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.ck-line-2{fill:none;stroke:var(--chart-c2);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.ck-dot{fill:var(--n-50);stroke:var(--chart-c2);stroke-width:2}
/* 面积渐变端点（stop 用 CSS 类着色，同样避开 attribute 的 var() 限制） */
.ck-g1a{stop-color:var(--chart-c1);stop-opacity:.40}
.ck-g1b{stop-color:var(--chart-c1);stop-opacity:.02}
.ck-g2a{stop-color:var(--chart-c2);stop-opacity:.36}
.ck-g2b{stop-color:var(--chart-c2);stop-opacity:.02}
/* 图例色块 —— 2026-09-18 店铺订单·成交额卡同步 Mono 编辑部语法（与 dm-sw 同款）：
   黑 = 主序列（订单数）、浅灰细条 = 次序列（成交额），明度即数据 */
.ck-sw1{background:#1C1C1A}
/* 高度收细条由页面内联 .dash-legend .sw.ck-sw2 提供（此处特异性不够） */
.ck-sw2{background:#C6C5BF}
/* 双系列横条填充 */
.ck-bar1{background:#1C1C1A}
.ck-bar2{background:#C6C5BF}
/* 库存分布条：语义色 */
.ck-tone-p{background:var(--n-700)}
.ck-tone-i{background:var(--warn-vivid)}
.ck-tone-r{background:var(--warn)}
.ck-tone-a{background:var(--ok)}
