| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <title>mobile-h5 · 明亮清爽配色 Demo</title>
- <style>
- * { box-sizing: border-box; }
- html, body { margin: 0; min-height: 100%; }
- body {
- font-family: "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", -apple-system, system-ui, sans-serif;
- color: #1e293b;
- background:
- radial-gradient(900px 420px at 8% -8%, rgba(52, 211, 153, 0.18), transparent 55%),
- radial-gradient(700px 380px at 92% 0%, rgba(125, 211, 252, 0.16), transparent 50%),
- linear-gradient(180deg, #f8fffc 0%, #f4f7fb 45%, #f7f8fa 100%);
- line-height: 1.45;
- }
- .page {
- max-width: 1180px;
- margin: 0 auto;
- padding: 28px 18px 64px;
- }
- .hero h1 {
- margin: 0 0 8px;
- font-size: 24px;
- letter-spacing: -0.02em;
- font-weight: 720;
- }
- .hero p {
- margin: 0;
- max-width: 720px;
- color: #64748b;
- font-size: 14px;
- }
- .hero .note {
- margin-top: 12px;
- display: inline-block;
- padding: 8px 12px;
- border-radius: 10px;
- background: #fff;
- border: 1px solid #e2e8f0;
- font-size: 12px;
- color: #64748b;
- }
- .hero .note strong { color: #0f766e; }
- .theme-tabs {
- display: flex;
- flex-wrap: wrap;
- gap: 10px;
- margin: 22px 0 20px;
- }
- .theme-tab {
- appearance: none;
- border: 1px solid #e2e8f0;
- background: #fff;
- border-radius: 999px;
- padding: 10px 16px;
- font-size: 13px;
- font-weight: 600;
- color: #475569;
- cursor: pointer;
- display: inline-flex;
- align-items: center;
- gap: 8px;
- transition: border-color .15s, box-shadow .15s, color .15s;
- }
- .theme-tab:hover { border-color: #94a3b8; }
- .theme-tab.is-active {
- color: var(--t-brand-dark);
- border-color: var(--t-brand);
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--t-brand) 22%, transparent);
- background: var(--t-brand-soft);
- }
- .theme-tab .dot {
- width: 10px; height: 10px; border-radius: 50%;
- background: var(--swatch, #22c55e);
- }
- .theme-tab .badge {
- font-size: 10px;
- font-weight: 700;
- padding: 2px 6px;
- border-radius: 999px;
- background: #ecfdf5;
- color: #047857;
- }
- .theme-tab.is-current .badge {
- background: #f1f5f9;
- color: #64748b;
- }
- .layout {
- display: grid;
- grid-template-columns: minmax(280px, 360px) 1fr;
- gap: 22px;
- align-items: start;
- }
- @media (max-width: 900px) {
- .layout { grid-template-columns: 1fr; }
- }
- .panel {
- background: rgba(255,255,255,.92);
- border: 1px solid #e2e8f0;
- border-radius: 18px;
- padding: 18px;
- box-shadow: 0 10px 30px rgba(15, 23, 42, 0.05);
- }
- .panel h2 {
- margin: 0 0 4px;
- font-size: 16px;
- }
- .panel .sub {
- margin: 0 0 14px;
- font-size: 12px;
- color: #64748b;
- }
- .token-grid {
- display: grid;
- gap: 8px;
- }
- .token {
- display: grid;
- grid-template-columns: 36px 1fr auto;
- gap: 10px;
- align-items: center;
- padding: 8px 10px;
- border-radius: 12px;
- border: 1px solid #eef2f7;
- background: #fafbfc;
- }
- .token i {
- width: 36px; height: 36px;
- border-radius: 10px;
- border: 1px solid rgba(15,23,42,.06);
- display: block;
- }
- .token .name {
- font-size: 12px;
- font-weight: 650;
- color: #334155;
- }
- .token .desc {
- font-size: 11px;
- color: #94a3b8;
- }
- .token code {
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
- font-size: 11px;
- color: #0f766e;
- background: #f0fdfa;
- padding: 3px 6px;
- border-radius: 6px;
- }
- .stage {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 14px;
- }
- .stage-caption {
- width: 100%;
- max-width: 390px;
- font-size: 13px;
- color: #64748b;
- text-align: center;
- }
- .stage-caption strong { color: #0f172a; }
- .phone {
- width: 390px;
- height: 780px;
- background: #0f172a;
- border-radius: 40px;
- padding: 10px;
- box-shadow:
- 0 28px 60px rgba(15, 23, 42, 0.18),
- inset 0 0 0 1px rgba(255,255,255,.08);
- position: relative;
- }
- .phone::before {
- content: "";
- position: absolute;
- top: 16px; left: 50%;
- transform: translateX(-50%);
- width: 108px; height: 24px;
- background: #020617;
- border-radius: 16px;
- z-index: 6;
- }
- .phone-screen {
- height: 100%;
- border-radius: 32px;
- overflow: hidden;
- background: var(--t-bg);
- color: var(--t-text);
- display: flex;
- flex-direction: column;
- }
- .screen-scroll {
- flex: 1;
- overflow-y: auto;
- -webkit-overflow-scrolling: touch;
- }
- /* —— 完整工作台界面 —— */
- .home-header {
- padding: 52px 16px 22px;
- position: relative;
- overflow: hidden;
- border-radius: 0 0 22px 22px;
- background: var(--t-header-bg);
- color: var(--t-header-fg);
- }
- .home-header::after {
- content: "";
- position: absolute;
- right: -36px; top: -28px;
- width: 140px; height: 140px;
- border-radius: 50%;
- background: var(--t-header-glow);
- pointer-events: none;
- }
- .home-header .brand {
- font-size: 12px;
- opacity: .78;
- letter-spacing: .04em;
- margin-bottom: 8px;
- position: relative;
- z-index: 1;
- }
- .home-header .row {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- gap: 12px;
- position: relative;
- z-index: 1;
- }
- .home-header h3 {
- margin: 0;
- font-size: 22px;
- font-weight: 720;
- letter-spacing: -.01em;
- }
- .home-header .logout {
- font-size: 12px;
- opacity: .85;
- padding: 4px 0;
- white-space: nowrap;
- }
- .home-header .meta {
- margin-top: 10px;
- display: flex;
- align-items: center;
- gap: 8px;
- font-size: 12px;
- opacity: .82;
- position: relative;
- z-index: 1;
- }
- .home-header .meta .dot {
- width: 4px; height: 4px; border-radius: 50%;
- background: currentColor; opacity: .55;
- }
- .home-body { padding: 12px 12px 20px; }
- .banner {
- height: 132px;
- border-radius: 16px;
- overflow: hidden;
- margin-bottom: 12px;
- border: 1px solid var(--t-border);
- background:
- linear-gradient(135deg, var(--t-banner-a), var(--t-banner-b)),
- var(--t-brand-soft);
- position: relative;
- display: flex;
- align-items: flex-end;
- padding: 14px;
- color: var(--t-banner-fg);
- }
- .banner::before {
- content: "";
- position: absolute;
- inset: 0;
- background:
- radial-gradient(180px 100px at 85% 20%, rgba(255,255,255,.45), transparent 60%),
- radial-gradient(120px 80px at 10% 80%, rgba(255,255,255,.2), transparent 55%);
- }
- .banner .txt { position: relative; z-index: 1; }
- .banner .kicker { font-size: 11px; opacity: .85; margin-bottom: 4px; }
- .banner .title { font-size: 16px; font-weight: 700; }
- .card {
- background: var(--t-surface);
- border: 1px solid var(--t-border);
- border-radius: 16px;
- box-shadow: var(--t-shadow);
- padding: 14px 12px;
- margin-bottom: 12px;
- }
- .card-hd {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 12px;
- padding: 0 4px;
- }
- .card-hd h4 {
- margin: 0;
- font-size: 15px;
- font-weight: 680;
- color: var(--t-text);
- }
- .card-hd .hint {
- font-size: 11px;
- color: var(--t-muted);
- }
- .menu-grid {
- display: grid;
- grid-template-columns: repeat(4, 1fr);
- gap: 8px 4px;
- }
- .menu-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 8px;
- padding: 8px 4px 6px;
- border-radius: 12px;
- }
- .menu-icon {
- width: 44px; height: 44px;
- border-radius: 14px;
- display: grid;
- place-items: center;
- font-size: 18px;
- font-weight: 700;
- }
- .menu-item span {
- font-size: 11px;
- color: var(--t-text);
- text-align: center;
- line-height: 1.25;
- }
- .todo {
- display: flex;
- gap: 10px;
- padding: 12px;
- border-radius: 14px;
- border: 1px solid var(--t-border);
- background: var(--t-todo-bg);
- margin-bottom: 8px;
- }
- .todo:last-child { margin-bottom: 0; }
- .todo .bar {
- width: 4px;
- border-radius: 4px;
- background: var(--todo-accent, var(--t-brand));
- flex-shrink: 0;
- }
- .todo .body { flex: 1; min-width: 0; }
- .todo .top {
- display: flex;
- justify-content: space-between;
- gap: 8px;
- margin-bottom: 4px;
- }
- .todo .name {
- font-size: 13px;
- font-weight: 650;
- color: var(--t-text);
- }
- .tag {
- font-size: 10px;
- font-weight: 650;
- padding: 2px 7px;
- border-radius: 999px;
- white-space: nowrap;
- }
- .tag.warn {
- background: color-mix(in srgb, var(--t-warning) 14%, #fff);
- color: var(--t-warning);
- }
- .tag.ok {
- background: color-mix(in srgb, var(--t-success) 14%, #fff);
- color: var(--t-success);
- }
- .todo .meta {
- font-size: 11px;
- color: var(--t-muted);
- }
- .cta-row {
- display: flex;
- gap: 8px;
- margin-top: 4px;
- }
- .btn {
- flex: 1;
- height: 40px;
- border-radius: 12px;
- border: 1px solid var(--t-border);
- background: #fff;
- color: var(--t-text);
- font-size: 13px;
- font-weight: 650;
- display: grid;
- place-items: center;
- }
- .btn.primary {
- background: var(--t-brand);
- border-color: var(--t-brand);
- color: #fff;
- box-shadow: 0 6px 16px color-mix(in srgb, var(--t-brand) 28%, transparent);
- }
- .compare {
- margin-top: 28px;
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 14px;
- }
- @media (max-width: 720px) {
- .compare { grid-template-columns: 1fr; }
- }
- .compare .mini {
- border-radius: 16px;
- overflow: hidden;
- border: 1px solid #e2e8f0;
- background: #fff;
- }
- .compare .mini-hd {
- padding: 10px 12px;
- font-size: 12px;
- font-weight: 650;
- border-bottom: 1px solid #eef2f7;
- color: #475569;
- }
- .compare .mini-body { height: 88px; }
- </style>
- </head>
- <body>
- <div class="page">
- <div class="hero">
- <h1>mobile-h5 · 明亮清爽配色方案</h1>
- <p>
- 针对「整体偏暗、顶栏沉重」的问题:去掉深绿顶栏(#14532d),改用浅色头图 + 通透背景。
- 下方可切换方案,左侧是完整 Token,右侧是工作台完整界面预览。
- </p>
- <div class="note">点选方案后,在对话里告诉我选哪套(或组合喜好)。文件也可本地打开:<strong>mobile-ui/zkxw-mobile-bright-theme-demos.html</strong></div>
- </div>
- <div class="theme-tabs" id="tabs"></div>
- <div class="layout">
- <aside class="panel">
- <h2 id="themeTitle">—</h2>
- <p class="sub" id="themeDesc">—</p>
- <div class="token-grid" id="tokens"></div>
- </aside>
- <section class="stage">
- <div class="stage-caption">完整界面预览 · <strong id="previewName">—</strong></div>
- <div class="phone" id="phone">
- <div class="phone-screen">
- <div class="screen-scroll">
- <header class="home-header">
- <div class="brand">中科兴皖 · 移动工作台</div>
- <div class="row">
- <h3>您好,张明</h3>
- <div class="logout">退出登录</div>
- </div>
- <div class="meta">
- <span>产品经理</span>
- <span class="dot"></span>
- <span>细胞存储事业部</span>
- </div>
- </header>
- <div class="home-body">
- <div class="banner">
- <div class="txt">
- <div class="kicker">今日提醒</div>
- <div class="title">有 3 条待办审批待处理</div>
- </div>
- </div>
- <div class="card">
- <div class="card-hd">
- <h4>功能菜单</h4>
- <span class="hint">共 8 项</span>
- </div>
- <div class="menu-grid" id="menus"></div>
- </div>
- <div class="card">
- <div class="card-hd">
- <h4>我的待办</h4>
- <span class="hint">最近更新</span>
- </div>
- <div class="todo" style="--todo-accent: var(--t-warning)">
- <div class="bar"></div>
- <div class="body">
- <div class="top">
- <div class="name">采集协议审批</div>
- <span class="tag warn">待处理</span>
- </div>
- <div class="meta">申请人 李华 · 今天 09:18</div>
- </div>
- </div>
- <div class="todo" style="--todo-accent: var(--t-brand)">
- <div class="bar"></div>
- <div class="body">
- <div class="top">
- <div class="name">样本入库确认</div>
- <span class="tag ok">进行中</span>
- </div>
- <div class="meta">库位 A-12 · 今天 08:42</div>
- </div>
- </div>
- <div class="cta-row">
- <div class="btn">查看全部</div>
- <div class="btn primary">发起审批</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </section>
- </div>
- <div class="compare">
- <div class="mini">
- <div class="mini-hd">现状顶栏(偏沉)</div>
- <div class="mini-body" style="background:linear-gradient(155deg,#14532d,#16a34a,#22c55e)"></div>
- </div>
- <div class="mini">
- <div class="mini-hd">目标顶栏(明亮)</div>
- <div class="mini-body" id="targetHeader" style="background:linear-gradient(160deg,#ecfdf5,#d1fae5)"></div>
- </div>
- </div>
- </div>
- <script>
- const THEMES = {
- mint: {
- id: 'mint',
- name: 'A · 薄荷微风',
- badge: '推荐',
- swatch: '#22c55e',
- desc: '保留绿色品牌,但顶栏改为浅绿渐变 + 深色字,页面通透。改造成本最低,最贴近现有业务。',
- tokens: [
- ['brand', '#22c55e', '主色 / 按钮'],
- ['brandDark', '#16a34a', '主色深 / 强调文字'],
- ['brandSoft', '#ecfdf5', '主色浅底'],
- ['headerBg', 'linear-gradient(160deg, #f0fdf4 0%, #d1fae5 58%, #a7f3d0 100%)', '顶栏背景'],
- ['headerFg', '#065f46', '顶栏文字'],
- ['bg', '#f7fffb', '页面背景'],
- ['surface', '#ffffff', '卡片表面'],
- ['text', '#0f291e', '主文字'],
- ['muted', '#5f7a6d', '次要文字'],
- ['border', '#d8f3e5', '边框'],
- ['accent', '#fbbf24', '辅助强调(大麦黄提亮)'],
- ['warning', '#d97706', '警告'],
- ['danger', '#ef4444', '危险'],
- ['success', '#10b981', '成功']
- ],
- css: {
- '--t-brand': '#22c55e',
- '--t-brand-dark': '#16a34a',
- '--t-brand-soft': '#ecfdf5',
- '--t-header-bg': 'linear-gradient(160deg, #f0fdf4 0%, #d1fae5 58%, #a7f3d0 100%)',
- '--t-header-fg': '#065f46',
- '--t-header-glow': 'rgba(255,255,255,.55)',
- '--t-bg': '#f7fffb',
- '--t-surface': '#ffffff',
- '--t-text': '#0f291e',
- '--t-muted': '#5f7a6d',
- '--t-border': '#d8f3e5',
- '--t-shadow': '0 8px 24px rgba(22, 163, 74, 0.07)',
- '--t-banner-a': '#bbf7d0',
- '--t-banner-b': '#86efac',
- '--t-banner-fg': '#14532d',
- '--t-todo-bg': 'linear-gradient(180deg, #f6fffa 0%, #ffffff 70%)',
- '--t-warning': '#d97706',
- '--t-success': '#059669'
- },
- menus: [
- ['审', '#ffe4e6', '#e11d48', '发起审批'],
- ['待', '#ecfdf5', '#16a34a', '我的待办'],
- ['协', '#e0f2fe', '#0284c7', '协议管理'],
- ['样', '#fef3c7', '#d97706', '样本查询'],
- ['质', '#ede9fe', '#7c3aed', '质检工单'],
- ['库', '#dcfce7', '#15803d', '入库登记'],
- ['报', '#f1f5f9', '#475569', '统计报表'],
- ['设', '#f8fafc', '#64748b', '个人设置']
- ]
- },
- sky: {
- id: 'sky',
- name: 'B · 晴空青',
- swatch: '#0ea5e9',
- desc: '顶栏用极浅天蓝,主操作偏青蓝,绿色作成功/进行态点缀。整体更「透气、白天感」。',
- tokens: [
- ['brand', '#0ea5e9', '主色 / 按钮'],
- ['brandDark', '#0284c7', '主色深'],
- ['brandSoft', '#e0f2fe', '主色浅底'],
- ['headerBg', 'linear-gradient(165deg, #f0f9ff 0%, #e0f2fe 55%, #bae6fd 100%)', '顶栏背景'],
- ['headerFg', '#0c4a6e', '顶栏文字'],
- ['bg', '#f8fbff', '页面背景'],
- ['surface', '#ffffff', '卡片表面'],
- ['text', '#0f172a', '主文字'],
- ['muted', '#64748b', '次要文字'],
- ['border', '#dbeafe', '边框'],
- ['accent', '#22c55e', '绿色点缀'],
- ['warning', '#d97706', '警告'],
- ['danger', '#ef4444', '危险'],
- ['success', '#22c55e', '成功']
- ],
- css: {
- '--t-brand': '#0ea5e9',
- '--t-brand-dark': '#0284c7',
- '--t-brand-soft': '#e0f2fe',
- '--t-header-bg': 'linear-gradient(165deg, #f0f9ff 0%, #e0f2fe 55%, #bae6fd 100%)',
- '--t-header-fg': '#0c4a6e',
- '--t-header-glow': 'rgba(255,255,255,.6)',
- '--t-bg': '#f8fbff',
- '--t-surface': '#ffffff',
- '--t-text': '#0f172a',
- '--t-muted': '#64748b',
- '--t-border': '#dbeafe',
- '--t-shadow': '0 8px 24px rgba(14, 165, 233, 0.08)',
- '--t-banner-a': '#bae6fd',
- '--t-banner-b': '#7dd3fc',
- '--t-banner-fg': '#0c4a6e',
- '--t-todo-bg': 'linear-gradient(180deg, #f0f9ff 0%, #ffffff 70%)',
- '--t-warning': '#d97706',
- '--t-success': '#16a34a'
- },
- menus: [
- ['审', '#ffe4e6', '#e11d48', '发起审批'],
- ['待', '#e0f2fe', '#0284c7', '我的待办'],
- ['协', '#ecfdf5', '#16a34a', '协议管理'],
- ['样', '#fef3c7', '#d97706', '样本查询'],
- ['质', '#ede9fe', '#7c3aed', '质检工单'],
- ['库', '#cffafe', '#0891b2', '入库登记'],
- ['报', '#f1f5f9', '#475569', '统计报表'],
- ['设', '#f8fafc', '#64748b', '个人设置']
- ]
- },
- teal: {
- id: 'teal',
- name: 'C · 青瓷医疗',
- swatch: '#14b8a6',
- desc: '偏医疗 / 实验室气质的青绿(teal),白瓷感背景,干净专业,不压抑。',
- tokens: [
- ['brand', '#14b8a6', '主色 / 按钮'],
- ['brandDark', '#0f766e', '主色深'],
- ['brandSoft', '#f0fdfa', '主色浅底'],
- ['headerBg', 'linear-gradient(160deg, #f0fdfa 0%, #ccfbf1 60%, #99f6e4 100%)', '顶栏背景'],
- ['headerFg', '#115e59', '顶栏文字'],
- ['bg', '#f7fffe', '页面背景'],
- ['surface', '#ffffff', '卡片表面'],
- ['text', '#134e4a', '主文字'],
- ['muted', '#5f7c78', '次要文字'],
- ['border', '#ccfbf1', '边框'],
- ['accent', '#f59e0b', '辅助强调'],
- ['warning', '#d97706', '警告'],
- ['danger', '#ef4444', '危险'],
- ['success', '#0d9488', '成功']
- ],
- css: {
- '--t-brand': '#14b8a6',
- '--t-brand-dark': '#0f766e',
- '--t-brand-soft': '#f0fdfa',
- '--t-header-bg': 'linear-gradient(160deg, #f0fdfa 0%, #ccfbf1 60%, #99f6e4 100%)',
- '--t-header-fg': '#115e59',
- '--t-header-glow': 'rgba(255,255,255,.55)',
- '--t-bg': '#f7fffe',
- '--t-surface': '#ffffff',
- '--t-text': '#134e4a',
- '--t-muted': '#5f7c78',
- '--t-border': '#ccfbf1',
- '--t-shadow': '0 8px 24px rgba(13, 148, 136, 0.08)',
- '--t-banner-a': '#99f6e4',
- '--t-banner-b': '#5eead4',
- '--t-banner-fg': '#115e59',
- '--t-todo-bg': 'linear-gradient(180deg, #f0fdfa 0%, #ffffff 70%)',
- '--t-warning': '#d97706',
- '--t-success': '#0d9488'
- },
- menus: [
- ['审', '#ffe4e6', '#e11d48', '发起审批'],
- ['待', '#f0fdfa', '#0f766e', '我的待办'],
- ['协', '#e0f2fe', '#0284c7', '协议管理'],
- ['样', '#fef3c7', '#d97706', '样本查询'],
- ['质', '#ede9fe', '#7c3aed', '质检工单'],
- ['库', '#ccfbf1', '#0f766e', '入库登记'],
- ['报', '#f1f5f9', '#475569', '统计报表'],
- ['设', '#f8fafc', '#64748b', '个人设置']
- ]
- },
- dawn: {
- id: 'dawn',
- name: 'D · 暖晨光',
- swatch: '#84cc16',
- desc: '浅暖米背景 + 柔和嫩绿顶栏,带一点大麦黄,像早晨阳光,亲和不沉重。',
- tokens: [
- ['brand', '#65a30d', '主色 / 按钮'],
- ['brandDark', '#4d7c0f', '主色深'],
- ['brandSoft', '#f7fee7', '主色浅底'],
- ['headerBg', 'linear-gradient(160deg, #fffbeb 0%, #fef9c3 45%, #d9f99d 100%)', '顶栏背景'],
- ['headerFg', '#3f6212', '顶栏文字'],
- ['bg', '#fffcf5', '页面背景'],
- ['surface', '#ffffff', '卡片表面'],
- ['text', '#1c1917', '主文字'],
- ['muted', '#78716c', '次要文字'],
- ['border', '#f5e6c8', '边框'],
- ['accent', '#eab308', '大麦黄'],
- ['warning', '#d97706', '警告'],
- ['danger', '#ef4444', '危险'],
- ['success', '#65a30d', '成功']
- ],
- css: {
- '--t-brand': '#65a30d',
- '--t-brand-dark': '#4d7c0f',
- '--t-brand-soft': '#f7fee7',
- '--t-header-bg': 'linear-gradient(160deg, #fffbeb 0%, #fef9c3 45%, #d9f99d 100%)',
- '--t-header-fg': '#3f6212',
- '--t-header-glow': 'rgba(255,255,255,.5)',
- '--t-bg': '#fffcf5',
- '--t-surface': '#ffffff',
- '--t-text': '#1c1917',
- '--t-muted': '#78716c',
- '--t-border': '#f5e6c8',
- '--t-shadow': '0 8px 24px rgba(101, 163, 13, 0.08)',
- '--t-banner-a': '#fde68a',
- '--t-banner-b': '#bef264',
- '--t-banner-fg': '#3f6212',
- '--t-todo-bg': 'linear-gradient(180deg, #fffbeb 0%, #ffffff 70%)',
- '--t-warning': '#d97706',
- '--t-success': '#65a30d'
- },
- menus: [
- ['审', '#ffe4e6', '#e11d48', '发起审批'],
- ['待', '#f7fee7', '#4d7c0f', '我的待办'],
- ['协', '#e0f2fe', '#0284c7', '协议管理'],
- ['样', '#fef3c7', '#d97706', '样本查询'],
- ['质', '#ede9fe', '#7c3aed', '质检工单'],
- ['库', '#ecfccb', '#4d7c0f', '入库登记'],
- ['报', '#f5f5f4', '#57534e', '统计报表'],
- ['设', '#fafaf9', '#78716c', '个人设置']
- ]
- }
- }
- const order = ['mint', 'sky', 'teal', 'dawn']
- let active = 'mint'
- const tabsEl = document.getElementById('tabs')
- const tokensEl = document.getElementById('tokens')
- const menusEl = document.getElementById('menus')
- const phoneEl = document.getElementById('phone')
- const root = document.documentElement
- function renderTabs() {
- tabsEl.innerHTML = order.map((id) => {
- const t = THEMES[id]
- const rec = id === 'mint' ? '<span class="badge">推荐</span>' : ''
- return `<button class="theme-tab ${id === active ? 'is-active' : ''}" data-id="${id}" style="--swatch:${t.swatch};--t-brand:${t.css['--t-brand']};--t-brand-dark:${t.css['--t-brand-dark']};--t-brand-soft:${t.css['--t-brand-soft']}">
- <span class="dot"></span>${t.name}${rec}
- </button>`
- }).join('')
- tabsEl.querySelectorAll('.theme-tab').forEach((btn) => {
- btn.addEventListener('click', () => {
- active = btn.dataset.id
- applyTheme()
- // for visual companion selection
- if (typeof toggleSelect === 'function') {
- const fake = { dataset: { choice: active }, classList: { add() {}, remove() {}, contains() { return false } } }
- }
- window.parent && window.parent.postMessage
- document.dispatchEvent(new CustomEvent('theme-selected', { detail: active }))
- try {
- const payload = { type: 'click', choice: active, text: THEMES[active].name, timestamp: Math.floor(Date.now() / 1000) }
- // companion helper may listen to option clicks; also expose for agent
- window.__selectedTheme = active
- } catch (e) {}
- })
- })
- }
- function applyTheme() {
- const t = THEMES[active]
- Object.entries(t.css).forEach(([k, v]) => phoneEl.style.setProperty(k, v))
- // also set on page for tab active colors
- Object.entries(t.css).forEach(([k, v]) => root.style.setProperty(k, v))
- document.getElementById('themeTitle').textContent = t.name
- document.getElementById('themeDesc').textContent = t.desc
- document.getElementById('previewName').textContent = t.name
- document.getElementById('targetHeader').style.background = t.css['--t-header-bg']
- tokensEl.innerHTML = t.tokens.map(([name, hex, desc]) => {
- const isGrad = String(hex).includes('gradient')
- const swatch = isGrad
- ? `<i style="background:${hex}"></i>`
- : `<i style="background:${hex}"></i>`
- return `<div class="token">${swatch}<div><div class="name">${name}</div><div class="desc">${desc}</div></div><code>${hex}</code></div>`
- }).join('')
- menusEl.innerHTML = t.menus.map(([ch, bg, fg, label]) =>
- `<div class="menu-item"><div class="menu-icon" style="background:${bg};color:${fg}">${ch}</div><span>${label}</span></div>`
- ).join('')
- renderTabs()
- }
- // companion-friendly selectable cards at bottom via data-choice hooks
- function injectCompanionHooks() {
- // Add invisible option markers for companion selection if wrapped
- order.forEach((id) => {
- const el = document.createElement('div')
- el.className = 'option'
- el.dataset.choice = id
- el.style.display = 'none'
- el.onclick = () => {}
- document.body.appendChild(el)
- })
- }
- applyTheme()
- injectCompanionHooks()
- </script>
- <!-- companion selectable options -->
- <div class="options" style="max-width:1180px;margin:0 auto;padding:0 18px 40px;display:grid;gap:10px">
- <p style="margin:0 0 4px;font-size:13px;color:#64748b">选择偏好方案(可点击下方卡片,也可在上方 Tab 预览):</p>
- <div class="option" data-choice="mint" onclick="toggleSelect && toggleSelect(this); document.querySelector('[data-id=mint]')?.click()" style="display:flex;gap:12px;align-items:center;padding:12px 14px;border:1px solid #e2e8f0;border-radius:14px;background:#fff;cursor:pointer">
- <div class="letter" style="width:28px;height:28px;border-radius:8px;background:#ecfdf5;color:#065f46;display:grid;place-items:center;font-weight:700">A</div>
- <div class="content"><h3 style="margin:0;font-size:14px">薄荷微风(推荐)</h3><p style="margin:2px 0 0;font-size:12px;color:#64748b">浅绿顶栏 + 品牌绿,最稳妥</p></div>
- </div>
- <div class="option" data-choice="sky" onclick="toggleSelect && toggleSelect(this); document.querySelector('[data-id=sky]')?.click()" style="display:flex;gap:12px;align-items:center;padding:12px 14px;border:1px solid #e2e8f0;border-radius:14px;background:#fff;cursor:pointer">
- <div class="letter" style="width:28px;height:28px;border-radius:8px;background:#e0f2fe;color:#0c4a6e;display:grid;place-items:center;font-weight:700">B</div>
- <div class="content"><h3 style="margin:0;font-size:14px">晴空青</h3><p style="margin:2px 0 0;font-size:12px;color:#64748b">天蓝顶栏,更透气</p></div>
- </div>
- <div class="option" data-choice="teal" onclick="toggleSelect && toggleSelect(this); document.querySelector('[data-id=teal]')?.click()" style="display:flex;gap:12px;align-items:center;padding:12px 14px;border:1px solid #e2e8f0;border-radius:14px;background:#fff;cursor:pointer">
- <div class="letter" style="width:28px;height:28px;border-radius:8px;background:#f0fdfa;color:#115e59;display:grid;place-items:center;font-weight:700">C</div>
- <div class="content"><h3 style="margin:0;font-size:14px">青瓷医疗</h3><p style="margin:2px 0 0;font-size:12px;color:#64748b">teal 专业、干净</p></div>
- </div>
- <div class="option" data-choice="dawn" onclick="toggleSelect && toggleSelect(this); document.querySelector('[data-id=dawn]')?.click()" style="display:flex;gap:12px;align-items:center;padding:12px 14px;border:1px solid #e2e8f0;border-radius:14px;background:#fff;cursor:pointer">
- <div class="letter" style="width:28px;height:28px;border-radius:8px;background:#f7fee7;color:#3f6212;display:grid;place-items:center;font-weight:700">D</div>
- <div class="content"><h3 style="margin:0;font-size:14px">暖晨光</h3><p style="margin:2px 0 0;font-size:12px;color:#64748b">暖米 + 嫩绿,亲和</p></div>
- </div>
- </div>
- </body>
- </html>
|