/* 智配One · 全局 UI 统一层 2.1
   只负责视觉、层级、触控与反馈，不承载任何业务规则。 */
:root{
  /* ===== 全局设计 Token · 单一真相源（Commit 2A） =====
     背景：历史上并存三套割裂的变量 —— app.css 的无前缀版（--bg/--card/--card2/--line/--muted；--soft 已于 Commit 4B 删除）、
           mobile-ui.css 的 --zp-* 版、本文件的 --ui-* 版，同一语义写三遍，改主题必须改三处。
     做法：将取值完全一致的语义统一收敛到 --zp-* 名下，放在本 :root。
           之所以选本文件作为权威层，是因为它是**唯一被全部页面加载**的 CSS
           （ui-unified.css 覆盖 14/14；app.css 缺 admin.html；mobile-ui.css 仅覆盖 7/14）。
     兼容：旧变量名一律保留为别名指向新 token，任何既有 var(...) 的解析结果逐字节不变。

     未合并项（勿强行统一，强行合并会造成视觉漂移）：
       ◆ danger 双值共役：--zp-danger=#FFB4AB（mobile-ui.css，当前 .message.error 在用，1 处）
                          --ui-danger =#FF8278（本文件，4 处在用）
         两者都在服役且取值不同，合并必然改变某一方的红色外观，故保持独立，列为待决策项。
       ◆ app.css 的 --soft=#202B36 其实是表面色（等同 surface-3），并非弱文字色，属历史命名错误。
         全仓核查确认它是死定义：admin.html 不加载 app.css 而用内联 --soft:#7F8A95，普通页面不引用 --soft，
         故已于 Commit 4B 直接删除，零视觉影响（无页面级 var(--soft) 解析值变化）。 */
  /* ===== 页面 / 表面 / 文字（Uber 风格中性灰阶 · 深色）=====
     对标 Uber Base Web：近黑底 + 纯白文字 + 中性灰梯度，
     主按钮深色模式反白（白底黑字）、浅色模式反黑（黑底白字）。 */
  --zp-bg:#0A0A0A;
  --zp-surface:#1A1A1A;
  --zp-surface-2:#262626;
  --zp-surface-3:#333333;
  --zp-line:#2E2E2E;
  --zp-text:#FFFFFF;
  --zp-muted:#A8A8A8;
  --zp-soft:#767676;
  --zp-radius:14px;
  /* 骨架微光条（加载占位）双外观 token：order_detail / home / data 三处
     页面级骨架共用同一取值。深色外观为暗灰微光；浅色外观在下方
     [data-zp-theme="light"] 覆盖为浅灰微光——修复浅色背景下骨架条
     仍是硬编码深色「大黑条」的问题（2026-10-16）。 */
  --zp-sk-a:#1A222C;
  --zp-sk-b:#202A31;
  /* ===== 全局按钮标准 · 分段式动作按钮（单一真相源）=====
     基准度量取自「外观模式」选项组（跟随系统/深色/浅色）与「线路切换」等
     行内动作按钮，两类按钮历史上各自起值（高 40/42、圆角 10/12、宽度
     自适应 vs 三等分），表现为跨页按钮胖瘦不一。现统一为：
       高度 42 / 圆角 12 / 字号 13·600 / 边框 1px / 水平内边距 8px
       段宽按钮（选项组内）= calc((容器宽 - 2*间隙)/3)
     新增同类按钮一律沿用本 token，禁止在页面级 CSS 另起度量。 */
  --zp-seg-btn-h:42px;
  --zp-seg-btn-radius:12px;
  --zp-seg-btn-pad:0 8px;
  --zp-seg-btn-font:13px;
  --zp-seg-btn-gap:8px;
  /* ===== 主按钮（Uber 风格：深色反白 / 浅色反黑）=====
     --zp-primary 是按钮「底色」：深色模式=白，浅色模式=近黑；
     --zp-on-primary 是按钮上的「文字/图标色」，与底色反相。 */
  --zp-primary:#FFFFFF;
  --zp-on-primary:#0A0A0A;
  /* 次按钮（描边 / 幽灵按钮） */
  --zp-secondary-bg:#1F1F1F;
  --zp-secondary-border:#404040;
  --zp-secondary-text:#FFFFFF;
  /* 禁用态 */
  --zp-disabled-bg:#2A2A2A;
  --zp-disabled-text:#6B6B6B;
  /* 浮层遮罩（弹窗 / 底部面板上方的半透明黑幕） */
  --zp-scrim:rgba(0,0,0,.72);
  /* 键盘 / 焦点可见环 */
  --zp-focus:#FFFFFF;
  /* 交互态：hover（悬停）、active（按压） */
  --zp-primary-hover:#EAEAEA;
  --zp-primary-active:#D4D4D4;
  --zp-secondary-hover:#2A2A2A;
  --zp-secondary-active:#333333;
  /* 半透明 / 不透明卡片底色（保留两种用途，取值随主题翻转） */
  --zp-card-translucent:rgba(26,26,26,.82);
  --zp-card-translucent-2:rgba(10,10,10,.88);
  --zp-card:var(--zp-surface);
  /* 列表分隔线（方案第十五章 Row，统一为 .10 单一来源） */
  --zp-divider:rgba(255,255,255,.10);
  /* ===== 功能状态色（成功 / 警告 / 错误 / 提示）=====
     -strong 用于边框 / 图标 / 危险操作；-soft 用于底色微染；
     --zp-danger 专用于「错误正文」（浅红，可读性优先），随主题翻转。 */
  --zp-success:#2ECC71;
  --zp-success-soft:rgba(46,204,113,.14);
  --zp-warning:#F5A623;
  --zp-warning-soft:rgba(245,166,35,.14);
  --zp-error:#FF6B5E;
  --zp-error-soft:rgba(255,107,94,.14);
  --zp-danger:#FFB4AB;
  --zp-info:#4DA3FF;
  --zp-info-soft:rgba(77,163,255,.14);

  /* ===== 间距与控件尺寸（方案第九 / 十一 / 十二章） =====
     取值取自当前代码的实际分布，不是凭空定的理想值，避免引入尺寸跳变：
       header-height 54px —— 现有值为 42/48/52/54/56，取方案第十一章推荐的标准值。
         注意：矮屏 @media(max-height:700px) 的压缩态属响应式特例，不套用此变量。
       control-height 48px —— Android 最小可靠触控靶区。现有取值从 40 到 44 不等，
         全部低于该标准，故本轮是「只放大不缩小」的单向收敛（见 css-touch-audit.cjs）。 */
  --zp-header-height:54px;
  --zp-control-height:48px;
  --zp-space-4:16px;

  --ui-bg:var(--zp-bg);
  --ui-surface:var(--zp-surface);
  --ui-surface-2:var(--zp-surface-2);
  --ui-surface-3:var(--zp-surface-3);
  --ui-line:var(--zp-line);
  --ui-text:var(--zp-text);
  --ui-muted:var(--zp-muted);
  --ui-soft:var(--zp-soft);
  --ui-radius:var(--zp-radius);
  /* danger 保持独立取值（不与 --zp-danger 合并），理由见顶部注释 */
  --ui-danger:#FF8278;
  --ui-danger-soft:rgba(255,130,120,.08);
  --ui-dialog-radius:18px;
  --ui-control-radius:11px;

  /* ===== 全局层级体系 3.0 =====
     目的：任何"后打开的弹窗都在上层"，Toast 永远可见，确认框永远盖不住。
     约定：同一层级内的元素不得互相覆盖；跨层级严格递进。
     规则：页面内所有 position:fixed / absolute + z-index 一律引用下列变量，禁止硬编码。 */
  --ui-z-topbar:10;        /* 顶栏：页面顶部固定栏 */
  --ui-z-float:90;         /* 悬浮操作：快速滚动、悬浮按钮（不遮挡弹窗） */
  --ui-z-menu:200;         /* 菜单浮层：下拉菜单、页面菜单、选择器（非模态） */
  --ui-z-modal:1000;       /* 模态第 1 层：业务弹窗（导入/订单/历史/账号/上传） */
  --ui-z-modal-stack:1100; /* 模态第 2 层：模态之上再弹（历史选择器等） */
  --ui-z-modal-top:1200;   /* 模态第 3 层：最终确认（删除等破坏性操作） */
  --ui-z-toast:2000;       /* 全局提示：Toast / 气泡反馈（永远最上） */
}
html,body{background:var(--ui-bg);color:var(--ui-text)}
button,a,input,select,textarea{font-family:inherit}
button,a{-webkit-tap-highlight-color:transparent}
button:active{transform:translateY(0)}
/* 细节微调（不改全局设计语言）：
   1) 移除所有可点元素的原生点击高亮，统一触控反馈（含 div 型行/卡片，此前只对 button/a 生效）；
   2) 首帧后开启颜色/背景/边框/阴影/不透明度的短过渡，让主题切换与状态变化更顺滑；
   3) 关键按钮按压时轻微缩放，点按手感一致。
   用 :where() 把覆盖特异性降到 0，确保各组件自带 transition（悬浮滚动、入场动画等）不被覆盖；
   首帧开关由 js/ui-unified.js 的 zp-ui-ready 类控制，初始渲染不闪。 */
