Files
jiu/design/prototype/atoms.css
T
wangjia 05203a9b5b
Design Source Checks / design-source (push) Failing after 14m23s
refactor: 原型迁移 .superpowers/prototype → design/prototype(与 CONTRACT 同目录)
- git mv 全目录(历史保留);.gitignore 收敛为整个 .superpowers/ 忽略
- 全仓 16 处引用同步(CI checks.yml / l1-sync / screens.mjs / hooks /
  CLAUDE.md / CONTRACT / SSR 模板注释 / docs / web 注释)
- 修 pre-commit 路径正则残留;5180 评审服务已切新路径
- 验证:check-ds 12 道 / l1-sync 6 道 / fidelity 抽查全过

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
2026-07-07 18:47:31 +08:00

499 lines
43 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================
岩美酒库 · 组件层(原子)
仅引用 tokens.css 的 var(),被设计系统文档与所有屏幕复用。
============================================================ */
*{box-sizing:border-box;}
svg{fill:none; stroke:currentColor;}
/* ---- 按钮 ---- */
.btn{height:38px; padding:0 16px; border-radius:var(--r-md); font-size:var(--fs-body); font-weight:600; display:inline-flex; align-items:center; gap:7px; cursor:pointer; border:1px solid transparent; transition:background-color .15s,border-color .15s,color .15s; font-family:var(--font);}
.btn svg{width:16px; height:16px; stroke-width:1.8;}
.btn.ghost{background:var(--surface); border-color:var(--border); color:var(--text);}
.btn.ghost:hover{background:var(--bg);}
.btn.primary{background:var(--primary); color:var(--on-primary);}
.btn.primary:hover{background:var(--primary-dark);}
.btn.danger{background:var(--danger); color:#fff;}
/* 浅蓝软变体:突出但不抢主操作(详细搜索等次强调入口);经典蓝主题 = 浅蓝底蓝字,其余主题自适应 */
.btn.soft{background:var(--brand50); border-color:var(--brand400); color:var(--primary);}
.btn.soft:hover{border-color:var(--primary); background:var(--info-soft);}
.btn.sm{height:32px; padding:0 12px; font-size:var(--fs-sm);}
.btn.lg{height:44px; padding:0 22px; font-size:14px;}
/* ---- 输入 / 控件 ---- */
.input{height:38px; width:100%; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); padding:0 11px; font-size:var(--fs-body); color:var(--text); outline:none; font-family:var(--font);}
.input:focus{border-color:var(--primary); box-shadow:0 0 0 3px var(--brand50);}
.input::placeholder{color:var(--faint);}
.input[readonly]{background:var(--bg); color:var(--muted); cursor:default;}
.input[readonly]:focus{border-color:var(--border); box-shadow:none;}
.ctrl{height:38px; width:100%; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); padding:0 11px; font-size:var(--fs-body); color:var(--text); display:flex; align-items:center; justify-content:space-between; cursor:pointer; font-family:var(--font);}
.ctrl.input-like{cursor:text;} .ctrl input{border:none; outline:none; background:transparent; width:100%; font-size:var(--fs-body); color:var(--text); font-family:var(--font);}
.ctrl .ph{color:var(--faint);}
.searchbox{height:34px; background:var(--bg); border:1px solid var(--border); border-radius:var(--r-md); display:flex; align-items:center; gap:8px; padding:0 11px;}
.searchbox svg{width:14px; height:14px; stroke-width:2; color:var(--faint); flex:none;}
.searchbox input{border:none; background:transparent; outline:none; font-size:var(--fs-body); color:var(--text); width:100%; font-family:var(--font);}
.searchbox input::placeholder{color:var(--faint);}
/* ---- Switch 开关(2026-07-07 新增:库存⇄在售 挂售切换等布尔即时生效场景) ----
38×22 pill 轨道 + 18px 圆点滑块;on=primaryoff=borderdisabled 半透明。 */
.switch{position:relative; width:38px; height:22px; border-radius:var(--r-pill); background:var(--border); border:none; padding:0; cursor:pointer; transition:background-color .18s; flex:none;}
.switch::after{content:""; position:absolute; top:2px; left:2px; width:18px; height:18px; border-radius:50%; background:var(--surface); box-shadow:var(--sh-1); transition:transform .18s;}
.switch.on{background:var(--primary);}
.switch.on::after{transform:translateX(16px);}
.switch:disabled{opacity:.45; cursor:default;}
/* ---- 日期字段(触发器)+ 滚轮日期选择器(年月日,单据/生产/明细共用) ---- */
.datefield{height:38px; width:100%; box-sizing:border-box; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); padding:0 11px; display:flex; align-items:center; gap:8px; cursor:pointer; outline:none; transition:border-color .15s,box-shadow .15s;}
.datefield:hover{border-color:var(--brand400);}
.datefield:focus{border-color:var(--primary); box-shadow:0 0 0 3px var(--brand50);}
.datefield.error{border-color:var(--danger);}
.datefield.disabled{background:var(--bg); color:var(--muted); pointer-events:none; opacity:.7;}
.datefield .dval{flex:1; min-width:0; font-size:var(--fs-body); color:var(--text); font-family:var(--font-mono); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.datefield .dval.ph{color:var(--faint); font-family:var(--font);}
.datefield svg{width:15px; height:15px; stroke-width:1.8; color:var(--faint); flex:none;}
/* 网格单元格变体:默认无边、矮,hover/focus 才显形(对齐 .combo.cell */
.datefield.gci-date{height:32px; border-color:transparent; background:transparent; border-radius:5px; padding:0 8px;}
.datefield.gci-date:hover{background:var(--bg);}
.datefield.gci-date:focus{background:var(--surface); border-color:var(--primary); box-shadow:0 0 0 2px var(--brand50);}
.datefield.gci-date.error{border-color:var(--danger); background:var(--danger-bg); box-shadow:none;}
.wheel-pop{position:fixed; z-index:var(--z-pop); background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); box-shadow:var(--sh-3); padding:8px; width:248px; display:none;}
.wheel-pop.show{display:block;}
.wheel-cols{position:relative; display:flex; height:180px; overflow:hidden;}
.wheel-center{position:absolute; left:4px; right:4px; top:72px; height:36px; border-radius:var(--r-md); background:var(--bg); border-top:1px solid var(--border); border-bottom:1px solid var(--border); pointer-events:none; z-index:0;}
.wheel-col{position:relative; z-index:1; flex:1; height:100%; overflow-y:scroll; scroll-snap-type:y mandatory; padding:72px 0; text-align:center; scrollbar-width:none; -ms-overflow-style:none;}
.wheel-col::-webkit-scrollbar{display:none;}
.wheel-item{height:36px; line-height:36px; scroll-snap-align:center; font-size:var(--fs-body); color:var(--muted); font-family:var(--font-mono); transition:color .12s,font-size .12s;}
.wheel-item.on{color:var(--primary); font-weight:700; font-size:16px;}
.wheel-foot{display:flex; justify-content:space-between; align-items:center; padding:8px 4px 2px; margin-top:6px; border-top:1px solid var(--border-subtle);}
.wheel-foot .wheel-today{font-size:var(--fs-sm); color:var(--muted); cursor:pointer; padding:4px 10px; border-radius:var(--r-sm);}
.wheel-foot .wheel-today:hover{background:var(--bg); color:var(--text);}
.wheel-foot .wheel-ok{font-size:var(--fs-sm); color:var(--on-primary); background:var(--primary); font-weight:600; cursor:pointer; padding:5px 16px; border-radius:var(--r-sm);}
.wheel-foot .wheel-ok:hover{background:var(--primary-dark);}
/* ---- Chip(筛选) ---- */
.chip{height:34px; padding:0 12px; border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface); font-size:var(--fs-sm); color:var(--text); display:inline-flex; align-items:center; gap:7px; cursor:pointer; transition:border-color .15s;}
.chip:hover{border-color:var(--brand400);}
.chip.on{border-color:var(--primary);}
.chip .cv{color:var(--primary); font-weight:600;}
.chip svg{width:14px; height:14px; stroke-width:1.8; color:var(--faint);}
/* ---- 状态徽章 ---- */
.badge{display:inline-flex; align-items:center; gap:5px; height:22px; padding:0 9px; border-radius:var(--r-pill); font-size:var(--fs-sm); font-weight:600;}
.badge::before{content:""; width:6px; height:6px; border-radius:50%; background:currentColor;}
/* 徽章图标化(2026-07-04):.bi=代表性图标替代圆点(桌面);.ico=纯图标紧凑徽章(移动卡片) */
.badge.bi::before, .badge.ico::before{content:none;}
.badge .ic{width:12px; height:12px; stroke-width:2.2;}
.badge.ico{width:22px; padding:0; justify-content:center; gap:0;}
.badge.ico .ic{width:13px; height:13px;}
.b-在售{background:var(--success-bg); color:var(--success);}
.b-缺货{background:var(--danger-bg); color:var(--danger);}
.b-预警{background:var(--warn-bg); color:var(--warn);}
/* 库存三态(2026-07-07 落库):库存=在库不公开 / 已售=卖光留痕 */
.b-库存{background:var(--info-soft); color:var(--primary);}
.b-已售{background:var(--border-subtle); color:var(--muted);}
/* 单据状态 */
.b-草稿{background:var(--info-soft); color:var(--muted);}
.b-待审核{background:var(--warn-bg); color:var(--warn);}
.b-已通过{background:var(--success-bg); color:var(--success);}
.b-已驳回{background:var(--danger-bg); color:var(--danger);}
/* 财务 / 往来 / 用户角色 */
.b-收款,.b-启用{background:var(--success-bg); color:var(--success);}
.b-付款{background:var(--danger-bg); color:var(--danger);}
.b-供应商,.b-管理员{background:var(--info-soft); color:var(--primary);}
.b-超级管理员{background:var(--danger-bg); color:var(--danger);}
.b-操作员{background:var(--ok-soft); color:var(--success);}
.b-客户{background:var(--accent-soft); color:var(--accent);}
.b-两者,.b-只读{background:var(--warn-bg); color:var(--warn);}
.b-停用,.b-普通,.b-离线{background:var(--border-subtle); color:var(--muted);}
/* 流水 / 设备 */
.b-入库,.b-在线{background:var(--success-bg); color:var(--success);}
.b-出库{background:var(--danger-bg); color:var(--danger);}
/* 待定价:入库进价留空/0(暂估),确认进价后回填真实成本 */
.pending-price{color:var(--warn); font-weight:600;}
.b-待定价{background:var(--warn-bg); color:var(--warn);}
/* ---- KPI 卡 ---- */
.kpi{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); padding:15px 16px; transition:background-color .28s,border-color .15s,box-shadow .15s;}
.kpi.click{cursor:pointer;} .kpi.click:hover{border-color:var(--brand400); box-shadow:var(--sh-1);}
.kpi .t{font-size:var(--fs-sm); color:var(--muted);}
.kpi .v{font-size:24px; font-weight:700; color:var(--heading); margin-top:7px; letter-spacing:.3px; font-family:var(--font-mono);}
.kpi.alert .v{color:var(--accent);}
.kpi.warn .v{color:var(--warn);}
.kpi .d{font-size:var(--fs-xs); margin-top:5px; display:inline-flex; align-items:center; gap:4px;}
.up{color:var(--success);} .down{color:var(--danger);}
.ic{width:30px; height:30px; border-radius:var(--r-md); display:flex; align-items:center; justify-content:center; float:right; margin-top:-2px;}
.ic svg{width:17px; height:17px; stroke-width:1.8;}
.ic-info{background:var(--info-soft); color:var(--primary);} .ic-ok{background:var(--ok-soft); color:var(--success);}
.ic-blue{background:var(--info-soft); color:var(--brand400);} .ic-alert{background:var(--accent-soft); color:var(--accent);}
.ic-warn{background:var(--warn-bg); color:var(--warn);} /* 暗黄(草稿类 KPI */
/* ---- 表格 ---- */
.table{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); overflow:hidden; transition:background-color .28s,border-color .28s;}
.table.flush-top{border-radius:0 0 var(--r-lg) var(--r-lg); border-top:none;}
table{width:100%; border-collapse:collapse;}
thead th{background:var(--th-bg); text-align:left; font-size:var(--fs-sm); font-weight:600; color:var(--muted); padding:11px 14px; border-bottom:1px solid var(--border); white-space:nowrap;}
th.num,td.num{text-align:right;}
th.act,td.act{width:78px;}
thead th .fh{display:inline-flex; align-items:center; gap:5px; cursor:pointer;}
thead th .fh.filtered{color:var(--primary);}
.funnel{width:12px; height:12px; stroke-width:1.6;}
/* 列头排序(2026-07-07):label+方向箭头;未排序淡 chevron-down 暗示可排,激活整体 primary。
点击循环 无→升→降→无(服务端全局排序)。 */
thead th .sh{display:inline-flex; align-items:center; gap:4px; cursor:pointer; user-select:none;}
thead th .sh.on{color:var(--primary);}
.sort-ic{width:12px; height:12px; stroke-width:2;}
thead th .sh:not(.on) .sort-ic{opacity:.45;}
tbody td{padding:12px 14px; font-size:var(--fs-body); border-bottom:1px solid var(--border-subtle); color:var(--text); white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr.click{cursor:pointer;} tbody tr:hover{background:var(--row-hover);}
.pname{font-weight:600; color:var(--heading);}
.pcode{font-size:var(--fs-xs); color:var(--faint); margin-top:2px; font-family:var(--font-mono);}
.qty{font-weight:600; font-family:var(--font-mono);} .qty.low{color:var(--accent);}
td.num{font-family:var(--font-mono);}
.row-act{display:flex; gap:8px; color:var(--muted);}
.row-act svg{width:16px; height:16px; stroke-width:1.7; cursor:pointer;}
.row-act svg:hover{color:var(--primary);}
.empty{padding:48px; text-align:center; color:var(--muted); font-size:var(--fs-body);}
/* ---- 分页 ---- */
.pager{display:flex; align-items:center; gap:12px; padding:13px 4px 2px; font-size:var(--fs-sm); color:var(--muted);}
.pager .pg{margin-left:auto; display:flex; gap:4px;}
.pg button{min-width:30px; height:30px; padding:0 6px; border:1px solid var(--border); background:var(--surface); border-radius:var(--r-sm); color:var(--text); font-size:var(--fs-sm); cursor:pointer; font-family:var(--font-mono);}
.pg button.cur{background:var(--primary); color:var(--on-primary); border-color:var(--primary);}
.pg button:disabled{color:var(--faint); cursor:default;}
.pager .pg-size{display:inline-flex; align-items:center; gap:6px;}
.pgsize-btn{display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 8px 0 10px; border:1px solid var(--border); border-radius:var(--r-sm); background:var(--surface); color:var(--text); font-size:var(--fs-sm); font-family:var(--font-mono); cursor:pointer;}
.pgsize-btn:hover{border-color:var(--primary);}
.pgsize-caret{width:12px; height:12px; color:var(--muted); flex:none;}
/* ---- 下拉菜单(JS 定位) ---- */
.menu{position:fixed; z-index:var(--z-menu); background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); box-shadow:var(--sh-2); padding:6px; min-width:160px;}
.menu-item{display:flex; align-items:center; gap:9px; padding:8px 10px; border-radius:var(--r-sm); font-size:var(--fs-body); color:var(--text); cursor:pointer;}
.menu-item:hover{background:var(--bg);}
.menu-item .ck{width:16px; height:16px; color:var(--primary);}
.menu-item .mi-ic{width:16px; height:16px; flex:none; stroke-width:1.8;}
.menu-item.sel{color:var(--primary); font-weight:600;}
/* 用户菜单(侧栏底部弹出):比激活导航略浅的同色系 + 浅色字 */
.menu.user-menu{background:var(--menu-user-bg); border-color:var(--menu-user-bg);}
.menu.user-menu .menu-item{color:var(--menu-user-fg);}
.menu.user-menu .menu-item .mi-ic{color:var(--menu-user-fg);}
.menu.user-menu .menu-item:hover{background:var(--menu-user-hover);}
/* ---- 弹窗 ---- */
.overlay{position:fixed; inset:0; background:var(--scrim); display:none; align-items:center; justify-content:center; z-index:var(--z-overlay);}
.overlay.show{display:flex;}
.modal{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-xl); width:680px; max-width:92vw; max-height:88vh; display:flex; flex-direction:column; box-shadow:0 24px 70px var(--shadow); overflow:hidden;}
.modal.narrow{width:520px;}
.modal-head{display:flex; align-items:center; padding:16px 20px; border-bottom:1px solid var(--border);}
.modal-head h3{margin:0; font-size:var(--fs-h2); color:var(--heading);}
.modal-head .x, .drawer-head .x{margin-left:auto; cursor:pointer; color:var(--muted); width:22px; height:22px;}
.modal-body{padding:18px 20px; overflow:auto;}
.modal-foot{display:flex; justify-content:flex-end; gap:10px; padding:14px 20px; border-top:1px solid var(--border);}
.frow{display:flex; gap:14px; margin-bottom:14px;}
.field{flex:1;} .field label{display:block; font-size:var(--fs-sm); color:var(--muted); margin-bottom:6px;}
.lines{border:1px solid var(--border); border-radius:var(--r-md); overflow:hidden; margin-bottom:6px;}
.lines .lh, .lines .lr{display:grid; grid-template-columns:1fr 80px 90px 90px 30px; gap:8px; align-items:center; padding:9px 12px; font-size:var(--fs-sm);}
.lines .lh{background:var(--th-bg); color:var(--muted); font-weight:600;}
.lines .lr{border-top:1px solid var(--border-subtle);}
.lines .lr input{height:30px; border:1px solid var(--border); border-radius:5px; padding:0 8px; font-size:var(--fs-sm); background:var(--bg); color:var(--text); width:100%; outline:none; font-family:var(--font);}
.lines .lr .amt{font-weight:600; color:var(--heading); text-align:right; font-family:var(--font-mono);}
.lines .lr .del{color:var(--faint); cursor:pointer; text-align:center;}
.lines .lr .del:hover{color:var(--danger);}
.ltotal{display:flex; justify-content:flex-end; gap:10px; align-items:center; font-size:var(--fs-body); color:var(--muted); padding:8px 4px 0;}
.ltotal b{font-size:18px; color:var(--accent); font-family:var(--font-mono);}
/* ---- 抽屉 ---- */
.drawer{position:fixed; top:0; right:0; height:100vh; width:480px; max-width:94vw; background:var(--surface); border-left:1px solid var(--border); box-shadow:-16px 0 50px var(--shadow); transform:translateX(100%); transition:transform .25s; z-index:var(--z-drawer); display:flex; flex-direction:column;}
.drawer.show{transform:translateX(0);}
.drawer.wide{width:600px;}
/* 抽屉遮罩:点击空白处关闭抽屉(z-index 在抽屉之下) */
.drawer-mask{position:fixed; inset:0; background:var(--scrim); opacity:0; pointer-events:none; transition:opacity .25s; z-index:var(--z-drawer-scrim);}
.drawer-mask.show{opacity:1; pointer-events:auto;}
.drawer-head{padding:18px 20px; border-bottom:1px solid var(--border); display:flex; align-items:center;}
.drawer-head h3{margin:0; font-size:var(--fs-h2); color:var(--heading);}
.drawer-body{padding:18px 20px; overflow:auto;}
.drow{display:flex; justify-content:space-between; padding:11px 0; border-bottom:1px solid var(--border-subtle); font-size:var(--fs-body);}
.drow span{color:var(--muted);} .drow b{color:var(--text); font-weight:600;}
/* ---- 商品编辑抽屉 .pe-*product-editor.js 注入,库存/基础数据共用)---- */
.pe-card{border:1px solid var(--border); border-radius:var(--r-lg); margin-bottom:14px; overflow:hidden; background:var(--surface);}
.pe-h{display:flex; align-items:center; gap:8px; padding:11px 13px; border-bottom:1px solid var(--border-subtle); font-size:var(--fs-body); font-weight:600; color:var(--heading);}
.pe-h .pe-ic{width:22px; height:22px; border-radius:var(--r-sm); background:var(--brand50); color:var(--primary); display:flex; align-items:center; justify-content:center; flex:none;}
.pe-h .pe-ic svg{width:14px; height:14px; stroke-width:1.9;}
.pe-h .pe-manage{margin-left:auto; font-size:var(--fs-sm); color:var(--primary); cursor:pointer;}
.pe-b{padding:13px;}
.pe-note{font-size:var(--fs-xs); color:var(--faint); margin-top:9px; line-height:1.6;}
.pe-gallery{display:flex; gap:9px; flex-wrap:wrap;}
.pe-tile{width:86px; height:106px; border:1.5px dashed var(--border); border-radius:var(--r-md); background:var(--bg); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px; cursor:pointer; color:var(--faint); font-size:var(--fs-xs); position:relative; overflow:hidden;}
.pe-tile:hover{border-color:var(--primary); color:var(--primary);}
.pe-tile svg{width:20px; height:20px; stroke-width:1.6;}
.pe-tile img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;}
.pe-tile.has{border-style:solid; border-color:var(--border);}
.pe-tile .rm{position:absolute; top:3px; right:3px; width:18px; height:18px; border-radius:50%; background:var(--danger); color:#fff; display:none; align-items:center; justify-content:center;}
.pe-tile.has .rm{display:flex;}
.pe-tile .cap{position:absolute; bottom:0; left:0; right:0; background:var(--scrim); color:#fff; font-size:var(--fs-xs); text-align:center; padding:1px 0;}
.pe-pick{display:flex; align-items:center; gap:8px; height:38px; padding:0 11px; border:1px solid var(--border); border-radius:var(--r-md); cursor:pointer; color:var(--text); font-size:var(--fs-body); background:var(--surface);}
.pe-pick:hover{border-color:var(--primary);}
.pe-pick .ph{color:var(--faint);}
.pe-pick svg{margin-left:auto; width:14px; height:14px; color:var(--muted);}
.pe-text{width:100%; box-sizing:border-box; min-height:84px; resize:vertical; border:1px solid var(--border); border-radius:var(--r-md); padding:10px 11px; font-size:var(--fs-body); color:var(--text); background:var(--surface); outline:none; font-family:var(--font); line-height:1.7; margin-top:10px;}
.pe-text:focus{border-color:var(--primary);}
.pe-foot{display:flex; gap:10px; justify-content:flex-end; margin-top:6px;}
/* 明细行三行式:商品名 / 编码 / 系列·规格 */
.lcell{min-width:0;}
.lcell .ln{display:block; color:var(--heading); font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.lcell .lcode{display:block; font-family:var(--font-mono); color:var(--muted); font-size:var(--fs-xs); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.lcell .lspec{display:block; color:var(--muted); font-size:var(--fs-xs); margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.lcell .lser{display:block; color:var(--text); font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
/* 抽屉底部操作分组:审核类 / 打印类 */
.dactions{margin-top:18px; display:flex; flex-direction:column; gap:14px;}
.dact-group{display:flex; flex-direction:column; gap:8px;}
.dact-label{font-size:var(--fs-xs); color:var(--muted); font-weight:600; letter-spacing:.4px;}
.dact-row{display:flex; flex-wrap:wrap; gap:10px;}
/* ---- Toast ---- */
.toast{position:fixed; bottom:26px; left:50%; transform:translateX(-50%) translateY(20px); background:var(--toast-bg); color:#fff; padding:11px 18px; border-radius:var(--r-md); font-size:var(--fs-body); opacity:0; pointer-events:none; transition:.25s; z-index:var(--z-toast);}
.toast.show{opacity:1; transform:translateX(-50%) translateY(0);}
/* ---- 底部状态栏(app-shell 底,statusbar.js 注入) ---- */
.statusbar{flex:none; height:34px; display:flex; align-items:center; padding:0 6px; background:var(--statusbar-bg); color:var(--statusbar-fg); font-size:var(--fs-xs); border-top:1px solid var(--statusbar-div); overflow:hidden;}
.statusbar .sb-group{display:flex; align-items:center; min-width:0;}
.statusbar .sb-group.right{margin-left:auto;}
.statusbar .sb-i{display:inline-flex; align-items:center; gap:6px; padding:0 13px; white-space:nowrap;}
.statusbar .sb-group .sb-i + .sb-i{border-left:1px solid var(--statusbar-div);}
.statusbar .sb-i svg{width:13px; height:13px; stroke-width:1.8; color:var(--statusbar-muted); flex:none;}
.statusbar .sb-i b{color:var(--statusbar-strong); font-weight:600; font-family:var(--font-mono);}
.statusbar .sb-i.ok, .statusbar .sb-i.ok svg, .statusbar .sb-i.ok b{color:var(--statusbar-ok);}
@media(max-width:760px){ .statusbar .sb-hideable{display:none;} }
/* ---- 顶栏通知(小喇叭 + 下拉面板) ---- */
.nbadge{position:absolute; top:2px; right:2px; min-width:15px; height:15px; padding:0 4px; border-radius:var(--r-pill); background:var(--danger); color:#fff; font-size:var(--fs-xs); font-weight:700; line-height:15px; text-align:center; box-shadow:0 0 0 2px var(--top-bg); pointer-events:none;}
.notify-pop{position:fixed; z-index:var(--z-pop); width:330px; max-width:92vw; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); box-shadow:var(--sh-3); display:none; flex-direction:column; overflow:hidden;}
.notify-pop.show{display:flex;}
.notify-pop .np-head{display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid var(--border-subtle);}
.notify-pop .np-head h4{margin:0; font-size:var(--fs-title); color:var(--heading);}
.notify-pop .np-head .np-clear{font-size:var(--fs-sm); color:var(--primary); cursor:pointer;}
.notify-pop .np-list{max-height:340px; overflow:auto;}
.notify-pop .np-item{display:flex; gap:11px; padding:11px 14px; border-bottom:1px solid var(--border-subtle); cursor:pointer; transition:background-color .12s;}
.notify-pop .np-item:hover{background:var(--bg);}
.notify-pop .np-item.unread{background:var(--brand50);}
.notify-pop .np-item.unread:hover{background:var(--brand50);}
.notify-pop .np-ic{width:30px; height:30px; border-radius:var(--r-md); flex:none; display:flex; align-items:center; justify-content:center;}
.notify-pop .np-ic svg{width:16px; height:16px; stroke-width:1.8;}
.notify-pop .np-ic.warn{background:var(--warn-bg); color:var(--warn);}
.notify-pop .np-ic.info{background:var(--info-soft); color:var(--primary);}
.notify-pop .np-ic.ok{background:var(--success-bg); color:var(--success);}
.notify-pop .np-tx{flex:1; min-width:0;}
.notify-pop .np-tx .np-t{font-size:var(--fs-body); color:var(--heading); font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.notify-pop .np-tx .np-d{font-size:var(--fs-xs); color:var(--muted); margin-top:2px;}
.notify-pop .np-time{font-size:var(--fs-xs); color:var(--faint); flex:none;}
.notify-pop .np-empty{padding:30px; text-align:center; color:var(--muted); font-size:var(--fs-sm);}
.notify-pop .np-foot{padding:9px 14px; text-align:center; border-top:1px solid var(--border-subtle); font-size:var(--fs-sm); color:var(--primary); cursor:pointer; background:var(--bg);}
/* ---- 通知中心 .nt-*(列表行 + 类型图标,桌面/移动共用,登记于 index.html---- */
.nt-item{display:flex; gap:12px; align-items:flex-start; padding:13px 15px; border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface); cursor:pointer; text-decoration:none; color:var(--text); transition:border-color .15s,background-color .15s;}
.nt-item+.nt-item{margin-top:10px;}
.nt-item:hover{border-color:var(--brand400);}
.nt-item.unread{background:var(--brand50);}
.nt-ic{width:38px; height:38px; border-radius:var(--r-md); flex:none; display:flex; align-items:center; justify-content:center;}
.nt-ic svg{width:19px; height:19px; stroke-width:1.8;}
.nt-ic.warn{background:var(--warn-bg); color:var(--warn);}
.nt-ic.info{background:var(--info-soft); color:var(--primary);}
.nt-ic.ok{background:var(--success-bg); color:var(--success);}
.nt-ic.danger{background:var(--danger-bg); color:var(--danger);}
.nt-ic.lg{width:50px; height:50px; border-radius:var(--r-lg);}
.nt-ic.lg svg{width:25px; height:25px;}
.nt-bd{flex:1; min-width:0;}
.nt-t{display:flex; align-items:center; gap:7px;}
.nt-t .nt-dot{width:7px; height:7px; border-radius:50%; background:var(--primary); flex:none;}
.nt-t .nt-tt{flex:1; min-width:0; font-size:var(--fs-body); font-weight:600; color:var(--heading); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.nt-t .nt-time{font-size:var(--fs-xs); color:var(--faint); flex:none; white-space:nowrap;}
.nt-d{font-size:var(--fs-sm); color:var(--muted); margin-top:3px; line-height:1.55;}
/* ============================================================
录单表单新增原子(入库 / 出库录单屏复用)
仍只引用 tokens.css 的 var(),禁硬编码 hex。
============================================================ */
/* ---- 分段切换 .seg(入库 / 出库 等二三选一)---- */
.seg{display:inline-flex; background:var(--bg); border:1px solid var(--border); border-radius:var(--r-md); padding:3px; gap:3px;}
.seg button{height:30px; padding:0 16px; border:none; background:transparent; border-radius:var(--r-sm); font-size:var(--fs-sm); font-weight:600; color:var(--muted); cursor:pointer; font-family:var(--font); transition:color .15s,background-color .15s;}
.seg button.on{background:var(--surface); color:var(--primary); box-shadow:var(--sh-1);}
/* ---- 可搜索选择器 .combo(单据头全尺寸 + 网格单元格变体 .cell)---- */
.combo{position:relative; height:38px; width:100%; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); display:flex; align-items:center; cursor:text; transition:border-color .15s,box-shadow .15s;}
.combo input{border:none; outline:none; background:transparent; width:100%; height:100%; padding:0 30px 0 11px; font-size:var(--fs-body); color:var(--text); font-family:var(--font); cursor:text; border-radius:inherit;}
.combo input::placeholder{color:var(--faint);}
.combo .caf{position:absolute; right:8px; top:50%; transform:translateY(-50%); width:16px; height:16px; color:var(--faint); display:flex; align-items:center; justify-content:center;}
.combo .caf svg{width:14px; height:14px; stroke-width:2;}
.combo.has .caf{cursor:pointer;}
.combo.has .caf:hover{color:var(--danger);}
.combo:focus-within{border-color:var(--primary); box-shadow:0 0 0 3px var(--brand50);}
.combo.error{border-color:var(--danger); box-shadow:0 0 0 3px var(--danger-bg);}
/* 网格单元格变体:默认无边、矮,hover/focus 才显形 */
.combo.cell{height:32px; border-color:transparent; background:transparent; border-radius:5px;}
.combo.cell input{padding:0 24px 0 8px; font-size:var(--fs-body);}
.combo.cell:hover{background:var(--bg);}
.combo.cell:focus-within{background:var(--surface); border-color:var(--primary); box-shadow:0 0 0 2px var(--brand50);}
.combo.cell.error{border-color:var(--danger); background:var(--danger-bg); box-shadow:none;}
.combo.cell .caf{right:6px;}
/* combo 浮层(JS fixed 定位,视觉承袭 .menu---- */
.combo-pop{position:fixed; z-index:var(--z-pop); background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md); box-shadow:var(--sh-2); display:flex; flex-direction:column; overflow:hidden; min-width:200px;}
.combo-pop .cp-list{overflow:auto; padding:5px; max-height:264px;}
.combo-pop .cp-grp{font-size:var(--fs-xs); color:var(--faint); font-weight:600; letter-spacing:.5px; padding:8px 9px 4px;}
.combo-pop .cp-item{display:flex; align-items:center; gap:9px; padding:8px 10px; border-radius:var(--r-sm); font-size:var(--fs-body); color:var(--text); cursor:pointer; white-space:nowrap;}
.combo-pop .cp-item .nm{overflow:hidden; text-overflow:ellipsis;}
.combo-pop .cp-item small{color:var(--faint); font-family:var(--font-mono); font-size:var(--fs-xs); margin-left:auto; padding-left:12px;}
.combo-pop .cp-item.cur{background:var(--row-hover);}
.combo-pop .cp-item.sel{color:var(--primary); font-weight:600;}
.combo-pop .cp-item .ck{width:15px; height:15px; color:var(--primary); flex:none;}
.combo-pop .cp-item .hl{color:var(--primary); font-weight:700;}
.combo-pop .cp-new{display:flex; align-items:center; gap:8px; padding:10px 12px; border-top:1px solid var(--border-subtle); color:var(--primary); font-size:var(--fs-sm); font-weight:600; cursor:pointer;}
.combo-pop .cp-new.cur{background:var(--row-hover);}
.combo-pop .cp-new svg{width:14px; height:14px; stroke-width:2; flex:none;}
.combo-pop .cp-empty{padding:20px; text-align:center; color:var(--muted); font-size:var(--fs-sm);}
/* 弹层置顶搜索框(单据头供应商/仓库等显式搜索下拉用) */
.combo-pop .cp-search{display:flex; align-items:center; gap:8px; padding:9px 11px; border-bottom:1px solid var(--border-subtle); flex:none;}
.combo-pop .cp-search svg{width:14px; height:14px; stroke-width:2; color:var(--faint); flex:none;}
.combo-pop .cp-search input{border:none; outline:none; background:transparent; width:100%; font-size:var(--fs-body); color:var(--text); font-family:var(--font);}
.combo-pop .cp-search input::placeholder{color:var(--faint);}
.combo-pop .cp-body{display:flex; flex-direction:column; overflow:hidden;}
/* 弹层底部结果统计(内容多时启用:显示总返回条数) */
.combo-pop .cp-foot{flex:none; padding:7px 12px; border-top:1px solid var(--border-subtle); font-size:var(--fs-xs); color:var(--muted); background:var(--bg);}
.combo-pop .cp-foot b{color:var(--text); font-weight:600; font-family:var(--font-mono);}
/* ---- 可编辑明细网格 .grid ---- */
.grid{border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface); display:flex; flex-direction:column; min-height:0; overflow:hidden; transition:background-color .28s,border-color .28s;}
.grid-scroll{overflow:auto; flex:1; min-height:0;}
.grid table{width:100%; border-collapse:separate; border-spacing:0; min-width:920px;}
.grid thead th{position:sticky; top:0; z-index:3; background:var(--th-bg); color:var(--muted); font-size:var(--fs-sm); font-weight:600; text-align:left; padding:10px 10px; border-bottom:1px solid var(--border); white-space:nowrap;}
.grid th.req::after{content:"*"; color:var(--danger); margin-left:3px;}
.grid th.num, .grid td.num{text-align:right;}
.grid tbody td{border-bottom:1px solid var(--border-subtle); background:var(--surface); vertical-align:middle; transition:background-color .15s;}
.grid tbody tr.gr:hover td{background:var(--row-hover);}
.grid td.cpad{padding:4px 6px;}
.grid td.gidx{width:38px; text-align:center; color:var(--faint); font-family:var(--font-mono); font-size:var(--fs-sm);}
.grid tr.gr.error td{box-shadow:inset 3px 0 0 var(--danger);}
.grid .gci{height:32px; width:100%; border:1px solid transparent; background:transparent; border-radius:5px; padding:0 8px; font-size:var(--fs-body); color:var(--text); outline:none; font-family:var(--font);}
.grid td.num .gci{text-align:right; font-family:var(--font-mono);}
.grid .gci:hover{background:var(--bg);}
.grid .gci:focus{background:var(--surface); border-color:var(--primary); box-shadow:0 0 0 2px var(--brand50);}
.grid .gci.error{border-color:var(--danger); background:var(--danger-bg);}
.grid td.ro{color:var(--muted); padding:0 10px; font-size:var(--fs-body); white-space:nowrap;}
.grid td.ro.num{font-family:var(--font-mono);}
.grid td.amt{font-family:var(--font-mono); font-weight:600; color:var(--heading); padding:0 12px; white-space:nowrap;}
.grid td.gact, .grid th.gact{width:92px;}
.grid .gact-in{display:flex; gap:8px; justify-content:center; color:var(--muted);}
.grid .gact-in svg{width:16px; height:16px; stroke-width:1.7; cursor:pointer;}
.grid .gact-in svg:hover{color:var(--primary);} .grid .gact-in .gdel:hover{color:var(--danger);}
.grid-add{display:flex; align-items:center; gap:8px; padding:11px 14px; color:var(--primary); font-size:var(--fs-body); font-weight:600; cursor:pointer; border-top:1px solid var(--border-subtle); flex:none;}
.grid-add:hover{background:var(--row-hover);}
.grid-add svg{width:16px; height:16px; stroke-width:2;}
.grid-add kbd{margin-left:6px; font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--faint); font-weight:500;}
/* ---- 状态徽章(单据状态,承袭 .badge 机制)---- */
.b-草稿{background:var(--bg); color:var(--muted);}
.b-待审核{background:var(--info-soft); color:var(--primary);}
.b-已通过{background:var(--success-bg); color:var(--success);}
.b-已驳回{background:var(--danger-bg); color:var(--danger);}
/* ---- 提示条 .notice(草稿恢复 / 驳回理由)---- */
.notice{display:flex; align-items:center; gap:10px; padding:11px 14px; border-radius:var(--r-md); font-size:var(--fs-body); margin-bottom:14px; border:1px solid var(--border-subtle);}
.notice svg{width:17px; height:17px; stroke-width:1.8; flex:none;}
.notice .nb{margin-left:auto; display:flex; gap:8px; flex:none;}
.notice.info{background:var(--info-soft); color:var(--primary);}
.notice.danger{background:var(--danger-bg); color:var(--danger);}
.notice .lk{cursor:pointer; font-weight:600; text-decoration:underline; text-underline-offset:2px;}
/* ---- 移动端明细卡 .mcard ---- */
.mcard{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); overflow:hidden; transition:border-color .15s;}
.mcard.error{border-color:var(--danger);}
.mcard-head{display:flex; align-items:center; padding:11px 14px; background:var(--th-bg); border-bottom:1px solid var(--border-subtle);}
.mcard-head .mt{font-weight:600; color:var(--heading); font-size:var(--fs-body);}
.mcard-head .msub{margin-left:9px; color:var(--faint); font-size:var(--fs-xs); font-family:var(--font-mono);}
.mcard-head .mact{margin-left:auto; display:flex; gap:14px; color:var(--muted);}
.mcard-head .mact svg{width:18px; height:18px; stroke-width:1.7; cursor:pointer;}
.mcard-head .mact .gdel:hover{color:var(--danger);}
.mcard-body{padding:4px 14px 12px;}
.mrow{display:flex; align-items:center; gap:12px; padding:9px 0; border-bottom:1px solid var(--border-subtle); min-height:46px;}
.mrow:last-child{border-bottom:none;}
.mrow > label{width:64px; flex:none; font-size:var(--fs-sm); color:var(--muted);}
.mrow > label.req::after{content:"*"; color:var(--danger); margin-left:2px;}
.mrow .mv{flex:1; min-width:0;}
.mrow .mv.amt{text-align:right; font-family:var(--font-mono); font-weight:700; color:var(--accent); font-size:var(--fs-h2);}
.mrow .mv input{height:36px; width:100%; border:1px solid var(--border); background:var(--surface); border-radius:var(--r-md); padding:0 10px; font-size:var(--fs-body); color:var(--text); outline:none; font-family:var(--font);}
.mrow .mv input:focus{border-color:var(--primary); box-shadow:0 0 0 3px var(--brand50);}
.mrow .mv input.error{border-color:var(--danger);}
/* ---- 行内选填折叠区(入库:产地/保质期/储存/介绍文档)---- */
.grid .gexp{transition:transform .2s;} .grid .gexp.on{transform:rotate(180deg); color:var(--primary);}
.grid tr.gsub td{background:var(--info-soft); box-shadow:inset 3px 0 0 var(--primary);}
.grid .gsub-pad{padding:12px 16px 14px;}
.opt-head{font-size:var(--fs-sm); color:var(--muted); margin-bottom:10px;}
.opt-grid{display:flex; flex-wrap:wrap; gap:14px;}
.opt-field{width:210px;} .opt-field label{display:block; font-size:var(--fs-xs); color:var(--muted); margin-bottom:5px;}
/* ---- 从库存批量挑货(出库)---- */
.pick-head, .pick-row{display:grid; grid-template-columns:28px minmax(0,1fr) 86px 84px 92px; gap:10px; align-items:center;}
.pick-head{padding:9px 12px; background:var(--th-bg); font-size:var(--fs-sm); color:var(--muted); font-weight:600; border:1px solid var(--border); border-bottom:none; border-radius:var(--r-md) var(--r-md) 0 0;}
.pick-list{border:1px solid var(--border); border-radius:0 0 var(--r-md) var(--r-md); max-height:46vh; overflow-y:auto;}
.pick-row{padding:9px 12px; border-bottom:1px solid var(--border-subtle); cursor:pointer; font-size:var(--fs-body);}
.pick-row:last-child{border-bottom:none;}
.pick-row:hover{background:var(--row-hover);}
.pick-row.on{background:var(--info-soft);}
.pick-row .ck{width:18px; height:18px; border:1.5px solid var(--border); border-radius:5px; display:flex; align-items:center; justify-content:center; color:#fff;}
.pick-row.on .ck{background:var(--primary); border-color:var(--primary);}
.pick-row .pn{font-weight:600; color:var(--heading);}
.pick-row .ps{color:var(--muted); font-size:var(--fs-sm);}
.pick-row .pm{text-align:right; font-family:var(--font-mono); color:var(--text);}
.pick-row .pq{text-align:right; font-family:var(--font-mono); font-weight:600;}
/* ---- 状态徽章补全(兑换券 / 盘点 / 账单结清,对齐 schema 真实枚举)---- */
.b-未使用{background:var(--info-soft); color:var(--primary);}
.b-已兑换{background:var(--success-bg); color:var(--success);}
.b-作废{background:var(--bg); color:var(--muted);}
.b-进行中{background:var(--warn-bg); color:var(--warn);}
.b-已完成{background:var(--success-bg); color:var(--success);}
.b-未结清{background:var(--warn-bg); color:var(--warn);}
.b-已结清{background:var(--success-bg); color:var(--success);}
/* ============================================================
app-shell(顶栏 + 侧栏)—— 单一真源,shell.js 注入;所有管理屏复用
============================================================ */
.top{height:56px; background:var(--top-bg); border-bottom:1px solid var(--top-border); display:flex; align-items:center; gap:16px; padding:0 18px; flex:none; z-index:var(--z-header); transition:background-color .28s,border-color .28s;}
.brand-prod{display:flex; align-items:center; gap:7px;}
.brand-prod .prod-mk{width:30px; height:30px; display:flex; align-items:center; justify-content:center; flex:none;}
.brand-prod .prod-mk svg{width:30px; height:30px;}
.brand-prod .prod-nm{font-weight:700; font-size:var(--fs-h2); color:var(--top-fg); letter-spacing:.3px; white-space:nowrap;}
.brand-sep{width:1px; height:20px; background:var(--top-border); flex:none; margin:0 8px;}
.logo{display:flex; align-items:center; gap:9px; font-weight:700; font-size:var(--fs-body); color:var(--top-fg);}
.logo .mk{width:26px; height:26px; border-radius:8px; background:var(--top-mark-bg); color:var(--top-mark-fg); display:flex; align-items:center; justify-content:center; font-weight:800; font-size:var(--fs-body);}
.logo .shop-nm{font-weight:600;}
.gsearch{flex:1; max-width:400px; height:36px; background:var(--top-control); border:1px solid var(--top-border); border-radius:var(--r-md); display:flex; align-items:center; gap:8px; padding:0 12px; color:var(--top-faint); font-size:var(--fs-body); cursor:text;}
.gsearch svg{stroke-width:2; color:var(--top-faint); flex:none;}
.top-right{margin-left:auto; display:flex; align-items:center; gap:14px; color:var(--top-fg);}
.theme-pill{display:flex; align-items:center; gap:7px; height:30px; padding:0 11px; border:1px solid var(--top-border); border-radius:var(--r-pill); font-size:var(--fs-sm); color:var(--top-fg); background:var(--top-control); cursor:pointer;}
.theme-pill .dot{width:11px; height:11px; border-radius:50%; background:var(--top-fg);}
.theme-pill .tp-shirt{color:var(--side-fg); flex:none;}
.icon-btn{width:34px; height:34px; border-radius:8px; display:flex; align-items:center; justify-content:center; color:var(--top-fg); cursor:pointer;}
.icon-btn:hover{background:var(--top-control);}
.body{flex:1; display:flex; min-height:0;}
.side{width:218px; background:var(--side-bg); border-right:1px solid var(--side-border); padding:12px 12px 0; display:flex; flex-direction:column; flex:none; transition:background-color .28s,border-color .28s;}
.nav-label{font-size:var(--fs-xs); color:var(--side-muted); font-weight:600; letter-spacing:.6px; padding:10px 10px 6px;}
.nav{display:flex; align-items:center; gap:11px; height:40px; padding:0 11px; border-radius:var(--r-md); color:var(--side-fg); font-size:var(--fs-body); font-weight:500; margin-bottom:2px; cursor:pointer; text-decoration:none; transition:background-color .15s,color .15s;}
.nav svg{width:19px; height:19px; flex:none; stroke-width:1.7;}
.nav:hover{background:var(--side-hover); color:var(--side-active-fg);}
.nav.active{background:var(--side-active-bg); color:var(--side-active-fg); font-weight:600;}
.side-bottom{margin-top:auto; padding-bottom:8px;}
.side-div{height:1px; background:var(--side-border); margin:8px 4px;}
.side-user{display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:var(--r-md); cursor:pointer; transition:background-color .15s;}
.side-user:hover{background:var(--side-hover);}
.su-pic{width:34px; height:34px; border-radius:50%; background:var(--side-active-bg); color:var(--side-active-fg); display:flex; align-items:center; justify-content:center; font-weight:700; font-size:14px; flex:none;}
.su-who{flex:1; min-width:0; line-height:1.3;}
.su-who b{display:block; color:var(--side-active-fg); font-size:var(--fs-body); font-weight:600;}
.su-who span{color:var(--side-muted); font-size:var(--fs-xs);}
.su-caret{width:14px; height:14px; color:var(--side-muted); flex:none;}
.main{flex:1; min-width:0; overflow:auto; padding:22px 26px;}
/* 侧栏右侧内容列:主区 + 底部状态栏(状态栏不贯穿侧栏) */
.content-col{flex:1; min-width:0; display:flex; flex-direction:column;}
.content-col > .main, .content-col > .work{flex:1; min-height:0;}