feat(fe): 建立设计 token 层,收敛圆角/字号/字重/阴影/配色

改的是 app.wxss 里既有 class 的「值」,类名一个没动——全局类被 28 种弹层
和 9 个页面共同依赖,改名要动约 180 处 class,漏一处的后果是元素完全
裸奔(无 padding 无背景),不报错、不在 diff 里,只在用户点开某个特定
弹层时才暴露。

token:
- 圆角 22 种 → 5 档(xs12/sm20/md28/lg40/full)
- 字号 26 档 → 6 档(22/24/28/32/40/48)
- 字重 700/800/900 混用 → 只留 400/600,强调改靠颜色和字号
- 阴影 7 处一次性写法 → 3 档,且整体压轻(0 24rpx 60rpx .08 → 0 12rpx 32rpx .06)
- 9 种近似浅橙 → 一个 --primary-soft;4 个语义色补齐 soft/base/ink 三件套
- 7 种硬编码正文灰 → --text-2;卡内次级底色 → --surface-2

新增(没有往旧类上塞,避免语义冲突):
- .btn-dark 深色主 CTA。.btn-primary 保持暖橙不动——它有 36 处使用、
  绝大多数是弹层里的「保存」,改成深色会让全站主色消失
- .tone-1~4 四色分类块、.chip 状态标、.empty 空态(原本 6 套写法散在各页)

