125 lines
40 KiB
HTML
125 lines
40 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>记之 · 高保真配色实验室</title>
|
||
<style>
|
||
:root{--brand:#00b386;--deep:#009973;--soft:#e6f7f1;--bg:#f6f7f9;--card:#ffffff;--ink:#191f26;--muted:#5e6772;--faint:#9aa3ad;--line:#eef0f3;--ai:#5b6bf5;--aiSoft:#eef0fe;--expense:#f0642d;--expenseSoft:#fff3ec;--warning:#f5a623;--warningSoft:#fff7e8;--page:#edf0f2;--shadow:rgba(25,31,38,.12)}
|
||
*{box-sizing:border-box}body{margin:0;color:var(--ink);background:var(--page);font-family:"Noto Sans SC","Microsoft YaHei",sans-serif}.page{width:min(1380px,calc(100% - 32px));margin:auto;padding:52px 0 80px}.head{display:grid;grid-template-columns:1fr auto;align-items:end;gap:28px;margin:0 4px 34px}.kicker{margin-bottom:10px;color:var(--brand);font:800 11px "Noto Sans SC","Microsoft YaHei",sans-serif;letter-spacing:.16em}h1{margin:0;font-family:"Noto Serif SC","Songti SC",serif;font-size:clamp(38px,5vw,66px);line-height:1}.intro{max-width:700px;margin:17px 0 0;color:var(--muted);font-size:14px;line-height:1.75}.palette{display:flex;gap:9px;padding:13px;border:1px solid var(--line);border-radius:17px;background:#fff}.palette i{width:34px;height:34px;border:3px solid #fff;border-radius:50%;background:var(--c);box-shadow:0 0 0 1px var(--line)}
|
||
.grid{display:grid;grid-template-columns:repeat(3,minmax(360px,1fr));gap:26px 22px;align-items:start}.case{padding:17px 15px 21px;border:1px solid #dce3e0;border-radius:23px;background:#fff}.caseHead{display:flex;justify-content:space-between;width:min(100%,370px);margin:0 auto 14px}.idx{color:var(--brand);font:800 10px "Noto Sans SC","Microsoft YaHei",sans-serif;letter-spacing:.14em}.case h2{margin:5px 0 3px;font-size:20px}.note{color:var(--muted);font-size:11px}.tag{align-self:flex-start;padding:5px 9px;border:1px solid var(--brand);border-radius:999px;color:var(--brand);background:var(--soft);font-size:9px;font-weight:800}
|
||
.phone{position:relative;width:min(100%,370px);height:780px;margin:auto;overflow:hidden;border:7px solid #1d2422;border-radius:43px;background:var(--bg);box-shadow:0 18px 36px var(--shadow)}.status{display:flex;justify-content:space-between;height:34px;padding:8px 19px 0;font-size:10px;font-weight:800}.sys{letter-spacing:2px}.screen{height:calc(100% - 34px);overflow:hidden;padding:8px 16px 82px;background:var(--bg)}.top{display:flex;align-items:center;justify-content:space-between;min-height:42px;margin-bottom:12px}.title{font-size:16px;font-weight:800}.brand{display:flex;align-items:center;gap:9px}.logo{width:34px;height:34px;border:1px solid var(--line);border-radius:10px;object-fit:cover}.brand b{font-family:"Noto Serif SC","Songti SC",serif;font-size:18px}.micro,.sub{margin-top:2px;color:var(--muted);font-size:8px;line-height:1.45}.square{display:grid;width:31px;height:31px;place-items:center;border:1px solid var(--line);border-radius:10px;background:#fff;font-size:15px}.action{color:var(--brand);font-size:10px;font-weight:800}.panel{border:1px solid var(--line);border-radius:17px;background:#fff}.st{font-size:11px;font-weight:800}.link{color:var(--brand);font-size:8px;font-weight:800}.section{display:flex;justify-content:space-between;align-items:center;margin:13px 1px 4px}
|
||
.hero{padding:17px 18px;border-radius:19px;color:#fff;background:var(--brand)}.hero small{color:#d9efeb}.heroValue{margin:5px 0 14px;font:700 29px/1.1 "Noto Sans SC","Microsoft YaHei",sans-serif}.heroMeta{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.heroMeta span{color:#c9e6e0;font-size:8px}.heroMeta b{display:block;margin-top:3px;color:#fff;font:700 11px "Noto Sans SC","Microsoft YaHei",sans-serif}.quick{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin:11px 0}.quick>div{padding:9px 2px 8px;border:1px solid var(--line);border-radius:14px;text-align:center;background:#fff}.qicon,.cicon,.ricon{display:grid;place-items:center;color:var(--brand);background:var(--soft)}.qicon{width:28px;height:28px;margin:0 auto 5px;border-radius:9px;font-size:13px}.quick span{font-size:8px;font-weight:700}.budget{display:grid;grid-template-columns:1fr auto;align-items:center;gap:12px;padding:12px 13px}.track{height:5px;margin-top:8px;overflow:hidden;border-radius:99px;background:var(--soft)}.track i{display:block;width:var(--w,63%);height:100%;background:var(--brand)}.budgetVal{color:var(--brand);font:800 16px "Noto Sans SC","Microsoft YaHei",sans-serif}
|
||
.tx{display:grid;grid-template-columns:34px 1fr auto;align-items:center;gap:9px;padding:9px 0;border-bottom:1px solid var(--line)}.cicon{width:34px;height:34px;border-radius:11px;font-size:12px;font-weight:800}.tx b{font-size:10px}.tx small{display:block;margin-top:2px;color:var(--muted);font-size:8px}.money{font:800 11px "Noto Sans SC","Microsoft YaHei",sans-serif}.out{color:var(--expense)}.income{color:var(--brand)}.nav{position:absolute;right:0;bottom:0;left:0;display:grid;grid-template-columns:repeat(4,1fr);height:68px;padding:8px 9px 9px;border-top:1px solid var(--line);background:#fff}.nav>div{display:grid;place-items:center;gap:2px;color:var(--faint);font-size:8px}.nav b{font-size:14px}.nav .on{color:var(--brand);font-weight:800}.nav .add{transform:translateY(-15px)}.fab{display:grid;width:42px;height:42px;place-items:center;border:4px solid var(--bg);border-radius:50%;color:#fff;background:var(--brand);box-shadow:0 7px 15px var(--shadow);font-size:20px}
|
||
.chat{display:grid;grid-template-rows:auto 1fr auto;padding:8px 13px 14px}.person{display:flex;align-items:center;gap:8px}.aiAvatar{display:grid;width:34px;height:34px;place-items:center;border-radius:11px;color:var(--ai);background:var(--aiSoft);font-size:16px}.online{color:var(--brand);font-size:8px}.log{overflow:hidden;padding:9px 3px}.stamp{margin-bottom:13px;color:var(--faint);font-size:8px;text-align:center}.msg{display:flex;gap:7px;margin-bottom:11px}.msg.me{justify-content:flex-end}.miniAI{display:grid;flex:0 0 25px;height:25px;place-items:center;border-radius:8px;color:var(--ai);background:var(--aiSoft);font-size:9px;font-weight:800}.bubble{max-width:77%;padding:10px 11px;border:1px solid var(--line);border-radius:6px 15px 15px 15px;background:#fff;font-size:10px;line-height:1.55}.me .bubble{border-color:var(--brand);border-radius:15px 6px 15px 15px;color:#fff;background:var(--brand)}.thinking{display:inline-flex;gap:6px;margin:0 0 11px 32px;padding:6px 9px;border-radius:99px;color:var(--ai);background:var(--aiSoft);font-size:8px;font-weight:700}.chatBill{margin:0 0 11px 32px;padding:11px;border-color:#cfd9e4}.billHead{display:flex;justify-content:space-between;margin-bottom:7px;color:var(--ai);font-size:8px;font-weight:800}.ok{padding:3px 7px;border-radius:99px;color:var(--brand);background:var(--soft)}.composer{display:grid;grid-template-columns:30px 1fr 30px 34px;align-items:center;gap:6px;padding:7px;border:1px solid var(--line);border-radius:18px;background:#fff}.composeBtn{display:grid;width:30px;height:30px;place-items:center;border:0;border-radius:10px;color:var(--muted);background:var(--bg)}.composeBtn.send{color:#fff;background:var(--brand)}.placeholder{color:var(--faint);font-size:9px}
|
||
.segments{display:grid;grid-template-columns:1fr 1fr;gap:4px;padding:4px;border:1px solid var(--line);border-radius:13px;background:#fff}.seg{padding:9px;border-radius:9px;color:var(--muted);text-align:center;font-size:10px;font-weight:800}.seg.on{color:#fff;background:var(--brand)}.amount{padding:24px 0 18px;text-align:center}.amount small{color:var(--muted)}.amount b{display:block;margin-top:4px;color:var(--expense);font:700 38px/1.1 "Noto Sans SC","Microsoft YaHei",sans-serif}.cats{display:grid;grid-template-columns:repeat(4,1fr);gap:8px 6px;margin-top:10px}.cat{padding:7px 2px;border:1px solid transparent;border-radius:12px;text-align:center}.cat.on{border-color:var(--brand);background:var(--soft)}.cat .cicon{margin:0 auto 5px}.cat span{font-size:8px;font-weight:700}.form{margin-top:13px;padding:2px 13px}.formRow{display:grid;grid-template-columns:20px 67px 1fr 15px;align-items:center;gap:5px;min-height:42px;border-bottom:1px solid var(--line);font-size:9px}.formRow:last-child{border:0}.lab{color:var(--muted)}.val{text-align:right;font-weight:700}.primary{display:grid;width:100%;min-height:44px;margin-top:14px;place-items:center;border:0;border-radius:14px;color:#fff;background:var(--brand);font-size:11px;font-weight:800}
|
||
.months{display:flex;justify-content:center;gap:18px;margin:1px 0 11px;color:var(--muted);font-size:9px}.months b{color:var(--ink);font-size:11px}.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:7px}.metric{padding:11px 9px}.metric span{color:var(--muted);font-size:8px}.metric b{display:block;margin-top:5px;font:700 14px "Noto Sans SC","Microsoft YaHei",sans-serif}.chartCard{margin-top:10px;padding:13px}.barRow{display:grid;grid-template-columns:44px 1fr 43px;align-items:center;gap:7px;margin-top:10px;font-size:8px}.bar{height:7px;overflow:hidden;border-radius:99px;background:var(--soft)}.bar i{display:block;width:var(--w);height:100%;background:var(--brand)}.barRow b{font:700 9px "Noto Sans SC","Microsoft YaHei",sans-serif;text-align:right}.aiReport{margin-top:10px;padding:13px;border-color:#cfd9e4;background:var(--aiSoft)}.aiHead{color:var(--ai);font-size:9px;font-weight:800}.aiReport strong{display:block;margin-top:8px;font-size:12px;line-height:1.45}.aiReport p{margin:5px 0 0;color:var(--muted);font-size:8px;line-height:1.55}
|
||
.profile{display:grid;grid-template-columns:50px 1fr auto;align-items:center;gap:11px;padding:14px}.avatar{display:grid;width:50px;height:50px;place-items:center;border-radius:16px;color:#fff;background:var(--brand);font:800 20px serif}.profileName{font-size:14px;font-weight:800}.ledger{margin-top:10px;padding:13px}.ledgerTop{display:flex;justify-content:space-between}.ledgerName{display:flex;align-items:center;gap:8px;font-size:10px;font-weight:800}.dot{width:9px;height:9px;border-radius:3px;background:var(--brand)}.ledgerStats{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:11px}.ledgerStat{padding:9px;border-radius:10px;background:var(--bg)}.ledgerStat span{color:var(--muted);font-size:8px}.ledgerStat b{display:block;margin-top:3px;font:700 12px "Noto Sans SC","Microsoft YaHei",sans-serif}.settings{margin-top:10px;padding:0 13px}.setting{display:grid;grid-template-columns:31px 1fr auto;align-items:center;gap:9px;min-height:49px;border-bottom:1px solid var(--line)}.setting:last-child{border:0}.ricon{width:31px;height:31px;border-radius:10px;font-size:12px;font-weight:800}.ricon.ai{color:var(--ai);background:var(--aiSoft)}.setting b{font-size:10px}.setting p{margin:2px 0 0;color:var(--muted);font-size:8px}.chev{color:var(--faint)}
|
||
.captureState{display:flex;align-items:center;gap:9px;margin-bottom:10px;padding:10px 11px;color:var(--deep);background:var(--soft)}.stateMark{display:grid;width:25px;height:25px;place-items:center;border-radius:50%;color:#fff;background:var(--brand)}.captureState b{font-size:9px}.captureState p{margin:2px 0 0;color:var(--muted);font-size:8px}.warning{display:flex;gap:7px;margin-bottom:9px;padding:9px 10px;border:1px solid #f1d79e;border-radius:12px;color:var(--warning);background:var(--warningSoft);font-size:8px;line-height:1.45}.parsed{margin-bottom:9px;padding:12px}.parsedHead{display:flex;justify-content:space-between;margin-bottom:9px;font-size:9px;font-weight:800}.confidence{color:var(--brand);font-size:8px}.parsedMain{display:grid;grid-template-columns:38px 1fr auto;align-items:center;gap:9px}.parsedMain .cicon{width:38px;height:38px}.parsedAmount{color:var(--expense);font:800 16px "Noto Sans SC","Microsoft YaHei",sans-serif}.chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}.chip{padding:5px 7px;border:1px solid var(--line);border-radius:9px;color:var(--muted);background:var(--bg);font-size:8px}.captureFooter{position:absolute;right:13px;bottom:13px;left:13px}.captureFooter .primary{margin:0}
|
||
@media(max-width:1180px){.grid{grid-template-columns:repeat(2,minmax(350px,1fr))}}@media(max-width:790px){.page{width:min(100% - 18px,430px);padding:30px 0 52px}.head{grid-template-columns:1fr;gap:18px}.palette{justify-self:start}.grid{grid-template-columns:1fr;gap:18px}.case{padding:15px 9px 18px}.phone{height:760px}}
|
||
/* Theme studio controls. App mockup geometry stays unchanged. */
|
||
body{padding-left:326px;transition:padding-left .22s ease}.page{width:min(1380px,calc(100% - 36px));padding-top:42px}.studio{position:fixed;z-index:20;inset:0 auto 0 0;width:326px;overflow:auto;border-right:1px solid #dfe3e7;background:#fff;color:#191f26;box-shadow:8px 0 24px rgba(25,31,38,.06)}.studioInner{padding:22px 18px 28px}.studioBrand{display:flex;align-items:center;gap:11px;padding-bottom:18px;border-bottom:1px solid #eef0f3}.studioBrand img{width:42px;height:42px;border:1px solid #e6e9ed;border-radius:12px}.studioBrand b{display:block;font-size:15px}.studioBrand span{display:block;margin-top:3px;color:#7b8490;font-size:10px}.studioTitle{display:flex;align-items:end;justify-content:space-between;margin:20px 0 10px}.studioTitle b{font-size:12px}.studioTitle span{color:#8a939e;font-size:9px}.presets{display:grid;grid-template-columns:1fr 1fr;gap:7px}.preset{display:flex;align-items:center;gap:7px;min-height:38px;padding:7px 8px;border:1px solid #e7eaee;border-radius:11px;background:#fff;color:#303741;font:700 10px inherit;cursor:pointer}.preset:hover,.preset.active{border-color:var(--preview,#00b386);box-shadow:inset 0 0 0 1px var(--preview,#00b386)}.presetDot{width:17px;height:17px;border:4px solid var(--softPreview,#e6f7f1);border-radius:6px;background:var(--preview,#00b386)}.tokenGroups{display:grid;gap:15px;margin-top:18px}.tokenGroup{display:grid;gap:7px}.tokenGroup h3{margin:0;color:#89919b;font-size:9px;font-weight:800;letter-spacing:.08em}.tokenRow{display:grid;grid-template-columns:78px 31px 1fr;align-items:center;gap:8px}.tokenRow label{font-size:10px;font-weight:700}.tokenRow input[type=color]{width:31px;height:31px;padding:2px;border:1px solid #dfe3e7;border-radius:9px;background:#fff;cursor:pointer}.tokenRow input[type=color]::-webkit-color-swatch{border:0;border-radius:6px}.tokenRow input[type=text]{min-width:0;height:31px;padding:0 8px;border:1px solid #e1e5e9;border-radius:9px;outline:0;color:#424a55;background:#f8f9fa;font:700 10px ui-monospace,Consolas,monospace;text-transform:uppercase}.tokenRow input[type=text]:focus{border-color:#98a2ad;background:#fff}.tokenBlock{margin-bottom:5px;padding:9px 10px;border:1px solid #eef0f3;border-radius:12px;background:#fafbfc}.tokenSliders{display:grid;grid-template-columns:28px 1fr 26px 28px 1fr 26px 28px 1fr 26px;align-items:center;gap:4px;margin-top:7px}.tokenSliders label{font-size:8px;color:#89919b;font-weight:700}.tokenSliders span{font-size:8px;color:#424a55;font-weight:700;text-align:right}.tokenSliders input[type=range]{width:100%;height:4px;-webkit-appearance:none;appearance:none;background:#e1e5e9;border-radius:2px;outline:none;cursor:pointer}.tokenSliders input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:15px;height:15px;border:2px solid #fff;border-radius:50%;background:#424a55;box-shadow:0 1px 3px rgba(0,0,0,.18);cursor:pointer}.contrast{display:grid;gap:7px;margin-top:18px;padding:12px;border:1px solid #e7eaee;border-radius:13px;background:#f8f9fa}.contrastHead{display:flex;justify-content:space-between;font-size:10px;font-weight:800}.contrastGrid{display:grid;grid-template-columns:1fr 1fr;gap:6px}.contrastItem{padding:7px;border-radius:8px;background:#fff;font-size:8px}.contrastItem b{display:block;margin-top:2px;font-size:11px}.contrastItem.pass b{color:#14805e}.contrastItem.fail b{color:#c23e35}.studioActions{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-top:13px}.studioButton{min-height:38px;border:1px solid #dfe3e7;border-radius:11px;background:#fff;color:#303741;font:800 10px inherit;cursor:pointer}.studioButton.primaryAction{border-color:#20252b;color:#fff;background:#20252b}.studioHint{margin:12px 2px 0;color:#8b949f;font-size:9px;line-height:1.55}.toast{position:fixed;z-index:40;left:344px;bottom:22px;padding:10px 14px;border-radius:11px;color:#fff;background:#20252b;font-size:11px;opacity:0;pointer-events:none;transform:translateY(8px);transition:.2s}.toast.show{opacity:1;transform:none}.studioToggle{display:none;position:fixed;z-index:30;right:14px;bottom:14px;width:48px;height:48px;border:0;border-radius:15px;color:#fff;background:#20252b;font-size:18px;box-shadow:0 10px 24px rgba(25,31,38,.2)}
|
||
.panel,.quick>div,.square,.composer,.segments,.nav,.case{background:var(--card)}.screen,.phone{background:var(--bg)}.hero small,.heroMeta span{color:rgba(255,255,255,.78)}.aiReport,.thinking,.miniAI,.aiAvatar,.ricon.ai{background:var(--aiSoft)}.chatBill,.aiReport{border-color:var(--ai)}.warning{border-color:var(--warning)}.cicon.food{color:#d85b37;background:#fff0e9}.cicon.transit{color:#168f8a;background:#e7f7f5}.cicon.salary{color:#17855f;background:#e8f7f0}.cicon.shopping{color:#4078c9;background:#edf3fc}.cicon.housing{color:#9b7138;background:#f8f0e3}.cicon.gift{color:#c25174;background:#fbeaf0}.cicon.fun{color:#7e5fc4;background:#f1edfb}.cicon.cardcat{color:#5a6877;background:#eef1f4}.livePalette i{background:var(--swatch)}
|
||
@media(max-width:1500px) and (min-width:981px){.grid{grid-template-columns:repeat(2,minmax(350px,1fr))}}@media(max-width:980px){body{padding-left:0}.studio{transform:translateX(-104%);transition:transform .22s ease}.studio.open{transform:none}.studioToggle{display:grid;place-items:center}.toast{left:16px;bottom:76px}.page{width:min(100% - 18px,760px)}.grid{grid-template-columns:1fr}.head{grid-template-columns:1fr}.palette{justify-self:start}}
|
||
</style></head>
|
||
<body>
|
||
<aside class="studio" id="studio"><div class="studioInner">
|
||
<div class="studioBrand"><img src="frontend/assets/branding/jizhi-app-icon-centered.png" alt="记之"><div><b>记之主题编辑器</b><span>实时预览 · 不修改 App</span></div></div>
|
||
<div class="studioTitle"><b>快速方案</b><span>全部为纯色</span></div>
|
||
<div class="presets" id="presets"></div>
|
||
<div class="tokenGroups" id="tokenGroups"></div>
|
||
<div class="contrast"><div class="contrastHead"><span>可读性检查</span><span>WCAG 对比度</span></div><div class="contrastGrid" id="contrastGrid"></div></div>
|
||
<div class="studioActions"><button class="studioButton" id="resetTheme">恢复当前配色</button><button class="studioButton primaryAction" id="copyTheme">复制色板 JSON</button></div>
|
||
<p class="studioHint">颜色只保存在当前浏览器。拖动 H/S/L 滑块可按色相、饱和度、明度微调每个色值。分类图标保留独立颜色,避免所有账单都变成同一种色块。</p>
|
||
</div></aside>
|
||
<button class="studioToggle" id="studioToggle" aria-label="打开配色编辑器">🎨</button>
|
||
<div class="toast" id="toast">色板已复制</div><main class="page"><header class="head"><div><div class="kicker">JIZHI THEME STUDIO · LIVE</div><h1>记之 · 高保真配色实验室</h1><p class="intro">保持当前 App 的页面结构,只调整颜色。使用左侧面板实时修改品牌色、AI 色、背景、卡片、文字和语义色,六个页面会同步预览。全稿只使用纯色。</p></div><div class="palette livePalette"><i data-swatch="bg"></i><i data-swatch="card"></i><i data-swatch="brand"></i><i data-swatch="ai"></i><i data-swatch="ink"></i></div></header><section class="grid">
|
||
<article class="case"><header class="caseHead"><div><div class="idx">SCREEN 01</div><h2>首页 · 明细</h2><div class="note">结余、预算和今日账单</div></div><span class="tag">主视觉</span></header><div class="phone"><div class="status"><span>9:41</span><span class="sys">◢ ▰</span></div><div class="screen"><div class="top"><div class="brand"><img class="logo" src="frontend/assets/branding/jizhi-app-icon-centered.png"><div><b>记之</b><div class="micro">日常账本</div></div></div><div class="square">•••</div></div><section class="hero"><small>七月结余</small><div class="heroValue">¥ 4,286.50</div><div class="heroMeta"><span>收入<b>¥ 8,640</b></span><span>支出<b>¥ 4,353</b></span><span>共计<b>48 笔</b></span></div></section><div class="quick"><div><i class="qicon">声</i><span>语音记账</span></div><div><i class="qicon">拍</i><span>拍照识别</span></div><div><i class="qicon">截</i><span>截屏记账</span></div><div><i class="qicon">问</i><span>问一问</span></div></div><section class="panel budget"><div><b class="st">本月预算</b><div class="sub">已使用 63%,当前节奏正常</div><div class="track"><i></i></div></div><div class="budgetVal">¥ 1,847</div></section><div class="section"><b class="st">今天</b><span class="link">全部明细</span></div><div class="tx"><div class="cicon food">餐</div><div><b>午餐</b><small>餐饮 · 12:26</small></div><div class="money out">- ¥28</div></div><div class="tx"><div class="cicon transit">行</div><div><b>地铁</b><small>交通 · 08:41</small></div><div class="money out">- ¥4</div></div><div class="tx"><div class="cicon salary">收</div><div><b>稿费到账</b><small>兼职 · 07:30</small></div><div class="money income">+ ¥680</div></div></div><nav class="nav"><div class="on"><b>⌂</b><span>明细</span></div><div><b>▥</b><span>统计</span></div><div class="add"><div class="fab">+</div><span>记一笔</span></div><div><b>○</b><span>我的</span></div></nav></div></article>
|
||
<article class="case"><header class="caseHead"><div><div class="idx">SCREEN 02</div><h2>AI 聊天</h2><div class="note">AI 色仅标识 AI 身份与状态</div></div></header><div class="phone"><div class="status"><span>9:41</span><span class="sys">◢ ▰</span></div><div class="screen chat"><div class="top"><div class="person"><div class="square">‹</div><div class="aiAvatar">✦</div><div><b class="title">小记</b><div class="online">已连接 · 日常账本</div></div></div><div class="square">•••</div></div><div class="log"><div class="stamp">今天 14:28</div><div class="msg me"><div class="bubble">今天兼职赚了 680 元,午饭花了 28。</div></div><div class="thinking">● 正在核对账本分类</div><div class="msg"><div class="miniAI">记</div><div class="bubble">已识别到 2 笔:兼职收入 680 元、餐饮支出 28 元。</div></div><section class="panel chatBill"><div class="billHead"><span>✦ AI 入账结果</span><span class="ok">已记录</span></div><div class="tx"><div class="cicon salary">收</div><div><b>兼职收入</b><small>今天 14:28</small></div><div class="money income">+ ¥680</div></div><div class="tx"><div class="cicon food">餐</div><div><b>午饭</b><small>餐饮 · 14:28</small></div><div class="money out">- ¥28</div></div></section><div class="msg"><div class="miniAI">记</div><div class="bubble">本月收入是 8,640 元,结余 4,286.50 元。</div></div></div><div class="composer"><button class="composeBtn">⌨</button><div class="placeholder">说说今天的收入或支出...</div><button class="composeBtn">☺</button><button class="composeBtn send">↑</button></div></div></div></article>
|
||
<article class="case"><header class="caseHead"><div><div class="idx">SCREEN 03</div><h2>记一笔</h2><div class="note">纯色切换、分类和确认操作</div></div></header><div class="phone"><div class="status"><span>9:41</span><span class="sys">◢ ▰</span></div><div class="screen"><div class="top"><div class="square">‹</div><div class="title">记一笔</div><span class="action">日常账本</span></div><div class="segments"><div class="seg on">支出</div><div class="seg">收入</div></div><div class="amount"><small>金额</small><b>¥ 28.00</b></div><b class="st">选择分类</b><div class="cats"><div class="cat on"><div class="cicon food">餐</div><span>餐饮</span></div><div class="cat"><div class="cicon shopping">购</div><span>购物</span></div><div class="cat"><div class="cicon transit">行</div><span>交通</span></div><div class="cat"><div class="cicon housing">住</div><span>居住</span></div><div class="cat"><div class="cicon gift">礼</div><span>人情</span></div><div class="cat"><div class="cicon cardcat">卡</div><span>账单</span></div><div class="cat"><div class="cicon fun">娱</div><span>娱乐</span></div><div class="cat"><div class="cicon">•••</div><span>其他</span></div></div><section class="panel form"><div class="formRow"><span>✎</span><span class="lab">备注</span><span class="val">园区食堂</span><span class="chev">›</span></div><div class="formRow"><span>▭</span><span class="lab">支付方式</span><span class="val">微信支付</span><span class="chev">›</span></div><div class="formRow"><span>□</span><span class="lab">时间</span><span class="val">今天 12:26</span><span class="chev">›</span></div></section><button class="primary">确认记账</button></div></div></article>
|
||
<article class="case"><header class="caseHead"><div><div class="idx">SCREEN 04</div><h2>统计 · 月报</h2><div class="note">业务图表使用品牌色,AI 摘要使用 AI 色</div></div></header><div class="phone"><div class="status"><span>9:41</span><span class="sys">◢ ▰</span></div><div class="screen"><div class="top"><div class="title">统计</div><div class="square">□</div></div><div class="months"><span>六月</span><b>2026 年 7 月</b><span>八月</span></div><div class="metrics"><section class="panel metric"><span>收入</span><b class="income">¥8,640</b></section><section class="panel metric"><span>支出</span><b class="out">¥4,353</b></section><section class="panel metric"><span>结余</span><b>¥4,286</b></section></div><section class="panel chartCard"><div class="section" style="margin-top:0"><b class="st">支出分类</b><span class="link">共 48 笔</span></div><div class="barRow"><span>餐饮</span><div class="bar"><i style="--w:78%"></i></div><b>¥1,420</b></div><div class="barRow"><span>购物</span><div class="bar"><i style="--w:54%"></i></div><b>¥986</b></div><div class="barRow"><span>交通</span><div class="bar"><i style="--w:34%"></i></div><b>¥628</b></div><div class="barRow"><span>居住</span><div class="bar"><i style="--w:26%"></i></div><b>¥480</b></div></section><section class="panel chartCard"><div class="section" style="margin-top:0"><b class="st">预算进度</b><span class="budgetVal">63%</span></div><div class="sub">本月预算 ¥6,200,剩余 ¥1,847</div><div class="track"><i></i></div></section><section class="panel aiReport"><div class="aiHead">✦ 小记月报</div><strong>这个月花得更稳了,结余比上月多 12%</strong><p>餐饮支出下降 186 元,交通预算仍有 372 元可用。以上金额均来自当前账本。</p></section></div><nav class="nav"><div><b>⌂</b><span>明细</span></div><div class="on"><b>▥</b><span>统计</span></div><div class="add"><div class="fab">+</div><span>记一笔</span></div><div><b>○</b><span>我的</span></div></nav></div></article>
|
||
<article class="case"><header class="caseHead"><div><div class="idx">SCREEN 05</div><h2>我的</h2><div class="note">账号、账本和数据入口</div></div></header><div class="phone"><div class="status"><span>9:41</span><span class="sys">◢ ▰</span></div><div class="screen"><div class="top"><div class="title">我的</div><div class="square">⚙</div></div><section class="panel profile"><div class="avatar">南</div><div><div class="profileName">南浔</div><div class="sub">已连续记账 26 天</div></div><span class="chev">›</span></section><section class="panel ledger"><div class="ledgerTop"><div class="ledgerName"><i class="dot"></i>日常账本</div><span class="link">切换</span></div><div class="ledgerStats"><div class="ledgerStat"><span>本月结余</span><b>¥4,286</b></div><div class="ledgerStat"><span>本月账单</span><b>48 笔</b></div></div></section><section class="panel settings"><div class="setting"><div class="ricon">预</div><div><b>预算管理</b><p>本月剩余 ¥1,847</p></div><span class="chev">›</span></div><div class="setting"><div class="ricon">类</div><div><b>分类管理</b><p>自定义图标与排序</p></div><span class="chev">›</span></div><div class="setting"><div class="ricon ai">AI</div><div><b>AI 伙伴</b><p>小记 · 理性陪伴</p></div><span class="chev">›</span></div></section><section class="panel settings"><div class="setting"><div class="ricon">本</div><div><b>账本管理</b><p>新建、重命名和切换</p></div><span class="chev">›</span></div><div class="setting"><div class="ricon">数</div><div><b>账号与数据</b><p>导出、密码与账号管理</p></div><span class="chev">›</span></div></section></div><nav class="nav"><div><b>⌂</b><span>明细</span></div><div><b>▥</b><span>统计</span></div><div class="add"><div class="fab">+</div><span>记一笔</span></div><div class="on"><b>○</b><span>我的</span></div></nav></div></article>
|
||
<article class="case"><header class="caseHead"><div><div class="idx">SCREEN 06</div><h2>截屏识别确认</h2><div class="note">多账单、时间和分类确认</div></div></header><div class="phone"><div class="status"><span>9:41</span><span class="sys">◢ ▰</span></div><div class="screen" style="padding-bottom:68px"><div class="top"><div class="square">‹</div><div class="title">确认识别结果</div><span class="action">2 笔</span></div><section class="panel captureState"><div class="stateMark">✓</div><div><b>图片解析完成</b><p>请核对金额、分类和原始交易时间</p></div></section><div class="warning"><span>△</span><span>第 2 笔只识别到日期,已使用当前时间,可点击时间重新选择。</span></div><section class="panel parsed"><div class="parsedHead"><span>账单 1</span><span class="confidence">识别可信</span></div><div class="parsedMain"><div class="cicon food">餐</div><div><b>午餐</b><div class="sub">美团支付 · 餐饮</div></div><div class="parsedAmount">- ¥32.80</div></div><div class="chips"><span class="chip">餐饮</span><span class="chip">7月18日 12:36</span><span class="chip">修改</span></div></section><section class="panel parsed"><div class="parsedHead"><span>账单 2</span><span class="confidence" style="color:var(--warning)">需核对时间</span></div><div class="parsedMain"><div class="cicon shopping">购</div><div><b>生活用品</b><div class="sub">支付宝 · 购物</div></div><div class="parsedAmount">- ¥86.50</div></div><div class="chips"><span class="chip">购物</span><span class="chip">今天 14:41</span><span class="chip">修改</span></div></section></div><div class="captureFooter"><button class="primary">确认保存 2 笔账单</button></div></div></article>
|
||
</section></main><script>
|
||
const tokenMeta = {
|
||
brand:['主品牌色','品牌与操作'], deep:['品牌深色','强调文字'], soft:['品牌浅底','选中背景'],
|
||
ai:['AI 标识色','AI 身份'], aiSoft:['AI 浅底','AI 卡片'], bg:['页面背景','App 底色'],
|
||
card:['卡片颜色','内容承载'], ink:['正文颜色','主文字'], muted:['次级文字','说明文字'],
|
||
faint:['弱文字','占位与图标'], line:['边框颜色','分割线'], expense:['支出颜色','金额与错误'],
|
||
warning:['警告颜色','需核对状态'], warningSoft:['警告浅底','提示背景']
|
||
};
|
||
const groups = [
|
||
['品牌与 AI',['brand','deep','soft','ai','aiSoft']],
|
||
['界面基础',['bg','card','ink','muted','faint','line']],
|
||
['业务语义',['expense','warning','warningSoft']]
|
||
];
|
||
const currentTheme = {brand:'#00B386',deep:'#009973',soft:'#E6F7F1',ai:'#5B6BF5',aiSoft:'#EEF0FE',bg:'#F6F7F9',card:'#FFFFFF',ink:'#191F26',muted:'#5E6772',faint:'#9AA3AD',line:'#EEF0F3',expense:'#F0642D',warning:'#F5A623',warningSoft:'#FFF7E8'};
|
||
const presets = [
|
||
{name:'当前薄荷',brand:'#00B386',deep:'#009973',soft:'#E6F7F1',ai:'#5B6BF5',aiSoft:'#EEF0FE',bg:'#F6F7F9',card:'#FFFFFF',ink:'#191F26',muted:'#5E6772',faint:'#9AA3AD',line:'#EEF0F3',expense:'#F0642D',warning:'#F5A623',warningSoft:'#FFF7E8'},
|
||
{name:'清晰蓝白',brand:'#2F6BFF',deep:'#2456D8',soft:'#EAF0FF',ai:'#4859B8',aiSoft:'#EEF0FA',bg:'#F5F7FA',card:'#FFFFFF',ink:'#172033',muted:'#667085',faint:'#98A2B3',line:'#E5E9F0',expense:'#D95040',warning:'#C88412',warningSoft:'#FFF5E3'},
|
||
{name:'暖纸橙棕',brand:'#C45D26',deep:'#9E451B',soft:'#FBECE4',ai:'#416A8A',aiSoft:'#EAF0F4',bg:'#F5F2EC',card:'#FFFEFB',ink:'#28231F',muted:'#746B62',faint:'#A39A91',line:'#E8E1D8',expense:'#C6473A',warning:'#A96A12',warningSoft:'#F8EDD9'},
|
||
{name:'墨黑工具',brand:'#25282C',deep:'#111315',soft:'#ECEEF0',ai:'#4967A9',aiSoft:'#EBEFF7',bg:'#F3F4F5',card:'#FFFFFF',ink:'#181A1D',muted:'#626A73',faint:'#9AA1A9',line:'#E3E6E9',expense:'#D24B3C',warning:'#B47717',warningSoft:'#F6EEDC'},
|
||
{name:'湖蓝青灰',brand:'#147D89',deep:'#0E626C',soft:'#E5F2F3',ai:'#536AA6',aiSoft:'#ECEFF8',bg:'#F3F6F6',card:'#FFFFFF',ink:'#192326',muted:'#647276',faint:'#98A3A6',line:'#E1E7E8',expense:'#D25443',warning:'#B87917',warningSoft:'#F7EFDC'},
|
||
{name:'柔和莓红',brand:'#B44B68',deep:'#913A53',soft:'#F9EAF0',ai:'#5668A9',aiSoft:'#ECEFF8',bg:'#F7F4F5',card:'#FFFFFF',ink:'#271D21',muted:'#74656B',faint:'#A5979D',line:'#EAE1E4',expense:'#C73F35',warning:'#B47717',warningSoft:'#F8EFDC'}
|
||
];
|
||
const root = document.documentElement;
|
||
const normalize = value => /^#[0-9a-f]{6}$/i.test(value) ? value.toUpperCase() : null;
|
||
/* HSL helpers */
|
||
function rgb(hex){const v=parseInt(hex.slice(1),16);return [(v>>16)&255,(v>>8)&255,v&255]}
|
||
function hslFromHex(hex){const[r,g,b]=rgb(hex).map(v=>v/255);const max=Math.max(r,g,b),min=Math.min(r,g,b);let h=0;const l=(max+min)/2;if(max!==min){const d=max-min;const s=l>.5?d/(2-max-min):d/(max+min);h=r===max?((g-b)/d+(g<b?6:0))/6:g===max?((b-r)/d+2)/6:((r-g)/d+4)/6;return[Math.round(h*360),Math.round(s*100),Math.round(l*100)]}return[0,0,Math.round(l*100)]}
|
||
function hexFromHsl(h,s,l){h/=360;s/=100;l/=100;const a=s*Math.min(l,1-l);const f=n=>{n=(n+h*12)%12;const t=Math.round((l-a*Math.max(-1,Math.min(n-3,9-n,1)))*255);return Math.max(0,Math.min(255,t))};return'#'+[f(0),f(8),f(4)].map(v=>v.toString(16).padStart(2,'0').toUpperCase()).join('')}
|
||
function luminance(hex){return rgb(hex).map(v=>{v/=255;return v<=.03928?v/12.92:Math.pow((v+.055)/1.055,2.4)}).reduce((sum,v,i)=>sum+v*[.2126,.7152,.0722][i],0)}
|
||
function ratio(a,b){const x=luminance(a),y=luminance(b);return (Math.max(x,y)+.05)/(Math.min(x,y)+.05)}
|
||
/* Core */
|
||
function setToken(key,value,persist=true){const hex=normalize(value);if(!hex)return false;root.style.setProperty('--'+key,hex);const color=document.querySelector(`[data-color="${key}"]`);const text=document.querySelector(`[data-text="${key}"]`);if(color)color.value=hex;if(text)text.value=hex;document.querySelectorAll(`[data-swatch="${key}"]`).forEach(el=>el.style.setProperty('--swatch',hex));if(persist)save();updateContrast();return true}
|
||
function applyTheme(theme,persist=true){Object.keys(tokenMeta).forEach(key=>setToken(key,theme[key]||currentTheme[key],false));document.querySelectorAll('.preset').forEach(button=>button.classList.toggle('active',button.dataset.name===theme.name));updateAllSliders();if(persist)save()}
|
||
function readTheme(){return Object.fromEntries(Object.keys(tokenMeta).map(key=>[key,getComputedStyle(root).getPropertyValue('--'+key).trim().toUpperCase()]))}
|
||
function save(){localStorage.setItem('jizhi-theme-studio',JSON.stringify(readTheme()))}
|
||
/* Render controls with HSL sliders per token */
|
||
function renderControls(){
|
||
document.getElementById('presets').innerHTML=presets.map(p=>`<button class="preset" data-name="${p.name}" style="--preview:${p.brand};--softPreview:${p.soft}"><i class="presetDot"></i>${p.name}</button>`).join('');
|
||
document.getElementById('tokenGroups').innerHTML=groups.map(([name,keys])=>`<section class="tokenGroup"><h3>${name}</h3>${keys.map(key=>`<div class="tokenBlock"><div class="tokenRow"><label>${tokenMeta[key][0]}</label><input type="color" data-color="${key}" aria-label="${tokenMeta[key][0]}"><input type="text" data-text="${key}" maxlength="7" aria-label="${tokenMeta[key][0]} HEX"></div><div class="tokenSliders"><label>色相</label><input type="range" data-hue="${key}" min="0" max="360" value="0" aria-label="色相"><span data-hue-val="${key}">0</span><label>饱和度</label><input type="range" data-sat="${key}" min="0" max="100" value="0" aria-label="饱和度"><span data-sat-val="${key}">0</span><label>明度</label><input type="range" data-lit="${key}" min="0" max="100" value="0" aria-label="明度"><span data-lit-val="${key}">0</span></div></div>`).join('')}</section>`).join('');
|
||
}
|
||
function updateSliders(key){
|
||
const el = document.querySelector(`[data-text="${key}"]`); if (!el) return;
|
||
const hex = normalize(el.value); if (!hex) return;
|
||
const [h,s,l] = hslFromHex(hex);
|
||
const kinds = ['hue','sat','lit'];
|
||
[h,s,l].forEach((v,i) => {
|
||
const slider = document.querySelector(`[data-${kinds[i]}="${key}"]`);
|
||
const span = document.querySelector(`[data-${kinds[i]}-val="${key}"]`);
|
||
if (slider) slider.value = v;
|
||
if (span) span.textContent = v;
|
||
});
|
||
}
|
||
function updateAllSliders(){Object.keys(tokenMeta).forEach(key=>updateSliders(key))}
|
||
function updateContrast(){const t=readTheme();const checks=[['正文 / 卡片',t.ink,t.card,4.5],['次文 / 卡片',t.muted,t.card,4.5],['白字 / 主色','#FFFFFF',t.brand,4.5],['支出 / 卡片',t.expense,t.card,3]];document.getElementById('contrastGrid').innerHTML=checks.map(([name,a,b,min])=>{const value=ratio(a,b);return `<div class="contrastItem ${value>=min?'pass':'fail'}"><span>${name}</span><b>${value.toFixed(2)} : 1</b></div>`}).join('')}
|
||
function toast(message){const el=document.getElementById('toast');el.textContent=message;el.classList.add('show');clearTimeout(window.toastTimer);window.toastTimer=setTimeout(()=>el.classList.remove('show'),1600)}
|
||
renderControls();
|
||
/* Events */
|
||
document.getElementById('presets').addEventListener('click',event=>{const button=event.target.closest('.preset');if(!button)return;const preset=presets.find(item=>item.name===button.dataset.name);applyTheme(preset);toast('已应用 '+preset.name)});
|
||
// color picker / hex text
|
||
document.getElementById('tokenGroups').addEventListener('input',event=>{const key=event.target.dataset.color||event.target.dataset.text;if(!key)return;setToken(key,event.target.value);updateSliders(key)});
|
||
document.getElementById('tokenGroups').addEventListener('change',event=>{const key=event.target.dataset.text;if(key&&!setToken(key,event.target.value)){event.target.value=readTheme()[key];toast('请输入 6 位十六进制颜色')}});
|
||
// H / S / L sliders —— build hex on the fly
|
||
document.getElementById('tokenGroups').addEventListener('input',event=>{
|
||
const kind = event.target.dataset.hue !== undefined ? 'hue' : event.target.dataset.sat !== undefined ? 'sat' : event.target.dataset.lit !== undefined ? 'lit' : null;
|
||
if (!kind) return;
|
||
const key = event.target.dataset[kind]; if (!key) return;
|
||
const hue = document.querySelector(`[data-hue="${key}"]`);
|
||
const sat = document.querySelector(`[data-sat="${key}"]`);
|
||
const lit = document.querySelector(`[data-lit="${key}"]`);
|
||
if (!hue || !sat || !lit) return;
|
||
const h = parseInt(hue.value), s = parseInt(sat.value), l = parseInt(lit.value);
|
||
const hex = hexFromHsl(h, s, l); if (!hex) return;
|
||
setToken(key, hex);
|
||
document.querySelector(`[data-color="${key}"]`).value = hex;
|
||
document.querySelector(`[data-hue-val="${key}"]`).textContent = h;
|
||
document.querySelector(`[data-sat-val="${key}"]`).textContent = s;
|
||
document.querySelector(`[data-lit-val="${key}"]`).textContent = l;
|
||
});
|
||
document.getElementById('resetTheme').addEventListener('click',()=>{localStorage.removeItem('jizhi-theme-studio');applyTheme({...currentTheme,name:'当前薄荷'});toast('已恢复当前 App 配色')});
|
||
document.getElementById('copyTheme').addEventListener('click',async()=>{await navigator.clipboard.writeText(JSON.stringify(readTheme(),null,2));toast('色板 JSON 已复制')});
|
||
document.getElementById('studioToggle').addEventListener('click',()=>document.getElementById('studio').classList.toggle('open'));
|
||
let stored=null;try{stored=JSON.parse(localStorage.getItem('jizhi-theme-studio'))}catch(_){stored=null}applyTheme(stored&&Object.keys(stored).length?stored:{...currentTheme,name:'当前薄荷'},false);
|
||
</script></body></html>
|