*{ -webkit-tap-highlight-color:transparent; -webkit-touch-callout:none }
.zp-ui-ready :where(*):not(:where(svg,svg *)){
  transition:background-color .22s ease,border-color .22s ease,color .22s ease,box-shadow .2s ease,opacity .2s ease;
}
.zp-ui-ready :where(button,a,[role="button"],.data-action-btn,.account-logout,.login-submit,.trend-year,.trend-metric-btn,.source-option,.choice-btn){
  transition:background-color .22s ease,border-color .22s ease,color .22s ease,box-shadow .2s ease,opacity .2s ease,transform .1s ease;
}
.zp-ui-ready :where(.data-action-btn,.account-logout,.login-submit,.trend-year,.trend-metric-btn,.source-option,.choice-btn):active{
  transform:scale(.98);
}
@media (prefers-reduced-motion:reduce){
  .zp-ui-ready :where(*){transition:none!important}
  .zp-ui-ready :where(.data-action-btn,.account-logout,.login-submit,.trend-year,.trend-metric-btn,.source-option,.choice-btn):active{transform:none}
}
/* hidden 属性必须始终生效，且优先级高于所有遮罩层 display 规则。
   用 !important + 属性选择器双写，确保任何后出现的 !important 规则都无法覆盖它。
   背景：弹窗遮罩统一使用 display:flex!important 后，与 [hidden] 权重相同，
   若顺序靠后会导致 hidden 失效、弹窗无法关闭。此处以 [hidden][hidden] 提升权重。 */
[hidden],
[hidden][hidden]{display:none!important}

/* 页面层级：页面 > 卡片 > 次级区域，避免无意义的多层嵌套视觉 */
.card,.page2-card,.data-route-card,.data-list-card,.task-card{
  border-color:rgba(255,255,255,.075);
  box-shadow:none;
}
.card,.page2-card{border-radius:var(--ui-radius)}
.confirm-panel,.pending-box{background:var(--ui-surface-2);border-color:rgba(255,255,255,.07)}

/* 顶部栏统一：标准 Header 钩子 .topbar（阶段 6 · 5A）
   布局由各页旧类规则承载（保留差异：dispatch 白字标题 / data 头 padding / history 占位 /
   order 按钮返回 #backBtn / home flex 无返回），.topbar 仅提供统一钩子 + 共享三栏排版 +
   标题字重。不在此设 margin-bottom（dispatch/data 头间距由各自规则控制，避免零回归外的位移）。
   详见资产审计台账第二十四章。 */
.topbar{
  display:grid;
  grid-template-columns:var(--zp-control-height) 1fr var(--zp-control-height);
  align-items:center;
  min-height:var(--zp-header-height);
  position:relative;
}
.topbar strong,.order-title{font-weight:650}
/* 统一返回钩子 .app-back（阶段 6 · 5A）：link 型返回键统一为 48px 触控靶区；
   order 页返回为 <button id="backBtn>（由 ID 接线，不在此类）。 */