按钮渐变改实色,主色更稳;圆角整体收小,视觉更利落。
preview-v2.html 由 app.wxss 自动翻译生成(rpx→px),已逐块截图核对。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-29 10:34:24 +08:00
parent b99099759f
commit 91caac1b92
2 changed files with 631 additions and 142 deletions
+168 -103
View File
@@ -1,35 +1,81 @@
/* ===== 全局设计令牌 + 通用样式(由 preview.html 迁移,px→rpx ×2 ===== */
/* ===== 全局设计令牌 + 通用样式 =====
规则:任何页面/组件都不要再写死色值、圆角、字号,一律用下面的 token。
收敛前的现状是 22 种圆角、26 档字号、9 种近似浅橙、7 处一次性阴影,
font-weight 900 到处都是——什么都在喊,于是什么都不突出。 */
page{
/* ── 底色与文字 ── */
--bg:#F8F6F2;
--bg2:#FBF8F3;
--card:#FFFFFF;
--surface-2:#FBFAF8; /* 卡片内的次级底色(原本硬编码出现 10+ 次) */
--text:#2D2925;
--text-2:#5F554D; /* 正文次级灰(原本有 7 种近似值散落各处) */
--muted:#8D8277;
--muted2:#B5A99D;
--line:#EEE6DC;
/* ── 主色 ── */
--primary:#F5A947;
--primary2:#FFBF68;
--primary-dark:#DD8420;
--green:#73BE9D;
--green-soft:#EAF7F1;
--red:#EE7D73;
--red-soft:#FFF0EE;
--blue:#78A6E8;
--blue-soft:#EEF5FF;
--purple:#A993E8;
--purple-soft:#F4F0FF;
--primary-soft:#FFF4E4; /* 唯一的浅橙底(收编了 9 种近似值) */
--primary-line:#FFD6A1; /* 浅橙块的描边 */
--primary-ink:#A96500; /* 浅橙底上的文字 */
/* ── 语义色:soft 底 / base 主体 / ink 文字,三件套配齐 ── */
--green:#73BE9D; --green-soft:#EAF7F1; --green-ink:#2E7D5B;
--red:#EE7D73; --red-soft:#FFF0EE; --red-ink:#C95348;
--blue:#78A6E8; --blue-soft:#EEF5FF; --blue-ink:#3C6EBA;
--purple:#A993E8; --purple-soft:#F4F0FF; --purple-ink:#765AC5;
--yellow-soft:#FFF6E4;
--shadow:0 24rpx 60rpx rgba(70,48,25,.08);
--shadow2:0 36rpx 88rpx rgba(70,48,25,.13);
--radius:44rpx;
/* ── 深色主 CTA。全页最多一个,用来指明「这一步该点哪」 ── */
--cta:#2D2925;
/* ── 圆角 5 档 ── */
--r-xs:12rpx;
--r-sm:20rpx;
--r-md:28rpx;
--r-lg:40rpx; /* 卡片 */
--r-full:999rpx;
--radius:var(--r-lg); /* 兼容旧名,页面里还有引用 */
/* ── 字号 6 档 ── */
--fs-cap:22rpx;
--fs-sm:24rpx;
--fs-md:28rpx;
--fs-lg:32rpx;
--fs-xl:40rpx;
--fs-2xl:48rpx;
/* ── 字重只留两档。强调靠颜色和字号,不靠把所有东西都加粗 ── */
--fw:400;
--fw-b:600;
/* ── 间距 6 档 ── */
--sp-1:8rpx; --sp-2:12rpx; --sp-3:16rpx;
--sp-4:24rpx; --sp-5:32rpx; --sp-6:40rpx;
/* ── 控件高度 3 档 ── */
--h-sm:68rpx;
--h-md:80rpx;
--h-lg:96rpx;
/* ── 阴影 3 档(原来 7 处一次性阴影,且都偏重) ── */
--sd-1:0 12rpx 32rpx rgba(70,48,25,.06);
--sd-2:0 20rpx 48rpx rgba(70,48,25,.10);
--sd-3:0 -20rpx 60rpx rgba(70,48,25,.14);
--shadow:var(--sd-1); /* 兼容旧名 */
--shadow2:var(--sd-2);
/* 页面留白。FAB 固定在 bottom:190rpx、高 116rpx,上沿距底 306rpx
内容必须让开这段距离,否则最后一张卡会被它压住(7 个挂 FAB 的页面都中过这个招)。 */
内容必须让开这段距离,否则最后一张卡会被它压住。 */
--pad-x:40rpx;
--pad-b-fab:calc(330rpx + env(safe-area-inset-bottom));
--pad-b-plain:calc(60rpx + env(safe-area-inset-bottom));
color:var(--text);
font-weight:var(--fw);
font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","PingFang SC","Microsoft YaHei",sans-serif;
background:
radial-gradient(circle at 10% 8%, rgba(245,169,71,.26), transparent 30%),
@@ -48,7 +94,7 @@ view,text{box-sizing:border-box}
/* 页面骨架:nav-bar → .page-scroll(承载滚动) → .page-body(内容留白) */
.page-scroll{flex:1;min-height:0}
.page-body{padding:8rpx var(--pad-x) var(--pad-b-fab)}
.page-body{padding:var(--sp-1) var(--pad-x) var(--pad-b-fab)}
/* 没挂 FAB 的页面(目前只有文章详情)不需要给它让位 */
.page-body.no-fab{padding-bottom:var(--pad-b-plain)}
@@ -65,204 +111,223 @@ page{scrollbar-width:none;-ms-overflow-style:none}
/* 文本 */
.muted{color:var(--muted)}
.tiny{font-size:24rpx;color:var(--muted)}
.tiny{font-size:var(--fs-sm);color:var(--muted)}
.bold{font-weight:var(--fw-b)}
/* 区块标题 */
.section-head{
display:flex;align-items:center;justify-content:space-between;margin:8rpx 0 24rpx;
display:flex;align-items:center;justify-content:space-between;margin:var(--sp-1) 0 var(--sp-4);
}
.section-head .sh-title{font-size:36rpx;letter-spacing:-.4rpx;font-weight:700}
.link{
color:var(--primary-dark);font-weight:900;font-size:26rpx;
}
.head-links{display:flex;align-items:center;gap:26rpx}
.section-head .sh-title{font-size:var(--fs-lg);letter-spacing:-.4rpx;font-weight:var(--fw-b)}
.link{color:var(--primary-dark);font-weight:var(--fw-b);font-size:var(--fs-md)}
.head-links{display:flex;align-items:center;gap:var(--sp-4)}
/* 页面标题。
注意:小程序没有 h2/p/b/span 标签,从 preview.html 迁移来的标签选择器全是死规则,
各页当初都自建了替身 class(.pt-h2 在 5 个文件里逐字重复)这里统一收编。 */
.page-title{margin:4rpx 0 28rpx}
.pt-h2{font-size:46rpx;letter-spacing:-.6rpx;font-weight:800}
.pt-p{color:var(--muted);font-size:26rpx;margin-top:10rpx}
小程序没有 h2/p/b/span 标签,从 preview.html 迁移来的标签选择器全是死规则,
各页当初都自建了替身 class(.pt-h2 在 5 个文件里逐字重复)这里统一收编。 */
.page-title{margin:4rpx 0 var(--sp-4)}
.pt-h2{font-size:var(--fs-2xl);letter-spacing:-.6rpx;font-weight:var(--fw-b)}
.pt-p{color:var(--muted);font-size:var(--fs-md);margin-top:10rpx}
/* 按钮 */
.btn{
border:0;height:96rpx;border-radius:34rpx;padding:0 32rpx;
display:inline-flex;align-items:center;justify-content:center;gap:16rpx;
font-weight:900;font-size:30rpx;line-height:96rpx;transition:.16s ease;
border:0;height:var(--h-lg);border-radius:var(--r-md);padding:0 var(--sp-5);
display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
font-weight:var(--fw-b);font-size:var(--fs-lg);line-height:var(--h-lg);transition:.16s ease;
}
.btn::after{border:none}
.btn:active{transform:scale(.98)}
.btn-primary{
color:#fff;background:linear-gradient(135deg,var(--primary),var(--primary2));
box-shadow:0 24rpx 48rpx rgba(245,169,71,.28);
}
/* 主按钮保持暖橙:它在 36 处被使用,绝大多数是弹层里的「保存」,
把它改成深色会让整个 App 的主色消失。深色 CTA 走 .btn-dark。 */
.btn-primary{color:#fff;background:var(--primary);box-shadow:0 12rpx 28rpx rgba(245,169,71,.24)}
.btn-dark{color:#fff;background:var(--cta)}
.btn-ghost{color:var(--text);background:#fff;border:1rpx solid var(--line)}
.btn-soft{color:#9E6200;background:var(--yellow-soft)}
.btn-green{color:#fff;background:linear-gradient(135deg,#69B991,#86CEB0)}
.btn-soft{color:var(--primary-ink);background:var(--primary-soft)}
.btn-green{color:#fff;background:var(--green)}
.btn-block{width:100%;display:flex}
.btn-small{height:68rpx;border-radius:24rpx;padding:0 22rpx;font-size:24rpx;line-height:68rpx}
.btn-small{height:var(--h-sm);border-radius:var(--r-sm);padding:0 var(--sp-4);font-size:var(--fs-sm);line-height:var(--h-sm)}
/* 卡片 */
.card{
background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
padding:32rpx;margin-bottom:28rpx;position:relative;overflow:hidden;
background:var(--card);border-radius:var(--r-lg);box-shadow:var(--sd-1);
padding:var(--sp-5);margin-bottom:var(--sp-4);position:relative;overflow:hidden;
}
.card.no-shadow{box-shadow:none;border:1rpx solid var(--line)}
/* 标签 */
.tag{
display:inline-flex;align-items:center;height:48rpx;border-radius:999rpx;padding:0 18rpx;
font-size:24rpx;font-weight:900;background:var(--green-soft);color:#377A61;white-space:nowrap;
display:inline-flex;align-items:center;height:48rpx;border-radius:var(--r-full);padding:0 var(--sp-3);
font-size:var(--fs-sm);font-weight:var(--fw-b);background:var(--green-soft);color:var(--green-ink);white-space:nowrap;
}
.tag.warn{background:#FFF0D7;color:#A96500}
.tag.red{background:var(--red-soft);color:#C95348}
.tag.blue{background:var(--blue-soft);color:#3C6EBA}
.tag.purple{background:var(--purple-soft);color:#765AC5}
.tag.warn{background:var(--primary-soft);color:var(--primary-ink)}
.tag.red{background:var(--red-soft);color:var(--red-ink)}
.tag.blue{background:var(--blue-soft);color:var(--blue-ink)}
.tag.purple{background:var(--purple-soft);color:var(--purple-ink)}
/* 状态 chip:比 tag 矮,可带图标,用于「体重稳定」「驱虫将到期」这类瞬时状态 */
.chip{
display:inline-flex;align-items:center;gap:var(--sp-1);height:44rpx;padding:0 var(--sp-3);
border-radius:var(--r-full);font-size:var(--fs-cap);font-weight:var(--fw-b);
background:var(--primary-soft);color:var(--primary-ink);white-space:nowrap;
}
.chip.green{background:var(--green-soft);color:var(--green-ink)}
.chip.red{background:var(--red-soft);color:var(--red-ink)}
.chip.blue{background:var(--blue-soft);color:var(--blue-ink)}
/* 4 色分类块。用在快速记录入口这类并列的功能格上,靠颜色区分类别而不是靠 emoji */
.tone-1{background:var(--primary-soft);color:var(--primary-ink)}
.tone-2{background:var(--green-soft);color:var(--green-ink)}
.tone-3{background:var(--blue-soft);color:var(--blue-ink)}
.tone-4{background:var(--purple-soft);color:var(--purple-ink)}
/* 空态。原本有 6 套长得差不多的写法散在各页 */
.empty{padding:56rpx var(--sp-1);text-align:center;color:var(--muted);font-size:var(--fs-sm)}
.empty.lg{padding:96rpx 0}
/* 表单 */
.field{margin-bottom:28rpx}
.field{margin-bottom:var(--sp-4)}
.field:last-child{margin-bottom:0}
.field label{display:block;font-size:26rpx;color:var(--muted);font-weight:800;margin-bottom:16rpx}
.field label{display:block;font-size:var(--fs-md);color:var(--muted);font-weight:var(--fw-b);margin-bottom:var(--sp-3)}
.input,input,textarea,.picker-box{
width:100%;border:1rpx solid var(--line);background:#FBFAF8;height:88rpx;border-radius:30rpx;
padding:0 26rpx;color:var(--text);font-size:30rpx;outline:none;box-sizing:border-box;
width:100%;border:1rpx solid var(--line);background:var(--surface-2);height:88rpx;border-radius:var(--r-md);
padding:0 var(--sp-4);color:var(--text);font-size:var(--fs-lg);outline:none;box-sizing:border-box;
display:flex;align-items:center;
}
.textarea{
width:100%;border:1rpx solid var(--line);background:#FBFAF8;height:184rpx;border-radius:30rpx;
padding:24rpx 26rpx;color:var(--text);font-size:30rpx;box-sizing:border-box;
width:100%;border:1rpx solid var(--line);background:var(--surface-2);height:184rpx;border-radius:var(--r-md);
padding:var(--sp-4);color:var(--text);font-size:var(--fs-lg);box-sizing:border-box;
}
.placeholder{color:var(--muted2)}
/* 分段选择 */
.seg{display:flex;gap:16rpx}
.seg{display:flex;gap:var(--sp-3)}
.seg .seg-btn{
flex:1;height:80rpx;line-height:80rpx;text-align:center;border-radius:26rpx;
border:1rpx solid var(--line);background:#fff;color:var(--muted);font-weight:800;font-size:28rpx;
flex:1;height:var(--h-md);line-height:var(--h-md);text-align:center;border-radius:var(--r-md);
border:1rpx solid var(--line);background:#fff;color:var(--muted);font-weight:var(--fw-b);font-size:var(--fs-md);
}
.seg .seg-btn.selected{color:var(--primary-dark);background:#FFF2DC;border-color:#FFD39A}
.seg .seg-btn.selected{color:var(--primary-dark);background:var(--primary-soft);border-color:var(--primary-line)}
/* 多选 check */
.check-list{display:flex;flex-direction:column;gap:20rpx;margin:32rpx 0}
.check-list{display:flex;flex-direction:column;gap:var(--sp-3);margin:var(--sp-5) 0}
.check{
display:flex;align-items:center;gap:20rpx;background:#fff;box-shadow:var(--shadow);
border-radius:32rpx;padding:26rpx;border:1rpx solid transparent;font-size:28rpx;font-weight:700;
display:flex;align-items:center;gap:var(--sp-3);background:#fff;box-shadow:var(--sd-1);
border-radius:var(--r-md);padding:var(--sp-4);border:1rpx solid transparent;font-size:var(--fs-md);font-weight:var(--fw-b);
}
.box{
width:44rpx;height:44rpx;border-radius:16rpx;border:4rpx solid #DDCEC1;
width:44rpx;height:44rpx;border-radius:var(--r-xs);border:4rpx solid #DDCEC1;
display:flex;align-items:center;justify-content:center;color:#fff;flex:none;
font-size:26rpx;font-weight:900;
font-size:var(--fs-md);font-weight:var(--fw-b);
}
.check.selected{background:#FFF8EC;border-color:#FFD29A}
.check.selected{background:var(--primary-soft);border-color:var(--primary-line)}
.check.selected .box{background:var(--primary);border-color:var(--primary)}
/* 圆形/条形选项 */
.mini-options{display:flex;flex-wrap:wrap;gap:16rpx;margin:20rpx 0 28rpx}
.mini-options{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin:var(--sp-3) 0 var(--sp-4)}
.option{
border:1rpx solid var(--line);background:#fff;border-radius:999rpx;height:68rpx;line-height:68rpx;
padding:0 24rpx;color:#5F554D;font-weight:800;font-size:24rpx;
border:1rpx solid var(--line);background:#fff;border-radius:var(--r-full);height:var(--h-sm);line-height:var(--h-sm);
padding:0 var(--sp-4);color:var(--text-2);font-weight:var(--fw-b);font-size:var(--fs-sm);
}
.option.selected{background:#FFF2DC;color:var(--primary-dark);border-color:#FFD39A}
.option.selected{background:var(--primary-soft);color:var(--primary-dark);border-color:var(--primary-line)}
/* 进度条 */
.progress-row{
display:flex;align-items:center;justify-content:space-between;margin-bottom:16rpx;
font-size:26rpx;color:#6A5D52;font-weight:900;
display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sp-3);
font-size:var(--fs-md);color:var(--text-2);font-weight:var(--fw-b);
}
.bar{height:20rpx;border-radius:999rpx;background:#F0E7DD;overflow:hidden}
.bar{height:var(--sp-3);border-radius:var(--r-full);background:#F0E7DD;overflow:hidden}
.bar .bar-fill{
height:100%;border-radius:999rpx;
height:100%;border-radius:var(--r-full);
background:linear-gradient(90deg,var(--primary),#FFD57F);display:block;transition:.25s ease;
}
/* 头像 */
.avatar{
width:120rpx;height:120rpx;border-radius:44rpx;
width:120rpx;height:120rpx;border-radius:var(--r-lg);
background:linear-gradient(135deg,#FFE5B7,#FFC06B);
display:flex;align-items:center;justify-content:center;font-size:64rpx;
box-shadow:0 24rpx 52rpx rgba(245,169,71,.18);flex:none;
box-shadow:var(--sd-1);flex:none;
}
/* 多宠切换 */
.pet-switch{display:flex;gap:20rpx;overflow-x:auto;padding:0 0 24rpx;white-space:nowrap}
.pet-switch{display:flex;gap:var(--sp-3);overflow-x:auto;padding:0 0 var(--sp-4);white-space:nowrap}
.pet-switch::-webkit-scrollbar{display:none}
.pet-chip{
flex:none;display:inline-flex;border:1rpx solid var(--line);background:#fff;border-radius:40rpx;
padding:18rpx 24rpx;align-items:center;gap:16rpx;color:var(--muted);font-weight:900;font-size:28rpx;
box-shadow:0 12rpx 36rpx rgba(70,48,25,.05);
flex:none;display:inline-flex;border:1rpx solid var(--line);background:#fff;border-radius:var(--r-full);
padding:var(--sp-2) var(--sp-4);align-items:center;gap:var(--sp-2);color:var(--muted);font-weight:var(--fw-b);font-size:var(--fs-md);
}
.pet-chip.active{color:var(--primary-dark);background:#FFF4E4;border-color:#FFD6A1}
.pet-chip.active{color:var(--primary-dark);background:var(--primary-soft);border-color:var(--primary-line)}
.pet-chip .mini-avatar{
width:56rpx;height:56rpx;border-radius:20rpx;display:flex;align-items:center;
width:52rpx;height:52rpx;border-radius:var(--r-sm);display:flex;align-items:center;
justify-content:center;background:#FFE4B7;font-size:30rpx;
}
/* 任务列表 */
.task-list{display:flex;flex-direction:column;gap:20rpx}
.task{display:flex;gap:20rpx;align-items:flex-start;background:#FBFAF8;border-radius:32rpx;padding:24rpx;transition:.15s ease}
.task-list{display:flex;flex-direction:column;gap:var(--sp-2)}
.task{display:flex;gap:var(--sp-3);align-items:flex-start;background:var(--surface-2);border-radius:var(--r-md);padding:var(--sp-4);transition:.15s ease}
.circle{
width:46rpx;height:46rpx;border-radius:50%;border:4rpx solid #DED1C4;display:flex;
align-items:center;justify-content:center;color:#fff;font-size:24rpx;flex:none;margin-top:2rpx;font-weight:900;
width:44rpx;height:44rpx;border-radius:50%;border:4rpx solid #DED1C4;display:flex;
align-items:center;justify-content:center;color:#fff;font-size:var(--fs-sm);flex:none;margin-top:2rpx;
}
.task.done{opacity:.55}
.task.done .circle{background:var(--green);border-color:var(--green)}
.task-text{flex:1}
.tt-b{font-size:28rpx;font-weight:700}
.tt-p{font-size:24rpx;color:var(--muted);margin-top:8rpx;line-height:1.45}
.tt-b{font-size:var(--fs-md);font-weight:var(--fw-b)}
.tt-p{font-size:var(--fs-sm);color:var(--muted);margin-top:var(--sp-1);line-height:1.45}
.priority{
font-size:22rpx;color:#A96500;background:#FFF0D7;border-radius:999rpx;padding:8rpx 14rpx;font-weight:900;flex:none;
font-size:var(--fs-cap);color:var(--primary-ink);background:var(--primary-soft);
border-radius:var(--r-full);padding:6rpx var(--sp-2);font-weight:var(--fw-b);flex:none;
}
/* 记录行 */
.record-row{
display:flex;justify-content:space-between;align-items:center;padding:24rpx 0;
border-bottom:1rpx solid var(--line);font-size:26rpx;
display:flex;justify-content:space-between;align-items:center;padding:var(--sp-4) 0;
border-bottom:1rpx solid var(--line);font-size:var(--fs-md);
}
.record-row:last-child{border-bottom:0}
/* 统计格 */
.stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16rpx;margin:28rpx 0}
.stat{background:#fff;border:1rpx solid var(--line);border-radius:32rpx;padding:24rpx 14rpx;text-align:center}
.stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3);margin:var(--sp-4) 0}
.stat{background:#fff;border:1rpx solid var(--line);border-radius:var(--r-md);padding:var(--sp-4) var(--sp-2);text-align:center}
/* 文章卡 */
.article-card{
display:flex;gap:24rpx;background:#fff;border-radius:40rpx;padding:26rpx;box-shadow:var(--shadow);margin-bottom:24rpx;
display:flex;gap:var(--sp-4);background:#fff;border-radius:var(--r-lg);padding:var(--sp-4);box-shadow:var(--sd-1);margin-bottom:var(--sp-4);
}
.article-icon{
width:116rpx;height:116rpx;border-radius:36rpx;flex:none;display:flex;align-items:center;
justify-content:center;background:#FFF1D8;font-size:56rpx;
width:104rpx;height:104rpx;border-radius:var(--r-md);flex:none;display:flex;align-items:center;
justify-content:center;background:var(--primary-soft);color:var(--primary-ink);font-size:48rpx;
}
.ac-b{font-size:30rpx;font-weight:700}
.ac-p{color:var(--muted);font-size:24rpx;line-height:1.45;margin-top:10rpx}
.ac-b{font-size:var(--fs-lg);font-weight:var(--fw-b)}
.ac-p{color:var(--muted);font-size:var(--fs-sm);line-height:1.45;margin-top:10rpx}
/* 海报 */
.poster{
background:
radial-gradient(circle at 100% 0%, rgba(245,169,71,.24), transparent 35%),
linear-gradient(160deg,#FFF7E8,#FFFFFF);
border:1rpx solid #F2DFC3;border-radius:52rpx;padding:36rpx;text-align:center;overflow:hidden;position:relative;
border:1rpx solid #F2DFC3;border-radius:var(--r-lg);padding:var(--sp-5);text-align:center;overflow:hidden;position:relative;
}
.poster-avatar{
width:152rpx;height:152rpx;margin:16rpx auto 20rpx;border-radius:54rpx;
width:152rpx;height:152rpx;margin:var(--sp-3) auto var(--sp-3);border-radius:var(--r-lg);
background:linear-gradient(135deg,#FFE5B7,#FFC06B);display:flex;align-items:center;justify-content:center;
font-size:80rpx;box-shadow:0 24rpx 52rpx rgba(245,169,71,.20);
font-size:80rpx;box-shadow:var(--sd-1);
}
.poster-list{
background:rgba(255,255,255,.78);border-radius:32rpx;padding:24rpx;margin:28rpx 0;text-align:left;line-height:1.8;font-size:26rpx;
background:rgba(255,255,255,.78);border-radius:var(--r-md);padding:var(--sp-4);margin:var(--sp-4) 0;text-align:left;line-height:1.8;font-size:var(--fs-md);
}
/* 风险盒 */
.risk-box{
background:#FFF0D8;color:#A96500;padding:24rpx;border-radius:32rpx;font-weight:900;
display:flex;gap:18rpx;margin-bottom:24rpx;align-items:center;
background:var(--primary-soft);color:var(--primary-ink);padding:var(--sp-4);border-radius:var(--r-md);font-weight:var(--fw-b);
display:flex;gap:var(--sp-3);margin-bottom:var(--sp-4);align-items:center;
}
/* 弹层内动作行 */
.sheet-actions{display:flex;gap:20rpx;margin-top:24rpx}
.sheet-actions{display:flex;gap:var(--sp-3);margin-top:var(--sp-4)}
.sheet-actions .btn{flex:1}
/* 聊天气泡 */
.plan-chat{display:flex;flex-direction:column;gap:20rpx;margin-bottom:24rpx}
.msg{max-width:88%;border-radius:36rpx;padding:22rpx 26rpx;font-size:26rpx;line-height:1.55}
.msg.ai{background:#F3F8F5;align-self:flex-start}
.msg.user{background:#FFF1D8;align-self:flex-end}
.plan-chat{display:flex;flex-direction:column;gap:var(--sp-3);margin-bottom:var(--sp-4)}
.msg{max-width:88%;border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-md);line-height:1.55}
.msg.ai{background:var(--green-soft);align-self:flex-start}
.msg.user{background:var(--primary-soft);align-self:flex-end}
+463 -39
View File
@@ -2,32 +2,35 @@
<meta charset="utf-8">
<title>肉垫计划 · 设计预览 v2</title>
<!--
这是给「人和 Claude 都能看见」的设计验证页,不参与小程序打包(见 project.config.json 的 packOptions.ignore)。
换算:1px = 2rpx。这里定死 token 数值和门面版式,再翻译进 app.wxss。
设计验证页:由 app.wxss 自动翻译而来(rpx→px,÷2),不参与小程序打包
(见 project.config.json 的 packOptions.ignore)。改 app.wxss 后重新生成即可
-->
<style>
body{font-family:-apple-system,"PingFang SC",sans-serif;background:#F8F6F2;color:#2D2925;margin:0;padding:28px 32px 60px}
h2{font-size:17px;font-weight:600;margin:34px 0 6px}
body{font-family:-apple-system,"PingFang SC",sans-serif;background:#F1EEE8;color:#2D2925;margin:0;padding:28px 32px 80px}
h2{font-size:17px;font-weight:600;margin:36px 0 6px}
h2:first-of-type{margin-top:0}
.hint{font-size:12px;color:#8D8277;margin:0 0 16px}
.pt-i{display:inline-block;-webkit-mask-image:var(--m);mask-image:var(--m);
-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;
-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;width:1em;height:1em;vertical-align:-.125em}
.hint{font-size:12px;color:#8D8277;margin:8px 0 14px}
.wall{display:grid;grid-template-columns:repeat(10,1fr);gap:16px 8px;max-width:760px}
.cell{text-align:center;font-size:10px;color:#8D8277}
.cell .pt-i{font-size:20px;color:#2D2925;display:block;margin:0 auto 6px}
.cell .pt-i{width:20px;height:20px;color:#2D2925;display:block;margin:0 auto 6px}
.sizes span{margin-right:26px}
.s16{font-size:16px}.s20{font-size:20px}.s24{font-size:24px}.s28{font-size:28px}
.tones{display:grid;grid-template-columns:repeat(4,116px);gap:12px}
.tone{border-radius:20px;padding:14px 0;text-align:center;font-size:12px}
.t1{background:#FFF4E4;color:#A96500}.t2{background:#EAF7F1;color:#2E7D5B}
.t3{background:#EEF5FF;color:#3C6EBA}.t4{background:#F4F0FF;color:#765AC5}
.tone .pt-i{font-size:24px;display:block;margin:0 auto 6px}
.dark{background:#2D2925;color:#fff;border-radius:20px;padding:13px 22px;display:inline-block;font-size:14px}
.row{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.stage{max-width:375px;background:#F8F6F2;border-radius:16px;padding:14px}
.grid4{display:grid;grid-template-columns:repeat(4,88px);gap:9px}
.qk{border-radius:16px;padding:12px 0;display:flex;flex-direction:column;align-items:center;gap:6px;font-size:12px;font-weight:600}
.stat-b{display:block;font-size:18px;font-weight:600;margin-bottom:4px}
.stat-s{font-size:11px;color:#8D8277}
.tabbar{display:flex;max-width:375px;background:#fff;border-top:1px solid #EEE6DC;border-radius:0 0 12px 12px}
.tb{flex:1;text-align:center;padding:9px 0 12px;font-size:10px;color:#8D8277}
.tb.on{color:#DD8420}
.tb .pt-i{font-size:21px;display:block;margin:0 auto 3px}
.tb .pt-i{width:21px;height:21px;display:block;margin:0 auto 3px}
.dark{background:#2D2925;color:#fff;border-radius:20px;padding:13px 22px;display:inline-block;font-size:14px}
.pt-i{display:inline-block;flex:none;background-color:currentColor;
-webkit-mask-image:var(--m);mask-image:var(--m);
-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
-webkit-mask-position:center;mask-position:center;
-webkit-mask-size:100% 100%;mask-size:100% 100%;vertical-align:-.15em}
.pt-i-weight{--m:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPjxwYXRoIGQ9Ik03IDIwbDEwIDAiIC8+PHBhdGggZD0iTTYgNmw2IC0xbDYgMSIgLz48cGF0aCBkPSJNMTIgM2wwIDE3IiAvPjxwYXRoIGQ9Ik05IDEybC0zIC02bC0zIDZhMyAzIDAgMCAwIDYgMCIgLz48cGF0aCBkPSJNMjEgMTJsLTMgLTZsLTMgNmEzIDMgMCAwIDAgNiAwIiAvPjwvc3ZnPg==")}
.pt-i-poop{--m:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPjxwYXRoIGQ9Ik0xMCAxMmguMDEiIC8+PHBhdGggZD0iTTE0IDEyaC4wMSIgLz48cGF0aCBkPSJNMTAgMTZhMy41IDMuNSAwIDAgMCA0IDAiIC8+PHBhdGggZD0iTTExIDRjMiAwIDMuNSAxLjUgMy41IDRsLjE2NCAwYTIuNSAyLjUgMCAwIDEgMi4xOTYgMy4zMmEzIDMgMCAwIDEgMS42MTUgMy4wNjNhMyAzIDAgMCAxIC0xLjI5OSA1LjYwN2wtLjE3NiAwaC0xMGEzIDMgMCAwIDEgLTEuNDc0IC01LjYxM2EzIDMgMCAwIDEgMS42MTUgLTMuMDYyYTIuNSAyLjUgMCAwIDEgMi4xOTUgLTMuMzJsLjE2NCAwYzEuNSAwIDIuNSAtMiAxLjUgLTRsMCAuMDA1IiAvPjwvc3ZnPg==")}
.pt-i-food{--m:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPjxwYXRoIGQ9Ik00IDExaDE2YTEgMSAwIDAgMSAxIDF2LjVjMCAxLjUgLTIuNTE3IDUuNTczIC00IDYuNXYxYTEgMSAwIDAgMSAtMSAxaC04YTEgMSAwIDAgMSAtMSAtMXYtMWMtMS42ODcgLTEuMDU0IC00IC01IC00IC02LjV2LS41YTEgMSAwIDAgMSAxIC0xIiAvPjxwYXRoIGQ9Ik04IDdjMS42NTcgMCAzIC0uODk1IDMgLTJzLTEuMzQzIC0yIC0zIC0ycy0zIC44OTUgLTMgMnMxLjM0MyAyIDMgMiIgLz48cGF0aCBkPSJNMTEgNWg5IiAvPjwvc3ZnPg==")}
@@ -66,35 +69,357 @@ h2:first-of-type{margin-top:0}
.pt-i-dog{--m:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPjxwYXRoIGQ9Ik0xMSA1aDIiIC8+PHBhdGggZD0iTTE5IDEyYy0uNjY3IDUuMzMzIC0yLjMzMyA4IC01IDhoLTRjLTIuNjY3IDAgLTQuMzMzIC0yLjY2NyAtNSAtOCIgLz48cGF0aCBkPSJNMTEgMTZjMCAuNjY3IC4zMzMgMSAxIDFzMSAtLjMzMyAxIC0xaC0yIiAvPjxwYXRoIGQ9Ik0xMiAxOHYyIiAvPjxwYXRoIGQ9Ik0xMCAxMXYuMDEiIC8+PHBhdGggZD0iTTE0IDExdi4wMSIgLz48cGF0aCBkPSJNNSA0bDYgLjk3bC02LjIzOCA2LjY4OGExLjAyMSAxLjAyMSAwIDAgMSAtMS40MSAuMTExYS45NTMgLjk1MyAwIDAgMSAtLjMyNyAtLjk1NGwxLjk3NSAtNi44MTUiIC8+PHBhdGggZD0iTTE5IDRsLTYgLjk3bDYuMjM4IDYuNjg4Yy4zNTggLjQwOCAuOTg5IC40NTggMS40MSAuMTExYS45NTMgLjk1MyAwIDAgMCAuMzI3IC0uOTU0bC0xLjk3NSAtNi44MTUiIC8+PC9zdmc+")}
.pt-i-user{--m:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPjxwYXRoIGQ9Ik04IDdhNCA0IDAgMSAwIDggMGE0IDQgMCAwIDAgLTggMCIgLz48cGF0aCBkPSJNNiAyMXYtMmE0IDQgMCAwIDEgNCAtNGg0YTQgNCAwIDAgMSA0IDR2MiIgLz48L3N2Zz4=")}
.pt-i-clock{--m:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgPjxwYXRoIGQ9Ik0zIDEyYTkgOSAwIDEgMCAxOCAwYTkgOSAwIDAgMCAtMTggMCIgLz48cGF0aCBkPSJNMTIgN3Y1bDMgMyIgLz48L3N2Zz4=")}
</style>
<h2>1 · 图标全集(38 个,20px ≈ 40rpx</h2>
<p class="hint">来源 Tabler Icons (MIT)。用 mask-image + currentColor,不是字体——Tabler 是描边图标,转字体要先展开轮廓,漏了会生成空字形。</p>
<div class="wall">
<div class="cell"><i class="pt-i pt-i-weight"></i><span>weight</span></div><div class="cell"><i class="pt-i pt-i-poop"></i><span>poop</span></div><div class="cell"><i class="pt-i pt-i-food"></i><span>food</span></div><div class="cell"><i class="pt-i pt-i-symptom"></i><span>symptom</span></div><div class="cell"><i class="pt-i pt-i-medicine"></i><span>medicine</span></div><div class="cell"><i class="pt-i pt-i-cost"></i><span>cost</span></div><div class="cell"><i class="pt-i pt-i-vaccine"></i><span>vaccine</span></div><div class="cell"><i class="pt-i pt-i-deworm"></i><span>deworm</span></div><div class="cell"><i class="pt-i pt-i-photo"></i><span>photo</span></div><div class="cell"><i class="pt-i pt-i-home"></i><span>home</span></div><div class="cell"><i class="pt-i pt-i-plan"></i><span>plan</span></div><div class="cell"><i class="pt-i pt-i-record"></i><span>record</span></div><div class="cell"><i class="pt-i pt-i-report"></i><span>report</span></div><div class="cell"><i class="pt-i pt-i-community"></i><span>community</span></div><div class="cell"><i class="pt-i pt-i-back"></i><span>back</span></div><div class="cell"><i class="pt-i pt-i-next"></i><span>next</span></div><div class="cell"><i class="pt-i pt-i-plus"></i><span>plus</span></div><div class="cell"><i class="pt-i pt-i-check"></i><span>check</span></div><div class="cell"><i class="pt-i pt-i-close"></i><span>close</span></div><div class="cell"><i class="pt-i pt-i-trash"></i><span>trash</span></div><div class="cell"><i class="pt-i pt-i-edit"></i><span>edit</span></div><div class="cell"><i class="pt-i pt-i-share"></i><span>share</span></div><div class="cell"><i class="pt-i pt-i-comment"></i><span>comment</span></div><div class="cell"><i class="pt-i pt-i-like"></i><span>like</span></div><div class="cell"><i class="pt-i pt-i-like-on"></i><span>like-on</span></div><div class="cell"><i class="pt-i pt-i-more"></i><span>more</span></div><div class="cell"><i class="pt-i pt-i-bell"></i><span>bell</span></div><div class="cell"><i class="pt-i pt-i-settings"></i><span>settings</span></div><div class="cell"><i class="pt-i pt-i-ai"></i><span>ai</span></div><div class="cell"><i class="pt-i pt-i-warn"></i><span>warn</span></div><div class="cell"><i class="pt-i pt-i-doc"></i><span>doc</span></div><div class="cell"><i class="pt-i pt-i-note"></i><span>note</span></div><div class="cell"><i class="pt-i pt-i-book"></i><span>book</span></div><div class="cell"><i class="pt-i pt-i-trend"></i><span>trend</span></div><div class="cell"><i class="pt-i pt-i-cat"></i><span>cat</span></div><div class="cell"><i class="pt-i pt-i-dog"></i><span>dog</span></div><div class="cell"><i class="pt-i pt-i-user"></i><span>user</span></div><div class="cell"><i class="pt-i pt-i-clock"></i><span>clock</span></div></div>
/* ===== 全局设计令牌 + 通用样式 =====
规则:任何页面/组件都不要再写死色值、圆角、字号,一律用下面的 token。
收敛前的现状是 22 种圆角、26 档字号、9 种近似浅橙、7 处一次性阴影,
font-weight 900 到处都是——什么都在喊,于是什么都不突出。 */
.mp{
/* ── 底色与文字 ── */
--bg:#F8F6F2;
--bg2:#FBF8F3;
--card:#FFFFFF;
--surface-2:#FBFAF8; /* 卡片内的次级底色(原本硬编码出现 10+ 次) */
--text:#2D2925;
--text-2:#5F554D; /* 正文次级灰(原本有 7 种近似值散落各处) */
--muted:#8D8277;
--muted2:#B5A99D;
--line:#EEE6DC;
/* ── 主色 ── */
--primary:#F5A947;
--primary2:#FFBF68;
--primary-dark:#DD8420;
--primary-soft:#FFF4E4; /* 唯一的浅橙底(收编了 9 种近似值) */
--primary-line:#FFD6A1; /* 浅橙块的描边 */
--primary-ink:#A96500; /* 浅橙底上的文字 */
/* ── 语义色:soft 底 / base 主体 / ink 文字,三件套配齐 ── */
--green:#73BE9D; --green-soft:#EAF7F1; --green-ink:#2E7D5B;
--red:#EE7D73; --red-soft:#FFF0EE; --red-ink:#C95348;
--blue:#78A6E8; --blue-soft:#EEF5FF; --blue-ink:#3C6EBA;
--purple:#A993E8; --purple-soft:#F4F0FF; --purple-ink:#765AC5;
--yellow-soft:#FFF6E4;
/* ── 深色主 CTA。全页最多一个,用来指明「这一步该点哪」 ── */
--cta:#2D2925;
/* ── 圆角 5 档 ── */
--r-xs:6px;
--r-sm:10px;
--r-md:14px;
--r-lg:20px; /* 卡片 */
--r-full:499.5px;
--radius:var(--r-lg); /* 兼容旧名,页面里还有引用 */
/* ── 字号 6 档 ── */
--fs-cap:11px;
--fs-sm:12px;
--fs-md:14px;
--fs-lg:16px;
--fs-xl:20px;
--fs-2xl:24px;
/* ── 字重只留两档。强调靠颜色和字号,不靠把所有东西都加粗 ── */
--fw:400;
--fw-b:600;
/* ── 间距 6 档 ── */
--sp-1:4px; --sp-2:6px; --sp-3:8px;
--sp-4:12px; --sp-5:16px; --sp-6:20px;
/* ── 控件高度 3 档 ── */
--h-sm:34px;
--h-md:40px;
--h-lg:48px;
/* ── 阴影 3 档(原来 7 处一次性阴影,且都偏重) ── */
--sd-1:0 6px 16px rgba(70,48,25,.06);
--sd-2:0 10px 24px rgba(70,48,25,.10);
--sd-3:0 -10px 30px rgba(70,48,25,.14);
--shadow:var(--sd-1); /* 兼容旧名 */
--shadow2:var(--sd-2);
/* 页面留白。FAB 固定在 bottom:95px、高 58px,上沿距底 153px
内容必须让开这段距离,否则最后一张卡会被它压住。 */
--pad-x:20px;
--pad-b-fab:calc(165px + 0px);
--pad-b-plain:calc(30px + 0px);
color:var(--text);
font-weight:var(--fw);
font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","PingFang SC","Microsoft YaHei",sans-serif;
background:
radial-gradient(circle at 10% 8%, rgba(245,169,71,.26), transparent 30%),
radial-gradient(circle at 88% 10%, rgba(115,190,157,.20), transparent 26%),
radial-gradient(circle at 72% 88%, rgba(120,166,232,.14), transparent 28%),
linear-gradient(135deg,#FBF5EA,#EEF6F1 55%,#F8F1E7);
/* 页面自身不滚,滚动交给 .page-scroll,这样 nav-bar 和 tabBar 才能固定住。
这 4 行原本在 9 个页面的 wxss 里逐字重复。 */
display:flex;
flex-direction:column;
}
view,text{box-sizing:border-box}
/* 页面骨架:nav-bar → .page-scroll(承载滚动) → .page-body(内容留白) */
.page-scroll{flex:1;min-height:0}
.page-body{padding:var(--sp-1) var(--pad-x) var(--pad-b-fab)}
/* 没挂 FAB 的页面(目前只有文章详情)不需要给它让位 */
.page-body.no-fab{padding-bottom:var(--pad-b-plain)}
/* 全局隐藏滚动条(页面级 + 组件级),保留正常滚动 */
::-webkit-scrollbar{
width:0 !important;
height:0 !important;
display:none;
-webkit-appearance:none;
background:transparent;
color:transparent;
}
/* 文本 */
.muted{color:var(--muted)}
.tiny{font-size:var(--fs-sm);color:var(--muted)}
.bold{font-weight:var(--fw-b)}
/* 区块标题 */
.section-head{
display:flex;align-items:center;justify-content:space-between;margin:var(--sp-1) 0 var(--sp-4);
}
.section-head .sh-title{font-size:var(--fs-lg);letter-spacing:-0.2px;font-weight:var(--fw-b)}
.link{color:var(--primary-dark);font-weight:var(--fw-b);font-size:var(--fs-md)}
.head-links{display:flex;align-items:center;gap:var(--sp-4)}
/* 页面标题。
小程序没有 h2/p/b/span 标签,从 preview.html 迁移来的标签选择器全是死规则,
各页当初都自建了替身 class(.pt-h2 在 5 个文件里逐字重复),这里统一收编。 */
.page-title{margin:2px 0 var(--sp-4)}
.pt-h2{font-size:var(--fs-2xl);letter-spacing:-0.3px;font-weight:var(--fw-b)}
.pt-p{color:var(--muted);font-size:var(--fs-md);margin-top:5px}
/* 按钮 */
.btn{
border:0;height:var(--h-lg);border-radius:var(--r-md);padding:0 var(--sp-5);
display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
font-weight:var(--fw-b);font-size:var(--fs-lg);line-height:var(--h-lg);transition:.16s ease;
}
.btn::after{border:none}
.btn:active{transform:scale(.98)}
/* 主按钮保持暖橙:它在 36 处被使用,绝大多数是弹层里的「保存」,
把它改成深色会让整个 App 的主色消失。深色 CTA 走 .btn-dark。 */
.btn-primary{color:#fff;background:var(--primary);box-shadow:0 6px 14px rgba(245,169,71,.24)}
.btn-dark{color:#fff;background:var(--cta)}
.btn-ghost{color:var(--text);background:#fff;border:0.5px solid var(--line)}
.btn-soft{color:var(--primary-ink);background:var(--primary-soft)}
.btn-green{color:#fff;background:var(--green)}
.btn-block{width:100%;display:flex}
.btn-small{height:var(--h-sm);border-radius:var(--r-sm);padding:0 var(--sp-4);font-size:var(--fs-sm);line-height:var(--h-sm)}
/* 卡片 */
.card{
background:var(--card);border-radius:var(--r-lg);box-shadow:var(--sd-1);
padding:var(--sp-5);margin-bottom:var(--sp-4);position:relative;overflow:hidden;
}
.card.no-shadow{box-shadow:none;border:0.5px solid var(--line)}
/* 标签 */
.tag{
display:inline-flex;align-items:center;height:24px;border-radius:var(--r-full);padding:0 var(--sp-3);
font-size:var(--fs-sm);font-weight:var(--fw-b);background:var(--green-soft);color:var(--green-ink);white-space:nowrap;
}
.tag.warn{background:var(--primary-soft);color:var(--primary-ink)}
.tag.red{background:var(--red-soft);color:var(--red-ink)}
.tag.blue{background:var(--blue-soft);color:var(--blue-ink)}
.tag.purple{background:var(--purple-soft);color:var(--purple-ink)}
/* 状态 chip:比 tag 矮,可带图标,用于「体重稳定」「驱虫将到期」这类瞬时状态 */
.chip{
display:inline-flex;align-items:center;gap:var(--sp-1);height:22px;padding:0 var(--sp-3);
border-radius:var(--r-full);font-size:var(--fs-cap);font-weight:var(--fw-b);
background:var(--primary-soft);color:var(--primary-ink);white-space:nowrap;
}
.chip.green{background:var(--green-soft);color:var(--green-ink)}
.chip.red{background:var(--red-soft);color:var(--red-ink)}
.chip.blue{background:var(--blue-soft);color:var(--blue-ink)}
/* 4 色分类块。用在快速记录入口这类并列的功能格上,靠颜色区分类别而不是靠 emoji */
.tone-1{background:var(--primary-soft);color:var(--primary-ink)}
.tone-2{background:var(--green-soft);color:var(--green-ink)}
.tone-3{background:var(--blue-soft);color:var(--blue-ink)}
.tone-4{background:var(--purple-soft);color:var(--purple-ink)}
/* 空态。原本有 6 套长得差不多的写法散在各页 */
.empty{padding:28px var(--sp-1);text-align:center;color:var(--muted);font-size:var(--fs-sm)}
.empty.lg{padding:48px 0}
/* 表单 */
.field{margin-bottom:var(--sp-4)}
.field:last-child{margin-bottom:0}
.field label{display:block;font-size:var(--fs-md);color:var(--muted);font-weight:var(--fw-b);margin-bottom:var(--sp-3)}
.input,input,textarea,.picker-box{
width:100%;border:0.5px solid var(--line);background:var(--surface-2);height:44px;border-radius:var(--r-md);
padding:0 var(--sp-4);color:var(--text);font-size:var(--fs-lg);outline:none;box-sizing:border-box;
display:flex;align-items:center;
}
.textarea{
width:100%;border:0.5px solid var(--line);background:var(--surface-2);height:92px;border-radius:var(--r-md);
padding:var(--sp-4);color:var(--text);font-size:var(--fs-lg);box-sizing:border-box;
}
.placeholder{color:var(--muted2)}
/* 分段选择 */
.seg{display:flex;gap:var(--sp-3)}
.seg .seg-btn{
flex:1;height:var(--h-md);line-height:var(--h-md);text-align:center;border-radius:var(--r-md);
border:0.5px solid var(--line);background:#fff;color:var(--muted);font-weight:var(--fw-b);font-size:var(--fs-md);
}
.seg .seg-btn.selected{color:var(--primary-dark);background:var(--primary-soft);border-color:var(--primary-line)}
/* 多选 check */
.check-list{display:flex;flex-direction:column;gap:var(--sp-3);margin:var(--sp-5) 0}
.check{
display:flex;align-items:center;gap:var(--sp-3);background:#fff;box-shadow:var(--sd-1);
border-radius:var(--r-md);padding:var(--sp-4);border:0.5px solid transparent;font-size:var(--fs-md);font-weight:var(--fw-b);
}
.box{
width:22px;height:22px;border-radius:var(--r-xs);border:2px solid #DDCEC1;
display:flex;align-items:center;justify-content:center;color:#fff;flex:none;
font-size:var(--fs-md);font-weight:var(--fw-b);
}
.check.selected{background:var(--primary-soft);border-color:var(--primary-line)}
.check.selected .box{background:var(--primary);border-color:var(--primary)}
/* 圆形/条形选项 */
.mini-options{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin:var(--sp-3) 0 var(--sp-4)}
.option{
border:0.5px solid var(--line);background:#fff;border-radius:var(--r-full);height:var(--h-sm);line-height:var(--h-sm);
padding:0 var(--sp-4);color:var(--text-2);font-weight:var(--fw-b);font-size:var(--fs-sm);
}
.option.selected{background:var(--primary-soft);color:var(--primary-dark);border-color:var(--primary-line)}
/* 进度条 */
.progress-row{
display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sp-3);
font-size:var(--fs-md);color:var(--text-2);font-weight:var(--fw-b);
}
.bar{height:var(--sp-3);border-radius:var(--r-full);background:#F0E7DD;overflow:hidden}
.bar .bar-fill{
height:100%;border-radius:var(--r-full);
background:linear-gradient(90deg,var(--primary),#FFD57F);display:block;transition:.25s ease;
}
/* 头像 */
.avatar{
width:60px;height:60px;border-radius:var(--r-lg);
background:linear-gradient(135deg,#FFE5B7,#FFC06B);
display:flex;align-items:center;justify-content:center;font-size:32px;
box-shadow:var(--sd-1);flex:none;
}
/* 多宠切换 */
.pet-switch{display:flex;gap:var(--sp-3);overflow-x:auto;padding:0 0 var(--sp-4);white-space:nowrap}
.pet-switch::-webkit-scrollbar{display:none}
.pet-chip{
flex:none;display:inline-flex;border:0.5px solid var(--line);background:#fff;border-radius:var(--r-full);
padding:var(--sp-2) var(--sp-4);align-items:center;gap:var(--sp-2);color:var(--muted);font-weight:var(--fw-b);font-size:var(--fs-md);
}
.pet-chip.active{color:var(--primary-dark);background:var(--primary-soft);border-color:var(--primary-line)}
.pet-chip .mini-avatar{
width:26px;height:26px;border-radius:var(--r-sm);display:flex;align-items:center;
justify-content:center;background:#FFE4B7;font-size:15px;
}
/* 任务列表 */
.task-list{display:flex;flex-direction:column;gap:var(--sp-2)}
.task{display:flex;gap:var(--sp-3);align-items:flex-start;background:var(--surface-2);border-radius:var(--r-md);padding:var(--sp-4);transition:.15s ease}
.circle{
width:22px;height:22px;border-radius:50%;border:2px solid #DED1C4;display:flex;
align-items:center;justify-content:center;color:#fff;font-size:var(--fs-sm);flex:none;margin-top:1px;
}
.task.done{opacity:.55}
.task.done .circle{background:var(--green);border-color:var(--green)}
.task-text{flex:1}
.tt-b{font-size:var(--fs-md);font-weight:var(--fw-b)}
.tt-p{font-size:var(--fs-sm);color:var(--muted);margin-top:var(--sp-1);line-height:1.45}
.priority{
font-size:var(--fs-cap);color:var(--primary-ink);background:var(--primary-soft);
border-radius:var(--r-full);padding:3px var(--sp-2);font-weight:var(--fw-b);flex:none;
}
/* 记录行 */
.record-row{
display:flex;justify-content:space-between;align-items:center;padding:var(--sp-4) 0;
border-bottom:0.5px solid var(--line);font-size:var(--fs-md);
}
.record-row:last-child{border-bottom:0}
/* 统计格 */
.stats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3);margin:var(--sp-4) 0}
.stat{background:#fff;border:0.5px solid var(--line);border-radius:var(--r-md);padding:var(--sp-4) var(--sp-2);text-align:center}
/* 文章卡 */
.article-card{
display:flex;gap:var(--sp-4);background:#fff;border-radius:var(--r-lg);padding:var(--sp-4);box-shadow:var(--sd-1);margin-bottom:var(--sp-4);
}
.article-icon{
width:52px;height:52px;border-radius:var(--r-md);flex:none;display:flex;align-items:center;
justify-content:center;background:var(--primary-soft);color:var(--primary-ink);font-size:24px;
}
.ac-b{font-size:var(--fs-lg);font-weight:var(--fw-b)}
.ac-p{color:var(--muted);font-size:var(--fs-sm);line-height:1.45;margin-top:5px}
/* 海报 */
.poster{
background:
radial-gradient(circle at 100% 0%, rgba(245,169,71,.24), transparent 35%),
linear-gradient(160deg,#FFF7E8,#FFFFFF);
border:0.5px solid #F2DFC3;border-radius:var(--r-lg);padding:var(--sp-5);text-align:center;overflow:hidden;position:relative;
}
.poster-avatar{
width:76px;height:76px;margin:var(--sp-3) auto var(--sp-3);border-radius:var(--r-lg);
background:linear-gradient(135deg,#FFE5B7,#FFC06B);display:flex;align-items:center;justify-content:center;
font-size:40px;box-shadow:var(--sd-1);
}
.poster-list{
background:rgba(255,255,255,.78);border-radius:var(--r-md);padding:var(--sp-4);margin:var(--sp-4) 0;text-align:left;line-height:1.8;font-size:var(--fs-md);
}
/* 风险盒 */
.risk-box{
background:var(--primary-soft);color:var(--primary-ink);padding:var(--sp-4);border-radius:var(--r-md);font-weight:var(--fw-b);
display:flex;gap:var(--sp-3);margin-bottom:var(--sp-4);align-items:center;
}
/* 弹层内动作行 */
.sheet-actions{display:flex;gap:var(--sp-3);margin-top:var(--sp-4)}
.sheet-actions .btn{flex:1}
/* 聊天气泡 */
.plan-chat{display:flex;flex-direction:column;gap:var(--sp-3);margin-bottom:var(--sp-4)}
.msg{max-width:88%;border-radius:var(--r-md);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-md);line-height:1.55}
.msg.ai{background:var(--green-soft);align-self:flex-start}
.msg.user{background:var(--primary-soft);align-self:flex-end}
</style>
<body class="mp">
<h2>1 · 图标全集(38 个)</h2>
<p class="hint">来源 Tabler Icons (MIT)。mask-image + currentColor,不是字体——Tabler 是描边图标,转字体要先展开轮廓,漏了会生成空字形。</p>
<div class="wall"><div class="cell"><i class="pt-i pt-i-weight"></i><span>weight</span></div><div class="cell"><i class="pt-i pt-i-poop"></i><span>poop</span></div><div class="cell"><i class="pt-i pt-i-food"></i><span>food</span></div><div class="cell"><i class="pt-i pt-i-symptom"></i><span>symptom</span></div><div class="cell"><i class="pt-i pt-i-medicine"></i><span>medicine</span></div><div class="cell"><i class="pt-i pt-i-cost"></i><span>cost</span></div><div class="cell"><i class="pt-i pt-i-vaccine"></i><span>vaccine</span></div><div class="cell"><i class="pt-i pt-i-deworm"></i><span>deworm</span></div><div class="cell"><i class="pt-i pt-i-photo"></i><span>photo</span></div><div class="cell"><i class="pt-i pt-i-home"></i><span>home</span></div><div class="cell"><i class="pt-i pt-i-plan"></i><span>plan</span></div><div class="cell"><i class="pt-i pt-i-record"></i><span>record</span></div><div class="cell"><i class="pt-i pt-i-report"></i><span>report</span></div><div class="cell"><i class="pt-i pt-i-community"></i><span>community</span></div><div class="cell"><i class="pt-i pt-i-back"></i><span>back</span></div><div class="cell"><i class="pt-i pt-i-next"></i><span>next</span></div><div class="cell"><i class="pt-i pt-i-plus"></i><span>plus</span></div><div class="cell"><i class="pt-i pt-i-check"></i><span>check</span></div><div class="cell"><i class="pt-i pt-i-close"></i><span>close</span></div><div class="cell"><i class="pt-i pt-i-trash"></i><span>trash</span></div><div class="cell"><i class="pt-i pt-i-edit"></i><span>edit</span></div><div class="cell"><i class="pt-i pt-i-share"></i><span>share</span></div><div class="cell"><i class="pt-i pt-i-comment"></i><span>comment</span></div><div class="cell"><i class="pt-i pt-i-like"></i><span>like</span></div><div class="cell"><i class="pt-i pt-i-like-on"></i><span>like-on</span></div><div class="cell"><i class="pt-i pt-i-more"></i><span>more</span></div><div class="cell"><i class="pt-i pt-i-bell"></i><span>bell</span></div><div class="cell"><i class="pt-i pt-i-settings"></i><span>settings</span></div><div class="cell"><i class="pt-i pt-i-ai"></i><span>ai</span></div><div class="cell"><i class="pt-i pt-i-warn"></i><span>warn</span></div><div class="cell"><i class="pt-i pt-i-doc"></i><span>doc</span></div><div class="cell"><i class="pt-i pt-i-note"></i><span>note</span></div><div class="cell"><i class="pt-i pt-i-book"></i><span>book</span></div><div class="cell"><i class="pt-i pt-i-trend"></i><span>trend</span></div><div class="cell"><i class="pt-i pt-i-cat"></i><span>cat</span></div><div class="cell"><i class="pt-i pt-i-dog"></i><span>dog</span></div><div class="cell"><i class="pt-i pt-i-user"></i><span>user</span></div><div class="cell"><i class="pt-i pt-i-clock"></i><span>clock</span></div></div>
<h2>2 · 尺寸可读性</h2>
<p class="hint">32rpx(16px) 是正文里最常用的尺寸,重点看这一档描边够不够清楚。</p>
<div class="sizes">
<span class="s16"><i class="pt-i pt-i-weight"></i> 16px / 32rpx</span>
<span class="s20"><i class="pt-i pt-i-weight"></i> 20px / 40rpx</span>
<span class="s24"><i class="pt-i pt-i-weight"></i> 24px / 48rpx</span>
<span class="s28"><i class="pt-i pt-i-weight"></i> 28px / 56rpx</span>
<span><i class="pt-i pt-i-weight" style="width:16px;height:16px"></i> 16px / 32rpx</span>
<span><i class="pt-i pt-i-weight" style="width:20px;height:20px"></i> 20px / 40rpx</span>
<span><i class="pt-i pt-i-weight" style="width:24px;height:24px"></i> 24px / 48rpx</span>
<span><i class="pt-i pt-i-weight" style="width:28px;height:28px"></i> 28px / 56rpx</span>
</div>
<h2>3 · currentColor 染色 · 4 色分类块</h2>
<p class="hint">图标颜色跟随文字色,选中态只改一个 color 即可,emoji 做不到这点。</p>
<div class="tones">
<div class="tone t1"><i class="pt-i pt-i-weight"></i>体重</div>
<div class="tone t2"><i class="pt-i pt-i-food"></i>饮食</div>
<div class="tone t3"><i class="pt-i pt-i-symptom"></i>异常</div>
<div class="tone t4"><i class="pt-i pt-i-photo"></i>照片</div>
</div>
<h2>4 · 深色 CTA 上反白</h2>
<div class="dark"><i class="pt-i pt-i-ai"></i> 问问 AI 养宠助手</div>
<h2>5 · tabBar(替换 🏠📅✍️📊🐾)</h2>
<h2>3 · tabBar</h2>
<div class="tabbar">
<div class="tb on"><i class="pt-i pt-i-home"></i>首页</div>
<div class="tb"><i class="pt-i pt-i-plan"></i>计划</div>
@@ -102,3 +427,102 @@ h2:first-of-type{margin-top:0}
<div class="tb"><i class="pt-i pt-i-report"></i>报告</div>
<div class="tb"><i class="pt-i pt-i-community"></i>社区</div>
</div>
<h2>4 · 圆角 5 档</h2>
<div class="row">
<span class="tag" style="border-radius:var(--r-xs)">xs 12</span>
<span class="tag" style="border-radius:var(--r-sm)">sm 20</span>
<span class="tag" style="border-radius:var(--r-md)">md 28</span>
<span class="tag" style="border-radius:var(--r-lg)">lg 40</span>
<span class="tag" style="border-radius:var(--r-full)">full</span>
</div>
<h2>5 · 字号 6 档 / 字重只留两档</h2>
<div>
<div style="font-size:var(--fs-2xl);font-weight:var(--fw-b)">2xl 48 · 页面大标题</div>
<div style="font-size:var(--fs-xl);font-weight:var(--fw-b)">xl 40 · 卡片主数值</div>
<div style="font-size:var(--fs-lg);font-weight:var(--fw-b)">lg 32 · 小标题与按钮</div>
<div style="font-size:var(--fs-md)">md 28 · 正文</div>
<div style="font-size:var(--fs-sm);color:var(--muted)">sm 24 · 辅助说明</div>
<div style="font-size:var(--fs-cap);color:var(--muted)">cap 22 · 角标</div>
</div>
<h2>6 · 按钮</h2>
<div class="row">
<div class="btn btn-primary">保存记录</div>
<div class="btn btn-dark"><i class="pt-i pt-i-ai" style="width:16px;height:16px"></i> 问问 AI</div>
<div class="btn btn-ghost">取消</div>
<div class="btn btn-soft">开通 Pro</div>
<div class="btn btn-small">管理</div>
</div>
<p class="hint">主按钮保持暖橙:它有 36 处使用、绝大多数是弹层里的「保存」,改成深色会让全站主色消失。深色只给页面级首要 CTA。</p>
<h2>7 · 标签 / 状态 chip / 4 色分类块</h2>
<div class="row">
<span class="tag">已完成</span><span class="tag warn">待处理</span>
<span class="tag red">异常</span><span class="tag blue">经验</span><span class="tag purple">精选</span>
</div>
<div class="row" style="margin-top:10px">
<span class="chip"><i class="pt-i pt-i-trend" style="width:12px;height:12px"></i> 体重稳定</span>
<span class="chip green"><i class="pt-i pt-i-check" style="width:12px;height:12px"></i> 任务全清</span>
<span class="chip red"><i class="pt-i pt-i-warn" style="width:12px;height:12px"></i> 驱虫将到期</span>
</div>
<div class="grid4" style="margin-top:14px">
<div class="qk tone-1"><i class="pt-i pt-i-weight" style="width:22px;height:22px"></i><span>体重</span></div>
<div class="qk tone-2"><i class="pt-i pt-i-food" style="width:22px;height:22px"></i><span>饮食</span></div>
<div class="qk tone-3"><i class="pt-i pt-i-symptom" style="width:22px;height:22px"></i><span>异常</span></div>
<div class="qk tone-4"><i class="pt-i pt-i-photo" style="width:22px;height:22px"></i><span>照片</span></div>
</div>
<h2>8 · 卡片 / 任务 / 统计 / 进度</h2>
<div class="stage">
<div class="card">
<div class="section-head"><span class="sh-title">今日任务</span><span class="link">管理</span></div>
<div class="task-list">
<div class="task done"><span class="circle"><i class="pt-i pt-i-check" style="width:11px;height:11px"></i></span><div class="task-text"><div class="tt-b">早餐喂食</div><div class="tt-p">已完成</div></div></div>
<div class="task"><span class="circle"></span><div class="task-text"><div class="tt-b">记录体重</div><div class="tt-p">上次 4.2kg,建议每周一次</div></div><span class="priority">重要</span></div>
</div>
</div>
<div class="card">
<div class="progress-row"><span>本周完成度</span><span>72%</span></div>
<div class="bar"><div class="bar-fill" style="width:72%"></div></div>
<div class="stats-grid">
<div class="stat"><div class="stat-b">9</div><div class="stat-s">记录</div></div>
<div class="stat"><div class="stat-b">4.2</div><div class="stat-s">体重kg</div></div>
<div class="stat"><div class="stat-b">12</div><div class="stat-s">距驱虫</div></div>
</div>
<div class="record-row"><span class="bold">疫苗进度</span><span class="muted">3/4 已完成</span></div>
<div class="record-row"><span class="bold">驱虫状态</span><span class="muted">12 天后到期</span></div>
</div>
</div>
<h2>9 · 表单族(弹层里 28 种 type 全靠这几个类)</h2>
<div class="stage">
<div class="card">
<div class="field"><label>体重 (kg)</label><div class="input">4.2</div></div>
<div class="field"><label>状态</label>
<div class="seg"><div class="seg-btn selected">正常</div><div class="seg-btn">软便</div><div class="seg-btn">拉稀</div></div>
</div>
<div class="field"><label>症状</label>
<div class="mini-options"><span class="option selected">呕吐</span><span class="option">拉稀</span><span class="option">精神差</span><span class="option">皮肤红</span></div>
</div>
<div class="field"><label>备注</label><div class="textarea placeholder">写点什么…</div></div>
<div class="check-list">
<div class="check selected"><span class="box"><i class="pt-i pt-i-check" style="width:11px;height:11px"></i></span>健康档案与体重趋势</div>
<div class="check"><span class="box"></span>AI 深度分析</div>
</div>
<div class="sheet-actions"><div class="btn btn-ghost">取消</div><div class="btn btn-primary">保存</div></div>
</div>
</div>
<h2>10 · 其它公共块</h2>
<div class="stage">
<div class="card">
<div class="risk-box"><i class="pt-i pt-i-warn" style="width:18px;height:18px"></i> 风险中 · 建议观察 24 小时</div>
<div class="article-card no-shadow"><div class="article-icon"><i class="pt-i pt-i-vaccine" style="width:24px;height:24px"></i></div><div><div class="ac-b">幼猫疫苗怎么打</div><div class="ac-p">首免、二免、三免的时间点和注意事项</div></div></div>
<div class="plan-chat"><div class="msg ai">小橘最近体重稳定,继续保持现在的喂食量就好。</div><div class="msg user">那驱虫呢?</div></div>
<div class="empty">还没有记录,来记第一笔吧</div>
</div>
</div>