/*!
 * web/assets/css/index/18-bencho-motion.css
 * 2026-09-18 —— bencho.dev（UI interactive blocks）微交互融入层（全端加载）
 *
 * 原则：
 *  1. 只增强「交互动效」，不改变系统既有视觉体系（颜色/字号/布局不动）。
 *  2. 尊重 prefers-reduced-motion；触摸设备默认关闭 hover 磁吸/倾斜。
 *  3. 全部用 transform/opacity 动画，避免触发重排抖动业务布局。
 */

/* ========== 0. 全局：尊重系统减弱动效设置 ========== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ========== 1. Card tilt / 卡片抬升（tilt card）========== */
@media (hover: hover) and (pointer: fine) {
  .pos-card, .el-card, .ep-cell, .stat-card, .tilt-card {
    transition: transform .28s cubic-bezier(.22,.9,.3,1.2), box-shadow .28s ease;
  }
  /* will-change 只许挂在真会动的那一态：挂在常态等于每张卡片长期占一个合成层，
     没有 hover 的低端机也照样吃显存。 */
  .pos-card:hover, .el-card:hover, .ep-cell:hover, .stat-card:hover, .tilt-card:hover {
    will-change: transform;
    transform: translateY(-2px);
    box-shadow: 0 8px 22px rgba(30,30,30,.10);
  }
  .tilt-card { transform-style: preserve-3d; }
}

/* ========== 2. Magnetic / 按钮磁吸按压（magnetic select）========== */
@media (hover: hover) and (pointer: fine) {
  .el-button, .ep-btn, .pos-add, .fab-btn {
    transition: transform .18s cubic-bezier(.25,1.4,.5,1), box-shadow .2s ease, background-color .2s ease;
  }
  .el-button:active, .ep-btn:active, .pos-add:active, .fab-btn:active {
    transform: scale(.94);
  }
  .el-button--primary:hover:not(.is-disabled) {
    transform: translateY(-1px);
    box-shadow: 0 6px 16px rgba(var(--ep-color-primary-rgb,64,158,255), .28);
  }
  .mag-btn { display:inline-block; }
}

/* ========== 3. Liquid toggle / 液态开关（el-switch 弹性过渡）========== */
.el-switch .el-switch__core {
  transition: background-color .28s cubic-bezier(.34,1.3,.5,1), border-color .28s ease;
}
.el-switch .el-switch__core::after {
  transition: left .28s cubic-bezier(.34,1.56,.4,1);
}
.el-switch.is-checked .el-switch__core::after {
  left: calc(100% - 18px);
}

/* ========== 4. Progress ticks / 进度刻度流动（到货/发货/配额进度条）========== */
.el-progress-bar__inner, .po-item__fill, .progress-fill {
  background-image: linear-gradient(100deg,
    rgba(255,255,255,0) 0%, rgba(255,255,255,.28) 50%, rgba(255,255,255,0) 100%);
  background-size: 220% 100%;
  animation: bencho-progress-shine 2.4s linear infinite;
}
@keyframes bencho-progress-shine {
  0% { background-position: 120% 0; }
  100% { background-position: -120% 0; }
}
/* 进度环（radial dial）*/
.el-progress--circle .el-progress-circle__track, .el-progress--circle .el-progress-circle__path {
  transition: stroke-dashoffset .9s cubic-bezier(.4,0,.2,1);
}

