| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634 |
- /* ==========================================================================
- fmode 移动端 UI Demo · 样式表
- · 令牌层:机械搬运自 src/app/core/styles/_base.scss + _palette.scss(唯一出现色值的地方)
- · 其余样式只用 var(--xx):字号 8 档 / 圆角 4 档 / 间距 7 级 / z-index 9 级
- ========================================================================== */
- /* ---------- 基底令牌(_base.scss :root) ---------- */
- :root {
- --canvas: #edf1f6; --surface: #ffffff; --surface-2: #f5f7fa; --surface-hover: #eaf0f7;
- --surface-active: #dfe6f0; --rail-surface: #f0f3f8;
- --edge: #dce3ed; --edge-strong: #c5d0df;
- --ink: #172337; --ink-2: #495b74; --muted: #61728a; --inverse: #ffffff;
- --success: #207550; --success-subtle: #edf7f1;
- --warning: #91600e; --warning-subtle: #fff7e8;
- --danger: #c33f42; --danger-subtle: #fff0f0; --on-danger: #ffffff;
- --info: #315fa8; --info-subtle: #edf3fd;
- --primary: #315acb; --primary-hover: #2548aa; --primary-active: #2548aa;
- --primary-subtle: #eaf0ff; --primary-content: #ffffff; --primary-ring: rgb(49 90 203 / .35);
- --metric-fill: #5476ca;
- --avatar-ink: #46618c; --avatar-bg: #eaf0fa; --avatar-ink-alt: #596780; --avatar-bg-alt: #edf0f5;
- --neutral: #687385; --neutral-soft: #eff1f5;
- --overlay: #18223966;
- --fs-11: 11px; --fs-12: 12px; --fs-13: 13px; --fs-15: 14px;
- --fs-17: 16px; --fs-20: 20px; --fs-26: 28px; --fs-42: 36px;
- --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-tag: 999px;
- --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;
- --z-affix: 900; --z-float: 950; --z-mask: 980; --z-popover: 1000;
- --z-modal: 1100; --z-preview: 1300; --z-toast: 1400;
- --motion-fast: 120ms; --motion-page: 160ms; --motion-detail: 200ms;
- --motion-panel: 240ms; --motion-exit: 160ms;
- --ease-standard: cubic-bezier(.2, 0, 0, 1);
- --shadow-soft: 0 1px 2px rgb(23 36 60 / .04), 0 4px 12px rgb(23 36 60 / .06);
- --shadow-card: 0 1px 2px rgb(23 36 60 / .05), 0 8px 24px rgb(23 36 60 / .07);
- --shadow-pop: 0 4px 8px rgb(23 36 60 / .08), 0 16px 32px rgb(23 36 60 / .12);
- --shadow-overlay: 0 8px 16px rgb(23 36 60 / .1), 0 24px 48px rgb(23 36 60 / .18);
- --mob-navbar-h: 68px; --mob-tabbar-h: 70px; --mob-gutter: 20px;
- --mob-safe-top: env(safe-area-inset-top, 0px);
- --mob-safe-bottom: env(safe-area-inset-bottom, 0px);
- --touch-min: 44px;
- /* Demo 新增:正文基准字号(设置页 8 档滑块改写它) */
- --fs-body: var(--fs-15);
- --fs-body-line: 1.65;
- }
- .dark {
- --canvas: #11151c; --surface: #191f29; --surface-2: #1e2531; --surface-hover: #2a3342;
- --surface-active: #333c4c; --rail-surface: #141b26;
- --edge: #2d3747; --edge-strong: #414f65;
- --ink: #edf1f8; --ink-2: #b8c2d2; --muted: #98a6bc; --inverse: #14203b;
- --success: #8ed2ac; --success-subtle: #1d352c;
- --warning: #e8bf77; --warning-subtle: #382f22;
- --danger: #f2a0a5; --danger-subtle: #3b272f; --on-danger: #3b272f;
- --info: #acc9fa; --info-subtle: #273a55;
- --primary: #93b5ff; --primary-hover: #b0c9ff; --primary-active: #93b5ff;
- --primary-subtle: #253451; --primary-content: #14203b; --primary-ring: rgb(147 181 255 / .4);
- --metric-fill: #a8c2ff;
- --avatar-ink: #b7cdf2; --avatar-bg: #2b3b56; --avatar-ink-alt: #bac7db; --avatar-bg-alt: #2d3748;
- --neutral: #acb7c9; --neutral-soft: #2b3341;
- --overlay: #070b12a6;
- --shadow-soft: 0 1px 2px rgb(0 0 0 / .3), 0 4px 12px rgb(0 0 0 / .28);
- --shadow-card: 0 1px 2px rgb(0 0 0 / .34), 0 8px 24px rgb(0 0 0 / .32);
- --shadow-pop: 0 4px 8px rgb(0 0 0 / .38), 0 16px 32px rgb(0 0 0 / .34);
- --shadow-overlay: 0 8px 16px rgb(0 0 0 / .42), 0 24px 48px rgb(0 0 0 / .4);
- }
- /* ---------- 四套整体配色(_palette.scss 原样搬运) ---------- */
- :root[data-palette='platinum'] {
- --canvas: #f2f3f5; --surface: #ffffff; --surface-2: #f7f7f8; --surface-hover: #e9eaec;
- --rail-surface: #eceef0; --ink: #202124; --ink-2: #45474b; --muted: #62666d;
- --edge: #dfe1e4; --edge-strong: #c4c7cc;
- --primary: #25272a; --primary-hover: #111214; --primary-subtle: #e8e9eb; --primary-content: #ffffff;
- --nav-surface: #202124; --nav-ink: #f5f5f6; --nav-text: #c6c8cc; --nav-muted: #a9adb4;
- --nav-line: #393b3f; --nav-hover: #303236; --nav-active: #3b3d41;
- --nav-accent: #ffffff; --nav-brand: #f5f5f6; --nav-on-brand: #202124;
- --metric-fill: #6c737d;
- --avatar-ink: #565d67; --avatar-bg: #e9eaec; --avatar-ink-alt: #62666d; --avatar-bg-alt: #eeeff0;
- --neutral: #656a72; --neutral-soft: #eceef0;
- --overlay: #11121470; --shadow: 0 16px 56px #2021241f;
- }
- .dark[data-palette='platinum'] {
- --canvas: #18191b; --surface: #222426; --surface-2: #292b2e; --surface-hover: #383b3f;
- --rail-surface: #1d1f21; --ink: #f2f3f4; --ink-2: #c5c8cc; --muted: #a7abb1;
- --edge: #383b3f; --edge-strong: #565a60;
- --primary: #f1f2f3; --primary-hover: #ffffff; --primary-subtle: #373a3e; --primary-content: #202124;
- --nav-surface: #111214; --nav-ink: #f2f3f4; --nav-text: #c6c8cc; --nav-muted: #a4a8ae;
- --nav-line: #303236; --nav-hover: #25272a; --nav-active: #34373b;
- --nav-accent: #f1f2f3; --nav-brand: #f1f2f3; --nav-on-brand: #202124;
- --metric-fill: #c0c4ca;
- --avatar-ink: #c9cdd3; --avatar-bg: #373a3e; --avatar-ink-alt: #c5c8cd; --avatar-bg-alt: #393c40;
- --neutral: #bec2c8; --neutral-soft: #373a3e;
- --overlay: #08090bb0; --shadow: 0 18px 70px #00000066;
- }
- :root[data-palette='ice'] {
- --canvas: #f6f8fc; --surface: #ffffff; --surface-2: #f1f4f9; --surface-hover: #e7ecf5;
- --rail-surface: #edf1f7; --ink: #202a3c; --ink-2: #46536b; --muted: #606e86;
- --edge: #dce2ec; --edge-strong: #c2ccdc;
- --primary: #4056c7; --primary-hover: #3045ae; --primary-subtle: #e8ecfb; --primary-content: #ffffff;
- --nav-surface: #e9edf5; --nav-ink: #202a3c; --nav-text: #394761; --nav-muted: #53617a;
- --nav-line: #d3dae7; --nav-hover: #dce3ef; --nav-active: #d9e1f2;
- --nav-accent: #4056c7; --nav-brand: #4056c7; --nav-on-brand: #ffffff;
- --metric-fill: #536ac9;
- --avatar-ink: #475b9a; --avatar-bg: #e6ebf7; --avatar-ink-alt: #55647f; --avatar-bg-alt: #e9edf3;
- --neutral: #626e83; --neutral-soft: #e9edf3;
- --overlay: #18243b66; --shadow: 0 16px 56px #27354d1c;
- }
- .dark[data-palette='ice'] {
- --canvas: #171b24; --surface: #202632; --surface-2: #272f3d; --surface-hover: #343f51;
- --rail-surface: #1b222e; --ink: #f0f3fa; --ink-2: #bec8d9; --muted: #a1aec3;
- --edge: #343e4f; --edge-strong: #515f76;
- --primary: #b4c2ff; --primary-hover: #cbd4ff; --primary-subtle: #303957; --primary-content: #1d2546;
- --nav-surface: #111722; --nav-ink: #f0f3fa; --nav-text: #c7d0e0; --nav-muted: #a6b3c9;
- --nav-line: #2b3546; --nav-hover: #212b3c; --nav-active: #2c3954;
- --nav-accent: #b4c2ff; --nav-brand: #b4c2ff; --nav-on-brand: #1d2546;
- --metric-fill: #acbcff;
- --avatar-ink: #becbfa; --avatar-bg: #2d3854; --avatar-ink-alt: #c1cce0; --avatar-bg-alt: #303a4c;
- --neutral: #bdc7d8; --neutral-soft: #303947;
- --overlay: #080c14b0; --shadow: 0 18px 70px #00000066;
- }
- :root[data-palette='clay'] {
- --canvas: #f3f0eb; --surface: #fffdfa; --surface-2: #f7f3ee; --surface-hover: #ede7df;
- --rail-surface: #eee9e2; --ink: #2a2623; --ink-2: #514943; --muted: #70665f;
- --edge: #e2dbd3; --edge-strong: #cfc4b9;
- --primary: #af482b; --primary-hover: #92391f; --primary-subtle: #f6e8e1; --primary-content: #ffffff;
- --nav-surface: #302c29; --nav-ink: #f7f3ef; --nav-text: #d5cbc3; --nav-muted: #b9ada4;
- --nav-line: #49413c; --nav-hover: #403a35; --nav-active: #50453d;
- --nav-accent: #f1ad8e; --nav-brand: #f1ad8e; --nav-on-brand: #30211b;
- --metric-fill: #ad674d;
- --avatar-ink: #795643; --avatar-bg: #f0e7df; --avatar-ink-alt: #6d5d52; --avatar-bg-alt: #eee9e4;
- --neutral: #70665f; --neutral-soft: #eee9e4;
- --overlay: #211b1770; --shadow: 0 16px 56px #38281e1c;
- }
- .dark[data-palette='clay'] {
- --canvas: #1d1a18; --surface: #292522; --surface-2: #322d29; --surface-hover: #433a34;
- --rail-surface: #221f1c; --ink: #f3eee9; --ink-2: #d0c5bc; --muted: #b2a69c;
- --edge: #403832; --edge-strong: #5d5047;
- --primary: #f0a184; --primary-hover: #ffb89c; --primary-subtle: #49342c; --primary-content: #3b2119;
- --nav-surface: #171513; --nav-ink: #f3eee9; --nav-text: #d2c7be; --nav-muted: #afa197;
- --nav-line: #38302b; --nav-hover: #2b2521; --nav-active: #3c3029;
- --nav-accent: #f0a184; --nav-brand: #f0a184; --nav-on-brand: #3b2119;
- --metric-fill: #e09a7c;
- --avatar-ink: #e3b99c; --avatar-bg: #40332c; --avatar-ink-alt: #d7c2b2; --avatar-bg-alt: #3a332e;
- --neutral: #cec0b5; --neutral-soft: #39332e;
- --overlay: #0d0a08b0; --shadow: 0 18px 70px #00000066;
- }
- :root[data-palette='slate'] {
- --canvas: #f1f0f5; --surface: #ffffff; --surface-2: #f6f5f9; --surface-hover: #eae8f0;
- --rail-surface: #eceaf1; --ink: #282633; --ink-2: #4c4a5d; --muted: #666476;
- --edge: #dfdde7; --edge-strong: #c7c3d2;
- --primary: #6952a3; --primary-hover: #55418b; --primary-subtle: #efebf8; --primary-content: #ffffff;
- --nav-surface: #282735; --nav-ink: #f4f2fa; --nav-text: #d1cde0; --nav-muted: #b2adc6;
- --nav-line: #403e50; --nav-hover: #373546; --nav-active: #48445d;
- --nav-accent: #c9baf1; --nav-brand: #c9baf1; --nav-on-brand: #302844;
- --metric-fill: #7a66ad;
- --avatar-ink: #655a91; --avatar-bg: #eeebf5; --avatar-ink-alt: #666174; --avatar-bg-alt: #efedf2;
- --neutral: #686678; --neutral-soft: #edecf1;
- --overlay: #201d2b70; --shadow: 0 16px 56px #2826331c;
- }
- .dark[data-palette='slate'] {
- --canvas: #1b1a22; --surface: #26242f; --surface-2: #302d3b; --surface-hover: #413d50;
- --rail-surface: #211f29; --ink: #f2f0f8; --ink-2: #c9c5d7; --muted: #aaa6bc;
- --edge: #3d394a; --edge-strong: #5a556d;
- --primary: #c9baf1; --primary-hover: #dacff7; --primary-subtle: #3c354f; --primary-content: #302844;
- --nav-surface: #17161e; --nav-ink: #f2f0f8; --nav-text: #d0cce0; --nav-muted: #aaa5bf;
- --nav-line: #343141; --nav-hover: #282634; --nav-active: #383447;
- --nav-accent: #c9baf1; --nav-brand: #c9baf1; --nav-on-brand: #302844;
- --metric-fill: #c1b1ee;
- --avatar-ink: #c9bdf0; --avatar-bg: #373249; --avatar-ink-alt: #c9c2da; --avatar-bg-alt: #393644;
- --neutral: #c4bfd2; --neutral-soft: #383543;
- --overlay: #0c0b10b0; --shadow: 0 18px 70px #00000066;
- }
- /* ==========================================================================
- 基础
- ========================================================================== */
- * { box-sizing: border-box; }
- html, body { height: 100%; margin: 0; }
- body {
- background: var(--canvas); color: var(--ink);
- font-family: "PingFang SC", "HarmonyOS Sans SC", "Noto Sans SC", system-ui, -apple-system, sans-serif;
- font-size: var(--fs-body); line-height: var(--fs-body-line);
- -webkit-font-smoothing: antialiased;
- overscroll-behavior: none;
- }
- button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
- input, textarea { font: inherit; font-size: var(--fs-17); color: inherit; }
- a { color: var(--primary); text-decoration: none; }
- :focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: var(--r-sm); }
- .icon { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: none; }
- .icon-sm { width: 16px; height: 16px; }
- .icon-lg { width: 24px; height: 24px; }
- /* ==========================================================================
- App 外壳
- ========================================================================== */
- #app {
- position: relative; height: 100dvh; max-width: 520px; margin: 0 auto;
- background: var(--canvas); overflow: hidden;
- display: flex; flex-direction: column;
- }
- .view {
- position: absolute; inset: 0; display: flex; flex-direction: column;
- background: var(--canvas); opacity: 0; pointer-events: none;
- }
- .view.active { opacity: 1; pointer-events: auto; }
- .view.enter { animation: view-in var(--motion-detail) var(--ease-standard); }
- .view.leave { animation: view-out var(--motion-detail) var(--ease-standard); }
- @keyframes view-in { from { transform: translateX(24px); opacity: 0; } to { transform: none; opacity: 1; } }
- @keyframes view-out { from { transform: none; opacity: 1; } to { transform: translateX(24px); opacity: 0; } }
- /* 页面骨架:navbar 固定 + 滚动区 + 可选吸底 */
- .page { display: flex; flex-direction: column; height: 100%; min-height: 0; }
- .page-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; min-height: 0; }
- .page-body.has-tabbar { padding-bottom: var(--sp-4); }
- /* 底部区域:输入坞 + TabBar 一起贴在视口底部,不随内容滚动 */
- .bottom { flex: none; padding-bottom: var(--sp-3); }
- .bottom.with-tabbar { padding-bottom: calc(var(--mob-tabbar-h) + var(--mob-safe-bottom) + var(--sp-2)); }
- .bottom .dock { margin-bottom: 0; }
- /* ---------- 顶部导航(WorkBuddy 式圆形浮动按钮) ---------- */
- .navbar {
- height: calc(var(--mob-navbar-h) + var(--mob-safe-top)); padding-top: var(--mob-safe-top);
- display: flex; align-items: center; gap: var(--sp-3);
- padding-left: var(--sp-4); padding-right: var(--sp-4);
- flex: none; position: relative; z-index: var(--z-affix);
- }
- .navbar .title { flex: 1; text-align: center; font-size: var(--fs-17); font-weight: 600; }
- .navbar .title small { display: block; font-size: var(--fs-11); font-weight: 400; color: var(--muted); }
- .fab {
- width: var(--touch-min); height: var(--touch-min); border-radius: var(--r-tag);
- display: grid; place-items: center; background: var(--surface);
- box-shadow: var(--shadow-soft); color: var(--ink); flex: none;
- transition: background var(--motion-fast) var(--ease-standard);
- }
- .fab:active { background: var(--surface-hover); }
- .fab.ghost { box-shadow: none; background: transparent; }
- .navbar .spacer { width: var(--touch-min); flex: none; }
- /* ---------- 底部 TabBar ---------- */
- .tabbar {
- position: absolute; left: 0; right: 0; bottom: 0; z-index: var(--z-float);
- height: calc(var(--mob-tabbar-h) + var(--mob-safe-bottom));
- padding-bottom: var(--mob-safe-bottom);
- display: flex; align-items: stretch;
- background: color-mix(in srgb, var(--canvas) 92%, transparent);
- backdrop-filter: blur(16px);
- border-top: 1px solid var(--edge);
- }
- .tabbar button {
- flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-1);
- color: var(--muted); font-size: var(--fs-11); position: relative;
- }
- .tabbar button.on { color: var(--primary); font-weight: 600; }
- .tabbar .badge-dot {
- position: absolute; top: var(--sp-3); margin-left: 22px;
- min-width: 16px; height: 16px; padding: 0 var(--sp-1); border-radius: var(--r-tag);
- background: var(--danger); color: var(--on-danger); font-size: var(--fs-11); line-height: 16px;
- }
- /* ==========================================================================
- 通用组件
- ========================================================================== */
- .section { padding: 0 var(--mob-gutter); }
- .section + .section { margin-top: var(--sp-6); }
- .section-title {
- display: flex; align-items: center; justify-content: space-between;
- font-size: var(--fs-13); color: var(--muted); margin-bottom: var(--sp-3);
- }
- .card {
- background: var(--surface); border-radius: var(--r-lg);
- box-shadow: var(--shadow-soft); border: 1px solid var(--edge);
- }
- .card.plain { box-shadow: none; }
- .list { background: var(--surface); border-radius: var(--r-lg); border: 1px solid var(--edge); overflow: hidden; }
- .list > * + * { border-top: 1px solid var(--edge); }
- .row {
- display: flex; align-items: center; gap: var(--sp-3);
- min-height: 56px; padding: var(--sp-3) var(--sp-4);
- width: 100%; text-align: left; background: var(--surface);
- transition: background var(--motion-fast) var(--ease-standard);
- }
- .row:active { background: var(--surface-hover); }
- .row .grow { flex: 1; min-width: 0; }
- .row .t1 { display: block; font-size: var(--fs-15); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
- .row .t2 { display: block; font-size: var(--fs-13); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
- .row .time { font-size: var(--fs-12); color: var(--muted); flex: none; }
- .row .chev { color: var(--muted); }
- .avatar {
- width: 40px; height: 40px; border-radius: var(--r-tag); flex: none;
- display: grid; place-items: center; font-size: var(--fs-15); font-weight: 600;
- background: var(--avatar-bg); color: var(--avatar-ink);
- }
- .avatar.alt { background: var(--avatar-bg-alt); color: var(--avatar-ink-alt); }
- .avatar.sm { width: 32px; height: 32px; font-size: var(--fs-13); }
- .avatar.lg { width: 64px; height: 64px; font-size: var(--fs-20); }
- .badge {
- display: inline-flex; align-items: center; gap: var(--sp-1);
- height: 20px; padding: 0 var(--sp-2); border-radius: var(--r-sm);
- font-size: var(--fs-11); font-weight: 600; white-space: nowrap;
- background: var(--neutral-soft); color: var(--neutral);
- }
- .badge.success { background: var(--success-subtle); color: var(--success); }
- .badge.warning { background: var(--warning-subtle); color: var(--warning); }
- .badge.danger { background: var(--danger-subtle); color: var(--danger); }
- .badge.info { background: var(--info-subtle); color: var(--info); }
- .badge.primary { background: var(--primary-subtle); color: var(--primary); }
- .dot { width: 8px; height: 8px; border-radius: var(--r-tag); flex: none; background: var(--neutral); }
- .dot.success { background: var(--success); } .dot.warning { background: var(--warning); }
- .dot.danger { background: var(--danger); } .dot.info { background: var(--info); }
- .chips { display: flex; gap: var(--sp-2); overflow-x: auto; scrollbar-width: none; padding: var(--sp-1) var(--mob-gutter); }
- .chips::-webkit-scrollbar { display: none; }
- .chip {
- flex: none; height: 34px; padding: 0 var(--sp-3); border-radius: var(--r-tag);
- background: var(--surface); border: 1px solid var(--edge);
- font-size: var(--fs-13); color: var(--ink-2); display: inline-flex; align-items: center; gap: var(--sp-1);
- transition: background var(--motion-fast) var(--ease-standard);
- }
- .chip.on { background: var(--primary); border-color: var(--primary); color: var(--primary-content); font-weight: 600; }
- .chip .n { font-size: var(--fs-11); opacity: .8; }
- .segmented {
- display: flex; padding: var(--sp-1); border-radius: var(--r-tag);
- background: var(--surface-2); border: 1px solid var(--edge);
- width: 100%; max-width: 300px; margin: 0 auto;
- }
- .segmented button {
- flex: 1; height: 36px; border-radius: var(--r-tag);
- font-size: var(--fs-13); color: var(--muted);
- transition: background var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard);
- }
- .segmented button.on { background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-soft); }
- .btn {
- display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
- height: var(--touch-min); padding: 0 var(--sp-4); border-radius: var(--r-md);
- font-size: var(--fs-15); font-weight: 600;
- background: var(--surface); border: 1px solid var(--edge); color: var(--ink);
- }
- .btn.primary { background: var(--primary); border-color: var(--primary); color: var(--primary-content); }
- .btn.block { width: 100%; height: 52px; border-radius: var(--r-md); font-size: var(--fs-17); }
- .btn.ghost { background: transparent; border-color: transparent; color: var(--primary); }
- .btn:disabled { opacity: .5; cursor: not-allowed; }
- .switch {
- width: 48px; height: 28px; border-radius: var(--r-tag); background: var(--surface-active);
- position: relative; flex: none; transition: background var(--motion-fast) var(--ease-standard);
- }
- .switch::after {
- content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
- border-radius: var(--r-tag); background: var(--surface); box-shadow: var(--shadow-soft);
- transition: transform var(--motion-fast) var(--ease-standard);
- }
- .switch[aria-checked="true"] { background: var(--primary); }
- .switch[aria-checked="true"]::after { transform: translateX(20px); background: var(--primary-content); }
- .search {
- display: flex; align-items: center; gap: var(--sp-2);
- height: var(--touch-min); padding: 0 var(--sp-3); margin: 0 var(--mob-gutter);
- border-radius: var(--r-md); background: var(--surface); border: 1px solid var(--edge);
- color: var(--muted);
- }
- .search input { flex: 1; border: 0; outline: 0; background: transparent; }
- .empty {
- padding: var(--sp-8) var(--mob-gutter); text-align: center; color: var(--muted); font-size: var(--fs-13);
- }
- /* ---------- WorkBuddy 式居中式主视觉 ---------- */
- .hero {
- display: flex; flex-direction: column; align-items: center; justify-content: center;
- text-align: center; padding: var(--sp-6) var(--mob-gutter);
- background: var(--surface); /* 居中式主视觉作为一块独立面,与页面底 --canvas 区分(同 WorkBuddy) */
- margin: var(--sp-3) var(--sp-4) 0; border-radius: var(--r-lg);
- }
- .hero h1 { font-size: var(--fs-26); font-weight: 700; margin: 0 0 var(--sp-2); letter-spacing: -.01em; }
- .hero .sub { color: var(--muted); font-size: var(--fs-13); margin: 0; }
- /* 纯文字品牌主视觉(去掉了 WorkBuddy 的机器人图) */
- .wordmark {
- margin: 0 0 var(--sp-2);
- font-size: var(--fs-42);
- font-weight: 700;
- letter-spacing: -0.02em;
- color: var(--primary);
- }
- .dock {
- flex: none; margin: 0 var(--sp-4); padding: var(--sp-3) var(--sp-4);
- border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--shadow-pop);
- border: 1px solid var(--edge);
- }
- .dock textarea {
- width: 100%; border: 0; outline: 0; resize: none; background: transparent;
- padding: var(--sp-2) 0; min-height: 44px; max-height: 120px;
- }
- .dock .tools { display: flex; align-items: center; gap: var(--sp-3); color: var(--muted); }
- .dock .tools .send {
- margin-left: auto; width: 36px; height: 36px; border-radius: var(--r-tag);
- display: grid; place-items: center; background: var(--primary-subtle); color: var(--muted);
- transition: background var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard);
- }
- .dock .tools .send.ready { background: var(--primary); color: var(--primary-content); }
- /* ---------- 抽屉(左侧滑出,WorkBuddy 侧栏形态) ---------- */
- .sheet-mask { position: absolute; inset: 0; background: var(--overlay); z-index: calc(var(--z-modal) - 1); opacity: 0; transition: opacity var(--motion-panel) var(--ease-standard); }
- .sheet-mask.show { opacity: 1; }
- .drawer {
- position: absolute; top: 0; bottom: 0; left: 0; width: min(84%, 330px); z-index: var(--z-modal);
- background: var(--surface); border-radius: 0 var(--r-lg) var(--r-lg) 0;
- box-shadow: var(--shadow-pop);
- transform: translateX(-100%); transition: transform var(--motion-panel) var(--ease-standard);
- display: flex; flex-direction: column;
- padding: calc(var(--mob-safe-top) + var(--sp-4)) 0 var(--sp-4);
- overflow: hidden;
- }
- .drawer.show { transform: none; }
- .drawer-head, .drawer-body, .drawer-foot { padding-left: var(--sp-4); padding-right: var(--sp-4); }
- .drawer-head { padding-bottom: var(--sp-3); border-bottom: 1px solid var(--edge); }
- .drawer-body { flex: 1; overflow-y: auto; }
- /* 一级入口:图标 + 文字 + 可选操作,44 高 */
- .entry {
- display: flex; align-items: center; gap: var(--sp-3); width: 100%;
- min-height: var(--touch-min); padding: 0 var(--sp-2); border-radius: var(--r-sm);
- font-size: var(--fs-15); color: var(--ink); text-align: left;
- transition: background var(--motion-fast) var(--ease-standard);
- }
- .entry:hover, .entry:active { background: var(--surface-hover); }
- .entry .lead { width: 32px; height: 32px; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--surface-2); color: var(--ink-2); flex: none; }
- .entry.primary .lead { background: var(--primary-subtle); color: var(--primary); }
- .entry b { flex: 1; font-weight: 500; }
- .entry.primary b { font-weight: 600; color: var(--primary); }
- .entry .kbd { font-size: var(--fs-11); color: var(--muted); }
- .tree-toggle {
- display: flex; align-items: center; gap: var(--sp-1); width: 100%;
- min-height: 36px; padding: 0 var(--sp-2); border-radius: var(--r-sm);
- font-size: var(--fs-12); font-weight: 600; color: var(--muted);
- }
- .tree-toggle .n { margin-left: auto; font-weight: 400; }
- .tree-toggle .arrow { transition: transform var(--motion-fast) var(--ease-standard); }
- .tree-toggle[aria-expanded="false"] .arrow { transform: rotate(-90deg); }
- .tree-item {
- display: flex; align-items: center; gap: var(--sp-2); width: 100%;
- min-height: 40px; padding: var(--sp-2) var(--sp-2); border-radius: var(--r-sm);
- font-size: var(--fs-15); color: var(--ink-2); text-align: left;
- }
- .tree-item .t { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
- .tree-item.on { background: var(--primary-subtle); color: var(--primary); font-weight: 600; }
- .tree-item:active { background: var(--surface-hover); }
- .tree-item .n { font-size: var(--fs-11); color: var(--muted); }
- /* ---------- 底部弹层 ---------- */
- .sheet {
- position: absolute; left: 0; right: 0; bottom: 0; z-index: var(--z-modal);
- background: var(--surface); border-radius: var(--r-lg) var(--r-lg) 0 0;
- box-shadow: var(--shadow-overlay); max-height: 82%;
- display: flex; flex-direction: column;
- transform: translateY(100%); transition: transform var(--motion-panel) var(--ease-standard);
- padding-bottom: var(--mob-safe-bottom);
- }
- .sheet.show { transform: none; }
- .sheet .grabber { width: 36px; height: 4px; border-radius: var(--r-tag); background: var(--edge-strong); margin: var(--sp-2) auto; }
- .sheet .shead { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--mob-gutter) var(--sp-3); }
- .sheet .shead h2 { font-size: var(--fs-17); margin: 0; flex: 1; }
- .sheet .sbody { overflow-y: auto; padding: 0 var(--mob-gutter) var(--sp-6); }
- /* ---------- toast ---------- */
- .toast {
- position: absolute; left: 50%; bottom: calc(var(--mob-tabbar-h) + var(--sp-8)); transform: translateX(-50%);
- z-index: var(--z-toast); background: var(--ink); color: var(--canvas);
- padding: var(--sp-2) var(--sp-4); border-radius: var(--r-md); font-size: var(--fs-13);
- max-width: 80%; text-align: center; box-shadow: var(--shadow-pop);
- animation: toast-in var(--motion-detail) var(--ease-standard);
- }
- @keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }
- /* ---------- 全屏预览层 ---------- */
- .preview {
- position: absolute; inset: 0; z-index: var(--z-preview); background: var(--canvas);
- display: flex; flex-direction: column; animation: view-in var(--motion-detail) var(--ease-standard);
- }
- .preview .phead { display: flex; align-items: center; gap: var(--sp-3); padding: calc(var(--mob-safe-top) + var(--sp-3)) var(--sp-4) var(--sp-3); }
- .preview .phead .name { flex: 1; min-width: 0; }
- .preview .phead .name b { display: block; font-size: var(--fs-15); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
- .preview .phead .name span { font-size: var(--fs-12); color: var(--muted); }
- .preview .pbody { flex: 1; overflow: auto; padding: var(--sp-4) var(--mob-gutter) var(--sp-8); }
- /* 文件骨架:用表面色块模拟 pdf/表格/图片内容 */
- .doc-skeleton { background: var(--surface); border-radius: var(--r-md); border: 1px solid var(--edge); padding: var(--sp-5); box-shadow: var(--shadow-card); }
- .doc-skeleton .ln { height: 10px; border-radius: var(--r-sm); background: var(--surface-2); margin-bottom: var(--sp-3); }
- .doc-skeleton .ln.w80 { width: 80%; } .doc-skeleton .ln.w60 { width: 60%; } .doc-skeleton .ln.w40 { width: 40%; }
- .doc-skeleton .bar { height: 96px; border-radius: var(--r-sm); background: var(--primary-subtle); margin-bottom: var(--sp-4); }
- .table-mock { width: 100%; border-collapse: collapse; font-size: var(--fs-13); background: var(--surface); border-radius: var(--r-md); overflow: hidden; }
- .table-mock th, .table-mock td { padding: var(--sp-2) var(--sp-3); text-align: left; border-bottom: 1px solid var(--edge); }
- .table-mock th { background: var(--surface-2); color: var(--ink-2); font-weight: 600; }
- /* ==========================================================================
- 业务块
- ========================================================================== */
- .kv { display: grid; grid-template-columns: 96px 1fr; gap: var(--sp-2) var(--sp-3); font-size: var(--fs-13); }
- .kv dt { color: var(--muted); } .kv dd { margin: 0; color: var(--ink); }
- .metric { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
- .metric .m { background: var(--surface); border: 1px solid var(--edge); border-radius: var(--r-md); padding: var(--sp-3); }
- .metric .m span { display: block; font-size: var(--fs-11); color: var(--muted); }
- .metric .m b { font-size: var(--fs-20); font-weight: 600; }
- .bar { height: 6px; border-radius: var(--r-tag); background: var(--surface-active); overflow: hidden; margin-top: var(--sp-2); }
- .bar i { display: block; height: 100%; border-radius: var(--r-tag); background: var(--metric-fill); }
- .timeline { position: relative; padding-left: var(--sp-5); }
- .timeline::before { content: ""; position: absolute; left: 5px; top: 6px; bottom: 6px; width: 2px; background: var(--edge); }
- .timeline .tl { position: relative; padding-bottom: var(--sp-4); font-size: var(--fs-13); }
- .timeline .tl::before {
- content: ""; position: absolute; left: calc(var(--sp-5) * -1); top: 5px; width: 12px; height: 12px;
- border-radius: var(--r-tag); background: var(--surface); border: 2px solid var(--edge-strong);
- }
- .timeline .tl.done::before { border-color: var(--success); background: var(--success); }
- .timeline .tl.blocked::before { border-color: var(--danger); background: var(--danger); }
- .timeline .tl b { display: block; font-weight: 600; }
- .timeline .tl time { font-size: var(--fs-11); color: var(--muted); }
- .timeline .tl p { margin: var(--sp-1) 0 0; color: var(--ink-2); }
- /* 对话 */
- .chat-body { padding: var(--sp-3) var(--mob-gutter) var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-4); }
- .msg-me { align-self: flex-end; max-width: 82%; background: var(--surface-2); border: 1px solid var(--edge); color: var(--ink); padding: var(--sp-3) var(--sp-4); border-radius: var(--r-lg) var(--r-sm) var(--r-lg) var(--r-lg); }
- .msg-tag { display: inline-flex; align-items: center; gap: var(--sp-1); height: 24px; padding: 0 var(--sp-2); border-radius: var(--r-tag); background: var(--surface); border: 1px solid var(--edge); font-size: var(--fs-11); color: var(--ink-2); margin-bottom: var(--sp-2); }
- .process-line { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-13); color: var(--muted); }
- .process-line .pill { margin-left: auto; height: 24px; padding: 0 var(--sp-3); border-radius: var(--r-tag); border: 1px solid var(--edge); color: var(--primary); font-size: var(--fs-11); display: inline-flex; align-items: center; }
- .step {
- display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
- margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm);
- background: var(--surface-2); border: 1px solid var(--edge); font-size: var(--fs-13);
- }
- .step .l { color: var(--ink-2); } .step .r { display: flex; align-items: center; gap: var(--sp-1); }
- .md p { margin: 0 0 var(--sp-3); }
- .md h3 { font-size: var(--fs-17); margin: var(--sp-4) 0 var(--sp-2); }
- .md table { width: 100%; border-collapse: collapse; font-size: var(--fs-13); margin: var(--sp-2) 0; border: 1px solid var(--edge); border-radius: var(--r-md); overflow: hidden; }
- .md th, .md td { padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--edge); text-align: left; vertical-align: top; }
- .md th { background: var(--surface-2); color: var(--ink-2); font-weight: 600; width: 88px; }
- .md tr:last-child td, .md tr:last-child th { border-bottom: 0; }
- .ai-foot { display: flex; align-items: center; gap: var(--sp-4); font-size: var(--fs-12); color: var(--muted); margin-top: var(--sp-2); }
- .file-card {
- display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3);
- border: 1px solid var(--edge); border-radius: var(--r-md); background: var(--surface); width: 100%; text-align: left;
- }
- .file-card .ft { width: 36px; height: 36px; border-radius: var(--r-sm); display: grid; place-items: center; font-size: var(--fs-11); font-weight: 700; background: var(--primary-subtle); color: var(--primary); flex: none; }
- /* 任务卡 */
- .task-card { display: block; width: 100%; text-align: left; padding: var(--sp-4); background: var(--surface); border: 1px solid var(--edge); border-radius: var(--r-lg); box-shadow: var(--shadow-soft); }
- .task-card + .task-card { margin-top: var(--sp-3); }
- .task-card .top { display: flex; align-items: flex-start; gap: var(--sp-2); }
- .task-card .top b { flex: 1; font-size: var(--fs-15); font-weight: 600; }
- .task-card .meta { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); font-size: var(--fs-12); color: var(--muted); flex-wrap: wrap; }
- .task-card.blocked { border-color: var(--danger); box-shadow: 0 0 0 1px var(--danger-subtle), var(--shadow-soft); }
- /* 工作台卡 */
- .life-card { padding: var(--sp-4); background: var(--surface); border: 1px solid var(--edge); border-radius: var(--r-lg); box-shadow: var(--shadow-soft); }
- .life-card + .life-card { margin-top: var(--sp-3); }
- .life-card .head { display: flex; align-items: center; gap: var(--sp-3); }
- .life-card .cur { font-size: var(--fs-13); color: var(--ink-2); margin: var(--sp-3) 0; padding: var(--sp-2) var(--sp-3); background: var(--surface-2); border-radius: var(--r-sm); }
- /* 登录 */
- .login { flex: 1; display: flex; flex-direction: column; padding: 0 var(--sp-6) var(--sp-6); }
- .login .brand { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
- .login .brand h1 { font-size: var(--fs-26); margin: var(--sp-3) 0 var(--sp-2); }
- .login .field { display: flex; align-items: center; gap: var(--sp-2); height: 52px; padding: 0 var(--sp-4); border-radius: var(--r-md); background: var(--surface); border: 1px solid var(--edge); margin-bottom: var(--sp-3); }
- .login .field input { flex: 1; border: 0; outline: 0; background: transparent; }
- .login .field .get { color: var(--primary); font-size: var(--fs-13); font-weight: 600; }
- .login .agree { display: flex; align-items: center; justify-content: center; gap: var(--sp-2); font-size: var(--fs-12); color: var(--muted); margin-top: var(--sp-4); }
- .login .agree .cb { width: 18px; height: 18px; border-radius: var(--r-tag); border: 1.5px solid var(--edge-strong); display: grid; place-items: center; flex: none; }
- .login .agree .cb.on { background: var(--primary); border-color: var(--primary); color: var(--primary-content); }
- .oauth { display: flex; justify-content: space-around; margin-top: var(--sp-6); }
- .oauth button { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); font-size: var(--fs-12); color: var(--ink-2); min-width: var(--touch-min); }
- .oauth .orb { width: 48px; height: 48px; border-radius: var(--r-tag); background: var(--surface-2); border: 1px solid var(--edge); display: grid; place-items: center; }
- /* 登录 */
- .login { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; padding: var(--sp-6); }
- .login .brand { display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--sp-8) 0 var(--sp-6); }
- .login .brand img { width: 132px; height: auto; }
- .login .brand h1 { font-size: var(--fs-20); margin: var(--sp-3) 0 var(--sp-1); }
- .login .brand p { margin: 0; font-size: var(--fs-13); color: var(--muted); }
- .login .field { display: flex; align-items: center; gap: var(--sp-2); height: 52px; padding: 0 var(--sp-4); border-radius: var(--r-md); background: var(--surface); border: 1px solid var(--edge); margin-bottom: var(--sp-3); }
- .login .field input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; }
- .login .field .prefix { color: var(--ink-2); font-size: var(--fs-15); flex: none; }
- .login .field .get { color: var(--primary); font-size: var(--fs-13); font-weight: 600; white-space: nowrap; }
- .login .field .get:disabled { color: var(--muted); }
- .login .agree { display: flex; align-items: flex-start; justify-content: center; gap: var(--sp-2); font-size: var(--fs-12); color: var(--muted); margin-top: var(--sp-4); text-align: left; }
- .login .agree .cb { width: 16px; height: 16px; border-radius: var(--r-tag); border: 1.5px solid var(--edge-strong); display: grid; place-items: center; flex: none; margin-top: 2px; }
- .login .agree .cb.on { background: var(--primary); border-color: var(--primary); color: var(--primary-content); }
- .login .more { text-align: center; font-size: var(--fs-13); color: var(--primary); padding: var(--sp-3) 0; }
- .login .token { margin-top: var(--sp-2); }
- /* 我的 / 设置 */
- .palette-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-2); }
- .palette-grid button { padding: var(--sp-2); border-radius: var(--r-md); border: 1.5px solid var(--edge); background: var(--surface); display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); font-size: var(--fs-11); color: var(--ink-2); }
- .palette-grid button.on { border-color: var(--primary); color: var(--primary); font-weight: 600; }
- .swatch { width: 100%; height: 44px; border-radius: var(--r-sm); display: flex; overflow: hidden; border: 1px solid var(--edge); }
- .swatch i { flex: 1; }
- /* 配色缩略图:在各自作用域内渲染该套配色自身的 nav / primary / surface-2(同 _palette.scss 的 data-preview-palette 机制) */
- [data-preview-palette='platinum'] { --sw-nav: #202124; --sw-primary: #25272a; --sw-surface: #f7f7f8; }
- [data-preview-palette='ice'] { --sw-nav: #e9edf5; --sw-primary: #4056c7; --sw-surface: #f1f4f9; }
- [data-preview-palette='clay'] { --sw-nav: #302c29; --sw-primary: #af482b; --sw-surface: #f7f3ee; }
- [data-preview-palette='slate'] { --sw-nav: #282735; --sw-primary: #6952a3; --sw-surface: #f6f5f9; }
- .cb { padding: 0; }
- .swatch i:nth-child(1) { background: var(--sw-nav); }
- .swatch i:nth-child(2) { background: var(--sw-primary); }
- .swatch i:nth-child(3) { background: var(--sw-surface); }
- .slider { width: 100%; accent-color: var(--primary); }
- /* 宽屏提示 */
- .wide-hint {
- position: fixed; inset: 0; z-index: var(--z-toast); display: none;
- background: var(--canvas); color: var(--ink);
- align-items: center; justify-content: center; text-align: center; padding: var(--sp-8);
- }
- @media (min-width: 768px) { .wide-hint { display: flex; } }
- @media (prefers-reduced-motion: reduce) {
- *, *::before, *::after { animation: none !important; transition: none !important; }
- }
|