/* ============================================================ 移动端原子层 .m-* —— 复用 tokens.css(颜色/3主题/间距/圆角/字号), 仅新增移动专属组件(顶栏 / 底 tab / 页面骨架 / KPI / 列表卡 / sheet / 表单 / 搜索 / FAB / 筛选 pill)。 单一真源:颜色一律走 var(--*),禁硬编码。kit 展示见 mobile-kit.html。 ============================================================ */ /* ---- 移动壳:顶部 app 栏 ---- */ .m-top{position:fixed; top:0; left:0; right:0; height:52px; display:flex; align-items:center; gap:10px; padding:0 14px; background:var(--top-bg); color:var(--top-fg); z-index:var(--z-header);} .m-top .m-back{width:30px; height:30px; margin-left:-6px; display:flex; align-items:center; justify-content:center; color:var(--top-fg); cursor:pointer;} .m-top .m-back svg{width:22px; height:22px; stroke-width:2;} .m-top .m-title{font-size:var(--fs-title); font-weight:700; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;} .m-top .m-actions{margin-left:auto; display:flex; align-items:center; gap:13px;} .m-top .m-ic{width:24px; height:24px; display:flex; align-items:center; justify-content:center; color:var(--top-fg); position:relative; cursor:pointer;} .m-top .m-ic svg{width:20px; height:20px; stroke-width:1.9;} .m-top .m-dot{position:absolute; top:-2px; right:-2px; min-width:15px; height:15px; padding:0 3px; box-sizing:border-box; border-radius:var(--r-pill); background:var(--danger); color:#fff; font-size:var(--fs-xs); display:flex; align-items:center; justify-content:center;} .m-top .m-av{width:28px; height:28px; border-radius:50%; background:var(--brand-mid); color:#fff; display:flex; align-items:center; justify-content:center; font-weight:700; font-size:var(--fs-sm); cursor:pointer;} /* ---- 移动壳:底部 tab 栏 ---- */ .m-tabbar{position:fixed; bottom:0; left:0; right:0; min-height:56px; display:flex; background:var(--surface); border-top:1px solid var(--border); z-index:var(--z-header); padding-bottom:env(safe-area-inset-bottom);} .m-tab{flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; padding:8px 0; color:var(--muted); font-size:var(--fs-xs); text-decoration:none; cursor:pointer;} .m-tab svg{width:22px; height:22px; stroke-width:1.8;} .m-tab.on{color:var(--primary);} .m-tab.on svg{stroke-width:2;} /* ---- 页面骨架(固定顶 + 滚动体 + 固定底)---- */ .m-page{min-height:100vh; background:var(--page); padding-top:52px; padding-bottom:64px; box-sizing:border-box;} .m-page.has-tabs{padding-bottom:calc(56px + env(safe-area-inset-bottom) + 8px);} .m-scroll{padding:14px;} /* ---- KPI 卡(2×2)---- */ .m-kpi{display:grid; grid-template-columns:1fr 1fr; gap:10px;} .m-kpi .k{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); padding:12px 14px;} .m-kpi .k .kl{font-size:var(--fs-xs); color:var(--muted); display:flex; align-items:center; gap:5px;} .m-kpi .k .kl svg{width:13px; height:13px; stroke-width:1.9; color:var(--brand400);} .m-kpi .k .kv{font-size:var(--fs-h2); font-weight:800; color:var(--heading); margin-top:5px; letter-spacing:.2px;} .m-kpi .k .kd{font-size:var(--fs-xs); margin-top:3px; color:var(--muted);} .m-kpi .k .kd.up{color:var(--success);} .m-kpi .k .kd.down{color:var(--danger);} .m-kpi .k .kd.warn{color:var(--warn);} /* ---- 列表项卡片 ---- */ .m-card{display:block; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); padding:13px 14px; margin-bottom:10px; text-decoration:none; color:inherit;} .m-card:active{border-color:var(--primary);} .m-row{display:flex; align-items:center; gap:12px;} .m-row .mc-main{min-width:0; flex:1;} .m-row .mc-nm{font-weight:600; color:var(--heading); font-size:var(--fs-body); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;} .m-row .mc-nm .mc-date{font-weight:400; font-size:var(--fs-xs); color:var(--muted); font-family:var(--font-mono); margin-left:8px;} .m-row .mc-sub{font-size:var(--fs-xs); color:var(--muted); margin-top:3px; font-family:var(--font-mono); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;} .m-row .mc-right{display:flex; flex-direction:column; align-items:flex-end; gap:5px; flex:none;} .m-row .mc-amt{font-weight:700; color:var(--heading); font-size:var(--fs-body); font-family:var(--font-mono);} .m-row .mc-chev{color:var(--faint); flex:none;} .m-row .mc-chev svg{width:18px; height:18px; stroke-width:2;} .m-card .mc-foot{display:flex; align-items:center; gap:10px; margin-top:10px; padding-top:10px; border-top:1px solid var(--border-subtle); font-size:var(--fs-xs); color:var(--muted);} /* ---- 底部 sheet(筛选 / 选择 / 动作)---- */ .m-sheet-mask{position:fixed; inset:0; background:var(--scrim); opacity:0; pointer-events:none; transition:opacity .25s; z-index:var(--z-drawer-scrim);} .m-sheet-mask.show{opacity:1; pointer-events:auto;} .m-sheet{position:fixed; left:0; right:0; bottom:0; background:var(--surface); border-radius:var(--r-xl) var(--r-xl) 0 0; transform:translateY(100%); transition:transform .26s; z-index:var(--z-drawer); max-height:86vh; display:flex; flex-direction:column; padding-bottom:env(safe-area-inset-bottom);} .m-sheet.show{transform:translateY(0);} .m-sheet .grip{width:36px; height:4px; border-radius:var(--r-pill); background:var(--border); margin:8px auto 2px;} .m-sheet-h{display:flex; align-items:center; padding:10px 16px 12px; border-bottom:1px solid var(--border-subtle);} .m-sheet-h h3{margin:0; font-size:var(--fs-title); color:var(--heading);} .m-sheet-h .x{margin-left:auto; width:22px; height:22px; color:var(--muted); cursor:pointer;} .m-sheet-b{padding:14px 16px; overflow:auto;} .m-opt{display:flex; align-items:center; gap:10px; padding:13px 4px; border-bottom:1px solid var(--border-subtle); font-size:var(--fs-body); color:var(--text); cursor:pointer;} .m-opt:last-child{border-bottom:none;} .m-opt .ck{margin-left:auto; color:var(--primary); width:18px; height:18px; opacity:0;} .m-opt.sel .ck{opacity:1;} .m-opt.sel{color:var(--primary); font-weight:600;} .m-opt .oic{width:20px; height:20px; color:var(--muted); flex:none;} /* ---- 移动表单(全宽堆叠,触控高度 44)---- */ .m-form{display:block;} .m-field{margin-bottom:14px;} .m-field > label{display:block; font-size:var(--fs-sm); color:var(--muted); margin-bottom:6px; font-weight:600;} .m-input{width:100%; box-sizing:border-box; height:44px; border:1px solid var(--border); border-radius:var(--r-md); padding:0 12px; font-size:var(--fs-body); color:var(--text); background:var(--surface); outline:none; font-family:var(--font);} .m-input:focus{border-color:var(--primary);} textarea.m-input{height:auto; min-height:88px; padding:10px 12px; resize:vertical; line-height:1.7;} .m-select{display:flex; align-items:center; height:44px; padding:0 12px; border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface); color:var(--text); font-size:var(--fs-body); cursor:pointer;} .m-select .ph{color:var(--faint);} .m-select svg{margin-left:auto; width:16px; height:16px; color:var(--muted);} /* ---- 移动搜索条 ---- */ .m-search{display:flex; align-items:center; gap:8px; height:42px; padding:0 12px; background:var(--surface); border:1px solid var(--border); border-radius:var(--r-md);} .m-search svg{width:17px; height:17px; stroke-width:2; color:var(--muted); flex:none;} .m-search input{border:none; outline:none; background:transparent; flex:1; min-width:0; font-size:var(--fs-body); color:var(--text); font-family:var(--font);} /* ---- 横向筛选 pill 行 ---- */ .m-filters{display:flex; gap:8px; overflow-x:auto; scrollbar-width:none; margin-top:10px;} .m-filters::-webkit-scrollbar{display:none;} .m-pill{flex:none; height:32px; padding:0 13px; border:1px solid var(--border); border-radius:var(--r-pill); background:var(--surface); color:var(--text); font-size:var(--fs-sm); display:inline-flex; align-items:center; gap:5px; cursor:pointer;} .m-pill svg{width:13px; height:13px; stroke-width:2;} .m-pill.on{background:var(--brand50); border-color:var(--primary); color:var(--primary); font-weight:600;} /* ---- 悬浮新增 FAB ---- */ .m-fab{position:fixed; right:16px; bottom:74px; width:52px; height:52px; border-radius:50%; background:var(--primary); color:var(--on-primary); display:flex; align-items:center; justify-content:center; box-shadow:var(--sh-3); z-index:var(--z-fab); cursor:pointer;} .m-fab svg{width:24px; height:24px; stroke-width:2.2;} /* ---- 返回设计系统 悬浮球(左下,低调)---- */ /* 调试用「返回设计系统」球:默认右下,宽屏时移到手机框外的视口右下角(真实 app 不含此球) */ .m-ds-fab{position:fixed; left:auto; right:16px; bottom:134px; width:44px; height:44px; border-radius:50%; background:var(--surface); color:var(--muted); border:1px solid var(--border); display:flex; align-items:center; justify-content:center; box-shadow:var(--sh-2); z-index:var(--z-fab); opacity:.9; text-decoration:none;} .m-ds-fab:active{color:var(--primary); border-color:var(--primary);} .m-ds-fab svg{width:20px; height:20px; stroke-width:2;} /* ---- 分组标题 / 空态 ---- */ .m-section{font-size:var(--fs-sm); font-weight:700; color:var(--muted); margin:16px 2px 8px; letter-spacing:.4px;} .m-empty{text-align:center; color:var(--muted); padding:48px 16px; font-size:var(--fs-sm);} .m-empty svg{width:38px; height:38px; stroke-width:1.4; color:var(--faint); display:block; margin:0 auto 10px;} /* ---- 底部固定操作条(表单提交)---- */ .m-actionbar{position:fixed; left:0; right:0; bottom:0; display:flex; gap:10px; padding:12px 14px; background:var(--surface); border-top:1px solid var(--border); z-index:var(--z-header); padding-bottom:calc(12px + env(safe-area-inset-bottom));} .m-actionbar .btn{flex:1; justify-content:center;} /* ---- 我的:hub 列表行 ---- */ .m-hub{background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg); overflow:hidden;} .m-hub a{display:flex; align-items:center; gap:12px; padding:14px; border-bottom:1px solid var(--border-subtle); text-decoration:none; color:var(--text); font-size:var(--fs-body);} .m-hub a:last-child{border-bottom:none;} .m-hub a .hic{width:34px; height:34px; border-radius:var(--r-md); background:var(--brand50); color:var(--primary); display:flex; align-items:center; justify-content:center; flex:none;} .m-hub a .hic svg{width:18px; height:18px; stroke-width:1.8;} .m-hub a .hchev{margin-left:auto; color:var(--faint);} .m-hub a .hchev svg{width:18px; height:18px; stroke-width:2;} /* ---- 桌面预览:窄屏(<600=真机)全宽;宽屏(≥600)整套居中成 430px 手机列,不拉伸 ---- */ @media (min-width:600px){ .m-top, .m-tabbar, .m-actionbar{ left:50%; right:auto; transform:translateX(-50%); width:100%; max-width:430px; } .m-page{ max-width:430px; margin:0 auto; min-height:100vh; box-shadow:var(--sh-3); } .m-fab{ right:auto; left:50%; transform:translateX(147px); } .m-ds-fab{ left:auto; right:24px; bottom:24px; transform:none; } .m-sheet{ left:50%; right:auto; max-width:430px; width:100%; transform:translateX(-50%) translateY(100%); } .m-sheet.show{ transform:translateX(-50%) translateY(0); } }