/* ========== 5. Notify / 消息滑入（toast / message）========== */
.ep-toast, .el-message, .el-message-box {
  animation: bencho-notify-in .32s cubic-bezier(.25,1.4,.5,1);
}
@keyframes bencho-notify-in {
  0% { opacity: 0; transform: translateY(-14px) scale(.96); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* ========== 6. Dialog / 弹窗 pop 入场 ========== */
.el-dialog, .ep-dialog, .el-message-box {
  animation: bencho-dialog-in .26s cubic-bezier(.3,1.3,.5,1);
}
@keyframes bencho-dialog-in {
  0% { opacity: 0; transform: translateY(18px) scale(.96); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.el-overlay { animation: bencho-overlay-in .2s ease; }
@keyframes bencho-overlay-in {
  from { opacity: 0; } to { opacity: 1; }
}

/* ========== 7. Drag stepper / 步进器数字 tick ========== */
.el-input-number .el-input-number__decrease, .el-input-number .el-input-number__increase {
  transition: transform .16s ease, background-color .16s ease;
}
.el-input-number .el-input-number__decrease:active, .el-input-number .el-input-number__increase:active {
  transform: scale(.86);
}
.step-tick { display:inline-block; }
.step-tick.bump { animation: bencho-step-bump .3s cubic-bezier(.3,1.6,.5,1); }
@keyframes bencho-step-bump {
  0% { transform: translateY(6px); opacity: 0; }
  100% { transform: translateY(0); opacity: 1; }
}

/* ========== 8. Create menu / 悬浮动作按钮旋转展开 ========== */
.fab-btn:hover, .fab-btn:active { transform: rotate(90deg) scale(1.04); }

/* ========== 9. 列表入场 stagger（页面切换后逐项浮现）========== */
.ep-cell-group > *, .page .list-item, .el-table__body tr {
  animation: bencho-row-in .34s cubic-bezier(.25,.8,.35,1) backwards;
}
.ep-cell-group > *:nth-child(2) { animation-delay: .03s; }
.ep-cell-group > *:nth-child(3) { animation-delay: .06s; }
.ep-cell-group > *:nth-child(4) { animation-delay: .09s; }
.ep-cell-group > *:nth-child(5) { animation-delay: .12s; }
.ep-cell-group > *:nth-child(n+6) { animation-delay: .15s; }
@keyframes bencho-row-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
/* 表格行只保留透明度过渡，避免大表逐行延迟造成白屏感 */
.el-table__body tr { animation-name: bencho-fade-in; animation-duration: .22s; }
@keyframes bencho-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ========== 10. Reveal / 滚动进入视口显现（IntersectionObserver 驱动，JS 挂 .reveal） ========== */
.reveal { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .5s cubic-bezier(.22,.9,.3,1.1); }
.reveal.reveal-in { opacity: 1; transform: translateY(0); }

/* ========== 11. 底部 Tab 指示器弹性 ========== */
.tab-bar .tab-item.active { transform: translateY(-1px); }
.tab-bar .tab-item.active .tab-icon { transform: scale(1.08); }
.tab-bar .tab-item { transition: transform .22s cubic-bezier(.3,1.3,.5,1); }

/* ========== 12. Range dial / 数值卡片呼吸（统计卡） ========== */
.stat-num { display:inline-block; }
.stat-num.bump { animation: bencho-num-bump .45s cubic-bezier(.3,1.5,.5,1); }
@keyframes bencho-num-bump {
  0% { transform: scale(1); }
  35% { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* ========== 13. Inline confirm / 行内按钮二次确认脉冲 ========== */
.confirm-danger { animation: bencho-danger-pulse 1.1s ease infinite; }
@keyframes bencho-danger-pulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(244,67,54,.35); }
  55% { box-shadow: 0 0 0 6px rgba(244,67,54,0); }
}

/* ========== 14. Command bar / 顶栏毛玻璃 + 出现动画 ========== */
.ep-nav-bar { backdrop-filter: saturate(160%) blur(10px); -webkit-backdrop-filter: saturate(160%) blur(10px); }

/* ========== 11. Ripple 点击水波纹（bencho 风格，66-motion.js 事件委托生成） ========== */
.bencho-ripple {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, rgba(255,255,255,.55) 0%, rgba(255,255,255,0) 70%);
  transform: scale(0);
  animation: bencho-ripple .6s cubic-bezier(.2,.75,.3,1) forwards;
  z-index: 2;
  mix-blend-mode: overlay;
}
.el-button--warning .bencho-ripple, .el-button--danger .bencho-ripple { background: radial-gradient(circle, rgba(255,255,255,.6) 0%, rgba(255,255,255,0) 70%); }
@keyframes bencho-ripple { to { transform: scale(1); opacity: 0; } }
.el-button:not(.fab), .ep-btn, .pos-add, .fab-btn, .pos-bar__item, .ep-cell { position: relative; overflow: hidden; }

/* ========== 12. 页面切换入场（SPA 路由切换后整页淡入） ========== */
/* 2026-09-18：本动画绝不能使用 transform —— 任何非 none 的 transform（含 translateY(0)）
   都会让 .page 成为 fixed 元素的包含块，导致全项目底部 fixed 操作栏
   （结算/清退/调换/一键清退等）相对 .page 而非视口定位，最终遮挡内容。
   此内嵌浏览器在部分动画渲染下会停留在中间帧，所以必须只做 opacity 淡入。 */
.page { animation: bencho-page-in .3s ease-out backwards; }
@keyframes bencho-page-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ========== 13. 统计数字强调（卡片数字 hover 呼吸，bencho 风格） ========== */
.stat-card:hover .rs-num, .rs-card:hover .rs-num, .stat-num:hover { transform: scale(1.04); transition: transform .25s cubic-bezier(.22,.9,.3,1.2); }

/* ========== 14. 订单加急/置顶标签（2026-09-18 二轮：改为淡彩底+高对比彩字，参考 Element plain 风格） ==========
   背景低对比、文字高对比，不再实心渐变/发光/脉冲。 */
.ord-urgent-badge{
  background:#FDE8E8 !important; border:1px solid #F5B8B5 !important;
  color:#C81E1E !important; font-weight:700 !important;
}
.ord-top-badge{
  background:#FEF6E0 !important; border:1px solid #F5D98A !important;
  color:#B45309 !important; font-weight:700 !important;
}
/* #448（2026-11-01）：上面两枚加急/置顶标签是「淡彩底 + 深彩字」，暗档里就是深色页上两块浅色实心片。
   同语义换深底亮字；两边都带 !important，.dark 那条特异度更高（0,2,0 > 0,1,0）所以压得过。 */
.dark .ord-urgent-badge{
  background:#3A1414 !important; border:1px solid #5E2121 !important;
  color:#FF8A80 !important;
}
.dark .ord-top-badge{
  background:#3A2E10 !important; border:1px solid #5A4514 !important;
  color:#FFC46B !important;
}
/* 加急卡片左侧保留细色边做弱提示，不发光 */
.ord-card--urgent{ border-left:3px solid #F0A0A0 !important; }
.ord-card--top{ border-left:3px solid #E8C86A !important; }

/* 2026-09-18：.fab 悬浮按钮必须保持 fixed，避免被通用 .el-button{position:relative} 覆盖导致错位 */
.fab{position:fixed !important; left:auto !important; right:20px; z-index:60;}

/* ========== 15. 批次详情页：底部操作栏 + 关联订单卡片（2026-09-18；2026-09-25 改随内容排布） ==========
   2026-09-25 实测（1280x900 / 390x844，Edge headless + CDP，getBoundingClientRect 直读）：
   原 position:fixed 的悬浮条在三处盖住别的东西，而预留的底部 margin 并不解决它们——
     1) PC：left:12px 是相对**视口**的，整条滑进固定侧栏底下（.sidebar z-index:100 > 本条 20），
        与 .sidebar 实测重叠 208x53，「一键清退」611px 宽里有 196px 被一级菜单盖住；
     2) <768px：bottom:0 与 .mobile-tab（bottom:0 / z-index:99 / 高 58.4）完全重叠
        （实测 390x58.4），两个按钮在主力端既看不见也点不到；
     3) 文档末尾是 #gp-site-footer，任何贴底的 fixed 条滚到页尾都必然压住版权条
        （实测移动端 390x59，版权文字被盖掉 37.6px 高）。
   改成随内容排布在 .page 末尾（订单列表之后、版权条之前）：三处遮挡一次消除，
   不再需要给 .batch-orders-wrap 预留 120/150px 的底部 margin（那个预留本来就只兜住了订单卡）。 */
.batch-actions-bar{margin:0 12px;background:var(--bg);border-top:1px solid var(--bd);padding:10px 12px;display:flex;gap:10px}
@media(min-width:768px){.batch-actions-bar{max-width:860px;margin:0 auto;border-radius:14px;box-shadow:0 -2px 12px rgba(0,0,0,.06)}}
.batch-orders-wrap{margin:10px 12px 0}
@media(min-width:768px){.batch-orders-wrap{margin:10px auto 0;max-width:860px}}
.batch-ord-card{margin-bottom:10px;cursor:pointer}
/* #86 根因（2026-09-26 实测定位）：`.ord-card` 基类是**横向** flex（销售列表里它是
   「缩略图 + 右侧正文」两列），所以卡片必须像别的页面那样带 `ord-card--rows` 修饰类变成竖排。
   批次卡当初只加了 `batch-ord-card` 而漏了那个修饰类 → r1/r2/r3 三行被并排摆成一行，
   375px 下 .ord-card 的 scrollWidth 601 / clientWidth 271，「待收款」标签整只被推到屏幕外
   （right:390 > 视口 375，且父级 overflow 是 visible，所以既看不见也滚不到）。
   上一轮在这里试过给 .ord-r1 加 flex-wrap，结果"客户名消失、单号出界"——那不是 wrap 的错，
   是卡片本身还在横排：r1 拿到的宽度是被兄弟行分剩下的。**先修根因，再谈换行。** */
.batch-ord-card{flex-direction:column;align-items:stretch;gap:8px}
.batch-ord-card .ord-r1{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.batch-ord-card .ord-r1__cust{display:flex;align-items:center;gap:6px;flex:1 1 auto;min-width:0}
.batch-ord-card .ord-r1__cname{max-width:none}
.batch-ord-tags{margin-top:8px;display:flex;gap:6px;flex-wrap:wrap}