.app-back{
  width:var(--zp-control-height);
  height:var(--zp-control-height);
  display:inline-flex;
  align-items:center;
  justify-content:center;
  border:0;
  border-radius:12px;
  background:transparent;
  color:var(--ui-muted);
  text-decoration:none;
  font-size:0;
  box-sizing:border-box;
}
.app-back svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.app-back:active{background:rgba(20,28,37,.80);color:#fff}

/* 菜单统一为单层浮层 */
.data-page-menu, .order-menu{
  border:1px solid var(--ui-line);
  border-radius:12px;
  background:var(--ui-surface);
  box-shadow:0 14px 34px rgba(0,0,0,.34);
  overflow:hidden;
}
/* 菜单面板内的条目本身就是点击目标，不是「列表里的文字」，按第十三章必须 ≥48。
   注意：本条是跨页面的兜底值，data.css / order_detail.css 里还有同选择器的后续定义，
   后者会覆盖这里 —— 已一并收敛，改动是否真的生效以 css-button-resolve.cjs 的页面级结果为准。 */
.data-page-menu button, .order-menu button{
  min-height:var(--zp-control-height);
}
.menu-divider{background:rgba(255,255,255,.07)}

/* 统一按钮语义：主操作右侧、取消/次要操作左侧 */
.data-import-actions,.history-dialog-actions,.order-dialog-actions,.account-dialog-actions{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:10px;
}
.data-import-actions button,.history-dialog-actions button,.order-dialog-actions button,.account-dialog-actions button{
  min-height:var(--zp-control-height);
  border-radius:var(--ui-control-radius);
  font-size:14px;
  font-weight:550;
}
.data-import-actions button:first-child,.history-dialog-actions button:first-child,.order-dialog-actions button:first-child,.account-dialog-actions button:first-child{
  background:var(--ui-surface-2);
  border:1px solid #35404C;
  color:#E8EDF2;
}
.data-import-actions button:last-child,.history-dialog-actions button:last-child,.order-dialog-actions button:last-child,.account-dialog-actions button:last-child{
  background:var(--ui-surface-3);
  border:1px solid #3A4652;
  color:#fff;
}

/* 统一模态层：只保留一层遮罩 + 一个内容面板 */
.order-dialog,.history-dialog,.data-import,.upload-overlay{
  background:rgba(0,0,0,.58)!important;
}
.order-dialog-panel,.history-dialog-panel,.data-import-panel,.account-dialog,.upload-sheet{
  background:var(--ui-surface);
  border:1px solid var(--ui-line);
  border-radius:var(--ui-dialog-radius);
  box-shadow:0 18px 50px rgba(0,0,0,.42);
}
.order-dialog-panel,.history-dialog-panel,.data-import-panel,.account-dialog{
  max-width:398px;
}
.order-dialog-head,.data-import-head{
  min-height:40px;
}
.order-dialog-head strong,.data-import-head h3,.history-dialog-panel>strong,.account-dialog h2{
  font-size:17px;
  line-height:24px;
  font-weight:650;
}
.order-dialog-panel>p,.history-dialog-panel>p,.account-dialog>p{
  color:var(--ui-muted);
}

/* 二次确认：不再使用大图标/装饰层，突出标题、风险说明、操作 */
.page2-danger-btn,.data-swipe-delete{color:var(--ui-danger)!important}

/* 上传/处理：同一面板内切换内容，不叠加第二个面板 */
.upload-sheet{overflow:hidden}
.upload-source-menu,.upload-processing{background:transparent}
.sheet-handle{opacity:.8}

/* 表单统一：标签、输入、错误信息节奏一致 */
input,select,textarea{
  border-radius:var(--ui-control-radius)!important;
}
.message,.login-message{line-height:20px}
.message.error,.login-message[role=alert]{color:#FFB4AB}

/* Toast/轻反馈：用于成功、复制、保存等非破坏性反馈 */
.ui-toast{
  position:fixed;
  left:50%;
  bottom:calc(24px + env(safe-area-inset-bottom));
  z-index:400;
  max-width:calc(100vw - 32px);
  padding:10px 14px;
  border:1px solid var(--ui-line);
  border-radius:10px;
  background:var(--ui-surface);
  color:#fff;
  font-size:13px;
  line-height:18px;
  text-align:center;
  box-shadow:0 10px 28px rgba(0,0,0,.36);
  transform:translate(-50%,10px);
  opacity:0;
  pointer-events:none;
  transition:opacity .18s ease,transform .18s ease;
}
.ui-toast.show{opacity:1;transform:translate(-50%,0)}
.ui-toast.success{background:#1D2A24}
.ui-toast.error{background:#302326;border-color:#594048}

/* 状态文字与列表节奏统一 */
.empty,.dispatch-empty,.dispatch-message,.history-state{
  color:var(--ui-soft);
}
.store-row,.account-row,.request-row{
  border-bottom-color:rgba(255,255,255,.065);
}

/* 小屏：进一步减少外层留白，不缩小触控目标 */
@media(max-width:380px){
  .order-dialog,.history-dialog,.data-import,.upload-overlay{padding:14px}
  .order-dialog-panel,.history-dialog-panel,.data-import-panel,.account-dialog{border-radius:16px}
}
@media(prefers-reduced-motion:reduce){
  .ui-toast{transition:none}
}

/* 全局二次确认弹窗 */
.zp-confirm{position:fixed;top:0;right:0;bottom:0;left:0;inset:0;z-index:500;display:flex;align-items:center;justify-content:center;padding:18px;background:rgba(0,0,0,.58)}
.zp-confirm[hidden]{display:none}
.zp-confirm-panel{width:min(100%,360px);padding:20px 18px 16px;border:1px solid var(--ui-line);border-radius:18px;background:var(--ui-surface);box-shadow:0 18px 50px rgba(0,0,0,.45)}
.zp-confirm-panel h3{margin:0;color:#fff;font-size:17px;line-height:24px;font-weight:650}
.zp-confirm-panel p{margin:8px 0 0;color:var(--ui-muted);font-size:13px;line-height:20px;word-break:break-word}
.zp-confirm-actions{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:18px}
.zp-confirm-actions button{min-height:var(--zp-control-height);border-radius:11px;font-size:14px;font-weight:550}
.zp-confirm-actions button:first-child{border:1px solid #35404C;background:rgba(10,14,19,.88);color:#E8EDF2}
.zp-confirm-actions button:last-child{border:1px solid #3A4652;background:rgba(26,38,46,.82);color:#fff}

/* Android 移动端文字规范 2.4
   仅调整文字尺寸与行高，不改变业务规则、数据结构、交互逻辑或页面布局。
   目标层级：页面标题 20px / 区块标题 18px / 正文 16px / 辅助 15px / 元信息 14px。 */
.topbar strong,.account-page .topbar h1,.route-apply-page .topbar h1,.data-page .topbar h1,.dispatch-page .topbar h1,.order-title{font-size:20px!important;line-height:26px!important}
.card h2, .page2-card h2, .section-title, .data-route-title h2{font-size:18px!important;line-height:24px!important}
.data-import-actions button,.history-dialog-actions button,.order-dialog-actions button,.account-dialog-actions button,.zp-confirm-actions button{font-size:16px!important;line-height:22px!important}
.order-dialog-head strong,.data-import-head h3,.history-dialog-panel>strong,.account-dialog h2,.zp-confirm-panel h3{font-size:18px!important;line-height:24px!important}
.order-dialog-panel>p,.history-dialog-panel>p,.account-dialog>p,.zp-confirm-panel p{font-size:15px!important;line-height:22px!important}
.ui-toast{font-size:15px!important;line-height:21px!important}
.empty,.dispatch-empty,.dispatch-message,.history-state{font-size:15px!important;line-height:22px!important}

/* Modal positioning 2.5
   所有业务弹窗统一居中显示；菜单、Toast、悬浮操作不属于模态弹窗，不参与居中规则。 */
.order-dialog,
.history-dialog,
.history-picker,
.data-import,
.upload-overlay{
  align-items:center!important;
  justify-content:center!important;
}
.order-dialog-panel,
.history-dialog-panel,
.history-picker-panel,
.data-import-panel,
.account-dialog,
.upload-sheet{
  margin:0 auto!important;
  border-radius:18px!important;
  max-height:min(88vh,760px);max-height:min(88dvh,760px);
}
.upload-sheet{
  width:min(100%,390px)!important;
  padding:20px 18px calc(18px + env(safe-area-inset-bottom))!important;
}
@media(max-width:380px){
  .order-dialog,
  .history-dialog,
  .history-picker,
  .data-import,
  .upload-overlay{padding:14px!important}
  .order-dialog-panel,
  .history-dialog-panel,
  .history-picker-panel,
  .data-import-panel,
  .account-dialog,
  .upload-sheet{border-radius:16px!important}
}


/* 全局快速滚动箭头已下线（产品决策）：不再注入 ↑/↓ 悬浮按钮。 */


/* 全局密码显隐 2.7：所有密码输入统一使用小眼睛，空值时隐藏，输入后即时出现。 */
.zp-password-control{
  position:relative;display:flex;align-items:center;width:100%;min-height:48px;
  border:1px solid #35414D;border-radius:11px;background:rgba(10,14,19,.88);
  transition:border-color .16s ease,box-shadow .16s ease;
}
.zp-password-control:focus-within{border-color:#687584;box-shadow:0 0 0 3px rgba(184,194,204,.08)}
.zp-password-control input[type="password"],
.zp-password-control input[type="text"]{
  display:block;flex:1;min-width:0;width:100%;height:48px!important;min-height:48px!important;
  margin:0!important;padding:0 48px 0 12px!important;border:0!important;border-radius:10px!important;
  outline:none!important;box-shadow:none!important;background:transparent!important;color:#F5F7F9;
  font-size:16px;line-height:22px;letter-spacing:.01em;
}
.zp-password-control input::placeholder{color:#75818C}
.zp-password-eye{
  position:absolute;right:4px;top:50%;transform:translateY(-50%);
  display:flex;align-items:center;justify-content:center;width:38px;height:38px;
  padding:0;border:0;border-radius:9px;background:transparent;color:#8F9BA7;
  cursor:pointer;-webkit-tap-highlight-color:transparent;
}
.zp-password-eye svg{display:block;width:19px;height:19px;pointer-events:none}
.zp-password-eye:active{background:var(--zp-primary);color:var(--zp-on-primary)}
.zp-password-eye[hidden]{display:none!important}
.field .zp-password-control{margin-top:0}
.page2-label>.zp-password-control{margin-top:6px}
.reset-password-field>label{display:block;margin:0 0 8px;color:#DCE3E9;font-size:14px;line-height:20px;font-weight:600}
.reset-password-field{margin-top:16px}
@media(max-width:380px){.zp-password-eye{right:3px;width:36px;height:36px}}


/* ================================================================
 * 全局层级体系 3.0 · 落地规则
 * ----------------------------------------------------------------
 * 上面的变量只是"声明"，这里是"执行"：把所有既有的层级硬编码
 * 统一收口到变量上，使多层弹窗拥有确定且可预测的叠放秩序。
 *
 * 解决的问题：
 *   1) 原首页上传层 z-index:999 高于 Toast(400) 与确认框(500)，
 *      导致上传过程中弹出的确认框被遮挡、用户看不到按钮；
 *   2) 业务弹窗原分散在 100/120 两个值上，5 个弹窗抢同一层，
 *      叠放顺序取决于 CSS 加载顺序，不可控。
 *
 * 层级顺序（由低到高）：
 *   内容 1 → 顶栏 10 → 悬浮 90 → 菜单 200
 *   → 模态一层 1000 → 模态二层 1100 → 模态三层 1200 → 提示 2000
 * ================================================================ */

/* --- 模态第 1 层：所有业务弹窗归于同一层 --- */
.order-dialog,
.history-dialog,
.data-import,
.upload-overlay{
  z-index:var(--ui-z-modal)!important;
}

/* --- 模态第 2 层：在弹窗之上再开的浮层 --- */
.history-picker{
  z-index:var(--ui-z-modal-stack)!important;
}

/* --- 模态第 3 层：最终确认（破坏性操作） --- */
.zp-confirm{
  z-index:var(--ui-z-modal-top)!important;
}

/* --- 全局提示：永远在最上层，不被任何弹窗遮挡 --- */
.ui-toast,
.data-feedback{
  z-index:var(--ui-z-toast)!important;
}

/* --- 菜单浮层：非模态，低于一切弹窗 --- */
.data-page-menu, .order-menu{
  z-index:var(--ui-z-menu)!important;
}

/* --- 悬浮操作：位于内容之上、弹窗之下（快速滚动箭头已下线） --- */
.order-pending-fab{
  z-index:var(--ui-z-float)!important;
}

/* --- 顶栏 --- */
.home-app .topbar,
.order-shell .topbar{
  z-index:var(--ui-z-topbar)!important;
}


/* ================================================================
 * 弹窗样式收敛 4.0 · 单一来源
 * ----------------------------------------------------------------
 * 背景：同一弹窗曾散落在 2~4 个文件重复定义，且样式互相矛盾
 *       （例：.data-import 在 app.css 居中、在 data.css 底部弹出），
 *       最终靠"后面再补一条覆盖"打补丁，改一处不起作用。
 * 处理：以下弹窗的"遮罩层 + 面板"统一由本处定义，各页面 CSS
 *       不再重复定义这些属性，只保留页面特有的内部布局。
 *
 * 统一后所有业务弹窗行为一致：
 *   遮罩 rgba(0,0,0,.72) + 3px 模糊 · 居中显示 · 面板 18px 圆角
 *
 * ⚠ 数据中心（data.html）：弹窗外观与本文件 2.1/2.5 节的统一规则保持
 *   原版完全一致（原版即由本文件接管遮罩与面板：居中模态、398px 上限、
 *   18px 圆角）。css/data.css 只保留内部布局 + dvh 兜底 + 入场动效。
 *   本节（4.0）不得对 .data-import 追加 display 等强覆盖规则 ——
 *   data.html 用内联 style="display:none" 控制开关，任何 display!important
 *   都会让弹窗常驻展开、挡住整个页面（2026-10-03 已修复的缺陷）。
 * ================================================================ */

/* --- 统一遮罩层 --- */
.order-dialog,
.history-dialog,
.history-picker,
.upload-overlay{
  position:fixed!important;
  top:0!important;right:0!important;bottom:0!important;left:0!important;inset:0!important;
  display:flex!important;
  align-items:center!important;
  justify-content:center!important;
  padding:12px!important;
  background:rgba(0,0,0,.58)!important;
}

/* --- 统一面板 ---
   所有业务弹窗面板统一为 398px 宽（与上方 2.1 节 max-width 一致）。
   滚动策略保持各页原有行为：面板整体滚动（overflow:auto），
   订单确认弹窗的"头部固定+内容区滚动"由 order_detail.css 页面级定义。 */
.order-dialog-panel,
.history-dialog-panel,
.history-picker-panel,
.account-dialog,
.upload-sheet{
  width:min(100%,398px);
  max-height:min(88vh,760px);max-height:min(88dvh,760px);
  overflow:auto;
  margin:0 auto;
  padding:18px;
  border:1px solid var(--ui-line);
  border-radius:var(--ui-dialog-radius);
  background:var(--ui-surface);
  box-shadow:0 18px 50px rgba(0,0,0,.42);
}

/* --- 统一次级按钮（取消类）--- */
.order-dialog-actions,
.history-dialog-actions,
.account-dialog-actions{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:10px;
  margin-top:14px;
}
/* 与第 121 行的五元组是同一批按钮的两次定义（后者覆盖前者），
   两处都已收敛到 --zp-control-height。只改一处会被另一处盖回去 ——
   Commit 2B 在 history.css 已踩过这个坑，所以本轮以 css-button-resolve.cjs
   的「页面最终生效值」为准，不逐行数改了几处。 */
.order-dialog-actions button,
.history-dialog-actions button,
.account-dialog-actions button{
  min-height:var(--zp-control-height);
  border:1px solid #35404C;
  border-radius:var(--ui-control-radius);
  background:var(--ui-surface-2);
  color:#E8EDF2;
  font-size:16px;
  font-weight:550;
}
.order-dialog-actions button:last-child,
.history-dialog-actions button:last-child,
.account-dialog-actions button:last-child{
  border-color:#3A4652;
  background:var(--ui-surface-3);
  color:#fff;
}


/* ================================================================
 * 视觉细节收敛 5.0 · 同类同形
 * ----------------------------------------------------------------
 * 巡检发现的问题（均为"同类元素在不同页面长得不一样"）：
 *   1) 主按钮三处三种底色：#26313C(app) / #26313C(同) / #2E3B47(business)；
 *   2) 主按钮三处三种圆角：11px(app) / 11px(同) / 12px(部分页面)；
 *   3) 空状态三套内边距：28px 12px / 28px 10px / 30px 10px / 22px 16px；
 *   4) 焦点可见环只有部分页面有（业务页有，登录页无）；
 *   5) 状态类 .dispatch-* 在 ui-unified 中声明但页面用局部 \3c style> 重复实现。
 *
 * 角色色约定（核对此前渲染结果后确认保持不变）：
 *   错误文字 = #FFB4AB（浅红，正文可读优先）；危险操作 = #FF8278（深红，警示优先）。
 *
 * 处理原则：只统一"同类元素的形状与色值"，不改任何布局尺寸与业务逻辑。
 * 所有规则置于文件末尾，保证覆盖此前同名声明；不增加 !important，
 * 以便页面级"确有需要"的差异化仍可通过更高优先级表达。
 * ================================================================ */

/* --- 5.1 主按钮：Uber 招牌反色（深色白底黑字 / 浅色黑底白字） --- */
.primary-btn,
.login-submit,
.page2-primary,
.confirm-submit{
  background:var(--zp-primary);
  border:1px solid var(--zp-primary);
  border-radius:var(--ui-control-radius);
  color:var(--zp-on-primary);
  font-weight:650;
  transition:background .15s ease,transform .12s ease;
}
.primary-btn:hover:not(:disabled),
.login-submit:hover:not(:disabled),
.page2-primary:hover:not(:disabled),
.confirm-submit:hover:not(:disabled){
  background:var(--zp-primary-hover);
  border-color:var(--zp-primary-hover);
}
.primary-btn:active:not(:disabled),
.login-submit:active:not(:disabled),
.page2-primary:active:not(:disabled),
.confirm-submit:active:not(:disabled){
  background:var(--zp-primary-active);
  border-color:var(--zp-primary-active);
  transform:scale(.985);
}

/* --- 5.2 次按钮：描边 / 幽灵（与背景分离，靠边框与文字色区分层级） --- */
.secondary-btn,
.page2-secondary{
  background:var(--zp-secondary-bg);
  border:1px solid var(--zp-secondary-border);
  border-radius:var(--ui-control-radius);
  color:var(--zp-secondary-text);
  font-weight:600;
  transition:background .15s ease,transform .12s ease;
}
.secondary-btn:hover:not(:disabled),
.page2-secondary:hover:not(:disabled){
  background:var(--zp-secondary-hover);
}
.secondary-btn:active:not(:disabled),
.page2-secondary:active:not(:disabled){
  background:var(--zp-secondary-active);
  transform:scale(.985);
}

/* --- 5.3 危险按钮：统一危险色（错误正文用 --zp-error，随主题翻转保证对比度） --- */
.page2-danger-btn,
.page2-danger{
  color:var(--zp-error);
}
.page2-danger-btn{
  border-color:var(--zp-error);
  background:var(--zp-error-soft);
}
.page2-danger-btn:hover:not(:disabled){
  background:color-mix(in srgb,var(--zp-error) 18%,transparent);
}
.page2-danger-btn:active:not(:disabled){
  background:color-mix(in srgb,var(--zp-error) 28%,transparent);
  transform:scale(.985);
}

/* --- 5.4 错误文案：统一为可读性更好的语义红（深色更亮 / 浅色更深） --- */
.message.error,
.login-message,
.login-message[role=alert],
.processing-error-message{
  color:var(--zp-error);
}

/* --- 5.5 空状态 / 状态文字：统一内边距与居中节奏 ---
   注意：history-state 在 history.css 里被定义了两次（22px 16px 与 18px 8px），
   此处收口为同一个值，消除"改一处不生效"。 */
.empty,
.data-empty,
.history-state,
.dispatch-empty,
.dispatch-message{
  padding:28px 12px;
  text-align:center;
  color:var(--ui-soft);
}

/* --- 5.6 焦点可见环：全站统一（键盘/外接设备可访问性） --- */
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--zp-focus);
  outline-offset:2px;
}

/* --- 5.7 禁用态：统一配色与光标 --- */
button:disabled,
input:disabled,
select:disabled,
textarea:disabled,
[disabled]{
  cursor:default;
}
.primary-btn:disabled,
.login-submit:disabled,
.page2-primary:disabled,
.page2-secondary:disabled,
.secondary-btn:disabled,
.confirm-submit:disabled{
  background:var(--zp-disabled-bg);
  border-color:var(--zp-disabled-bg);
  color:var(--zp-disabled-text);
  opacity:1;
}

/* --- 5.8 加载态：全站 spinner / 进度条统一用主色与中性灰 --- */
.spinner,
.zp-spinner{
  border:2px solid var(--zp-line);
  border-top-color:var(--zp-primary);
}
.loading,
.is-loading{
  color:var(--zp-muted);
}

/* --- 5.8 小标签 / 状态胶囊：同圆角、同行高 --- */

/* UI 2.6：页面进入动效统一——
   所有业务页加载时统一 fade + 6px 上移（120ms），消除「页面突然换掉」的生硬感。
   仅作用于各页 <main> 主壳；dialog/picker/sheet 是 <main> 的兄弟节点，不受影响。
   尊重系统的「减少动态效果」偏好（mobile-ui.css 的 reduce-motion 媒体查询会将其压到 ~0ms）。
   ⚠ 禁止加 animation-fill-mode:both/forwards：动画结束后残留的恒等 transform
   会让 <main> 常驻成为 position:fixed 后代的包含块 + stacking context，
   把 main 内部的弹窗/反馈条（如 data 页的 .data-import、#dataFeedback）钉进
   main 的层级与文档坐标——表现为弹窗跑到文档中部、遮罩不满屏、
   body 级悬浮元素（z 90）反而盖住 z 1000 的弹窗。 */
@keyframes zpPageEnter{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.home-app,.shell,.login-shell,.auth-shell,.page2,.order-shell,.history-shell,.dispatch-page,.route-apply-page,.zp-offline{animation:zpPageEnter .12s ease-out}

/* UI 2.6：弹窗/选择框统一进入动效——
   遮罩淡现 + 面板轻微上移（16px / 160ms），替代「啪地出现」。
   普通业务弹窗不再使用 backdrop blur（稳、硬朗）。 */
@keyframes zpModalIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes zpModalFade{from{opacity:0}to{opacity:1}}
.order-dialog:not([hidden]),.history-dialog:not([hidden]),.history-picker:not([hidden]),.zp-confirm:not([hidden]){animation:zpModalFade .16s ease-out}
.order-dialog-panel,.history-dialog-panel,.history-picker-panel,.zp-confirm-panel{animation:zpModalIn .16s ease-out}

/* 菜单轻入场：opacity + 轻微上移，弱化 Web Dropdown 观感（全站通用） */

/* 业务端一级导航：所有业务页面统一常驻，避免页面各自维护不同版本。
   该类由 js/ui-unified.js 在业务页 body 上添加（原误置于 JS 文件内导致整文件语法错误，
   现回归此处）。 */
.zp-business-nav-page{padding-bottom:0!important;overflow-x:hidden}
.zp-business-nav-page .bottom-nav{
  position:fixed!important;left:50%!important;right:auto!important;bottom:0!important;z-index:40!important;
  width:min(100%,430px)!important;min-height:64px!important;
  padding:6px 8px calc(6px + env(safe-area-inset-bottom))!important;
  transform:translateX(-50%)!important;
  display:grid!important;grid-template-columns:repeat(5,1fr)!important;gap:4px!important;
  background:#05070A!important;border-top:1px solid #27323D!important;
  backdrop-filter:none!important;-webkit-backdrop-filter:none!important;
}
.zp-business-nav-page .bottom-nav-item{
  min-width:0!important;min-height:52px!important;border:0!important;border-radius:10px!important;
  background:transparent!important;color:#7F8A95!important;text-decoration:none!important;
  display:flex!important;flex-direction:column!important;align-items:center!important;justify-content:center!important;
  gap:3px!important;font-size:12px!important;line-height:17px!important;font-weight:600!important;
  -webkit-tap-highlight-color:transparent;
}
.zp-business-nav-page .bottom-nav-item:active{background:#18212B!important;color:#F2F5F7!important}
.zp-business-nav-page .bottom-nav-icon{width:22px!important;height:22px!important;display:flex!important;align-items:center!important;justify-content:center!important}
.zp-business-nav-page .bottom-nav-icon svg{width:21px!important;height:21px!important;fill:none!important;stroke:currentColor!important;stroke-width:1.8!important;stroke-linecap:round!important;stroke-linejoin:round!important}
.zp-business-nav-page .bottom-nav-item[aria-current="page"]{color:#F2F5F7!important}
/* 中间上传加号（底栏 5 位改版）：无文字标签的凸起圆形按钮。
   圆形由 .bottom-nav-icon 承载，上移凸出导航条；底色沿用唯一主色 --zp-primary，
   白 + 图标，按压提亮——不引入新的强调色。 */
.zp-business-nav-page .bottom-nav-plus .bottom-nav-icon{
  width:52px!important;height:52px!important;border-radius:50%!important;
  background:var(--zp-primary)!important;color:var(--zp-on-primary)!important;
  transform:translateY(-16px)!important;
  box-shadow:0 8px 20px rgba(5,7,10,.45)!important;
}
.zp-business-nav-page .bottom-nav-plus .bottom-nav-icon svg{width:24px!important;height:24px!important;stroke-width:2.2!important}
.zp-business-nav-page .bottom-nav-plus:active{background:transparent!important}
.zp-business-nav-page .bottom-nav-plus:active .bottom-nav-icon{filter:brightness(1.15)!important}
/* 底部让位已废弃（2026-10-18）：zp-shell / order-shell 均为 overflow:hidden 的 flex 外壳，
   main 不再滚动，旧 82px 让位只会把滚动容器底边抬到导航横线上方 ~18px，
   形成常驻黑色死区（任何滚动位置下内容都被悬空裁切）。
   让位职责由各滚动容器自身 padding-bottom（72px + 安全区 = 导航 64px + 8px 呼吸位）接管。 */
.zp-business-nav-page main{padding-bottom:0!important}
@media(max-width:430px){
  .zp-business-nav-page .bottom-nav{width:100%!important}
}
@media(max-width:380px){
  .zp-business-nav-page .bottom-nav{padding-left:6px!important;padding-right:6px!important}
}


/* ===== 用户外观偏好：主题与全局字号 · 浅色完整覆盖 ===== */
:root[data-zp-theme="light"]{
  color-scheme:light;
  /* ===== 页面 / 表面 / 文字（Uber 风格中性灰阶 · 浅色）===== */
  --zp-bg:#F2F2F2;
  --zp-surface:#FFFFFF;
  --zp-surface-2:#F5F5F5;
  --zp-surface-3:#EAEAEA;
  --zp-line:#E0E0E0;
  --zp-text:#141414;
  --zp-muted:#5A5A5A;
  --zp-soft:#767676;
  --zp-danger:#C2453A; /* 浅色主题的错误/危险提示文字，避免沿用深色浅红造成低对比度 */
  --zp-card:#FFFFFF;
  --zp-card-translucent:rgba(255,255,255,.82);
  --zp-card-translucent-2:#F5F5F5;
  /* 骨架微光条浅色化：白卡上改为浅灰微光，与表面色系同族 */
  --zp-sk-a:#E4E9EE;
  --zp-sk-b:#EDF1F5;
  --zp-divider:rgba(0,0,0,.08);
  /* ===== 主按钮反黑：黑底白字（Uber 浅色招牌）===== */
  --zp-primary:#0A0A0A;
  --zp-on-primary:#FFFFFF;
  --zp-secondary-bg:#FFFFFF;
  --zp-secondary-border:#D4D4D4;
  --zp-secondary-text:#0A0A0A;
  --zp-disabled-bg:#EAEAEA;
  --zp-disabled-text:#A0A0A0;
  --zp-scrim:rgba(0,0,0,.45);
  --zp-focus:#0A0A0A;
  --zp-primary-hover:#262626;
  --zp-primary-active:#404040;
  --zp-secondary-hover:#F0F0F0;
  --zp-secondary-active:#E6E6E6;
  /* 功能状态色（浅色：文字更深以保证对比度） */
  --zp-success:#157A45;
  --zp-success-soft:rgba(21,122,69,.12);
  --zp-warning:#9A5B00;
  --zp-warning-soft:rgba(154,91,0,.12);
  --zp-error:#C2453A;
  --zp-error-soft:rgba(194,69,58,.12);
  --zp-info:#1E6FD0;
  --zp-info-soft:rgba(30,111,208,.12);
  --ui-bg:var(--zp-bg);
  --ui-surface:var(--zp-surface);
  --ui-surface-2:var(--zp-surface-2);
  --ui-surface-3:var(--zp-surface-3);
  --ui-line:var(--zp-line);
  --ui-text:var(--zp-text);
  --ui-muted:var(--zp-muted);
  --ui-soft:var(--zp-soft);
  /* 兼容旧页面和管理员内联样式使用的无前缀变量 */
  --bg:#F2F2F2;
  --card:#FFFFFF;
  --card2:#F5F5F5;
  --line:#E0E0E0;
  --muted:#5A5A5A;
  --soft:#767676;
  --ui-danger:#B4232F;
  --ui-danger-soft:rgba(180,35,47,.08);
}
:root[data-zp-theme="light"] body,
:root[data-zp-theme="light"] .page2,
:root[data-zp-theme="light"] .shell,
:root[data-zp-theme="light"] .page,
:root[data-zp-theme="light"] .viewport{
  background-color:var(--zp-bg);
  color:var(--zp-text);
}
:root[data-zp-theme="light"] .page2-card, :root[data-zp-theme="light"] .card, :root[data-zp-theme="light"] .data-list-card, :root[data-zp-theme="light"] .data-route-card, :root[data-zp-theme="light"] .task-card, :root[data-zp-theme="light"] .confirm-panel, :root[data-zp-theme="light"] .pending-box, :root[data-zp-theme="light"] .account-dialog, :root[data-zp-theme="light"] .order-dialog-panel, :root[data-zp-theme="light"] .history-dialog-panel, :root[data-zp-theme="light"] .history-picker-panel, :root[data-zp-theme="light"] .data-import-panel, :root[data-zp-theme="light"] .upload-sheet, :root[data-zp-theme="light"] .zp-confirm-panel{
  background-color:var(--zp-surface);
  border-color:var(--zp-line);
  color:var(--zp-text);
  box-shadow:0 8px 24px rgba(20,30,40,.08);
}
:root[data-zp-theme="light"] .topbar,
:root[data-zp-theme="light"] .app-back,
:root[data-zp-theme="light"] .account-collapse-head,
:root[data-zp-theme="light"] .page2-secondary,
:root[data-zp-theme="light"] .page2-label,
:root[data-zp-theme="light"] .account-row,
:root[data-zp-theme="light"] .page2-row,
:root[data-zp-theme="light"] .section-title,
:root[data-zp-theme="light"] .order-title{
  color:var(--zp-text);
}
:root[data-zp-theme="light"] p,
:root[data-zp-theme="light"] label,
:root[data-zp-theme="light"] strong,
:root[data-zp-theme="light"] h1,
:root[data-zp-theme="light"] h2,
:root[data-zp-theme="light"] h3,
:root[data-zp-theme="light"] h4,
:root[data-zp-theme="light"] legend,
:root[data-zp-theme="light"] summary,
:root[data-zp-theme="light"] .page2-soft,
:root[data-zp-theme="light"] .summary,
:root[data-zp-theme="light"] .empty,
:root[data-zp-theme="light"] .dispatch-empty,
:root[data-zp-theme="light"] .dispatch-message,
:root[data-zp-theme="light"] .history-state{
  color:var(--zp-text);
}
/* span 不做全局强制改色：状态徽标、重量标签、成功/警告文字需保留语义颜色。 */
:root[data-zp-theme="light"] .page2-soft,
:root[data-zp-theme="light"] .field-hint,
:root[data-zp-theme="light"] .meta,
:root[data-zp-theme="light"] .hint,
:root[data-zp-theme="light"] .muted,
:root[data-zp-theme="light"] .empty,
:root[data-zp-theme="light"] .dispatch-empty,
:root[data-zp-theme="light"] .dispatch-message,
:root[data-zp-theme="light"] .history-state,
:root[data-zp-theme="light"] .account-row>span:first-child{
  color:var(--zp-muted);
}
:root[data-zp-theme="light"] input,
:root[data-zp-theme="light"] select,
:root[data-zp-theme="light"] textarea{
  background:#FFFFFF!important;
  color:#17202A!important;
  border-color:#C9D1D9!important;
  caret-color:#17202A;
}
:root[data-zp-theme="light"] input::placeholder,
:root[data-zp-theme="light"] textarea::placeholder{
  color:#687582!important;
  opacity:1;
}
:root[data-zp-theme="light"] input:focus,
:root[data-zp-theme="light"] select:focus,
:root[data-zp-theme="light"] textarea:focus{
  border-color:#7D8A98!important;
  box-shadow:0 0 0 3px rgba(65,85,105,.12)!important;
}
:root[data-zp-theme="light"] a{color:#34495E}
:root[data-zp-theme="light"] button{color:var(--zp-text)}
:root[data-zp-theme="light"] button:disabled{opacity:.55}
:root[data-zp-theme="light"] .page2-primary,
:root[data-zp-theme="light"] .login-submit,
:root[data-zp-theme="light"] .data-action-primary,
:root[data-zp-theme="light"] .primary,
:root[data-zp-theme="light"] button.primary,
:root[data-zp-theme="light"] .primary-btn,
:root[data-zp-theme="light"] .confirm-submit{
  background:var(--zp-primary)!important;
  border-color:var(--zp-primary)!important;
  color:#FFFFFF!important;
}
/* 浅色主题次按钮：app.css 的 .secondary-btn 为深底白字，而上面的 button
   通配浅色文字规则只改文字色不改底色，会出现「深底深字」不可读
   （route_apply 解除线路绑定）。按 order_detail 弹窗既有浅色值补齐。 */
:root[data-zp-theme="light"] .secondary-btn{
  background:#E8EDF1;
  border-color:#D1D8DF;
  color:var(--zp-text);
}
:root[data-zp-theme="light"] .page2-secondary{
  background:#F0F2F4;
  border-color:#D7DDE3;
  color:#17202A;
}
/* 折叠行不再填灰：浅色下 #F0F2F4 与页面背景 #F4F6F8 近同色，灰条浮在白卡外显得乱色。
   改为透明底融入白卡，仅按压时给轻灰反馈；文字色由上方浅色文本组统一。 */
:root[data-zp-theme="light"] .account-collapse-head{background:transparent;border-color:transparent;color:#17202A}
:root[data-zp-theme="light"] .account-collapse-head:active{background:#F0F2F4}
:root[data-zp-theme="light"] .appearance-theme-option.is-selected,
:root[data-zp-theme="light"] [aria-pressed="true"].appearance-theme-option{
  background:#DCE5EC;
  border-color:#778796;
  color:#17202A;
  box-shadow:inset 0 0 0 1px #778796;
}
:root[data-zp-theme="light"] .account-page .account-logout-section .account-logout{
  background:#FFFFFF;
  border-color:#D7DDE3;
  color:#17202A;
}
:root[data-zp-theme="light"] .order-dialog,
:root[data-zp-theme="light"] .history-dialog,
:root[data-zp-theme="light"] .history-picker,
:root[data-zp-theme="light"] .data-import,
:root[data-zp-theme="light"] .upload-overlay,
:root[data-zp-theme="light"] .zp-confirm{
  background:rgba(24,36,48,.32)!important;
}
:root[data-zp-theme="light"] .ui-toast{
  background:#FFFFFF!important;
  border-color:#D7DDE3!important;
  color:#17202A!important;
  box-shadow:0 8px 24px rgba(20,30,40,.16);
}
:root[data-zp-theme="light"] .ui-toast.success{
  background:#E8F5EC!important;
  border-color:#B8DCC3!important;
  color:#205C35!important;
}
:root[data-zp-theme="light"] .ui-toast.error{
  background:#FCEBEC!important;
  border-color:#E8BFC3!important;
  color:#8A2630!important;
}
:root[data-zp-theme="light"] .zp-confirm-panel h3{color:var(--zp-text)}
:root[data-zp-theme="light"] .zp-confirm-actions button:first-child{
  background:#F0F2F4;border-color:#D7DDE3;color:#26323D;
}
:root[data-zp-theme="light"] .zp-confirm-actions button:last-child{
  background:var(--zp-primary);border-color:var(--zp-primary);color:#FFFFFF;
}
:root[data-zp-theme="light"] .zp-password-control{
  background:#FFFFFF;border-color:#C9D1D9;
}
:root[data-zp-theme="light"] .zp-password-control input[type="password"],
:root[data-zp-theme="light"] .zp-password-control input[type="text"]{
  background:transparent!important;color:#17202A!important;
}
:root[data-zp-theme="light"] .zp-password-control input::placeholder{color:#687582!important}
:root[data-zp-theme="light"] .zp-password-eye{color:#536170}
:root[data-zp-theme="light"] .zp-password-eye:active{background:#E8EDF1;color:#17202A}
:root[data-zp-theme="light"] .data-page-menu, :root[data-zp-theme="light"] .order-menu{
  background:#FFFFFF;border-color:#D7DDE3;color:#17202A;
  box-shadow:0 12px 28px rgba(20,30,40,.14);
}
:root[data-zp-theme="light"] .menu-divider{background:rgba(20,30,40,.12)}
:root[data-zp-theme="light"] .store-row,
:root[data-zp-theme="light"] .account-row,
:root[data-zp-theme="light"] .request-row{border-bottom-color:rgba(20,30,40,.12)}


/* 管理员工作区浅色适配：覆盖 admin.html 内联样式中的固定深色值 */
:root[data-zp-theme="light"] .head .who .role,
:root[data-zp-theme="light"] .menu-btn,
:root[data-zp-theme="light"] .tab.active,
:root[data-zp-theme="light"] .add,
:root[data-zp-theme="light"] .search input,
:root[data-zp-theme="light"] .small-action,
:root[data-zp-theme="light"] .copy,
:root[data-zp-theme="light"] .invite-actions .small-action{
  color:#17202A;
}
:root[data-zp-theme="light"] .head .who .role{color:var(--zp-primary)!important}
:root[data-zp-theme="light"] .menu-btn,
:root[data-zp-theme="light"] .add,
:root[data-zp-theme="light"] .small-action,
:root[data-zp-theme="light"] .copy{
  background:#F0F2F4!important;border-color:#D7DDE3!important;color:#26323D!important;
}
:root[data-zp-theme="light"] .tab.active{background:#FFFFFF!important;color:#17202A!important}
:root[data-zp-theme="light"] .tabs{background:#F0F2F4!important;border-color:#D7DDE3!important}
:root[data-zp-theme="light"] .row,
:root[data-zp-theme="light"] .route,
:root[data-zp-theme="light"] .card,
:root[data-zp-theme="light"] .invite,
:root[data-zp-theme="light"] .row .content,
:root[data-zp-theme="light"] .invite-content,
:root[data-zp-theme="light"] .route-content{background:#FFFFFF!important;border-color:#D7DDE3!important;color:#17202A}
:root[data-zp-theme="light"] .person,
:root[data-zp-theme="light"] .row .meta,
:root[data-zp-theme="light"] .meta,
:root[data-zp-theme="light"] .route-count,
:root[data-zp-theme="light"] .head .who .uname{color:#596674!important}
:root[data-zp-theme="light"] .dialog-bg,
:root[data-zp-theme="light"] .menu-bg{background:rgba(24,36,48,.32)!important}
:root[data-zp-theme="light"] .dialog{background:#FFFFFF!important;border-color:#D7DDE3!important;color:#17202A}
:root[data-zp-theme="light"] .dialog h2,
:root[data-zp-theme="light"] .dialog p,
:root[data-zp-theme="light"] .field label{color:#17202A}
:root[data-zp-theme="light"] .dialog-actions .cancel{background:#F0F2F4!important;border-color:#D7DDE3!important;color:#26323D!important}
:root[data-zp-theme="light"] .dialog-actions .ok{background:var(--zp-primary)!important;border-color:var(--zp-primary)!important;color:#FFFFFF!important}
:root[data-zp-theme="light"] .toast{background:#FFFFFF!important;border-color:#D7DDE3!important;color:#17202A!important}

/* 浅色模式中的危险与错误状态采用深色语义色，确保浅底上可读 */
:root[data-zp-theme="light"] .message.error,
:root[data-zp-theme="light"] .login-message[role="alert"],
:root[data-zp-theme="light"] [role="alert"]{color:#B4232F}

/* ---- 浅色补充（全站审计）：body 底色兜底 + 注入底栏浅色 ---- */
/* 登录/注册等无 .page 容器的页面，body 硬编码 color:#fff 需在浅色下翻转 */
:root[data-zp-theme="light"] body{color:var(--zp-text)}
/* 注入底栏的深色定义在本文件（.zp-business-nav-page .bottom-nav），
   浅色覆盖必须同样全站可用——此前只写在 business-pages.css，
   history/order_detail 等不加载该文件的页面底栏一直是黑条 */
:root[data-zp-theme="light"] .zp-business-nav-page .bottom-nav{background:#FFFFFF!important;border-top-color:#D7DDE3!important;box-shadow:0 -4px 18px rgba(20,30,40,.06)}
:root[data-zp-theme="light"] .zp-business-nav-page .bottom-nav-item{color:#596674!important}
:root[data-zp-theme="light"] .zp-business-nav-page .bottom-nav-item:active{background:#E8EDF1!important;color:#17202A!important}
:root[data-zp-theme="light"] .zp-business-nav-page .bottom-nav-item[aria-current="page"]{color:#17202A!important}
/* 浅色下中间加号：圆形仍为主色底白图标，仅按压态与阴影适配（不加新强调色） */
:root[data-zp-theme="light"] .zp-business-nav-page .bottom-nav-plus .bottom-nav-icon{box-shadow:0 8px 20px rgba(20,30,40,.22)!important}
:root[data-zp-theme="light"] .zp-business-nav-page .bottom-nav-plus:active{background:transparent!important}

:root[data-zp-theme="light"] button[class*="delete"]:not(.account-collapse-head):disabled,
:root[data-zp-theme="light"] button[class*="danger"]:not(.account-collapse-head):disabled,
:root[data-zp-theme="light"] .history-choice-delete:disabled {
  opacity:.55;
  cursor:not-allowed;
}


/* 全站危险操作按钮颜色标准化：与全站次按钮统一采用中性色，不以红色作为常规操作按钮底色。
   深色：深灰底/灰边/浅字；浅色：浅灰底/浅灰边/深字。
   历史页整行滑动动作条单独保持无边框实底，避免两端出现白边。
   仅调整颜色和边框，不改变尺寸、位置、文案及确认逻辑。 */
button[class*="delete"]:not(.account-collapse-head):not(.history-delete),
a[class*="delete"],
button[class*="danger"]:not(.account-collapse-head),
a[class*="danger"],
.history-choice-delete,
.history-dialog-actions .delete,
.data-swipe-actions .data-swipe-delete,
.page2-danger-btn,
.invite-actions .small-action.danger {
  background:#11171D!important;
  border:1px solid #35404C!important;
  color:#E8EDF2!important;
  box-shadow:none!important;
}
button[class*="delete"]:not(.account-collapse-head):not(.history-delete):active,
a[class*="delete"]:active,
button[class*="danger"]:not(.account-collapse-head):active,
a[class*="danger"]:active,
.history-choice-delete:active,
.history-dialog-actions .delete:active,
.data-swipe-actions .data-swipe-delete:active,
.page2-danger-btn:active,
.invite-actions .small-action.danger:active {
  background:#202B36!important;
  border-color:#3A4652!important;
  color:#FFFFFF!important;
}
:root[data-zp-theme="light"] button[class*="delete"]:not(.account-collapse-head):not(.history-delete),
:root[data-zp-theme="light"] a[class*="delete"],
:root[data-zp-theme="light"] button[class*="danger"]:not(.account-collapse-head),
:root[data-zp-theme="light"] a[class*="danger"],
:root[data-zp-theme="light"] .history-choice-delete,
:root[data-zp-theme="light"] .history-dialog-actions .delete,
:root[data-zp-theme="light"] .data-swipe-actions .data-swipe-delete,
:root[data-zp-theme="light"] .page2-danger-btn,
:root[data-zp-theme="light"] .invite-actions .small-action.danger {
  background:#F0F2F4!important;
  border:1px solid #D7DDE3!important;
  color:#17202A!important;
  box-shadow:none!important;
}
:root[data-zp-theme="light"] button[class*="delete"]:not(.account-collapse-head):not(.history-delete):active,
:root[data-zp-theme="light"] a[class*="delete"]:active,
:root[data-zp-theme="light"] button[class*="danger"]:not(.account-collapse-head):active,
:root[data-zp-theme="light"] a[class*="danger"]:active,
:root[data-zp-theme="light"] .history-choice-delete:active,
:root[data-zp-theme="light"] .history-dialog-actions .delete:active,
:root[data-zp-theme="light"] .data-swipe-actions .data-swipe-delete:active,
:root[data-zp-theme="light"] .page2-danger-btn:active,
:root[data-zp-theme="light"] .invite-actions .small-action.danger:active {
  background:#E1E7EC!important;
  border-color:#C9D1D9!important;
  color:#17202A!important;
}
/* 历史页整行滑动删除：中性色实底且无边框，防止按钮两端混绘出白边。 */
:root:not([data-zp-theme="light"]) .history-delete {
  background:#11171D!important;
  border:0!important;
  color:#E8EDF2!important;
  box-shadow:none!important;
}
:root:not([data-zp-theme="light"]) .history-delete:active {
  background:#202B36!important;
  color:#FFFFFF!important;
}
:root[data-zp-theme="light"] .history-delete {
  background:#F0F2F4!important;
  border:0!important;
  color:#17202A!important;
  box-shadow:none!important;
}
:root[data-zp-theme="light"] .history-delete:active {
  background:#E1E7EC!important;
  color:#17202A!important;
}

/* ============================================================
   统一应用外壳 zp-shell（阶段 7 · 抖动修复 / 全局统一 UI）
   ------------------------------------------------------------
   问题：各页原用 position:sticky;top:0 固定顶栏，在 Android WebView
   惯性滚动时会随滚动上下抖动（sticky 重绘 jank）。order-shell 早已采用
   flex 列 + 内部滚动容器的方案（顶栏作为不参与滚动的 flex 子项），零抖动。
   本段把该方案提升为「全局统一外壳」，所有业务页 <main> 加 .zp-shell，
   内容包进 .zp-scroll，顶栏彻底静止。

   main.zp-shell 用 (元素+类)=0,1,1 的特异性，压过 .home-app / .shell /
   .page2 / .dispatch-page 等容器类（均 0,1,0），因此 padding/width/height
   等冲突项一律以本规则为准，无需逐个页面覆盖。
   ============================================================ */
main.zp-shell{
  width:100%;
  max-width:var(--zp-shell-max,520px);
  height:100vh;            /* 旧内核回退 */
  height:100dvh;
  margin:0 auto;
  display:flex;
  flex-direction:column;
  overflow:hidden;
  position:relative;
  background:var(--zp-bg);
  padding-top:0;           /* 抵消 .shell/.page2/.home-app 的上下 padding，
                             左右 padding 保留（仍来自各容器类），保证内容/顶栏对齐 */
  padding-bottom:0;
}
/* 顶栏：不再 sticky/fixed，作为不滚动的 flex 子项，绝无抖动；
   左右缩进由外壳的 padding 提供，这里只补顶部安全区与底色。 */
/* 顶栏统一规范（单一来源）：安全区只在此声明一次，覆盖全部外壳
   （zp-shell 与 order-shell 等）。各页旧类仅保留布局差异，不再重复声明安全区。 */
main > .topbar{
  flex:0 0 auto;
  position:static;
  z-index:100;
  padding-top:env(safe-area-inset-top);
  min-height:var(--zp-header-height);
  background:var(--zp-bg);
}
/* 内部唯一滚动容器：flex:1 撑满剩余高度，min-height:0 是 flex 列中
   能正确收缩并出现滚动条的关键。 */
.zp-scroll{
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-y:contain;
  /* 顶部留 14px 与顶栏间距；底部 72px 让出常驻导航（64px 高 + 8px 呼吸位）。
     旧值 84px 会在滚动到底时于横线上方多留 20px 空档。 */
  padding:14px 0 calc(72px + env(safe-area-inset-bottom));
}
/* 全局隐藏滚动条（移动端成熟做法，对标 iOS 原生应用）：
   滚动与惯性完全不变，位置反馈由手势/边缘效应承担；常驻滚动条属桌面
   习惯，在 WebView 下会沿内容右缘形成一条深色竖线，影响视觉。 */
*{scrollbar-width:none}
*::-webkit-scrollbar{display:none;width:0;height:0}
/* 线路页：首项 dispatch-intro 自带 18px 上间距，避免与 .zp-scroll 的 14px 叠加 */
main.zp-shell.dispatch-page .zp-scroll{padding-top:0}
